Add seats#show
route and action
Render the contents of the seats#show
controller action into the same
template as seats#index
, then embedded the template within a block
wrapped by a browser-native <dialog>
element declared
as a sibling to the seats#index
elements.
To achieve this, pass template: "seats/index"
, along with
the template’s local_assigns
into a call to render
from within
app/views/seats/show.html.erb
.
The modal <dialog>
element
When rendering the seats#show
template, specify that the wrapping
<dialog>
element has the open
attribute.
When initially rendered (and in environments with JavaScript disabled),
the <dialog>
element will be overlaid on top of the rest of
the page.
In JavaScript-capable environments, within turbolinks:load
events , find <dialog>
elements and ensure their
browser compatibility by wrapping them in calls to the
dialog-polyfill
-provided registerDialog
.
Then, for elements that specify the open
attribute , re-set
them to be closed, then manually invoke
dialog.showModal()
to render the dialog modally.
Collapse app/controllers/seats_controller.rb
Expand app/controllers/seats_controller.rb
app/controllers/seats_controller.rb
diff --git a/app/controllers/seats_controller.rb b/app/controllers/seats_controller.rb
index 376f7b2..e0f7494 100644
--- a/app/controllers/seats_controller.rb
+++ b/app/controllers/seats_controller.rb
@@ -10,4 +10,18 @@ class SeatsController < ApplicationController
sections: sections,
})
end
+
+ def show
+ venue = Venue.find_by!(slug: params[:venue_id])
+ floor = venue.floors.find_by!(slug: params[:floor_id])
+ sections = floor.sections.includes(:seats)
+ seat = floor.seats.find_by_row_number!(params[:id])
+
+ render(locals: {
+ venue: venue,
+ floor: floor,
+ sections: sections,
+ seat: seat,
+ })
+ end
end
Collapse app/javascript/packs/application.js
Expand app/javascript/packs/application.js
app/javascript/packs/application.js
diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js
index 28dc6eb..1c4f3d0 100644
--- a/app/javascript/packs/application.js
+++ b/app/javascript/packs/application.js
@@ -15,3 +15,16 @@ require("turbolinks").start()
// const imagePath = (name) => images(name, true)
import "controllers"
+
+import dialogPolyfill from "dialog-polyfill"
+
+document.addEventListener("turbolinks:load", () => {
+ for (const dialog of document.querySelectorAll("dialog")) {
+ dialogPolyfill.registerDialog(dialog)
+
+ if (dialog.hasAttribute("open")) {
+ dialog.open = false
+ dialog.showModal()
+ }
+ }
+})
Collapse app/models/floor.rb
Expand app/models/floor.rb
app/models/floor.rb
diff --git a/app/models/floor.rb b/app/models/floor.rb
index 9c9fe5f..8194910 100644
--- a/app/models/floor.rb
+++ b/app/models/floor.rb
@@ -3,4 +3,8 @@ class Floor < ApplicationRecord
has_many :sections
has_many :seats, through: :sections
+
+ def to_param
+ slug
+ end
end
Collapse app/models/seat.rb
Expand app/models/seat.rb
app/models/seat.rb
diff --git a/app/models/seat.rb b/app/models/seat.rb
index ee2368c..64992de 100644
--- a/app/models/seat.rb
+++ b/app/models/seat.rb
@@ -1,3 +1,13 @@
class Seat < ApplicationRecord
belongs_to :section
+
+ def self.find_by_row_number!(row_number)
+ row, number = row_number.split("-")
+
+ find_by!(row: row, number: number)
+ end
+
+ def row_number
+ "#{row}-#{number}"
+ end
end
Collapse app/models/venue.rb
Expand app/models/venue.rb
app/models/venue.rb
diff --git a/app/models/venue.rb b/app/models/venue.rb
index 4a7a6a3..cc2de9e 100644
--- a/app/models/venue.rb
+++ b/app/models/venue.rb
@@ -1,3 +1,7 @@
class Venue < ApplicationRecord
has_many :floors
+
+ def to_param
+ slug
+ end
end
Collapse app/views/seats/_dialog.html.erb
Expand app/views/seats/_dialog.html.erb
app/views/seats/_dialog.html.erb
diff --git a/app/views/seats/_dialog.html.erb b/app/views/seats/_dialog.html.erb
new file mode 100644
index 0000000..585d935
--- /dev/null
+++ b/app/views/seats/_dialog.html.erb
@@ -0,0 +1,6 @@
+<%= tag.dialog(
+ class: "syos-dialog",
+ open: true,
+) do %>
+ <%= yield %>
+<% end %>
Collapse app/views/seats/index.html.erb
Expand app/views/seats/index.html.erb
app/views/seats/index.html.erb
diff --git a/app/views/seats/index.html.erb b/app/views/seats/index.html.erb
index 06a06e7..b88ad58 100644
--- a/app/views/seats/index.html.erb
+++ b/app/views/seats/index.html.erb
@@ -22,16 +22,21 @@
<% sections.each do |section| %>
<g>
<% section.seats.each do |seat| %>
- <svg
- width="12px"
- height="12px"
- viewBox="0 0 24 24"
- x="<%= seat.x %>"
- y="<%= seat.y %>"
+ <a
+ href="<%= venue_floor_seat_path(venue, floor, seat.row_number) %>"
+ aria-label="<%= seat.row_number %>"
>
- <circle fill="#37b24d" r="12" cx="12" cy="12"></circle>
- <circle fill="#ffffff" r="6" cx="12" cy="12"></circle>
- </svg>
+ <svg
+ width="12px"
+ height="12px"
+ viewBox="0 0 24 24"
+ x="<%= seat.x %>"
+ y="<%= seat.y %>"
+ >
+ <circle fill="#37b24d" r="12" cx="12" cy="12"></circle>
+ <circle fill="#ffffff" r="6" cx="12" cy="12"></circle>
+ </svg>
+ </a>
<% end %>
</g>
<% end %>
Collapse app/views/seats/show.html.erb
Expand app/views/seats/show.html.erb
app/views/seats/show.html.erb
diff --git a/app/views/seats/show.html.erb b/app/views/seats/show.html.erb
new file mode 100644
index 0000000..0bc456b
--- /dev/null
+++ b/app/views/seats/show.html.erb
@@ -0,0 +1,81 @@
+<%= render(template: "seats/index", locals: local_assigns) %>
+
+<%= render("seats/dialog") do %>
+ <header class="syos-dialog__header">
+ <h2 class="syos-dialog__title">
+ Confirm seat selection
+ </h2>
+
+ <form method="dialog">
+ <button
+ class="syos-button syos-button--transparent"
+ >
+ <svg
+ xmlns="http://www.w3.org/2000/svg"
+ viewBox="0 0 24 24"
+ width="24"
+ height="24"
+ class="syos-icon syos-icon--large"
+ title="Close modal"
+ fill="none"
+ stroke="currentColor"
+ stroke-width="2"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ >
+ <circle cx="12" cy="12" r="10"></circle>
+ <line x1="15" y1="9" x2="9" y2="15"></line>
+ <line x1="9" y1="9" x2="15" y2="15"></line>
+ </svg>
+ </button>
+ </form>
+ </header>
+
+ <section class="syos-dialog__body">
+ <dl class="syos-grid syos-grid--2">
+ <div>
+ <dt>
+ Section
+ </dt>
+
+ <dd class="syos-u-font-size-large">
+ <%= seat.section.name %>
+ </dd>
+ </div>
+
+ <div>
+ <dt>
+ Seat
+ </dt>
+
+ <dd class="syos-u-font-size-large">
+ <%= seat.row_number %>
+ </dd>
+ </div>
+ </dl>
+ </section>
+
+ <footer class="syos-dialog__footer syos-block-stack syos-block-stack--bordered syos-block-stack--large">
+ <div class="syos-inline-stack syos-inline-stack--inline syos-block-stack__item">
+ <div class="syos-inline-stack__item">
+ <p class="syos-u-margin-bottom-0">
+ <%= seat.section.name %>
+ </p>
+ </div>
+
+ <div class="syos-inline-stack__item syos-inline-stack__item--push-start">
+ <p class="syos-u-margin-bottom-0">
+ <strong><%= number_to_currency(seat.section.price / 100.0) %></strong>
+ </p>
+ </div>
+
+ <div class="syos-inline-stack__item">
+ <button
+ class="syos-button"
+ >
+ Select
+ </button>
+ </div>
+ </div>
+ </footer>
+<% end %>
Collapse config/routes.rb
Expand config/routes.rb
config/routes.rb
diff --git a/config/routes.rb b/config/routes.rb
index 2b9f710..384d8e3 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -2,7 +2,7 @@ Rails.application.routes.draw do
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
resources :venues, only: [] do
resources :floors, only: [] do
- resources :seats, only: [:index]
+ resources :seats, only: [:index, :show]
end
end
Collapse package.json
Expand package.json
package.json
diff --git a/package.json b/package.json
index 6d2ab8d..8dbf528 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,7 @@
"@rails/ujs": "^6.0.0",
"@rails/webpacker": "4.2.2",
"breakpoint-sass": "2.7.1",
+ "dialog-polyfill": "^0.5.0",
"stimulus": "^1.1.1",
"turbolinks": "^5.2.0"
},
Collapse test/models/floor_test.rb
Expand test/models/floor_test.rb
test/models/floor_test.rb
diff --git a/test/models/floor_test.rb b/test/models/floor_test.rb
index 65c5512..87042cb 100644
--- a/test/models/floor_test.rb
+++ b/test/models/floor_test.rb
@@ -1,7 +1,12 @@
require 'test_helper'
class FloorTest < ActiveSupport::TestCase
- # test "the truth" do
- # assert true
- # end
+ test "#to_param returns the slug" do
+ slug = "the-slug"
+ floor = Floor.new(slug: slug)
+
+ to_param = floor.to_param
+
+ assert_equal(slug, to_param)
+ end
end
Collapse test/models/venue_test.rb
Expand test/models/venue_test.rb
test/models/venue_test.rb
diff --git a/test/models/venue_test.rb b/test/models/venue_test.rb
index bf495c6..bd260b7 100644
--- a/test/models/venue_test.rb
+++ b/test/models/venue_test.rb
@@ -1,7 +1,12 @@
require 'test_helper'
class VenueTest < ActiveSupport::TestCase
- # test "the truth" do
- # assert true
- # end
+ test "#to_param returns the slug" do
+ slug = "the-venue"
+ venue = Venue.new(slug: slug)
+
+ to_param = venue.to_param
+
+ assert_equal(slug, to_param)
+ end
end
Collapse yarn.lock
Expand yarn.lock
yarn.lock
diff --git a/yarn.lock b/yarn.lock
index 807787e..c3c792f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2401,6 +2401,11 @@ detect-node@^2.0.4:
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
+dialog-polyfill@^0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/dialog-polyfill/-/dialog-polyfill-0.5.0.tgz#bf67bc67abaf538e44fff80f2f71ff132befadd7"
+ integrity sha512-fOj68T8KB6UIsDFmK7zYbmORJMLYkRmtsLM1W6wbCVUWu4Hdcud5bqbvuueTxO84JXtK9HcpCHV9vNwlWUdCIw==
+
diffie-hellman@^5.0.0:
version "5.0.3"
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"