Skip to content

Commit

Permalink
Add map zoom controls to seats/index
Browse files Browse the repository at this point in the history
For comparison [see this commit]

The Superglue version is lengthier than the commit above. Instead of just
introducing HTML changes, this commit also introduces a React component to
control zoom behavior and refactoring to introduce a `_seating_map.json.props`

[commit]: seanpdoyle@fd394fc
  • Loading branch information
jho406 committed Oct 8, 2023
1 parent ca516c3 commit b6e8ef1
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 62 deletions.
1 change: 1 addition & 0 deletions app/assets/images/icons/minus.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/assets/images/icons/plus.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 36 additions & 31 deletions app/components/SeatingMap.js
@@ -1,5 +1,7 @@
import React from 'react'
import svgPanZoom from 'svg-pan-zoom'
import SvgZoomControls from './SvgZoomControls'

const buildSectionElements = (sections) => {
return sections.map((section, index) => {
const seatElements = section.seats.map((seat) => (
Expand Down Expand Up @@ -31,7 +33,7 @@ const buildSectionElements = (sections) => {
}

export default class extends React.Component {
constructor(props) {
constructor (props) {
super(props)
this.svgRef = React.createRef()
}
Expand All @@ -56,38 +58,41 @@ export default class extends React.Component {
const sectionElements = buildSectionElements(sections)

return(
<svg
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
className="syos-seat-map"
width="1600px"
height="1600px"
viewBox="0 0 1600 1600"
ref={this.svgRef}
>
<rect fill="none" x="0" y="0" width="1600" height="1600"></rect>
<svg style={{display: "none"}}>
<symbol
id="seat-icon-unselected"
width="24"
height="24"
viewBox="0 0 24 24"
>
<circle fill="#37b24d" r="12" cx="12" cy="12"></circle>
<circle fill="#ffffff" r="6" cx="12" cy="12"></circle>
</symbol>
<>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
className="syos-seat-map"
width="1600px"
height="1600px"
viewBox="0 0 1600 1600"
ref={this.svgRef}
>
<rect fill="none" x="0" y="0" width="1600" height="1600"></rect>
<svg style={{display: "none"}}>
<symbol
id="seat-icon-unselected"
width="24"
height="24"
viewBox="0 0 24 24"
>
<circle fill="#37b24d" r="12" cx="12" cy="12"></circle>
<circle fill="#ffffff" r="6" cx="12" cy="12"></circle>
</symbol>

<symbol
id="seat-icon-selected"
width="24"
height="24"
viewBox="0 0 24 24"
>
<circle fill="#37b24d" r="12" cx="12" cy="12"></circle>
</symbol>
<symbol
id="seat-icon-selected"
width="24"
height="24"
viewBox="0 0 24 24"
>
<circle fill="#37b24d" r="12" cx="12" cy="12"></circle>
</symbol>
</svg>
{ sectionElements }
</svg>
{ sectionElements }
</svg>
<SvgZoomControls />
</>
)
}
}
26 changes: 26 additions & 0 deletions app/components/SvgZoomControls.js
@@ -0,0 +1,26 @@
import React from 'react'
import SVG from 'react-inlinesvg';
import plusSvg from '../assets/images/icons/plus.svg'
import minusSvg from '../assets/images/icons/minus.svg'

export default class extends React.Component {
render() {
return (
<div className="syos-frame__map-zoom syos-control-zoom">
<button
className="syos-button syos-button--transparent syos-control-zoom__button"
type="button"
>
<SVG src={ minusSvg } className="syos-icon" title="zoom out"/>
</button>

<button
className="syos-button syos-button--transparent syos-control-zoom__button"
type="button"
>
<SVG src={ plusSvg } className="syos-icon" title="zoom in"/>
</button>
</div>
)
}
}
26 changes: 26 additions & 0 deletions app/views/seats/_seating_map.json.props
@@ -0,0 +1,26 @@
json.sections do
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
json.y seat.y
json.venue_floor_seat_path venue_floor_seat_path(venue, floor, seat.row_number)
json.aria_label seat.row_number

if Current.cart.include?(seat)
json.href "#seat-icon-selected"
else
json.href "#seat-icon-unselected"
end
end
end
end
end
24 changes: 0 additions & 24 deletions app/views/seats/_sections.json.props

This file was deleted.

3 changes: 2 additions & 1 deletion app/views/seats/index.js
Expand Up @@ -12,6 +12,7 @@ export default (props) => {
venueName,
sections,
cart,
seatingMap,
seat,
floors,
filters,
Expand All @@ -33,7 +34,7 @@ export default (props) => {
<div className="syos-frame__map">
<FloorSwitcher floors={floors}/>
<SeatingLegend />
<SeatingMap sections={sections} />
<SeatingMap {...seatingMap} />
</div>
<div className="syos-frame__sidebar">
<SeatFilter {...filters} />
Expand Down
2 changes: 1 addition & 1 deletion app/views/seats/index.json.props
@@ -1,6 +1,6 @@
json.venue_name venue.name

json.sections(partial: ['sections', locals: local_assigns]) do
json.seating_map(partial: ['seating_map', locals: local_assigns]) do
end

json.floors(partial: ['floors', locals: local_assigns]) do
Expand Down
2 changes: 1 addition & 1 deletion app/views/seats/show.json.props
@@ -1,6 +1,6 @@
json.venue_name venue.name

json.sections(partial: ["sections", locals: local_assigns]) do
json.seating_map(partial: ['seating_map', locals: local_assigns]) do
end

json.floors(partial: ['floors', locals: local_assigns]) do
Expand Down
8 changes: 4 additions & 4 deletions test/controllers/seats_controller_test.rb
Expand Up @@ -33,8 +33,8 @@ class SeatsControllerTest < ActionDispatch::IntegrationTest
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
assert_equal json["data"]["seatingMap"]["sections"][0]["opacity"], "1.0"
assert_equal json["data"]["seatingMap"]["sections"][0]["hidden"], false
end

test "#index when excluding sections when filtering by price" do
Expand All @@ -48,8 +48,8 @@ class SeatsControllerTest < ActionDispatch::IntegrationTest
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
assert_equal json["data"]["seatingMap"]["sections"][0]["opacity"], "0.3"
assert_equal json["data"]["seatingMap"]["sections"][0]["hidden"], true
end

test "#index with a ?maximum query parameter" do
Expand Down

0 comments on commit b6e8ef1

Please sign in to comment.