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
Syed Abdul Rahman
seat-booking
Commits
e24cd69d
Commit
e24cd69d
authored
Jun 17, 2025
by
Syed Abdul Rahman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
success modal implemented
parent
3d107cda
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
240 additions
and
97 deletions
+240
-97
db.json
db.json
+4
-4
Button.stories.jsx
src/components/Base/Button/Button.stories.jsx
+117
-23
Index.jsx
src/components/Base/Button/Index.jsx
+19
-14
styles.module.css
src/components/Base/Button/styles.module.css
+15
-2
Index.jsx
src/components/Layout/BookingWrapper/Index.jsx
+35
-23
Index.jsx
src/components/Layout/Header/Index.jsx
+6
-8
Index.jsx
src/components/TopLevel/ConfirmSeatContent/Index.jsx
+2
-2
Index.jsx
src/components/TopLevel/SuccessModal/Index.jsx
+2
-2
SuccessModal.stories.jsx
...components/TopLevel/SuccessModal/SuccessModal.stories.jsx
+11
-0
styles.module.css
src/components/TopLevel/SuccessModal/styles.module.css
+7
-0
Index.jsx
src/pages/BookingPage/Index.jsx
+22
-19
No files found.
db.json
View file @
e24cd69d
...
...
@@ -40,19 +40,19 @@
"userid"
:
"5ebc"
,
"selected"
:
[
{
"row"
:
6
,
"row"
:
2
,
"seat"
:
5
},
{
"row"
:
6
,
"row"
:
2
,
"seat"
:
6
},
{
"row"
:
6
,
"row"
:
2
,
"seat"
:
7
},
{
"row"
:
5
,
"row"
:
2
,
"seat"
:
8
}
]
...
...
src/components/Base/Button/Button.stories.jsx
View file @
e24cd69d
import
Button
from
'./Index'
;
import
Space
from
'../../Layout/Space/Index'
import
Space
from
'../../Layout/Space/Index'
;
export
default
{
title
:
'Component/Base/Button'
,
tags
:
[
'autodocs'
],
component
:
Button
}
}
;
export
const
Default
=
{
export
const
Primary
=
{
args
:
{
primary
:
true
,
label
:
'Button'
,
label
:
'Button'
},
render
:
()
=>
{
return
(
<>
<
h2
style=
{
{
fontFamily
:
"Poppins-Medium"
,
color
:
'white'
}
}
>
Size
</
h2
>
<
h2
style=
{
{
fontFamily
:
'Poppins-Medium'
,
color
:
'white'
}
}
>
Size
</
h2
>
<
Space
>
<
Button
size=
{
"sm"
}
>
Button - SM
</
Button
>
<
Button
size=
{
"md"
}
>
Button - MD
</
Button
>
<
Button
size=
{
"lg"
}
>
Button - LG
</
Button
>
<
Button
size=
{
'sm'
}
>
Small
</
Button
>
<
Button
size=
{
'md'
}
>
Medium
</
Button
>
<
Button
size=
{
'lg'
}
>
Large
</
Button
>
</
Space
>
<
h2
style=
{
{
fontFamily
:
"Poppins-Medium"
,
color
:
'white'
}
}
>
Loader
</
h2
>
<
h2
style=
{
{
fontFamily
:
'Poppins-Medium'
,
color
:
'white'
}
}
>
Loader
</
h2
>
<
Space
>
<
Button
size=
{
"sm"
}
loading=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
"md"
}
loading=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
"lg"
}
loading=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
'sm'
}
loading=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
'md'
}
loading=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
'lg'
}
loading=
{
true
}
>
Button
</
Button
>
</
Space
>
<
h2
style=
{
{
fontFamily
:
"Poppins-Medium"
,
color
:
'white'
}
}
>
Disabled
</
h2
>
<
h2
style=
{
{
fontFamily
:
'Poppins-Medium'
,
color
:
'white'
}
}
>
Disabled
</
h2
>
<
Space
>
<
Button
size=
{
"sm"
}
disabled=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
"md"
}
disabled=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
"lg"
}
disabled=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
'sm'
}
disabled=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
'md'
}
disabled=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
'lg'
}
disabled=
{
true
}
>
Button
</
Button
>
</
Space
>
<
h2
style=
{
{
fontFamily
:
"Poppins-Medium"
,
color
:
'white'
}
}
>
Loading
&
Disabled
</
h2
>
<
h2
style=
{
{
fontFamily
:
'Poppins-Medium'
,
color
:
'white'
}
}
>
Loading
&
Disabled
</
h2
>
<
Space
>
<
Button
size=
{
"sm"
}
disabled=
{
true
}
loading=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
"md"
}
disabled=
{
true
}
loading=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
"lg"
}
disabled=
{
true
}
loading=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
'sm'
}
disabled=
{
true
}
loading=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
'md'
}
disabled=
{
true
}
loading=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
'lg'
}
disabled=
{
true
}
loading=
{
true
}
>
Button
</
Button
>
</
Space
>
</>
)
)
;
}
};
\ No newline at end of file
};
export
const
Secondary
=
{
render
:
()
=>
{
return
(
<>
<
h2
style=
{
{
fontFamily
:
'Poppins-Medium'
,
color
:
'white'
}
}
>
Size
</
h2
>
<
Space
>
<
Button
size=
{
'sm'
}
variant=
"secondary"
>
Small
</
Button
>
<
Button
size=
{
'md'
}
variant=
"secondary"
>
Medium
</
Button
>
<
Button
size=
{
'lg'
}
variant=
"secondary"
>
Large
</
Button
>
</
Space
>
<
h2
style=
{
{
fontFamily
:
'Poppins-Medium'
,
color
:
'white'
}
}
>
Loader
</
h2
>
<
Space
>
<
Button
size=
{
'sm'
}
variant=
"secondary"
loading=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
'md'
}
variant=
"secondary"
loading=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
'lg'
}
variant=
"secondary"
loading=
{
true
}
>
Button
</
Button
>
</
Space
>
<
h2
style=
{
{
fontFamily
:
'Poppins-Medium'
,
color
:
'white'
}
}
>
Disabled
</
h2
>
<
Space
>
<
Button
size=
{
'sm'
}
variant=
"secondary"
disabled=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
'md'
}
variant=
"secondary"
disabled=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
'lg'
}
variant=
"secondary"
disabled=
{
true
}
>
Button
</
Button
>
</
Space
>
<
h2
style=
{
{
fontFamily
:
'Poppins-Medium'
,
color
:
'white'
}
}
>
Loading
&
Disabled
</
h2
>
<
Space
>
<
Button
size=
{
'sm'
}
variant=
"secondary"
disabled=
{
true
}
loading=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
'md'
}
variant=
"secondary"
disabled=
{
true
}
loading=
{
true
}
>
Button
</
Button
>
<
Button
size=
{
'lg'
}
variant=
"secondary"
disabled=
{
true
}
loading=
{
true
}
>
Button
</
Button
>
</
Space
>
</>
);
}
};
src/components/Base/Button/Index.jsx
View file @
e24cd69d
import
PropTypes
from
'prop-types'
;
import
styles
from
'./styles.module.css'
;
const
Button
=
({
loading
,
size
,
disabled
,
children
,
...
props
})
=>
{
return
(
<
button
className=
{
`${styles.button} ${styles[size]} ${disabled ? styles['disabled'] : ''}`
}
{
...
props
}
>
{
loading
&&
<
div
className=
{
`${styles.loader} ${styles[`
loader
-
$
{
size
}
`]}`
}
></
div
>
}{
children
}
</
button
>
)
}
const
Button
=
({
loading
,
size
,
disabled
,
children
,
variant
,
...
props
})
=>
{
return
(
<
button
className=
{
`${styles.button} ${styles[variant]} ${styles[size]} ${
disabled ? styles['disabled'] : ''
}`
}
{
...
props
}
>
{
loading
&&
(
<
div
className=
{
`${styles.loader} ${styles[`
loader
-
$
{
size
}
`]}`
}
></
div
>
)
}
{
children
}
</
button
>
);
};
export
default
Button
;
Button
.
propTypes
=
{
children
:
PropTypes
.
node
.
isRequired
,
disabled
:
PropTypes
.
bool
,
onClick
:
PropTypes
.
func
,
size
:
PropTypes
.
string
,
loading
:
PropTypes
.
bool
}
\ No newline at end of file
children
:
PropTypes
.
node
.
isRequired
,
disabled
:
PropTypes
.
bool
,
size
:
PropTypes
.
string
,
loading
:
PropTypes
.
bool
};
src/components/Base/Button/styles.module.css
View file @
e24cd69d
.button
{
border
:
none
;
outline
:
none
;
background-color
:
white
;
color
:
black
;
border-radius
:
10px
;
font-family
:
'Poppins-Medium'
;
font-weight
:
500
;
...
...
@@ -15,6 +13,21 @@
box-sizing
:
border-box
;
}
.primary
{
background-color
:
white
;
color
:
black
;
}
.secondary
{
background-color
:
rgb
(
155
,
17
,
17
);
color
:
white
;
}
.secondary
:hover
{
background-color
:
rgba
(
244
,
10
,
10
,
0.852
)
!important
;
color
:
black
!important
;
}
.button
:hover
{
background-color
:
rgba
(
161
,
161
,
245
,
0.358
);
color
:
white
;
...
...
src/components/Layout/BookingWrapper/Index.jsx
View file @
e24cd69d
...
...
@@ -16,44 +16,56 @@ const BookingWrapper = ({
}
};
const
processedSeatData
=
seatData
?.
map
((
row
,
rowIndex
)
=>
row
.
map
((
seat
)
=>
{
if
(
seat
===
'*'
)
{
return
{
type
:
'gap'
};
}
const
foundInCurrentSeats
=
currentSeats
?.
find
(
(
e
)
=>
e
.
row
===
rowIndex
+
1
&&
e
.
seat
===
seat
);
const
foundInSelectedSeats
=
selectedSeats
?.
some
(
(
e
)
=>
e
.
row
===
rowIndex
+
1
&&
e
.
seat
===
seat
);
let
status
=
''
;
if
(
foundInCurrentSeats
)
status
=
'current-selected'
;
else
if
(
foundInSelectedSeats
)
status
=
'selected-by-other'
;
return
{
seat
,
row
:
rowIndex
+
1
,
status
};
})
);
return
(
<
div
className=
{
styles
[
'booking-wrapper'
]
}
>
<
div
className=
{
styles
[
'theatre'
]
}
>
{
seatData
?.
map
((
row
,
row_i
ndex
)
=>
(
<
div
key=
{
`row-${row
_i
ndex}`
}
className=
{
styles
[
'seat-row'
]
}
>
{
row
?.
map
((
seat
,
column_i
ndex
)
=>
{
if
(
seat
===
'*
'
)
{
{
processedSeatData
?.
map
((
row
,
rowI
ndex
)
=>
(
<
div
key=
{
`row-${row
I
ndex}`
}
className=
{
styles
[
'seat-row'
]
}
>
{
row
.
map
((
seatObj
,
colI
ndex
)
=>
{
if
(
seat
Obj
.
type
===
'gap
'
)
{
return
(
<
div
key=
{
`gap-${row
_index}-${column_i
ndex}`
}
key=
{
`gap-${row
Index}-${colI
ndex}`
}
className=
{
styles
[
'seat-gap'
]
}
/>
);
}
const
seatKey
=
`${row_index + 1}-${seat}`
;
let
seatClass
=
''
;
const
foundInCurrentSeats
=
currentSeats
?.
find
(
(
e
)
=>
e
.
row
===
row_index
+
1
&&
e
.
seat
===
seat
);
const
foundInSelectedSeats
=
selectedSeats
?.
some
(
(
e
)
=>
e
.
row
===
row_index
+
1
&&
e
.
seat
===
seat
);
if
(
foundInCurrentSeats
)
{
seatClass
=
'current-selected'
;
}
else
if
(
foundInSelectedSeats
)
{
seatClass
=
'selected-by-other'
;
}
const
seatKey
=
`${seatObj.row}-${seatObj.seat}`
;
return
(
<
Seat
key=
{
seatKey
}
status=
{
seat
Clas
s
}
id=
{
seat
}
status=
{
seat
Obj
.
statu
s
}
id=
{
seat
Obj
.
seat
}
onClick=
{
()
=>
handleSeatClick
(
row_index
+
1
,
seat
,
seatClas
s
)
handleSeatClick
(
seatObj
.
row
,
seatObj
.
seat
,
seatObj
.
statu
s
)
}
/>
);
...
...
src/components/Layout/Header/Index.jsx
View file @
e24cd69d
import
PropTypes
from
"prop-types"
;
import
styles
from
"./styles.module.css"
;
import
PropTypes
from
'prop-types'
;
import
styles
from
'./styles.module.css'
;
const
Header
=
({
children
})
=>
{
return
(
<
section
className=
{
styles
[
"header-wrapper"
]
}
>
<
section
className=
{
styles
[
'header-wrapper'
]
}
>
<
div
className=
{
styles
.
title
}
>
{
children
}
</
div
>
<
div
className=
{
styles
.
screenWrapper
}
>
{
/* <svg viewBox="0 20 480 100" xmlns="http://www.w3.org/2000/svg">
...
...
@@ -69,8 +69,7 @@ const Header = ({ children }) => {
y1=
"70"
x2=
"0"
y2=
"150"
gradientUnits=
"userSpaceOnUse"
>
gradientUnits=
"userSpaceOnUse"
>
<
stop
offset=
"0%"
stop
-
color=
"#9c6ad5"
stop
-
opacity=
"1"
/>
<
stop
offset=
"60%"
stop
-
color=
"#9c6ad5"
stop
-
opacity=
"1"
/>
<
stop
offset=
"100%"
stop
-
color=
"#9c6ad5"
stop
-
opacity=
"1"
/>
...
...
@@ -95,8 +94,7 @@ const Header = ({ children }) => {
y1=
"100"
x2=
"0"
y2=
"150"
gradientUnits=
"userSpaceOnUse"
>
gradientUnits=
"userSpaceOnUse"
>
<
stop
offset=
"0%"
stop
-
color=
"#9c6ad5"
stop
-
opacity=
"0.4"
/>
<
stop
offset=
"50%"
stop
-
color=
"#9c6ad5"
stop
-
opacity=
"0.2"
/>
<
stop
offset=
"100%"
stop
-
color=
"#9c6ad5"
stop
-
opacity=
"0"
/>
...
...
@@ -116,7 +114,7 @@ const Header = ({ children }) => {
};
Header
.
propTypes
=
{
children
:
PropTypes
.
node
.
isRequired
,
children
:
PropTypes
.
node
.
isRequired
};
export
default
Header
;
src/components/TopLevel/ConfirmSeatContent/Index.jsx
View file @
e24cd69d
...
...
@@ -10,10 +10,10 @@ const Index = ({ onConfirm, onCancel }) => {
Please confirm to proceed with your booking.
</
p
>
<
div
className=
{
styles
[
'btn-wrapper'
]
}
>
<
Button
size=
{
'md'
}
onClick=
{
onCancel
}
>
<
Button
size=
"md"
variant=
"secondary"
onClick=
{
onCancel
}
>
Cancel
</
Button
>
<
Button
size=
{
'md'
}
onClick=
{
onConfirm
}
>
<
Button
size=
"md"
variant=
"primary"
onClick=
{
onConfirm
}
>
Confirm
</
Button
>
</
div
>
...
...
src/components/TopLevel/SuccessModal/Index.jsx
View file @
e24cd69d
...
...
@@ -6,12 +6,12 @@ import styles from './styles.module.css';
const
SuccessModal
=
({
onConfirm
})
=>
{
return
(
<
Modal
>
<
div
style=
{
{
height
:
'300px'
}
}
>
<
div
className=
{
styles
[
'content-wrapper'
]
}
>
<
div
className=
{
styles
[
'btn-wrapper'
]
}
>
<
p
>
Booked Successfully
</
p
>
</
div
>
<
Lottie
style=
{
{
height
:
'60%'
,
width
:
'100%'
}
}
className=
{
styles
.
lottieSvg
}
animationData=
{
animationData
}
loop=
{
false
}
autoplay=
{
true
}
...
...
src/components/TopLevel/SuccessModal/SuccessModal.stories.jsx
0 → 100644
View file @
e24cd69d
import
SuccessModal
from
'./Index'
;
export
default
{
title
:
'Component/TopLevel/SuccessModal'
,
tags
:
[
'autodocs'
],
component
:
SuccessModal
,
argTypes
:
{
onConfirm
:
{
action
:
'On Confirm'
}
}
};
export
const
SuccessModalContent
=
{};
src/components/TopLevel/SuccessModal/styles.module.css
View file @
e24cd69d
.content-wrapper
{
height
:
300px
;
}
.btn-wrapper
{
display
:
flex
;
justify-content
:
center
;
}
.lottieSvg
{
width
:
100%
;
height
:
60%
;
}
src/pages/BookingPage/Index.jsx
View file @
e24cd69d
...
...
@@ -18,7 +18,16 @@ import Button from '../../components/Base/Button/Index';
import
LegendWrapper
from
'../../components/TopLevel/LegendWrapper/Index'
;
import
img
from
'../../assets/images/power-button_12080802.png'
;
import
styles
from
'./styles.module.css'
;
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
,
'*'
]
];
const
BookingPage
=
()
=>
{
let
userId
=
getItem
(
appConstants
.
USER
);
const
navigate
=
useNavigate
();
...
...
@@ -58,17 +67,6 @@ const BookingPage = () => {
setCurrentSeats
(
currentData
?.
selected
);
};
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
,
'*'
]
];
const
logout
=
()
=>
{
reset
();
navigate
(
'/login'
);
...
...
@@ -97,7 +95,7 @@ const BookingPage = () => {
setShowSeatsConfirmationModal
(
false
);
};
const
on
SeatRemove
=
(
rowId
,
columnId
)
=>
{
const
handle
SeatRemove
=
(
rowId
,
columnId
)
=>
{
setCurrentSeats
((
prev
)
=>
{
let
updatedSeats
;
updatedSeats
=
prev
?.
filter
(
...
...
@@ -112,7 +110,7 @@ const BookingPage = () => {
});
};
const
on
SeatAdd
=
(
rowId
,
columnId
)
=>
{
const
handle
SeatAdd
=
(
rowId
,
columnId
)
=>
{
setCurrentSeats
((
prev
)
=>
{
let
updatedSeats
;
if
(
prev
?.
length
<
noOfSeats
||
!
prev
?.
length
)
{
...
...
@@ -133,7 +131,7 @@ const BookingPage = () => {
});
};
const
on
SeatsConfirm
=
()
=>
{
const
handle
SeatsConfirm
=
()
=>
{
setShowSeatsConfirmationModal
(
true
);
};
...
...
@@ -155,6 +153,11 @@ const BookingPage = () => {
setShowSuccessModal
(
true
);
};
const
handleSuccessModalConfirm
=
()
=>
{
setShowSuccessModal
(
false
);
setButtonState
(
true
);
};
return
(
<
div
className=
{
styles
[
'seat-booking-wrapper'
]
}
>
<
img
...
...
@@ -169,12 +172,12 @@ const BookingPage = () => {
seatData=
{
data
}
selectedSeats=
{
selectedSeats
}
currentSeats=
{
currentSeats
}
onSeatRemove=
{
on
SeatRemove
}
onSeatAdd=
{
on
SeatAdd
}
onSeatRemove=
{
handle
SeatRemove
}
onSeatAdd=
{
handle
SeatAdd
}
/>
</
div
>
<
div
className=
{
styles
[
'btn-wrapper'
]
}
>
<
Button
size=
{
'lg'
}
onClick=
{
on
SeatsConfirm
}
disabled=
{
buttonState
}
>
<
Button
size=
{
'lg'
}
onClick=
{
handle
SeatsConfirm
}
disabled=
{
buttonState
}
>
Confirm
</
Button
>
</
div
>
...
...
@@ -190,7 +193,7 @@ const BookingPage = () => {
<
ConfirmSeatContent
onConfirm=
{
seatsFinal
}
onCancel=
{
finalCancel
}
/>
)
}
{
showSuccessModal
&&
(
<
SuccessModal
onConfirm=
{
()
=>
setShowSuccessModal
(
false
)
}
/>
<
SuccessModal
onConfirm=
{
handleSuccessModalConfirm
}
/>
)
}
</
div
>
);
...
...
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