From 6afb27fa2e503b4b330b2f795981a5c95ce21e37 Mon Sep 17 00:00:00 2001 From: f3d0t Date: Fri, 12 Mar 2021 08:26:50 +0300 Subject: [PATCH] add js cinema task --- submissions/f3d0t/js-cinema/app.js | 105 +++++++ submissions/f3d0t/js-cinema/index.html | 209 +++++++++++++ submissions/f3d0t/js-cinema/style.css | 390 +++++++++++++++++++++++++ 3 files changed, 704 insertions(+) create mode 100644 submissions/f3d0t/js-cinema/app.js create mode 100644 submissions/f3d0t/js-cinema/index.html create mode 100644 submissions/f3d0t/js-cinema/style.css diff --git a/submissions/f3d0t/js-cinema/app.js b/submissions/f3d0t/js-cinema/app.js new file mode 100644 index 0000000..b6893dd --- /dev/null +++ b/submissions/f3d0t/js-cinema/app.js @@ -0,0 +1,105 @@ +const SEAT_PRICE = 2; +const ACTIVE_SEATS = []; + +const FORM_BOOKING = document.querySelector(".form__booking"); +const FORM_BUTTON = document.querySelector(".form__button"); +const FORM_TICKETS_COUNT = document.querySelector(".form__tickets-count"); +const FORM_TICKETS_COST = document.querySelector(".form__tickets-cost"); +const TICKETS_CONTAINER = document.querySelector(".tickets_cont"); +const MODAL_TICKETS_CONTAINER = document.querySelector(".modal__tickets_cont"); +const MODAL_WRAPPER = document.querySelector(".modal_wrapper"); +const MODAL_FORM = document.querySelector(".modal"); +const MODAL_COUNT = document.querySelector(".modal__count"); +const MODAL_COST = document.querySelector(".modal__cost"); +const MODAL_CLOSE = document.querySelector(".modal__close"); +const MODAL_BUTTON = document.querySelector(".modal__button"); + +const addSeat = (seatsArray, row, seat) => { + seatsArray.push(`${row}-${seat}`); +}; + +const deleteSeat = (seatsArray, row, seat) => { + seatsArray.splice(seatsArray.indexOf(`${row}-${seat}`), 1); +}; + +const updateForm = (formButton, formCount, formCost, seatsArray, seatPrice) => { + if (seatsArray.length > 0) { + formCount.textContent = seatsArray.length + " ticket"; + if (seatsArray.length > 1) formCount.textContent += "s"; + formCost.textContent = " for " + seatsArray.length * seatPrice + "$"; + formButton.disabled = false; + } else { + formCount.textContent = ""; + formCost.textContent = "Please, select seats"; + formButton.disabled = true; + } +}; + +const getTicketHtml = ([row, seat], price) => ` +
+ Row: ${row} + Seat: ${seat} + Price: ${price}$ +
`; + +const getTicketsHtml = (seatsArray, seatPrice) => { + if (seatsArray.length > 0) { + return seatsArray.map((bookedSeat) => getTicketHtml(bookedSeat.split("-"), seatPrice)).join(""); + } + return "

Select seats...=)

"; +}; + +const updateTickets = (ticketsContainer, seatsArray, seatPrice) => { + ticketsContainer.innerHTML = getTicketsHtml(seatsArray, seatPrice); +}; + +const openModal = (modalWrapper, modalTicketsContainer, modalCount, modalCost, modalButton, seatsArray, seatPrice) => { + updateTickets(modalTicketsContainer, seatsArray, seatPrice); + modalCount.textContent = seatsArray.length + " ticket"; + if (seatsArray.length > 1) modalCount.textContent += "s"; + modalCost.textContent = " for " + seatsArray.length * seatPrice + "$"; + modalWrapper.style.display = "flex"; + modalButton.focus(); +}; + +const closeModal = (modalWrapper) => { + modalWrapper.style.display = "none"; +}; + +const initApp = () => { + bindEventListeners(); +}; + +const bindEventListeners = () => { + FORM_BOOKING.addEventListener("input", ({ target }) => { + if (target.checked === true) { + addSeat(ACTIVE_SEATS, target.dataset.row, target.dataset.seat); + } else if (target.checked === false) { + deleteSeat(ACTIVE_SEATS, target.dataset.row, target.dataset.seat); + } + updateForm(FORM_BUTTON, FORM_TICKETS_COUNT, FORM_TICKETS_COST, ACTIVE_SEATS, SEAT_PRICE); + updateTickets(TICKETS_CONTAINER, ACTIVE_SEATS, SEAT_PRICE); + }); + FORM_BOOKING.addEventListener("submit", (event) => { + event.preventDefault(); + openModal(MODAL_WRAPPER, MODAL_TICKETS_CONTAINER, MODAL_COUNT, MODAL_COST, MODAL_BUTTON, ACTIVE_SEATS, SEAT_PRICE); + }); + document.addEventListener("keydown", (event) => { + if (event.key === "Escape") { + event.preventDefault(); + closeModal(MODAL_WRAPPER); + } + }); + MODAL_CLOSE.addEventListener("click", () => closeModal(MODAL_WRAPPER)); + MODAL_FORM.addEventListener("submit", (event) => { + event.preventDefault(); + alert("Sucsessfully booked!"); + setTimeout(() => { + location.reload(); + }, 1000); + }); +}; + +document.addEventListener("DOMContentLoaded", () => { + initApp(); +}); diff --git a/submissions/f3d0t/js-cinema/index.html b/submissions/f3d0t/js-cinema/index.html new file mode 100644 index 0000000..02edd74 --- /dev/null +++ b/submissions/f3d0t/js-cinema/index.html @@ -0,0 +1,209 @@ + + + + + + Fight Club | Movie ticket booking + + + + + + + +
+ + +
+
+ +
+
+

