Commit c70643c1 by Madhankumar

code optimized

parent 45e53639
{
"bookingSeats": [
"seatLayout": [
[
0,
"A1",
......@@ -101,20 +101,24 @@
{
"mobile": "9999999997",
"id": 3
},
{
"mobile": "3333333333",
"id": 4
}
],
"reservedSeats": [
{
"seats": [
"F4"
"H5"
],
"id": 1
},
{
"seats": [
"H2",
"H3",
"H1"
"H1",
"H4"
],
"id": 2
},
......@@ -126,6 +130,12 @@
"G4"
],
"id": 3
},
{
"seats": [
"G8"
],
"id": 4
}
]
}
\ No newline at end of file
import "./App.css";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import { _Login } from "../src/pages/login";
import { _Seatlayout } from "../src/pages/seat-layout";
import { _Confirmation } from "../src/pages/confirmation";
import { _seatLimit } from "../src/pages/seat-limit";
import { Route, Routes } from "react-router-dom";
import { LoginPage } from "../src/pages/login";
import { SeatLayoutPage } from "../src/pages/seat-layout";
import { ConfirmationPage } from "../src/pages/confirmation";
import { SeatLimitPage } from "../src/pages/seat-limit";
import { useEffect } from "react";
import { useNavigate } from "react-router-dom";
function App() {
const navigate = useNavigate();
useEffect(() => {
const userIsLoggedIn = sessionStorage.getItem("userId");
userIsLoggedIn ?? navigate("/");
// Navigate to the booking if the user is logged in
}, [navigate]);
return (
<div className="App">
<Router>
<Routes>
<Route path="/" element={<_Login />} />
<Route path="/seat-limit" element={<_seatLimit />} />
<Route path="/booking" element={<_Seatlayout />} />
<Route path="/confirmation" element={<_Confirmation />} />
{/* Default route */}
<Route path="*" element={<_Login />} />
</Routes>
</Router>
<Routes>
<Route path="/" element={<LoginPage />} />
<Route path="/seat-limit" element={<SeatLimitPage />} />
<Route path="/booking" element={<SeatLayoutPage />} />
<Route path="/confirmation" element={<ConfirmationPage />} />
{/* Default route */}
<Route path="*" element={<LoginPage />} />
</Routes>
</div>
);
}
......
......@@ -4,7 +4,7 @@ import style from "./confirmation.module.css";
import Button from "../../base/button";
import { Link } from "react-router-dom";
function Confirmation({ seatCount, seats, onLogOut, onEdit }) {
function Confirmation({ seatCount = 0, seats = 0, onLogOut, onEdit }) {
return (
<Layout title="Booking Confirmed">
<div className={style.confirmation}>
......
import { useState } from "react";
import Button from "../../base/button";
import Input from "../../base/input";
import Layout from "../../base/layout";
......@@ -12,7 +11,6 @@ function Login({ onSubmit }) {
e.preventDefault();
if (mobile.length < 10) {
setIsError(true);
toast.info("mobile should be 10 digits");
} else {
onSubmit({ mobile });
......@@ -26,21 +24,19 @@ function Login({ onSubmit }) {
return (
<Layout title="Login">
<form className="form" onSubmit={handleSubmit}>
<div>
<label className="label">Mobile:</label>
<Input
placeholder="Enter Mobile"
type="tel"
required
maxLength={10}
onChange={handleChange}
/>
{iserror && (
<span className={styles.span}>Please enter 10 digits</span>
)}
<form className={styles.form} onSubmit={handleSubmit}>
<label className={styles.label}>Mobile:</label>
<Input
placeholder="Enter Mobile"
type="tel"
required
maxLength={10}
onChange={handleChange}
/>
{iserror && <span className={styles.span}>Please enter 10 digits</span>}
<div className={styles.button}>
<Button>Submit</Button>
</div>
<Button>Submit</Button>
</form>
</Layout>
);
......
.span {
color: red;
}
.form {
margin-inline: 1rem;
}
.button {
margin-top: 1rem;
}
.label {
color: #6c6a6a;
font-weight: 500;
}
......@@ -14,6 +14,11 @@ function SeatLayout({
isLoading,
}) {
const [selectedseat, setSelectedSeat] = useState([...selectedSeats]);
useEffect(() => {
setSelectedSeat([...selectedSeats]);
}, [selectedSeats]);
const handleSeats = (seat) => {
if (!selectedseat?.includes(seat) && selectedseat.length < seatLimit) {
setSelectedSeat([...selectedseat, seat]);
......@@ -23,9 +28,7 @@ function SeatLayout({
toast.info(`Cannot select seat more than ${seatLimit}`);
}
};
useEffect(() => {
setSelectedSeat([...selectedSeats]);
}, [selectedSeats]);
const handleConfirm = (e) => {
e.preventDefault();
if (!selectedseat.length || selectedseat.length < seatLimit) {
......
......@@ -3,6 +3,7 @@ import Button from "../../base/button";
import Layout from "../../base/layout";
import Input from "../../base/input";
import { toast } from "react-toastify";
import styles from "./seat-limit.module.css";
function SeatLimit({ onLimit, ...props }) {
const [limit, setLimit] = useState(0);
const handleLimit = (e) => {
......@@ -15,18 +16,18 @@ function SeatLimit({ onLimit, ...props }) {
};
return (
<Layout title="How many seats?">
<form onSubmit={handleLimit} className="form">
<div>
<label className="label">No of seats:</label>
<Input
type="number"
value={limit}
onChange={(e) => setLimit(e.target.value)}
min="1"
max="10"
/>
<form onSubmit={handleLimit} className={styles.form}>
<label className="label">No of seats:</label>
<Input
type="number"
value={limit}
onChange={(e) => setLimit(e.target.value)}
min="1"
max="10"
/>
<div className={styles.button}>
<Button {...props}>Book Seats</Button>
</div>
<Button {...props}>Book Seats</Button>
</form>
</Layout>
);
......
/* .label {
color: #6c6a6a;
.form {
margin-inline: 1rem;
}
.form > *:not(input) {
padding: 17px;
.button {
margin-top: 1rem;
}
input[type="number"]::-webkit-inner-spin-button {
display: none;
.label {
color: #6c6a6a;
font-weight: 500;
}
input[type="number"] {
-moz-appearence: textfield;
} */
......@@ -11,20 +11,22 @@ input[type="checkbox"] {
border: 1px solid #ccc;
box-shadow: none;
padding: 0.7rem;
cursor: pointer;
}
.checkbox-reserved {
background: #848489;
border: none !important;
cursor: not-allowed;
}
.checkbox-selected {
background: #01fff7;
border: none !important;
cursor: pointer;
}
.checkbox-available {
padding: 0.6rem !important;
cursor: pointer;
}
.tooltip {
......
......@@ -5,61 +5,86 @@ export const AppContext = createContext();
export const useAppContext = () => useContext(AppContext);
export function ContextProvider({ children }) {
const [userseats, setUserSeats] = useState([]);
const [seats, setSeats] = useState([]);
const [userSeats, setUserSeats] = useState([]);
const [reservedSeats, setReservedSeats] = useState([]);
const [seatLayout, setSeatLayout] = useState([]);
const [isLoading, setisLoading] = useState(false);
const LoginOrRegister = async ({ mobile }) => {
const loginOrRegister = async ({ mobile }) => {
try {
const user = await api.GetUserByMobile({ mobile });
const user = await api.getUserByMobile({ mobile });
if (!user.length) {
//register
const response = await api.Register({ mobile });
return await response;
const response = await api.register({ mobile });
sessionStorage.setItem("userId", response?.id);
await getAllReservedSeats();
// return true for newly registered user
return true;
} else {
//login
return await user[0];
sessionStorage.setItem("userId", user?.[0]?.id);
const response = await getAllReservedSeats();
const userSelectedSeats = response.filter((e) => e.id == user[0]?.id);
sessionStorage.setItem(
"seatLimit",
userSelectedSeats?.[0]?.seats?.length
);
// return false for already registered user
return false;
}
} catch (err) {
toast.error(err.message);
}
};
const AddOrUpdateSeats = async ({ id, seats }) => {
const addOrUpdateSeats = async ({ id, seats }) => {
try {
const isSeats = userseats.filter((e) => e.id == id);
//check the id
if (!isSeats.length) {
//add seats
const response = await api.AddSeats({ seats });
setUserSeats([...userseats, response]);
//check user already booked seats or not
if (!userSeats.length) {
//add seats into reserved seats
const response = await api.addSeats({ seats });
setReservedSeats([...reservedSeats, response]);
} else {
//update seats
const response = await api.UpdateSeats({ id, seats });
const result = userseats.map((e) => (e[id] == id ? response : e));
setUserSeats(result);
//update user seats only
const response = await api.updateSeats({ id, seats });
setUserSeats(response.seats);
}
} catch (err) {
toast.error(err.message);
}
};
const GetAllSeats = async () => {
const getAllReservedSeats = async () => {
setisLoading(false);
try {
//to clear the data for glitch
setReservedSeats([]);
setUserSeats([]);
const response = await api.GetAllSeats();
setUserSeats(response);
const response = await api.getAllReservedSeats();
const userid = sessionStorage.getItem("userId");
response.map((e) =>
e.id != userid
? // condition1=get all reserved seats except logged user
setReservedSeats((prevReservedSeat) => [
...prevReservedSeat,
...e.seats,
])
: // condition2=get only reserved seats of logged user
setUserSeats(e.seats)
);
setisLoading(true);
return await response;
} catch (err) {
toast.error(err.message);
}
};
const GetSeats = async () => {
const getSeatLayout = async () => {
setisLoading(false);
try {
setSeats([]);
const response = await api.GetSeats();
setSeats(response);
setSeatLayout([]);
const response = await api.getSeatLayout();
setSeatLayout(response);
setisLoading(true);
} catch (err) {
toast.error(err.message);
......@@ -67,13 +92,14 @@ export function ContextProvider({ children }) {
};
const value = {
userseats,
userSeats,
reservedSeats,
isLoading,
seats,
LoginOrRegister,
AddOrUpdateSeats,
GetAllSeats,
GetSeats,
seatLayout,
loginOrRegister,
addOrUpdateSeats,
getAllReservedSeats,
getSeatLayout,
};
return <AppContext.Provider value={value}>{children}</AppContext.Provider>;
}
......@@ -18,13 +18,6 @@ code {
monospace;
}
.label {
color: #6c6a6a;
}
.form > *:not(input) {
padding: 17px;
}
input[type="number"]::-webkit-inner-spin-button {
display: none;
}
......
......@@ -3,27 +3,30 @@ import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { ContextProvider } from "./_context";
import { ContextProvider } from "./context";
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { BrowserRouter as Router } from "react-router-dom";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<ContextProvider>
<App />
<Router>
<ContextProvider>
<App />
<ToastContainer
position="top-right"
autoClose={3000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
theme="colored"
/>
</ContextProvider>
<ToastContainer
position="top-right"
autoClose={3000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
theme="colored"
/>
</ContextProvider>
</Router>
);
// If you want to start measuring performance in your app, pass a function
......
const BASE_URL = process.env.REACT_APP_BASE_URL;
export async function Login({ mobile }) {
export async function login({ mobile }) {
// Attempt to fetch user data
const response = await fetch(`${BASE_URL}/users?mobile=${mobile}`);
const result = await response.json();
return result;
}
export async function Register({ mobile }) {
export async function register({ mobile }) {
// User not found, register
const user = await fetch(`${BASE_URL}/users`, {
method: "POST",
......@@ -18,8 +18,9 @@ export async function Register({ mobile }) {
return await user.json();
}
export async function AddSeats({ id, seats }) {
export async function addSeats({ id, seats }) {
//add seat
//here id = userid
const response = await fetch(`${BASE_URL}/reservedSeats `, {
method: "POST",
headers: { "Content-Type": "application/json" },
......@@ -28,7 +29,7 @@ export async function AddSeats({ id, seats }) {
return await response.json();
}
export async function UpdateSeats({ id, seats }) {
export async function updateSeats({ id, seats }) {
//update
const response = await fetch(`${BASE_URL}/reservedSeats/${id}`, {
method: "PUT",
......@@ -38,21 +39,17 @@ export async function UpdateSeats({ id, seats }) {
return await response.json();
}
export async function GetAllSeats() {
export async function getAllReservedSeats() {
const response = await fetch(`${BASE_URL}/reservedSeats`);
return await response.json();
}
export async function GetSeats() {
const response = await fetch(`${BASE_URL}/bookingSeats`);
export async function getSeatLayout() {
const response = await fetch(`${BASE_URL}/seatLayout`);
return await response.json();
}
export async function GetUserByMobile({ mobile }) {
export async function getUserByMobile({ mobile }) {
const response = await fetch(`${BASE_URL}/users?mobile=${mobile}`);
return await response.json();
}
export async function GetSeatById(id) {
const response = await fetch(`${BASE_URL}/reservedSeats/${id}`);
return await response.json();
}
import Confirmation from "../components/top-level/confirmation";
import { useLocation, useNavigate } from "react-router-dom";
import { useEffect, useState } from "react";
import { useAppContext } from "../_context";
import { useNavigate } from "react-router-dom";
import { useAppContext } from "../context";
import { useLocation } from "react-router-dom";
export function _Confirmation() {
const [count, setCount] = useState(0);
const [reservedseat, setReservedSeat] = useState([]);
let { GetSeatById } = useAppContext();
export function ConfirmationPage() {
let { getAllReservedSeats } = useAppContext();
const navigate = useNavigate();
const location = useLocation();
useEffect(() => {
getSeatById();
}, []);
const getSeatById = async () => {
if (location?.state?.seats.length) {
setCount(location.state.seats.length);
setReservedSeat(location.state.seats);
} else {
const userid = sessionStorage.getItem("userId");
const userseats = await GetSeatById(userid);
setCount(userseats.seats.length);
setReservedSeat(userseats.seats);
}
};
const handleModify = (e) => {
const handleModify = async (e) => {
e.preventDefault();
await getAllReservedSeats();
navigate("/booking");
};
return (
<Confirmation
seatCount={count}
seats={reservedseat}
seatCount={location?.state?.seats?.length}
seats={location?.state?.seats}
onEdit={handleModify}
/>
);
......
import { useEffect, useState } from "react";
import { useAppContext } from "../_context";
import { useEffect } from "react";
import { useAppContext } from "../context";
import Login from "../components/top-level/login";
import { useNavigate } from "react-router-dom";
export function _Login() {
export function LoginPage() {
const navigate = useNavigate();
const { userseats, LoginOrRegister, GetAllSeats } = useAppContext();
const [isLogged, setIsLogged] = useState(false);
const { loginOrRegister } = useAppContext();
useEffect(() => {
sessionStorage.clear();
}, []);
useEffect(() => {
isLogged && handleSeats();
}, [isLogged]);
const handleLogin = async ({ mobile }) => {
//get all seats and then login
const users = await LoginOrRegister({ mobile });
sessionStorage.setItem("userId", users?.id);
await GetAllSeats();
setIsLogged(true);
};
const handleSeats = async () => {
const id = sessionStorage.getItem("userId");
const userReservedSeats = userseats.filter((e) => e.id == id);
if (!userReservedSeats.length) {
const isRegistered = await loginOrRegister({ mobile });
if (isRegistered) {
navigate("/seat-limit");
} else {
sessionStorage.setItem("seatLimit", userReservedSeats[0].seats.length);
navigate("/booking", { state: { seats: userseats } });
navigate("/booking");
}
};
return <Login onSubmit={handleLogin} />;
}
import { useEffect, useState } from "react";
import { useEffect } from "react";
import SeatLayout from "../components/top-level/seat-layout";
import { useAppContext } from "../_context";
import { useLocation, useNavigate } from "react-router-dom";
import { useAppContext } from "../context";
import { useNavigate } from "react-router-dom";
export function _Seatlayout() {
let { userseats, isLoading, seats, AddOrUpdateSeats, GetAllSeats, GetSeats } =
useAppContext();
export function SeatLayoutPage() {
let {
userSeats,
reservedSeats,
isLoading,
seatLayout,
addOrUpdateSeats,
getAllReservedSeats,
getSeatLayout,
} = useAppContext();
const [reservedSeat, setReservedSeat] = useState([]);
const [selectedSeat, setSelectedSeat] = useState([]);
const navigate = useNavigate();
const userId = sessionStorage.getItem("userId");
const seatLimit = sessionStorage.getItem("seatLimit");
const location = useLocation();
useEffect(() => {
GetSeats();
if (!location?.state?.seats.length) {
GetAllSeats();
}
const handleBeforeUnload = (event) => {
// Check if the page is about to unload or refresh
if (event.type === "beforeunload") {
navigate("/booking", { replace: true });
}
};
window.addEventListener("beforeunload", handleBeforeUnload);
return () => {
window.removeEventListener("beforeunload", handleBeforeUnload);
};
}, []);
// useEffect(() => {
// GetSeats();
// const handleBeforeUnload = (event) => {
// // Check if the page is about to unload or refresh
// if (event.type === "beforeunload") {
// sessionStorage.setItem("pageload", true);
// }
// };
// window.addEventListener("beforeunload", handleBeforeUnload);
// return () => {
// window.removeEventListener("beforeunload", handleBeforeUnload);
// };
// }, []);
// useEffect(() => {
// const reloadPage = sessionStorage.getItem("pageload");
// reloadPage && GetAllSeats();
// }, []);
useEffect(() => {
handleReservedSeats();
}, [userseats]);
const handleReservedSeats = async () => {
let seatArray = [];
const selectedSeats = await userseats?.find((e) => e.id == userId);
const results = selectedSeats?.seats;
setSelectedSeat(results);
const reservedSeats = userseats?.filter((e) => e.id != userId);
reservedSeats?.forEach((element) => {
element?.seats.forEach((e) => {
seatArray = [...seatArray, e];
setReservedSeat(seatArray);
});
});
};
//it will check only on page refresh ,at the time of page refresh it will be empty
!reservedSeats.length && getAllReservedSeats();
getSeatLayout();
}, []);
const handleConfirmed = async ({ id, seats }) => {
await AddOrUpdateSeats({ id, seats });
await addOrUpdateSeats({ id, seats });
navigate("/confirmation", { state: { seats: seats } });
};
......@@ -75,9 +34,9 @@ export function _Seatlayout() {
isLoading={isLoading}
userId={userId}
seatLimit={seatLimit}
seats={seats}
selectedSeats={selectedSeat}
reservedSeats={reservedSeat}
seats={seatLayout}
selectedSeats={userSeats}
reservedSeats={reservedSeats}
onClick={handleConfirmed}
/>
);
......
import SeatLimit from "../components/top-level/seat-limit";
import { useNavigate } from "react-router-dom";
export function _seatLimit() {
export function SeatLimitPage() {
const navigate = useNavigate();
const handleLimit = (e) => {
sessionStorage.setItem("seatLimit", e.limit);
//for Auth Guard
sessionStorage.setItem("currentPath", "/booking");
navigate("/booking");
};
return <SeatLimit onLimit={handleLimit} />;
......
export const bookingSeats = [
[0, "A1", "A2", "A3", 0, "A4", "A5", "A6", 0],
["B1", "B2", "B3", "B4", 0, "B5", "B6", "B7", "B8"],
["C1", "C2", "C3", "C4", 0, "C5", "C6", "C7", "C8"],
["D1", "D2", "D3", "D4", 0, "D5", "D6", "D7", "D8"],
["E1", "E2", "E3", "E4", 0, "E5", "E6", "E7", "E8"],
["F1", "F2", "F3", "F4", 0, "F5", "F6", "F7", "F8"],
["G1", "G2", "G3", "G4", 0, "G5", "G6", "G7", "G8"],
[0, "H1", "H2", "H3", 0, "H4", "H5", "H7", 0],
];
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment