diff --git a/app/assets/images/icons/check-circle.svg b/app/assets/images/icons/check-circle.svg
new file mode 100644
index 00000000..b29ec55d
--- /dev/null
+++ b/app/assets/images/icons/check-circle.svg
@@ -0,0 +1 @@
+
diff --git a/app/assets/images/icons/circle.svg b/app/assets/images/icons/circle.svg
new file mode 100644
index 00000000..e5c5512f
--- /dev/null
+++ b/app/assets/images/icons/circle.svg
@@ -0,0 +1 @@
+
diff --git a/app/components/SeatFilter.js b/app/components/SeatFilter.js
new file mode 100644
index 00000000..9be21de8
--- /dev/null
+++ b/app/components/SeatFilter.js
@@ -0,0 +1,55 @@
+import React from 'react'
+import SVG from 'react-inlinesvg';
+import uncheckedSvg from '../assets/images/icons/circle.svg'
+import checkedSvg from '../assets/images/icons/check-circle.svg'
+
+const MaxRadioButton = (props) => {
+ const { label, ...rest} = props
+
+ return (
+ <>
+
+
+ >
+ )
+}
+
+export default class extends React.Component {
+ render () {
+ const {
+ filterForm,
+ } = this.props
+
+ const controlElements = Object
+ .values(filterForm.inputs)
+ .map((inputProps) => );
+
+ return (
+
+ )
+ }
+}
diff --git a/app/components/SeatingMap.js b/app/components/SeatingMap.js
index b9b1fe18..828af8f8 100644
--- a/app/components/SeatingMap.js
+++ b/app/components/SeatingMap.js
@@ -18,7 +18,15 @@ const buildSectionElements = (sections) => {
))
- return {seatElements}
+ return (
+
+ {seatElements}
+
+ )
})
}
diff --git a/app/views/seats/_filters.json.props b/app/views/seats/_filters.json.props
new file mode 100644
index 00000000..0f0a4e00
--- /dev/null
+++ b/app/views/seats/_filters.json.props
@@ -0,0 +1,14 @@
+json.filter_form do
+ form_props(
+ url: venue_floor_seats_path(venue, floor),
+ method: :get
+ ) do |f|
+ [5_00, 10_00, 15_00, nil].each_cons(2).to_a.each do |max_nmax|
+ maximum = max_nmax[0]
+ next_maximum = max_nmax[1]
+ checked = params[:maximum].to_i == maximum || [params[:maximum], next_maximum].none?
+
+ f.radio_button(:maximum, maximum, checked: checked, label: number_to_currency(maximum / 100.0))
+ end
+ end
+end
diff --git a/app/views/seats/_sections.json.props b/app/views/seats/_sections.json.props
index 25cc16d4..5db86b98 100644
--- a/app/views/seats/_sections.json.props
+++ b/app/views/seats/_sections.json.props
@@ -1,4 +1,12 @@
json.array! sections do |section|
+ if params.fetch(:maximum, Float::INFINITY).to_f >= section.price
+ json.opacity "1.0"
+ json.hidden false
+ else
+ json.opacity "0.3"
+ json.hidden true
+ end
+
json.seats do
json.array! section.seats do |seat|
json.x seat.x
diff --git a/app/views/seats/index.js b/app/views/seats/index.js
index bf089cc2..4d3e5840 100644
--- a/app/views/seats/index.js
+++ b/app/views/seats/index.js
@@ -1,5 +1,6 @@
import React from 'react'
import SeatDialog from '../../components/SeatDialog'
+import SeatFilter from '../../components/SeatFilter'
import Cart from '../../components/Cart'
import SeatingMap from '../../components/SeatingMap'
import SeatingLegend from '../../components/SeatingLegend'
@@ -13,6 +14,7 @@ export default (props) => {
cart,
seat,
floors,
+ filters,
} = props
return (
@@ -34,6 +36,7 @@ export default (props) => {
+
diff --git a/app/views/seats/index.json.props b/app/views/seats/index.json.props
index bb845ae6..f123ee19 100644
--- a/app/views/seats/index.json.props
+++ b/app/views/seats/index.json.props
@@ -9,6 +9,9 @@ end
json.cart(partial: ['cart', locals: local_assigns]) do
end
+json.filters(partial: ['filters', locals: local_assigns]) do
+end
+
json.seat do
json.show false
end
diff --git a/app/views/seats/show.json.props b/app/views/seats/show.json.props
index 533ba34c..85e47ffb 100644
--- a/app/views/seats/show.json.props
+++ b/app/views/seats/show.json.props
@@ -9,6 +9,9 @@ end
json.cart(partial: ['cart', locals: local_assigns]) do
end
+json.filters(partial: ['filters', locals: local_assigns]) do
+end
+
json.seat do
json.show true
json.section_name seat.section.name
diff --git a/test/controllers/seats_controller_test.rb b/test/controllers/seats_controller_test.rb
index 67e9ce76..a247b6be 100644
--- a/test/controllers/seats_controller_test.rb
+++ b/test/controllers/seats_controller_test.rb
@@ -21,4 +21,57 @@ class SeatsControllerTest < ActionDispatch::IntegrationTest
assert_equal Cart.last.token, cookies[:cart_token]
end
+
+ test "#index when including sections when filtering by price" do
+ maximum = 10_00
+ price = maximum
+ venue = create(:benedum_center)
+ floor = create(:orchestra, venue: venue)
+ section = create(:section, floor: floor, price: price)
+ create(:seat, section: section)
+
+ get venue_floor_seats_path(venue, floor, maximum: maximum, format: :json)
+
+ json = JSON.parse(body)
+ assert_equal json["data"]["sections"][0]["opacity"], "1.0"
+ assert_equal json["data"]["sections"][0]["hidden"], false
+ end
+
+ test "#index when excluding sections when filtering by price" do
+ maximum = 5_00
+ price = 10_00
+ venue = create(:benedum_center)
+ floor = create(:orchestra, venue: venue)
+ section = create(:section, floor: floor, price: price)
+ create(:seat, section: section)
+
+ get venue_floor_seats_path(venue, floor, maximum: maximum, format: :json)
+
+ json = JSON.parse(body)
+ assert_equal json["data"]["sections"][0]["opacity"], "0.3"
+ assert_equal json["data"]["sections"][0]["hidden"], true
+ end
+
+ test "#index with a ?maximum query parameter" do
+ venue = create(:benedum_center)
+ floor = create(:orchestra, venue: venue)
+ maximum = 10_00
+
+ get venue_floor_seats_path(venue, floor, maximum: maximum, format: :json)
+
+ json = JSON.parse(body)
+ assert_equal json["data"]["filters"]["controls"][1]["maximum"], maximum
+ assert_equal json["data"]["filters"]["controls"][1]["isChecked"], true
+ end
+
+ test "#index without a ?maximum query parameter" do
+ venue = create(:benedum_center)
+ floor = create(:orchestra, venue: venue)
+
+ get venue_floor_seats_path(venue, floor, format: :json)
+
+ json = JSON.parse(body)
+ assert_equal json["data"]["filters"]["controls"][2]["maximum"], 1500
+ assert_equal json["data"]["filters"]["controls"][2]["isChecked"], true
+ end
end