"Fight club" movie tickets booking

+

Session time & date:

+

IMDB rating: 8.8 / 10

+

Language: English

+

Film format: 2D

+

Seat price: 2$

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Ticket price: 2$

+
+ Select seats + +
+
+ Taken Available Selected +
+
+
+

Your booking:

+
+

Select seats

+
+
+
+
+ + + + + diff --git a/submissions/f3d0t/js-cinema/style.css b/submissions/f3d0t/js-cinema/style.css new file mode 100644 index 0000000..dc8f1d7 --- /dev/null +++ b/submissions/f3d0t/js-cinema/style.css @@ -0,0 +1,390 @@ +* { + box-sizing: border-box; + margin: 0; +} +:root { + font-size: 14px; +} +body { + background-color: #222; + color: #ddd; + font-family: "Hind", sans-serif; + min-height: 100vh; +} +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + border: 0; + padding: 0; + clip: rect(0 0 0 0); + overflow: hidden; +} + +.header { + display: flex; + align-items: center; + padding: 1rem 2rem; + border-bottom: 1px solid #000; +} +.header_logo { + background: url("data:image/svg+xml,
🎞️
"); + background-size: 40px 40px; + width: 40px; + height: 44px; + margin-right: 1rem; +} +.header_menu { + display: flex; + padding: 0; + list-style-type: none; +} +.header_menu__item { + margin-left: 0.8rem; +} +.header_menu__item:first-child { + margin-left: 0px; +} +.header_menu__item a { + color: #eee; + text-decoration: none; +} +.header_menu__item a:hover { + text-decoration: underline; +} + +.main { + padding: 1rem 2rem; +} +.main_breadcrumbs { + display: flex; + list-style-type: none; + padding: 0; +} +.main_breadcrumbs__item { + margin: 0 0.25rem; +} +.main_breadcrumbs__item:first-child { + margin-left: 0px; +} +.main_breadcrumbs__item:not(:last-child):after { + content: "›"; + display: inline-block; + margin-left: 0.25rem; +} +.main_breadcrumbs__item a { + color: #eee; + text-decoration: none; +} +.main_breadcrumbs__item a:hover { + text-decoration: underline; +} + +.movie { + margin-top: 7rem; + text-align: right; + display: grid; + grid-template-rows: 100%; + grid-template-columns: 466px 360px 290px; + grid-template-areas: "textArea formArea ticketsArea"; + justify-content: center; +} +.movie__title { + margin-top: 1rem; + font-size: 2rem; +} +.movie__time { + margin-top: 1rem; + font-size: 1em; +} +.movie__info { + grid-area: textArea; + align-items: center; + padding-right: 40px; +} + +.form__booking { + grid-area: formArea; + width: 360px; + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-content: flex-start; + max-width: 500px; +} +.seats_booking { + position: relative; + padding: 0; + margin: 15px; + display: grid; + grid-template-rows: repeat(5, 30px); + grid-template-columns: repeat(11, 30px); + border: none; + padding-top: 3rem; +} +.seats_booking:before { + content: "SCREEN"; + text-align: center; + position: absolute; + top: 0; + left: -15px; + display: block; + width: 360px; + height: 2rem; + border-top-width: 2px; + border-radius: 50%; + border-top-color: #fff; + border-top-style: solid; + filter: drop-shadow(0px 3px 10px #fff); +} +.form__seat:before { + content: attr(for); + height: 26px; + width: 26px; + border-radius: 3px; + display: inline-flex; + justify-content: center; + align-items: center; + background-color: #ddd; + color: #222; + cursor: pointer; + transition: box-shadow 150ms linear; + box-shadow: 0px 0px 0px #fff; +} +.form__seat--placeholder:before { + content: ""; + background-color: transparent; + box-shadow: 0px 0px 0px #fff; + cursor: unset; +} +.form__seat_input:hover + .form__seat:before, +.form__seat_input:focus + .form__seat:before { + background-color: rgb(255, 255, 255); + box-shadow: 0px 0px 4px #fff; +} +.form__seat_input:checked + .form__seat:before, +.form__seat--selected:before { + background-color: rgb(240, 150, 150); +} +.form__seat_input:disabled + .form__seat:before, +.form__seat--taken:before { + cursor: unset; + background-color: #777; + box-shadow: 0px 0px 0px #fff; +} + +.form__seat[for="1-1"] { + grid-column-start: 2; +} +.form__seat[for="2-1"] { + grid-column-start: 4; +} +.form__seat[for="3-2"] { + grid-column-start: 4; +} +.form__seat[for="4-2"] { + grid-column-start: 4; +} + +.form__button { + width: 100px; + box-shadow: 0px 0px 0px #fff; + border-radius: 2px; + transition: all 150ms linear; + background-color: #ddd; + border-style: solid; + border-color: transparent; + margin-left: 7px; +} +.form__button:not(:disabled):hover, +.form__button:not(:disabled):focus { + background-color: rgb(255, 255, 255); + box-shadow: 0px 0px 4px #fff; + border: 2px solid white; +} +.form__tickets-count, +.modal__count { + color: rgb(240, 150, 150); +} + +.seats_labels { + margin: 15px auto 15px auto; + text-align: center; + line-height: 30px; + border: none; + padding: 0; +} +.seats_labels .form__seat:before { + cursor: unset; +} +.seats_labels__span { + margin: 0px 0.9rem 0px 0.3rem; +} +.seats_labels__span:last-child { + margin: 0px 0px 0px 0.3rem; +} + +.booked_tickets { + width: 100%; + text-align: left; + padding-left: 40px; + grid-area: ticketsArea; +} +.booked_tickets__heading { + font-size: 1.2rem; + margin-left: 14px; +} +.tickets_cont { + max-height: 370px; + overflow-y: auto; + width: 250px; +} +.booked_tickets__ticket { + width: 220px; + display: flex; + justify-content: space-between; + border-radius: 10px; + padding: 3px 14px; + background: linear-gradient(to bottom, #00000050, #00000050 10%, transparent); + border: 1px solid #ffffff50; + margin-bottom: 7px; + box-shadow: 1px 1px 1px #666; +} + +.footer { + padding: 1rem 2rem; + position: fixed; + bottom: 0; + width: 100%; +} +.footer__link { + color: #aaa; +} +.footer__link:hover { + color: #fff; +} + +.modal_wrapper { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + justify-content: center; + align-items: center; + background: #00000080; +} +.modal { + width: 270px; + max-height: 408px; + padding: 14px; + position: relative; + display: grid; + grid-template-rows: 23px auto 23px; + grid-template-columns: 100%; + gap: 23px; + align-content: flex-start; + justify-content: center; + grid-template-areas: + "modalHeader" + "modalTickets" + "modalText"; + + background: #111; + border: 1px solid #888; +} +.modal__header { + grid-area: modalHeader; + font-size: 1.1rem; + margin-left: 14px; + text-align: center; +} +.modal__tickets_cont { + grid-area: modalTickets; + max-height: 288px; + overflow-y: auto; +} +.modal__text { + grid-area: modalText; + text-align: right; +} +.modal__button { + margin-left: 7px; +} +.modal__close { + position: absolute; + top: 14px; + right: 14px; + cursor: pointer; + font-size: 1.2rem; +} + +@media (max-width: 1117px) { + .movie { + grid-template-rows: auto auto; + grid-template-columns: 360px 290px; + grid-template-areas: + "textArea textArea" + "formArea ticketsArea"; + justify-content: center; + margin-top: 1rem; + } + .movie__info { + text-align: center; + margin-bottom: 2rem; + } + .movie__info p { + display: inline-block; + margin-right: 0.5rem; + } + .tickets_cont { + max-height: 300px; + } +} + +@media (max-width: 730px) { + :root { + font-size: 12px; + } + .movie { + margin-top: 1rem; + text-align: center; + grid-template-rows: auto auto; + grid-template-columns: 100%; + grid-template-areas: + "textArea" + "formArea" + "ticketsArea"; + } + .movie__info { + padding-right: 0px; + } + .form__booking { + justify-self: center; + } + .booked__tickets { + padding-left: 0; + text-align: center; + } + .booked__tickets--ticket { + margin: auto; + } + .booked_tickets__heading { + text-align: center; + } + .tickets_cont { + margin: auto; + max-height: 220px; + } + .booked_tickets__ticket { + margin: 0 auto 7px auto; + } + .footer { + position: relative; + } + .modal__tickets_cont { + max-height: 200px; + } +}