Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
Seat-Booking
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Sujeeth AV
Seat-Booking
Commits
3b117683
Commit
3b117683
authored
Jun 18, 2025
by
Sujeeth AV
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Your commit message here
parent
5e7a4928
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
446 additions
and
308 deletions
+446
-308
db.json
db.json
+59
-71
global.css
global.css
+3
-1
Api.js
src/Api/Api.js
+0
-1
App.jsx
src/App.jsx
+33
-4
Success.png
src/Assets/Success.png
+0
-0
ProtectedRoute.jsx
src/ProtectedRoute.jsx
+8
-0
Input.jsx
src/components/Form/form/Input.jsx
+13
-1
Styles.module.css
src/components/Form/form/Styles.module.css
+13
-0
Login.jsx
src/components/Forms/Login/Login.jsx
+16
-8
Login.module.css
src/components/Forms/Login/Login.module.css
+1
-5
Sign.jsx
src/components/Forms/SignUp/Sign.jsx
+4
-0
Index.jsx
src/components/Response/Index.jsx
+68
-28
Styles.module.css
src/components/Response/Styles.module.css
+139
-29
Styles.module.css
src/components/Top-level/Counter/Styles.module.css
+0
-10
Layout.jsx
src/components/Top-level/FInalLayout/Layout.jsx
+0
-44
Styles.module.css
src/components/Top-level/FInalLayout/Styles.module.css
+0
-75
Index.jsx
src/components/Top-level/SeatSelection/Index.jsx
+1
-0
Index.jsx
src/context/Index.jsx
+51
-23
Forms.jsx
src/pages/Forms.jsx
+6
-4
SeatBooking.jsx
src/pages/SeatBooking.jsx
+10
-1
SeatLimit.jsx
src/pages/SeatLimit.jsx
+5
-1
Styles.module.css
src/pages/Styles.module.css
+16
-2
No files found.
db.json
View file @
3b117683
...
...
@@ -91,127 +91,115 @@
],
"users"
:
[
{
"id"
:
"9500403346"
,
"Mobile"
:
"9500403346"
,
"Name"
:
"sujeeth"
},
{
"id"
:
"7418601450"
,
"Mobile"
:
"7418601450"
,
"Name"
:
"ravi"
"id"
:
"9677655288"
,
"Mobile"
:
"9677655288"
,
"Name"
:
"Anitha"
},
{
"id"
:
"9
087654321
"
,
"Mobile"
:
"9
087654321
"
,
"Name"
:
"
oggy
"
"id"
:
"9
597003337
"
,
"Mobile"
:
"9
597003337
"
,
"Name"
:
"
venkatesh
"
},
{
"id"
:
"
7894561230
"
,
"Mobile"
:
"
7894561230
"
,
"Name"
:
"
khan
"
"id"
:
"
9500403346
"
,
"Mobile"
:
"
9500403346
"
,
"Name"
:
"
Sujeeth
"
},
{
"id"
:
"
809765432
1"
,
"Mobile"
:
"
809765432
1"
,
"Name"
:
"
john
"
"id"
:
"
997605117
1"
,
"Mobile"
:
"
997605117
1"
,
"Name"
:
"
JK
"
},
{
"id"
:
"
9677655288
"
,
"Mobile"
:
"
9677655288
"
,
"Name"
:
"
anitha
"
"id"
:
"
7418601450
"
,
"Mobile"
:
"
7418601450
"
,
"Name"
:
"
Hari
"
},
{
"id"
:
"
9597003337
"
,
"Mobile"
:
"
9597003337
"
,
"Name"
:
"
venkatesh
"
"id"
:
"
7890654312
"
,
"Mobile"
:
"
7890654312
"
,
"Name"
:
"
Guru
"
},
{
"id"
:
"6
379757115
"
,
"Mobile"
:
"6
379757115
"
,
"Name"
:
"
Shaganaz
"
"id"
:
"6
543217890
"
,
"Mobile"
:
"6
543217890
"
,
"Name"
:
"
praba
"
}
],
"seats"
:
[
{
"userId"
:
"9087654321"
,
"seats"
:
[
"D4"
],
"status"
:
"booked"
,
"id"
:
"9192"
},
{
"userId"
:
"9500403346"
,
"seats"
:
[
"A1"
,
"A2"
],
"status"
:
"booked"
,
"id"
:
"7685"
},
{
"id"
:
"4d7f"
,
"userId"
:
"7418601450"
,
"userId"
:
"9677655288"
,
"seats"
:
[
"D1"
,
"D2"
,
"D3"
],
"status"
:
"booked"
"status"
:
"booked"
,
"id"
:
"4271"
},
{
"userId"
:
"
8097654321
"
,
"userId"
:
"
9597003337
"
,
"seats"
:
[
"E6"
,
"E7"
"E1"
,
"E2"
,
"E3"
,
"E4"
],
"status"
:
"booked"
,
"id"
:
"
164e
"
"id"
:
"
4fcc
"
},
{
"userId"
:
"9
677655288
"
,
"userId"
:
"9
500403346
"
,
"seats"
:
[
"
H1
"
"
F3
"
],
"status"
:
"booked"
,
"id"
:
"
aa34
"
"id"
:
"
b4fe
"
},
{
"userId"
:
"9
597003337
"
,
"userId"
:
"9
976051171
"
,
"seats"
:
[
"
E
1"
,
"
E
2"
"
F
1"
,
"
F
2"
],
"status"
:
"booked"
,
"id"
:
"
9213
"
"id"
:
"
40ef
"
},
{
"userId"
:
"
6379757115
"
,
"userId"
:
"
7418601450
"
,
"seats"
:
[
"B1"
,
"B2"
"G5"
,
"G6"
,
"G7"
,
"G8"
],
"status"
:
"booked"
,
"id"
:
"
89cd
"
"id"
:
"
a74a
"
},
{
"id"
:
"7ace"
,
"userId"
:
null
,
"userId"
:
"7890654312"
,
"seats"
:
[
"B1"
,
"B2"
,
"B3"
,
"B4"
,
"E5"
,
"E8"
"B5"
,
"B8"
,
"B6"
,
"B7"
,
"C1"
,
"C2"
,
"C3"
,
"C4"
],
"status"
:
"booked"
"status"
:
"booked"
,
"id"
:
"cf53"
},
{
"id"
:
"
ab59
"
,
"userId"
:
null
,
"id"
:
"
b883
"
,
"userId"
:
"6543217890"
,
"seats"
:
[
"B3"
,
"B4"
,
"E5"
,
"E7"
,
"E8"
],
"status"
:
"booked"
...
...
global.css
View file @
3b117683
...
...
@@ -6,12 +6,14 @@
}
body
{
background-color
:
#303fb6
;
font-family
:
"
Times New Roman"
,
Times
,
serif
;
font-family
:
"
Poppins"
,
sans-
serif
;
min-height
:
50
svh
;
height
:
100
svh
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
padding
:
1rem
;
margin
:
0
;
}
h2
{
font-size
:
1.5rem
;
...
...
src/Api/Api.js
View file @
3b117683
...
...
@@ -9,7 +9,6 @@ export const loginUser = async (mobile) => {
console
.
log
(
"Login User API response:"
,
res
.
data
);
return
res
.
data
.
length
?
res
.
data
[
0
]
:
null
;
};
export
const
saveSeat
=
async
({
userId
,
seats
})
=>
{
const
response
=
await
axios
.
post
(
`
${
BASE_URL
}
/seats`
,{
userId
,
...
...
src/App.jsx
View file @
3b117683
...
...
@@ -5,15 +5,44 @@ import { SeatLimit } from "./pages/SeatLimit";
import
{
Summary
}
from
"./components/Response/Index"
;
import
{
LoginPage
}
from
"./pages/Forms"
;
import
{
ContextProvider
}
from
"./context/Index"
;
import
{
ProtectedRoute
}
from
"./ProtectedRoute"
;
function
App
()
{
return
(
<
ContextProvider
>
<
Routes
>
<
Route
path=
"/signup"
element=
{
<
LoginPage
/>
}
/>
<
Route
path=
"/"
element=
{
<
LoginPage
/>
}
/>
<
Route
path=
"/seat-limit"
element=
{
<
SeatLimit
/>
}
/>
<
Route
path=
"/booking"
element=
{
<
SeatBooking
/>
}
/>
<
Route
path=
"booking-summary"
element=
{
<
Summary
/>
}
/>
<
Route
path=
"/signup"
element=
{
<
ProtectedRoute
>
<
LoginPage
/>
</
ProtectedRoute
>
}
/>
<
Route
path=
"/seat-limit"
element=
{
<
ProtectedRoute
>
<
SeatLimit
/>
</
ProtectedRoute
>
}
/>
<
Route
path=
"/booking"
element=
{
<
ProtectedRoute
>
<
SeatBooking
/>
</
ProtectedRoute
>
}
/>
<
Route
path=
"Ticket"
element=
{
<
ProtectedRoute
>
<
Summary
/>
</
ProtectedRoute
>
}
/>
</
Routes
>
</
ContextProvider
>
);
...
...
src/Assets/Success.png
View replaced file @
5e7a4928
View file @
3b117683
265 KB
|
W:
|
H:
257 KB
|
W:
|
H:
2-up
Swipe
Onion skin
src/ProtectedRoute.jsx
0 → 100644
View file @
3b117683
import
{
Navigate
}
from
"react-router-dom"
;
export
const
ProtectedRoute
=
({
children
})
=>
{
const
isLoggedIn
=
!!
(
localStorage
.
getItem
(
"userId"
)
||
sessionStorage
.
getItem
(
"userId"
)
);
return
isLoggedIn
?
children
:
<
Navigate
to=
"/"
replace
/>;
};
src/components/Form/form/Input.jsx
View file @
3b117683
import
styles
from
"./Styles.module.css"
;
export
const
Input
=
({
value
,
onChange
,
placeholder
,
type
,
...
props
})
=>
{
export
const
Input
=
({
value
,
onChange
,
placeholder
,
type
,
icon
:
Icon
,
...
props
})
=>
{
return
(
<
div
className=
{
styles
.
input
}
>
{
Icon
&&
(
<
span
className=
{
styles
.
icon
}
>
<
Icon
/>
</
span
>
)
}
<
input
value=
{
value
}
placeholder=
{
placeholder
}
...
...
src/components/Form/form/Styles.module.css
View file @
3b117683
...
...
@@ -6,6 +6,7 @@ input {
font-size
:
1rem
;
width
:
100%
;
margin-bottom
:
1rem
;
padding-left
:
1.3rem
;
}
input
:focus
{
outline
:
none
;
...
...
@@ -15,3 +16,15 @@ input:focus {
display
:
flex
;
flex-direction
:
start
;
}
.icon
{
position
:
absolute
;
display
:
flex
;
justify-content
:
start
;
align-items
:
end
;
margin-top
:
17px
;
margin-left
:
9px
;
color
:
grey
;
}
input
{
padding-left
:
30px
;
}
src/components/Forms/Login/Login.jsx
View file @
3b117683
import
React
,
{
useState
}
from
"react"
;
import
{
useState
}
from
"react"
;
import
{
Header
}
from
"../../Layout/Card/Header"
;
import
{
Input
}
from
"../../Form/form/Input"
;
import
{
Button
}
from
"../../Form/Button/Button"
;
import
styles
from
"./Login.module.css"
;
import
{
toast
,
ToastContainer
}
from
"react-toastify"
;
import
Home
from
"../../../Assets/Login.png"
;
import
{
Link
}
from
"react-router-dom"
;
import
{
Sign
}
from
"../SignUp/Sign"
;
import
{
FaPhoneAlt
}
from
"react-icons/fa"
;
export
const
Login
=
({
onClick
,
onSwitch
})
=>
{
const
[
value
,
setValue
]
=
useState
(
""
);
const
[
islesser
,
setIsLesser
]
=
useState
(
false
);
const
InputChange
=
(
e
)
=>
{
setValue
(
e
.
target
.
value
);
const
updated
=
e
.
target
.
value
;
console
.
log
(
"executed"
);
if
(
/^
\d{0,10}
$/
.
test
(
updated
))
{
setValue
(
updated
);
}
};
const
HandleButton
=
(
e
)
=>
{
e
.
preventDefault
();
if
(
!
/^
[
6-9
]\d{9}
$/
.
test
(
value
))
{
toast
.
info
(
"Please enter a valid 10-digit number"
);
return
;
}
if
(
value
.
length
<
10
)
{
setIsLesser
(
true
);
toast
.
error
(
"Mobile Number is less than 10"
);
...
...
@@ -39,11 +45,13 @@ export const Login = ({ onClick, onSwitch }) => {
<
div
className=
{
styles
.
form
}
>
<
div
className=
{
styles
.
inp
}
>
<
Input
placeholder=
"Enter Your Number"
type=
"text"
placeholder=
"Enter Your Mobile Number"
value=
{
value
}
onChange=
{
InputChange
}
required
type=
"tel"
pattern=
"[6-9][0-9]{9}"
min=
"0"
icon=
{
FaPhoneAlt
}
/>
</
div
>
{
islesser
&&
(
...
...
src/components/Forms/Login/Login.module.css
View file @
3b117683
@import
url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap")
;
@import
url("https://fonts.googleapis.com/icon?family=Material+Icons")
;
body
{
font-family
:
"Poppins"
,
sans-serif
;
}
.container
{
min-height
:
100vh
;
display
:
flex
;
...
...
@@ -42,7 +38,7 @@ body {
.form
{
display
:
flex
;
flex-direction
:
column
;
gap
:
1
rem
;
gap
:
0.3
rem
;
}
.inp
{
...
...
src/components/Forms/SignUp/Sign.jsx
View file @
3b117683
...
...
@@ -5,6 +5,8 @@ import { Header } from "../../Layout/Card/Header";
import
style
from
"./Styles.module.css"
;
import
{
ToastContainer
}
from
"react-toastify"
;
import
{
toast
}
from
"react-toastify"
;
import
{
FaPhoneAlt
}
from
"react-icons/fa"
;
import
{
TiSortAlphabetically
}
from
"react-icons/ti"
;
export
const
Sign
=
({
onClick
,
onChange
,
onSwitch
})
=>
{
const
[
num
,
setNum
]
=
useState
(
""
);
...
...
@@ -65,6 +67,7 @@ export const Sign = ({ onClick, onChange, onSwitch }) => {
type=
"text"
pattern=
"[6-9][0-9]{9}"
min=
"0"
icon=
{
FaPhoneAlt
}
/>
</
div
>
<
div
className=
{
style
.
Inpname
}
>
...
...
@@ -74,6 +77,7 @@ export const Sign = ({ onClick, onChange, onSwitch }) => {
onChange=
{
Name
}
type=
"text"
maxLength=
{
255
}
icon=
{
TiSortAlphabetically
}
/>
</
div
>
<
div
className=
{
style
.
signbtn
}
>
...
...
src/components/Response/Index.jsx
View file @
3b117683
import
React
from
"react"
;
import
styles
from
"./Styles.module.css"
;
import
{
useLocation
,
useNavigate
}
from
"react-router-dom"
;
import
{
Button
}
from
"../Form/Button/Button"
;
import
{
IoMdLogOut
}
from
"react-icons/io"
;
import
{
MdHome
,
MdCheckCircle
}
from
"react-icons/md"
;
import
{
RiArrowGoBackLine
}
from
"react-icons/ri"
;
import
styles
from
"./Styles.module.css"
;
import
Success
from
"../../Assets/Success.png"
;
import
Failed
from
"../../Assets/Failed.png"
;
import
QRCode
from
"../../Assets/QRcode.png"
;
import
Ticket
from
"../../Assets/Success.png"
;
export
const
Summary
=
({
success
:
propSuccess
})
=>
{
const
navigate
=
useNavigate
();
const
location
=
useLocation
();
const
currentDateTime
=
new
Date
().
toLocaleString
();
const
success
=
propSuccess
??
location
.
state
?.
success
;
const
onLogout
=
()
=>
{
console
.
log
(
"exit"
);
navigate
(
"/"
);
};
const
bookingInfo
=
location
.
state
?.
bookingInfo
;
const
onLogout
=
()
=>
navigate
(
"/"
);
const
onBack
=
()
=>
navigate
(
"/seat-limit"
);
return
(
<
div
>
<
div
className=
{
styles
.
pageContainer
}
>
{
success
===
true
?
(
<
div
className=
{
styles
.
success
}
>
{
console
.
log
(
"Worked"
)
}
<
img
src=
{
Ticket
}
alt=
"Success"
className=
{
styles
.
symbol
}
/>
<
h2
className=
{
styles
.
hd
}
>
🎉 Hooray!!! Successfully Booked
</
h2
>
<
img
src=
{
QRCode
}
alt=
"QR-Code"
className=
{
styles
.
qr
}
/>
<
p
className=
{
styles
.
timeStamp
}
>
Booked On:
{
currentDateTime
}
</
p
>
<
div
className=
{
styles
.
logout
}
>
<
Button
onClick=
{
onLogout
}
>
<
IoMdLogOut
className=
{
styles
.
logoutIcon
}
/>
</
Button
>
<
div
>
<
MdCheckCircle
className=
{
styles
.
symbol
}
/>
</
div
>
<
h1
className=
{
styles
.
hd
}
>
Booking Confirmed!
</
h1
>
<
p
className=
{
styles
.
subtitle
}
>
Your tickets are ready. Enjoy the show!
</
p
>
<
div
className=
{
styles
.
qrContainer
}
>
<
img
src=
{
Success
}
alt=
"QR code"
className=
{
styles
.
qr
}
/>
<
p
className=
{
styles
.
qrNote
}
>
Scan this QR code at the entrance
</
p
>
</
div
>
{
bookingInfo
&&
(
<
div
className=
{
styles
.
info
}
>
<
div
className=
{
styles
.
row
}
>
<
span
className=
{
styles
.
label
}
>
Movie
</
span
>
<
span
className=
{
styles
.
value
}
>
Thug Life
</
span
>
</
div
>
<
div
className=
{
styles
.
row
}
>
<
span
className=
{
styles
.
label
}
>
Seats
</
span
>
<
div
className=
{
styles
.
seatWrapper
}
>
{
bookingInfo
.
seats
?.
map
((
seat
,
i
)
=>
(
<
span
key=
{
i
}
className=
{
styles
.
seatPill
}
>
{
seat
}
</
span
>
))
}
</
div
>
</
div
>
<
div
className=
{
styles
.
row
}
>
<
span
className=
{
styles
.
label
}
>
User Number
</
span
>
<
span
className=
{
styles
.
value
}
>
{
bookingInfo
.
userId
}
</
span
>
</
div
>
<
div
className=
{
styles
.
row
}
>
<
span
className=
{
styles
.
label
}
>
Booked On
</
span
>
<
span
className=
{
styles
.
value
}
>
{
bookingInfo
.
time
}
</
span
>
</
div
>
</
div
>
)
}
<
button
onClick=
{
onBack
}
className=
{
styles
.
downloadBtn
}
>
<
RiArrowGoBackLine
className=
{
styles
.
icon
}
/>
<
span
>
Book More Tickets
</
span
>
</
button
>
<
button
onClick=
{
onLogout
}
className=
{
styles
.
homeBtn
}
>
<
MdHome
className=
{
styles
.
icon
}
/>
<
span
>
Back to Home
</
span
>
</
button
>
</
div
>
)
:
(
<
div
className=
{
styles
.
error
}
>
{
console
.
log
(
"Failed"
)
}
<
img
src=
{
Failed
}
alt=
"Failed"
className=
{
styles
.
symbol
}
/>
<
h2
>
Something Went Wrong
</
h2
>
<
p
className=
{
styles
.
timeStamp
}
>
Booked On:
{
currentDateTime
}
</
p
>
<
div
className=
{
styles
.
logout
}
>
<
Button
onClick=
{
onLogout
}
>
<
IoMdLogOut
className=
{
styles
.
logoutIcon
}
/>
</
Button
>
</
div
>
<
h2
className=
{
styles
.
hdError
}
>
Something Went Wrong
</
h2
>
<
p
className=
{
styles
.
timeStamp
}
>
Booked On:
{
new
Date
().
toLocaleString
()
}
</
p
>
<
button
onClick=
{
onLogout
}
className=
{
styles
.
homeBtn
}
>
<
IoMdLogOut
className=
{
styles
.
icon
}
/>
<
span
>
Back to Home
</
span
>
</
button
>
</
div
>
)
}
</
div
>
...
...
src/components/Response/Styles.module.css
View file @
3b117683
.success
,
.error
{
.pageContainer
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
justify-content
:
center
;
padding
:
2rem
1rem
;
text-align
:
center
;
min-height
:
80vh
;
min-height
:
100vh
;
padding
:
1rem
;
}
.success
{
background-color
:
#ffffff
;
padding
:
2rem
;
border-radius
:
1.5rem
;
max-width
:
500px
;
width
:
100%
;
text-align
:
center
;
box-shadow
:
0
10px
25px
rgba
(
0
,
0
,
0
,
0.1
);
}
.error
{
background-color
:
#fff1f1
;
padding
:
2rem
;
border-radius
:
1.5rem
;
max-width
:
500px
;
width
:
100%
;
text-align
:
center
;
border
:
1px
solid
#fca5a5
;
box-shadow
:
0
10px
25px
rgba
(
239
,
68
,
68
,
0.1
);
}
.symbol
{
width
:
380px
;
height
:
300px
;
margin-bottom
:
1.5rem
;
font-size
:
64px
;
color
:
#22c55e
;
margin-bottom
:
1rem
;
}
.qr
{
width
:
128px
;
height
:
128px
;
border-radius
:
0.5rem
;
box-shadow
:
0
4px
10px
rgba
(
0
,
0
,
0
,
0.1
);
}
.qrContainer
{
background-color
:
#f3f4f6
;
padding
:
1.5rem
;
border-radius
:
1rem
;
margin-bottom
:
2rem
;
}
.qrNote
{
font-size
:
0.75rem
;
color
:
#6b7280
;
margin-top
:
0.5rem
;
}
.hd
{
font-size
:
1.5rem
;
font-weight
:
7
00
;
color
:
#
28a745
;
/* Success Green */
margin-bottom
:
1
rem
;
font-weight
:
6
00
;
color
:
#
1f2937
;
margin-bottom
:
0.5
rem
;
}
.error
.hd
{
color
:
#dc3545
;
/* Error Red */
.hdError
{
font-size
:
1.25rem
;
font-weight
:
600
;
color
:
#dc2626
;
margin-bottom
:
0.5rem
;
}
.qr
{
width
:
160px
;
height
:
auto
;
margin
:
1rem
0
;
border
:
1px
solid
#e0e0e0
;
border-radius
:
12px
;
padding
:
0.5rem
;
.subtitle
{
color
:
#4b5563
;
margin-bottom
:
2rem
;
}
.timeStamp
{
font-size
:
0.9rem
;
color
:
#555
;
margin
:
1rem
0
;
.info
{
margin-bottom
:
2rem
;
font-size
:
0.875rem
;
}
.row
{
display
:
flex
;
justify-content
:
space-between
;
margin-bottom
:
0.5rem
;
}
.label
{
color
:
#6b7280
;
}
.value
{
color
:
#1f2937
;
font-weight
:
500
;
}
.seatWrapper
{
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
0.25rem
;
margin-left
:
2rem
;
}
.seatPill
{
background-color
:
#e0e7ff
;
color
:
#4338ca
;
padding
:
0.25rem
0.75rem
;
border-radius
:
9999px
;
font-size
:
0.75rem
;
font-weight
:
500
;
}
.downloadBtn
{
width
:
100%
;
background-color
:
#4f46e5
;
color
:
white
;
font-weight
:
500
;
padding
:
0.75rem
1rem
;
border-radius
:
0.75rem
;
border
:
none
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
gap
:
0.5rem
;
box-shadow
:
0
4px
10px
rgba
(
0
,
0
,
0
,
0.1
);
transition
:
background-color
0.2s
ease
;
cursor
:
pointer
;
}
.downloadBtn
:hover
{
background-color
:
#4338ca
;
}
.homeBtn
{
margin-top
:
1rem
;
width
:
100%
;
background-color
:
#e5e7eb
;
color
:
#374151
;
font-weight
:
500
;
padding
:
0.75rem
1rem
;
border-radius
:
0.75rem
;
border
:
none
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
gap
:
0.5rem
;
transition
:
background-color
0.2s
ease
;
cursor
:
pointer
;
}
.homeBtn
:hover
{
background-color
:
#d1d5db
;
}
.
logout
{
margin-top
:
1.
5rem
;
.
icon
{
font-size
:
1.2
5rem
;
}
.logoutIcon
{
font-size
:
1.2rem
;
color
:
#000
;
.timeStamp
{
font-size
:
0.875rem
;
color
:
#6b7280
;
margin-bottom
:
1rem
;
}
src/components/Top-level/Counter/Styles.module.css
View file @
3b117683
body
{
font-family
:
"Poppins"
,
sans-serif
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
justify-content
:
center
;
padding
:
1rem
;
margin
:
0
;
}
.container
{
width
:
100%
;
max-width
:
15rem
;
...
...
src/components/Top-level/FInalLayout/Layout.jsx
deleted
100644 → 0
View file @
5e7a4928
import
React
,
{
useState
}
from
'react'
import
{
Header
}
from
'../../Layout/Card/Header'
import
{
Screen
}
from
'../Screen/Screen'
;
import
{
Index
}
from
'../Seatposition/Index'
;
import
styles
from
'./Styles.module.css'
import
{
Button
}
from
'../../Form/Button/Button'
;
import
{
Legend
}
from
'../../Layout/Legend/Legend'
;
export
const
Layout
=
()
=>
{
const
[
selectedseat
,
SetSelectedSeat
]
=
useState
([]);
const
Confirm
=
()
=>
{
if
(
selectedseat
.
length
>
0
){
alert
(
'Are You Sure To Book Tickets'
);
}
else
{
alert
(
"Choose Minimun One Ticket To Proceed"
);
}
}
return
(
<>
<
Header
className=
{
styles
.
head
}
title=
"Choose Your Seats"
Color=
"white"
/>
<
div
className=
{
styles
.
center
}
>
<
div
className=
{
styles
.
screen
}
>
<
Screen
/>
</
div
>
<
div
className=
{
styles
.
seat
}
>
<
Index
selectedseat=
{
selectedseat
}
SetSelectedseat=
{
SetSelectedSeat
}
className=
'seats'
/>
</
div
>
</
div
>
<
div
className=
{
styles
.
btn
}
>
<
Button
backgroundColor=
"white"
label=
"Confirm"
primary=
{
true
}
onClick=
{
Confirm
}
/>
</
div
>
<
div
className=
'legend'
>
<
Legend
/>
</
div
>
</>
)
}
src/components/Top-level/FInalLayout/Styles.module.css
deleted
100644 → 0
View file @
5e7a4928
*
{
margin
:
0
;
padding
:
0
;
}
body
{
width
:
100%
;
height
:
60
svh
;
}
.head
{
text-align
:
center
;
margin-top
:
25rem
;
}
.seat
{
overflow
:
visible
;
position
:
relative
;
}
.seat
::before
{
content
:
attr
(
data-tooltip
);
position
:
relative
;
bottom
:
120%
;
left
:
50%
;
transform
:
translateX
(
-50%
);
color
:
#fff
;
padding
:
3px
6px
;
font-size
:
12px
;
white-space
:
nowrap
;
border-radius
:
4px
;
opacity
:
0
;
pointer-events
:
none
;
transition
:
opacity
0.2s
ease-in-out
;
z-index
:
10
;
}
.seat
:hover::before
{
opacity
:
1
;
}
.screen
{
display
:
flex
;
justify-content
:
center
;
margin-bottom
:
-5rem
;
position
:
relative
;
}
.center
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
gap
:
0
;
width
:
100%
;
}
.btn
{
margin-top
:
4rem
;
display
:
flex
;
justify-content
:
center
;
height
:
3rem
;
}
button
{
height
:
3rem
;
width
:
25%
;
border-radius
:
10px
;
cursor
:
pointer
;
font-weight
:
700
;
}
.legend
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
}
.log
{
display
:
flex
;
justify-content
:
end
;
}
src/components/Top-level/SeatSelection/Index.jsx
View file @
3b117683
...
...
@@ -81,6 +81,7 @@ export const SeatSelectionComponent = ({
children=
"Confirm"
backgroundColor=
"#fff"
onClick=
{
ConfirmSeat
}
disabled=
{
selectedseats
.
length
<
seatLimit
}
/>
</
div
>
</
div
>
...
...
src/context/Index.jsx
View file @
3b117683
import
{
createContext
,
useContext
,
useEffect
,
useState
}
from
"react"
;
import
*
as
api
from
"../Api/Api"
;
import
{
toast
}
from
"react-toastify"
;
import
{
toast
,
ToastContainer
}
from
"react-toastify"
;
import
{
useNavigate
}
from
"react-router-dom"
;
export
const
AppContext
=
createContext
();
...
...
@@ -18,30 +18,50 @@ export function ContextProvider({ children }) {
console
.
log
(
reservedSeats
);
const
login
OrRegister
=
async
({
mobile
,
nam
e
})
=>
{
const
login
User
=
async
({
mobil
e
})
=>
{
try
{
const
user
=
await
api
.
loginUser
(
mobile
);
if
(
!
user
)
{
console
.
log
(
"registering:"
,
mobile
,
name
);
const
response
=
await
api
.
register
({
mobile
,
name
});
console
.
log
(
"Registered:"
,
response
);
sessionStorage
.
setItem
(
"userId"
,
response
?.
id
);
await
getAllReservedSeats
();
navigate
(
"/seat-limit"
);
return
response
;
}
else
{
sessionStorage
.
setItem
(
"userId"
,
user
?.
id
);
const
response
=
await
getAllReservedSeats
();
const
userSelectedSeats
=
response
.
find
((
e
)
=>
e
.
userId
==
user
?.
id
);
sessionStorage
.
setItem
(
"seatLimit"
,
userSelectedSeats
?.
seats
?.
length
||
0
);
navigate
(
"/booking"
);
return
user
;
toast
.
error
(
"User not found. Sign up now."
);
console
.
log
(
"New User"
);
return
;
}
sessionStorage
.
setItem
(
"userId"
,
user
.
id
);
const
response
=
await
api
.
getSeat
();
const
userSelectedSeats
=
response
.
find
((
e
)
=>
e
.
userId
==
user
.
id
);
sessionStorage
.
setItem
(
"seatLimit"
,
userSelectedSeats
?.
seats
?.
length
||
0
);
navigate
(
"/seat-limit"
);
return
user
;
}
catch
(
err
)
{
toast
.
error
(
err
.
message
);
toast
.
error
(
err
.
message
||
"Login failed"
);
}
};
const
registerUser
=
async
({
mobile
,
name
})
=>
{
try
{
const
existingUser
=
await
api
.
loginUser
(
mobile
);
if
(
existingUser
)
{
toast
.
error
(
"Mobile number already registered. Please log in."
);
navigate
(
"/"
);
return
;
}
const
newUser
=
await
api
.
register
({
mobile
,
name
});
sessionStorage
.
setItem
(
"userId"
,
newUser
.
id
);
sessionStorage
.
setItem
(
"seatLimit"
,
"0"
);
toast
.
success
(
"Signup successful!"
);
navigate
(
"/"
);
return
newUser
;
}
catch
(
err
)
{
toast
.
error
(
err
.
message
||
"Signup failed"
);
}
};
...
...
@@ -83,9 +103,11 @@ export function ContextProvider({ children }) {
api
.
getUserReservedSeats
(
id
),
]);
setReservedSeats
(
allReserved
);
setUserSeats
(
userReserved
);
setUserSeats
({
userId
:
id
,
seats
:
userReserved
});
return
true
;
}
catch
(
err
)
{
toast
.
error
(
err
.
message
||
"Something went wrong."
);
return
false
;
}
};
...
...
@@ -129,11 +151,17 @@ export function ContextProvider({ children }) {
reservedSeats
,
isLoading
,
seatLayout
,
loginOrRegister
,
loginUser
,
registerUser
,
addOrUpdateSeats
,
getAllReservedSeats
,
getSeatLayout
,
};
return
<
AppContext
.
Provider
value=
{
value
}
>
{
children
}
</
AppContext
.
Provider
>;
return
(
<
AppContext
.
Provider
value=
{
value
}
>
{
children
}
<
ToastContainer
position=
"top-right"
autoClose=
{
3000
}
/>
</
AppContext
.
Provider
>
);
}
src/pages/Forms.jsx
View file @
3b117683
...
...
@@ -7,7 +7,7 @@ import { useNavigate } from "react-router-dom";
export
const
LoginPage
=
()
=>
{
const
navigate
=
useNavigate
();
const
{
login
OrRegist
er
}
=
useAppContext
();
const
{
login
User
,
registerUs
er
}
=
useAppContext
();
const
[
showLogin
,
setShowLogin
]
=
useState
(
true
);
useEffect
(()
=>
{
...
...
@@ -15,12 +15,14 @@ export const LoginPage = () => {
},
[]);
const
handlelogin
=
async
({
mobile
})
=>
{
await
loginOrRegister
({
mobile
});
navigate
(
"/seat-limit"
);
const
res
=
await
loginUser
({
mobile
});
if
(
res
)
{
navigate
(
"/seat-limit"
);
}
};
const
handleSignup
=
async
({
name
,
mobile
})
=>
{
const
res
=
await
loginOrRegist
er
({
name
,
mobile
});
const
res
=
await
registerUs
er
({
name
,
mobile
});
console
.
log
(
"registered"
,
res
);
setShowLogin
(
true
);
};
...
...
src/pages/SeatBooking.jsx
View file @
3b117683
...
...
@@ -112,7 +112,16 @@ function SeatBooking() {
sessionStorage
.
setItem
(
"selectedSeats"
,
JSON
.
stringify
(
validSeats
));
if
(
typeof
clearSelection
===
"function"
)
clearSelection
();
navigate
(
"/booking-summary"
,
{
state
:
{
success
:
true
}
});
navigate
(
"/Ticket"
,
{
state
:
{
success
:
true
,
bookingInfo
:
{
userId
,
seats
:
validSeats
,
time
:
new
Date
().
toLocaleString
(),
},
},
});
}
catch
(
error
)
{
console
.
error
(
"Error saving seats:"
,
error
);
toast
.
error
(
"Failed to reserve seats. Please try again."
);
...
...
src/pages/SeatLimit.jsx
View file @
3b117683
...
...
@@ -2,6 +2,7 @@ import React from "react";
import
Counter
from
"../components/Top-level/Counter/Counter"
;
import
{
useAppContext
}
from
"../context/Index"
;
import
styles
from
"./Styles.module.css"
;
import
{
MdEventSeat
}
from
"react-icons/md"
;
export
const
SeatLimit
=
()
=>
{
const
totalSeats
=
60
;
const
{
reservedSeats
}
=
useAppContext
();
...
...
@@ -14,7 +15,10 @@ export const SeatLimit = () => {
return
(
<>
<
p
className=
{
styles
.
line
}
>
Remaining Seats Available:
{
Seat
}
</
p
>
<
div
className=
{
styles
.
seat
}
>
<
MdEventSeat
className=
{
styles
.
icon
}
/>
<
p
className=
{
styles
.
line
}
>
Remaining Seats Available:
{
Seat
}
</
p
>
</
div
>
<
Counter
onSubmit=
{
handleSeat
}
/>
</>
);
...
...
src/pages/Styles.module.css
View file @
3b117683
...
...
@@ -42,12 +42,20 @@
color
:
#c7d2fe
;
font-weight
:
500
;
margin-bottom
:
1rem
;
text-align
:
center
;
font-family
:
"Inter"
,
sans-serif
;
display
:
flex
;
justify-content
:
center
;
margin-left
:
1rem
;
}
.line
p
{
text-align
:
center
;
}
.icon
{
color
:
#fff
;
position
:
absolute
;
margin-left
:
0.5rem
;
margin-top
:
4px
;
}
@media
(
min-width
:
768px
)
{
.container
{
display
:
flex
;
...
...
@@ -62,4 +70,10 @@
.login
{
min-width
:
40rem
;
}
.icon
{
margin-left
:
3.5rem
;
}
.line
{
margin-left
:
2rem
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment