Commit 2beef710 by Syed Abdul Rahman

implemented toast message and api call fixes

parent 4505dda8
VITE_API_URL=http://192.168.1.73:3000
\ No newline at end of file
VITE_API_URL=http://localhost:3000
\ No newline at end of file
{
"users": [
{
"id": "0b2d",
"id": "7e7e",
"email": "syedabdul.rahman@krds.com"
},
{
"id": "1d58",
"id": "6e20",
"email": "abdul@gmail.com"
},
{
"id": "42f0",
"email": "lucy@gmail.com"
},
{
"id": "e770",
"email": "new@gmail.com"
},
{
"id": "5f85",
"email": "test@krds.fr"
},
{
"id": "5647",
"email": "anas@krds.fr"
},
{
"id": "ad86",
"email": "test@gmail.com"
}
],
"selectedSeats": [
{
"id": "0b2d",
"userid": "0b2d",
"id": "7e7e",
"userid": "7e7e",
"selected": [
{
"row": 7,
"seat": 5
},
{
"row": 6,
"seat": 5
},
{
"row": 8,
"seat": 4
}
]
},
{
"id": "1d58",
"userid": "1d58",
"selected": [
{
"row": 8,
"seat": 5
"seat": "H4"
},
{
"row": 8,
"seat": 6
},
{
"row": 7,
"seat": 7
}
]
},
{
"id": "42f0",
"userid": "42f0",
"selected": [
{
"row": 6,
"seat": 1
"seat": "H5"
},
{
"row": 6,
"seat": 2
},
{
"row": 6,
"seat": 3
},
{
"row": 6,
"seat": 4
}
]
},
{
"id": "5f85",
"userid": "5f85",
"selected": [
{
"row": 4,
"seat": 3
},
{
"row": 6,
"seat": 6
},
{
"row": 5,
"seat": 1
},
{
"row": 5,
"seat": 7
"row": 8,
"seat": "H6"
}
]
},
{
"id": "5647",
"userid": "5647",
"id": "6e20",
"userid": "6e20",
"selected": [
{
"row": 7,
"seat": 8
"seat": "G1"
},
{
"row": 7,
"seat": 6
}
]
},
{
"id": "e770",
"userid": "e770",
"selected": [
{
"row": 7,
"seat": 2
"seat": "G3"
},
{
"row": 7,
"seat": 3
}
]
},
{
"id": "ad86",
"userid": "ad86",
"selected": [
{
"row": 4,
"seat": 7
"seat": "G2"
},
{
"row": 4,
"seat": 8
"row": 7,
"seat": "G4"
}
]
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "seat-booking",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite --host",
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"dependencies": {
"lottie-react": "^2.4.1",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-router-dom": "^7.6.2"
},
"devDependencies": {
"@chromatic-com/storybook": "^4.0.0",
"@eslint/js": "^9.25.0",
"@storybook/addon-a11y": "^9.0.4",
"@storybook/addon-docs": "^9.0.4",
"@storybook/addon-onboarding": "^9.0.4",
"@storybook/addon-vitest": "^9.0.4",
"@storybook/react-vite": "^9.0.4",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
"@vitejs/plugin-react": "^4.4.1",
"@vitest/browser": "^3.2.0",
"@vitest/coverage-v8": "^3.2.0",
"eslint": "^9.25.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.19",
"eslint-plugin-storybook": "^9.0.4",
"globals": "^16.0.0",
"playwright": "^1.52.0",
"prop-types": "^15.8.1",
"storybook": "^9.0.4",
"vite": "^6.3.5",
"vitest": "^3.2.0"
}
"name": "seat-booking",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite --host",
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"server": "node server.cjs"
},
"dependencies": {
"lottie-react": "^2.4.1",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-router-dom": "^7.6.2"
},
"devDependencies": {
"@chromatic-com/storybook": "^4.0.0",
"@eslint/js": "^9.25.0",
"@storybook/addon-a11y": "^9.0.4",
"@storybook/addon-docs": "^9.0.4",
"@storybook/addon-onboarding": "^9.0.4",
"@storybook/addon-vitest": "^9.0.4",
"@storybook/react-vite": "^9.0.4",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
"@vitejs/plugin-react": "^4.4.1",
"@vitest/browser": "^3.2.0",
"@vitest/coverage-v8": "^3.2.0",
"eslint": "^9.25.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.19",
"eslint-plugin-storybook": "^9.0.4",
"globals": "^16.0.0",
"json-server": "^1.0.0-beta.3",
"playwright": "^1.52.0",
"prop-types": "^15.8.1",
"storybook": "^9.0.4",
"vite": "^6.3.5",
"vitest": "^3.2.0"
}
}
......@@ -2,7 +2,12 @@ import PropTypes from 'prop-types';
import styles from './styles.module.css';
const Seat = ({ id, status, ...rest }) => {
return <div {...rest} className={` ${styles[status]} ${styles.seat} `}></div>;
return (
<div
{...rest}
title={id}
className={` ${styles[status]} ${styles.seat} `}></div>
);
};
Seat.propTypes = {
......
import styles from './/styles.module.css';
const Toast = ({ message, type = 'info', onClose }) => {
return (
<div className={`${styles.toast} ${styles[type]}`}>
<span>{message}</span>
<button onClick={onClose}>&times;</button>
</div>
);
};
export default Toast;
/* toast.css */
.toast {
position: fixed;
bottom: 20px;
right: 20px;
background-color: #333;
color: white;
padding: 12px 16px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
display: flex;
align-items: center;
gap: 10px;
z-index: 9999;
animation: slideIn 0.3s ease-out;
}
.toast.success {
background-color: #28a745;
}
.toast.error {
background-color: #dc3545;
}
.toast.info {
background-color: #007bff;
}
.toast button {
background: transparent;
border: none;
color: white;
font-size: 16px;
cursor: pointer;
}
@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
export const login = async (email) => {
try {
const response = await fetch(`${import.meta.env.VITE_API_URL}/users`);
const response = await fetch(
`${import.meta.env.VITE_API_URL}/users?email=${email}`
);
const data = await response.json();
const user = data.find((e) => e.email === email);
return user;
// const user = data.find((e) => e.email === email);
return data;
} catch (error) {
console.error('Login error:', error);
throw error;
......
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'
import { BrowserRouter } from 'react-router-dom'
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App.jsx';
import { BrowserRouter } from 'react-router-dom';
createRoot(document.getElementById('root')).render(
// <StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
// </StrictMode>,
)
<BrowserRouter>
<App />
</BrowserRouter>
// </StrictMode>
);
......@@ -12,16 +12,17 @@ import LogoutButton from '@components/Shared/LogoutButton/Index';
import { getItem, reset, setItem } from '../../lib/sessionStorage';
import { appConstants } from '@lib/AppConstants';
import { getSelectedSeatsApi, editSeatsApi, createSeatApi } from '@lib/api';
import Toast from '@components/Shared/Toast/Index';
const data = [
['*', 1, 2, 3, '*', 4, 5, 6, '*'],
[1, 2, 3, 4, '*', 5, 6, 7, 8],
[1, 2, 3, 4, '*', 5, 6, 7, 8],
[1, 2, 3, 4, '*', 5, 6, 7, 8],
[1, 2, 3, 4, '*', 5, 6, 7, 8],
[1, 2, 3, 4, '*', 5, 6, 7, 8],
[1, 2, 3, 4, '*', 5, 6, 7, 8],
['*', 1, 2, 3, '*', 4, 5, 6, '*']
['*', 'A1', 'A2', 'A3', '*', 'A4', 'A5', 'A6', '*'],
['B1', 'B2', 'B3', 'B4', '*', 'B5', 'B6', 'B7', 'B8'],
['C1', 'C2', 'C3', 'C4', '*', 'C5', 'C6', 'C7', 'C8'],
['D1', 'D2', 'D3', 'D4', '*', 'D5', 'D6', 'D7', 'D8'],
['E1', 'E2', 'E3', 'E4', '*', 'E5', 'E6', 'E7', 'E8'],
['F1', 'F2', 'F3', 'F4', '*', 'F5', 'F6', 'F7', 'F8'],
['G1', 'G2', 'G3', 'G4', '*', 'G5', 'G6', 'G7', 'G8'],
['*', 'H1', 'H2', 'H3', '*', 'H4', 'H5', 'H6', '*']
];
const BookingPage = () => {
......@@ -39,15 +40,26 @@ const BookingPage = () => {
const [buttonState, setButtonState] = useState(true);
const [modalButtonState, setModalButtonState] = useState(true);
const [showSuccessModal, setShowSuccessModal] = useState(false);
const [toast, setToast] = useState(null);
useEffect(() => {
fetchSelectedSeats();
setShowSeatsModal(getItem(appConstants.MODAL));
const initializeSeatsData = async () => {
await fetchSelectedSeats();
setShowSeatsModal(getItem(appConstants.MODAL));
};
initializeSeatsData();
}, []);
const fetchSelectedSeats = async () => {
try {
const data = await getSelectedSeatsApi();
const currentData = data?.find((e) => e.userid == userId);
if (currentData?.selected?.length > 0) {
setItem('modal', false);
} else {
setItem('modal', true);
}
const structuredData = data.flatMap((user) => user.selected);
const temp = structuredData?.filter(
......@@ -128,6 +140,7 @@ const BookingPage = () => {
}
} else {
updatedSeats = prev ? [...prev] : [];
showToast('Seat Count Exeeded', 'info');
}
return updatedSeats;
});
......@@ -164,6 +177,11 @@ const BookingPage = () => {
setButtonState(true);
};
const showToast = (message, type = 'info') => {
setToast({ message, type });
setTimeout(() => setToast(null), 3000);
};
return (
<>
<LogoutButton onLogout={logout} />
......@@ -194,6 +212,14 @@ const BookingPage = () => {
{showSuccessModal && (
<SuccessModal onConfirm={handleSuccessModalConfirm} />
)}
{toast && (
<Toast
message={toast.message}
type={toast.type}
onClose={() => setToast(null)}
/>
)}
</>
);
};
......
......@@ -9,32 +9,13 @@ const LoginPage = () => {
const onSubmit = async (email) => {
try {
const userData = await login(email);
const fetchSeatSelectionCount = async (id) => {
try {
const data = await getSelectedSeatsApi();
const currentData = data?.find((e) => e.userid == id);
if (currentData?.selected?.length > 0) {
setItem('modal', false);
} else {
setItem('modal', true);
}
navigate('/');
} catch (error) {
console.error('Error fetching seat selection count:', error);
}
};
if (userData) {
setItem('user', userData.id);
fetchSeatSelectionCount(userData?.id);
if (userData?.length > 0) {
setItem('user', userData[0].id);
} else {
const data = await createUser(email);
setItem('user', data.id);
fetchSeatSelectionCount(data?.id);
}
navigate('/');
} catch (error) {
console.error('Error during login or user creation:', error);
}
......
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