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
58c584aa
Commit
58c584aa
authored
Jun 05, 2025
by
Syed Abdul Rahman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
changes in layoutwrapper
parent
b695a147
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
262 additions
and
53 deletions
+262
-53
db.json
db.json
+18
-0
styles.module.css
src/components/Base/Button/styles.module.css
+10
-1
styles.module.css
src/components/Base/Input/styles.module.css
+7
-5
Index.jsx
src/components/Base/Legend/Index.jsx
+1
-1
Legend.stories.jsx
src/components/Base/Legend/Legend.stories.jsx
+3
-1
BookingWrapper.stories.jsx
...mponents/Layout/BookingWrapper/BookingWrapper.stories.jsx
+146
-0
Index.jsx
src/components/Layout/BookingWrapper/Index.jsx
+28
-23
Seat.jsx
src/components/Layout/BookingWrapper/Seat.jsx
+4
-3
Seat.stories.jsx
src/components/Layout/BookingWrapper/Seat.stories.jsx
+1
-1
styles.module.css
src/components/Layout/BookingWrapper/styles.module.css
+15
-6
Index.jsx
src/components/Layout/Header/Index.jsx
+24
-1
styles.module.css
src/components/Layout/Header/styles.module.css
+0
-2
Index.jsx
src/components/TopLevel/Login/Index.jsx
+3
-4
styles.module.css
src/components/TopLevel/Login/styles.module.css
+2
-5
No files found.
db.json
0 → 100644
View file @
58c584aa
{
"users"
:
[
{
"id"
:
1
,
"email"
:
"john@gmail.com"
},
{
"id"
:
2
,
"email"
:
"lucy@gmail.com"
},
{
"id"
:
3
,
"email"
:
"abdul@gmail.com"
}
]
}
\ No newline at end of file
src/components/Base/Button/styles.module.css
View file @
58c584aa
...
...
@@ -14,6 +14,11 @@
}
.button
:hover
{
background-color
:
rgba
(
161
,
161
,
245
,
0.358
);
color
:
white
;
}
.sm
{
padding
:
0.5rem
1.5rem
;
font-size
:
12px
;
...
...
@@ -22,7 +27,7 @@
}
.md
{
padding
:
0.7rem
3
rem
;
padding
:
0.7rem
1.5
rem
;
font-size
:
16px
;
font-size
:
clamp
(
1rem
,
2vw
,
1.5rem
);
...
...
@@ -68,6 +73,10 @@
cursor
:
not-allowed
;
}
.disabled
:hover
{
background-color
:
rgba
(
168
,
166
,
166
,
0.214
);
}
@keyframes
rotate
{
0
%
{
...
...
src/components/Base/Input/styles.module.css
View file @
58c584aa
...
...
@@ -6,17 +6,18 @@
.label
{
font-family
:
'Inter-Medium'
;
font-size
:
clamp
(
1rem
,
2vw
,
1.5
rem
);
font-size
:
clamp
(
0.8rem
,
2vw
,
1
rem
);
}
.input
{
outline
:
none
;
padding
:
3%
5
%
;
padding
:
2%
2
%
;
border-radius
:
5px
;
width
:
9
0
%
;
width
:
9
5
%
;
font-family
:
'Inter-Medium'
;
color
:
#000000
db
;
font-size
:
clamp
(
1rem
,
2vw
,
1.5rem
);
font-size
:
clamp
(
0.8rem
,
2vw
,
1rem
);
border
:
none
;
outline
:
none
;
}
\ No newline at end of file
src/components/Base/Legend/Index.jsx
View file @
58c584aa
...
...
@@ -11,7 +11,7 @@ const Legend = ({ children, type="available" }) => {
)
}
Legend
.
propTypes
=
{
children
:
PropTypes
.
node
.
isRequired
,
// children: PropTypes.node
,
type
:
PropTypes
.
oneOf
([
"selected"
,
"reserved"
,
"available"
])
}
export
default
Legend
;
...
...
src/components/Base/Legend/Legend.stories.jsx
View file @
58c584aa
...
...
@@ -28,7 +28,9 @@ const getStoryTitle = (type) => {
}
export
const
Default
=
{
args
:{
type
:
"available"
},
render
:
(
args
)
=>
{
return
<
Legend
type=
{
args
.
type
}
>
{
getStoryTitle
(
args
.
type
)
}
</
Legend
>
}
...
...
src/components/Layout/BookingWrapper/BookingWrapper.stories.jsx
View file @
58c584aa
...
...
@@ -5,11 +5,156 @@ export default {
component
:
BookingWrapper
,
argTypes
:
{
onSeatClick
:
{
action
:
'Seat clicked'
},
}
}
export
const
Default
=
{
args
:
{
selectedSeats
:
[
{
userid
:
1
,
selected
:
[
{
row
:
1
,
seat
:
1
},
{
row
:
1
,
seat
:
2
}
]
},
{
userid
:
2
,
selected
:
[
{
row
:
2
,
seat
:
1
},
{
row
:
2
,
seat
:
2
},
{
row
:
5
,
seat
:
1
}
]
}
],
seatData
:
[
{
row_id
:
1
,
columnData
:
[
{
id
:
0
,
status
:
'aisle'
},
{
id
:
1
,
status
:
'reserved'
},
{
id
:
2
,
status
:
'available'
},
{
id
:
3
,
status
:
'reserved'
},
{
id
:
4
,
status
:
'available'
},
{
id
:
0
,
status
:
'aisle'
},
{
id
:
5
,
status
:
'available'
},
{
id
:
6
,
status
:
'reserved'
},
{
id
:
7
,
status
:
'available'
},
{
id
:
8
,
status
:
'reserved'
},
{
id
:
0
,
status
:
'aisle'
},
]
},
{
row_id
:
2
,
columnData
:
[
{
id
:
1
,
status
:
'available'
},
{
id
:
2
,
status
:
'available'
},
{
id
:
3
,
status
:
'available'
},
{
id
:
4
,
status
:
'available'
},
{
id
:
5
,
status
:
'available'
},
{
id
:
0
,
status
:
'aisle'
},
{
id
:
6
,
status
:
'available'
},
{
id
:
7
,
status
:
'available'
},
{
id
:
8
,
status
:
'available'
},
{
id
:
9
,
status
:
'available'
},
{
id
:
10
,
status
:
'available'
},
]
},
{
row_id
:
3
,
columnData
:
[
{
id
:
1
,
status
:
'available'
},
{
id
:
2
,
status
:
'available'
},
{
id
:
3
,
status
:
'available'
},
{
id
:
4
,
status
:
'available'
},
{
id
:
5
,
status
:
'available'
},
{
id
:
0
,
status
:
'aisle'
},
{
id
:
6
,
status
:
'available'
},
{
id
:
7
,
status
:
'available'
},
{
id
:
8
,
status
:
'available'
},
{
id
:
9
,
status
:
'available'
},
{
id
:
10
,
status
:
'available'
},
]
},
{
row_id
:
4
,
columnData
:
[
{
id
:
1
,
status
:
'available'
},
{
id
:
2
,
status
:
'available'
},
{
id
:
3
,
status
:
'available'
},
{
id
:
4
,
status
:
'available'
},
{
id
:
5
,
status
:
'available'
},
{
id
:
0
,
status
:
'aisle'
},
{
id
:
6
,
status
:
'available'
},
{
id
:
7
,
status
:
'available'
},
{
id
:
8
,
status
:
'available'
},
{
id
:
9
,
status
:
'available'
},
{
id
:
10
,
status
:
'available'
},
]
},
{
row_id
:
5
,
columnData
:
[
{
id
:
1
,
status
:
'available'
},
{
id
:
2
,
status
:
'available'
},
{
id
:
3
,
status
:
'available'
},
{
id
:
4
,
status
:
'available'
},
{
id
:
5
,
status
:
'available'
},
{
id
:
0
,
status
:
'aisle'
},
{
id
:
6
,
status
:
'available'
},
{
id
:
7
,
status
:
'available'
},
{
id
:
8
,
status
:
'available'
},
{
id
:
9
,
status
:
'available'
},
{
id
:
10
,
status
:
'available'
},
]
},
{
row_id
:
6
,
columnData
:
[
{
id
:
1
,
status
:
'available'
},
{
id
:
2
,
status
:
'available'
},
{
id
:
3
,
status
:
'available'
},
{
id
:
4
,
status
:
'available'
},
{
id
:
5
,
status
:
'available'
},
{
id
:
0
,
status
:
'aisle'
},
{
id
:
6
,
status
:
'available'
},
{
id
:
7
,
status
:
'available'
},
{
id
:
8
,
status
:
'available'
},
{
id
:
9
,
status
:
'available'
},
{
id
:
10
,
status
:
'available'
},
]
},
{
row_id
:
7
,
columnData
:
[
{
id
:
1
,
status
:
'available'
},
{
id
:
2
,
status
:
'available'
},
{
id
:
3
,
status
:
'available'
},
{
id
:
4
,
status
:
'available'
},
{
id
:
5
,
status
:
'available'
},
{
id
:
0
,
status
:
'aisle'
},
{
id
:
6
,
status
:
'available'
},
{
id
:
7
,
status
:
'available'
},
{
id
:
8
,
status
:
'available'
},
{
id
:
9
,
status
:
'available'
},
{
id
:
10
,
status
:
'available'
},
]
},
{
row_id
:
8
,
columnData
:
[
{
id
:
0
,
status
:
'aisle'
},
{
id
:
1
,
status
:
'reserved'
},
{
id
:
2
,
status
:
'available'
},
{
id
:
3
,
status
:
'reserved'
},
{
id
:
4
,
status
:
'available'
},
{
id
:
0
,
status
:
'aisle'
},
{
id
:
5
,
status
:
'available'
},
{
id
:
6
,
status
:
'reserved'
},
{
id
:
7
,
status
:
'available'
},
{
id
:
8
,
status
:
'reserved'
},
{
id
:
9
,
status
:
'available'
},
]
},
]
}
}
\ No newline at end of file
src/components/Layout/BookingWrapper/Index.jsx
View file @
58c584aa
import
styles
from
'./styles.module.css'
;
import
Seat
from
'./Seat'
;
const
BookingWrapper
=
({
onSeatClick
})
=>
{
const
BookingWrapper
=
({
onSeatClick
,
selectedSeats
,
seatData
})
=>
{
const
aisleIndex
=
5
;
const
seatData
=
[
{
id
:
0
,
status
:
'aisle'
},
{
id
:
1
,
status
:
'reserved'
},
{
id
:
2
,
status
:
'available'
},
{
id
:
3
,
status
:
'reserved'
},
{
id
:
4
,
status
:
'available'
},
{
id
:
0
,
status
:
'aisle'
},
{
id
:
5
,
status
:
'available'
},
{
id
:
6
,
status
:
'reserved'
},
{
id
:
7
,
status
:
'available'
},
{
id
:
8
,
status
:
'reserved'
},
{
id
:
9
,
status
:
'available'
},
];
const
currentUser
=
2
;
const
selectedSeatMap
=
new
Map
();
selectedSeats
?.
forEach
(
user
=>
{
user
.
selected
.
forEach
(
seat
=>
{
const
key
=
`
${
seat
.
row
}
-
${
seat
.
seat
}
`
;
selectedSeatMap
.
set
(
key
,
user
.
userid
);
});
});
const
isLeftBlock
=
(
col
)
=>
col
<
aisleIndex
;
...
...
@@ -26,24 +25,23 @@ const BookingWrapper = ({ onSeatClick }) => {
return
(
<
div
>
<
div
className=
{
styles
[
'theatre'
]
}
>
{
Array
.
from
({
length
:
2
},
(
_
,
row_index
)
=>
(
{
seatData
?.
map
((
row
,
row_index
)
=>
(
<
div
className=
{
styles
[
'seat-row'
]
}
>
{
seatData
.
map
((
ele
,
column_index
)
=>
{
{
row
.
columnData
?.
map
((
column
,
column_index
)
=>
{
const
isFirstRow
=
row_index
===
0
;
const
isLastRow
=
row_index
===
2
-
1
;
const
isLastRow
=
row_index
===
seatData
.
length
-
1
;
if
(
isLeftBlock
(
column_index
)
&&
column_index
===
0
&&
(
isFirstRow
||
isLastRow
))
{
// return <div key=
{
`gap-left-${row_index}-${column_index}`
}
className
=
{
styles
[
"seat-gap"
]}
/>
;
return
<
div
className=
{
styles
[
'aisle'
]
}
></
div
>;
return
<
div
key=
{
`gap-left-${row_index}-${column_index}`
}
className=
{
styles
[
"seat-gap"
]
}
/>;
}
if
(
isRightBlock
(
column_index
)
&&
column_index
===
seat
Data
.
length
-
1
&&
column_index
===
row
.
column
Data
.
length
-
1
&&
(
isFirstRow
||
isLastRow
)
)
{
// return <div key=
{
`gap-right-${row_index}-${row_index}`
}
className
=
{
styles
[
"seat-gap"
]}
/>
;
return
<
div
className=
{
styles
[
'aisle'
]
}
></
div
>;
return
<
div
key=
{
`gap-right-${row_index}-${row_index}`
}
className=
{
styles
[
"seat-gap"
]
}
/>;
}
if
(
column_index
==
aisleIndex
)
{
...
...
@@ -51,8 +49,15 @@ const BookingWrapper = ({ onSeatClick }) => {
<
div
className=
{
styles
[
'aisle'
]
}
></
div
>
)
}
const
seatKey
=
`${row.row_id}-${column.id}`
;
const
selectedBy
=
selectedSeatMap
.
get
(
seatKey
);
let
seatClass
=
``
;
if
(
selectedBy
)
{
seatClass
+=
selectedBy
===
currentUser
?
'selected-by-me'
:
'selected-by-other'
;
}
return
(
<
Seat
status=
{
ele
.
status
}
id=
{
ele
.
id
}
onClick=
{
()
=>
onSeatClick
(
ele
.
id
)
}
/>
<
Seat
status=
{
seatClass
}
id=
{
column
.
id
}
onClick=
{
()
=>
onSeatClick
(
row
.
row_id
,
column
.
id
)
}
/>
)
})
}
</
div
>
...
...
src/components/Layout/BookingWrapper/Seat.jsx
View file @
58c584aa
...
...
@@ -2,15 +2,15 @@ import styles from './styles.module.css'
import
PropTypes
from
'prop-types'
;
const
Seat
=
({
id
,
status
,
...
rest
})
=>
{
console
.
log
(
status
,
"status"
)
return
(
<
div
{
...
rest
}
className=
{
` ${styles[status]} ${styles.seat} `
}
>
{
id
}
</
div
>
<
div
{
...
rest
}
className=
{
` ${styles[status]} ${styles.seat} `
}
></
div
>
)
}
Seat
.
propTypes
=
{
onClick
:
PropTypes
.
func
.
isRequired
,
status
:
PropTypes
.
oneOf
([
'available'
,
'reserved'
,
'selected'
])
//
status: PropTypes.oneOf(['available', 'reserved', 'selected'])
}
export
default
Seat
;
\ No newline at end of file
src/components/Layout/BookingWrapper/Seat.stories.jsx
View file @
58c584aa
...
...
@@ -9,7 +9,7 @@ export default {
control
:
{
type
:
'select'
},
options
:
[
'available'
,
'reserved'
,
'selected'
],
},
onClick
:
{
action
:
"clicked"
}
,
//
onClick: {action: "clicked"} ,
},
};
...
...
src/components/Layout/BookingWrapper/styles.module.css
View file @
58c584aa
.seat
{
width
:
20px
;
height
:
20px
;
width
:
1.2em
;
height
:
1.2em
;
border
:
.5px
solid
rgba
(
255
,
255
,
255
,
0.603
);
border-radius
:
5px
;
cursor
:
pointer
;
...
...
@@ -49,13 +49,22 @@
visibility
:
hidden
;
}
.selected-by-me
{
background-color
:
aqua
!important
;
/* your color */
border
:
unset
;
}
.selected-by-other
{
background-color
:
#bec0c26
d
!important
;
/* another color */
}
@media
screen
and
(
min-width
:
768px
)
{
.seat
{
width
:
40px
;
height
:
40px
;
width
:
2em
;
height
:
2em
;
}
.aisle
{
...
...
@@ -63,8 +72,8 @@
}
.seat-gap
{
width
:
4
0px
;
height
:
4
0px
;
width
:
3
0px
;
height
:
3
0px
;
}
...
...
src/components/Layout/Header/Index.jsx
View file @
58c584aa
...
...
@@ -9,7 +9,7 @@ const Header = ({ children }) => {
{
children
}
</
div
>
<
div
className=
{
styles
.
screenWrapper
}
>
<
svg
viewBox=
"0 0 480 260"
xmlns=
"http://www.w3.org/2000/svg"
>
{
/*
<svg viewBox="0 0 480 260" xmlns="http://www.w3.org/2000/svg">
<path d="M 30 70 Q 240 20 450 70" stroke="white" stroke-width="5" fill="none" />
<defs>
<linearGradient id="glowGradient" x1="0" y1="70" x2="0" y2="180" gradientUnits="userSpaceOnUse">
...
...
@@ -28,6 +28,29 @@ const Header = ({ children }) => {
<rect x="0" y="0" width="480" height="260"
fill="url(#glowGradient)"
clip-path="url(#glowClip)" />
</svg> */
}
<
svg
viewBox=
"0 0 480 260"
xmlns=
"http://www.w3.org/2000/svg"
>
<
path
d=
"M 30 70 Q 240 20 450 70"
stroke=
"white"
stroke
-
width=
"5"
fill=
"none"
/>
<
defs
>
<
linearGradient
id=
"glowGradient"
x1=
"0"
y1=
"70"
x2=
"0"
y2=
"130"
gradientUnits=
"userSpaceOnUse"
>
<
stop
offset=
"0%"
stop
-
color=
"#addfff"
stop
-
opacity=
"0.15"
/>
<
stop
offset=
"100%"
stop
-
color=
"#addfff"
stop
-
opacity=
"0"
/>
</
linearGradient
>
<
clipPath
id=
"glowClip"
>
<
path
d=
"
M 30 70
Q 240 20 450 70
L 470 130
L 10 130
Z"
/>
</
clipPath
>
</
defs
>
<
rect
x=
"0"
y=
"0"
width=
"480"
height=
"260"
fill=
"url(#glowGradient)"
clip
-
path=
"url(#glowClip)"
/>
</
svg
>
</
div
>
</
section
>
...
...
src/components/Layout/Header/styles.module.css
View file @
58c584aa
...
...
@@ -2,9 +2,7 @@
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
/* justify-content: center; */
width
:
100%
;
/* outline: 2px solid red; */
}
.title
{
...
...
src/components/TopLevel/Login/Index.jsx
View file @
58c584aa
...
...
@@ -22,13 +22,12 @@ const Login = () => {
name=
"email"
type=
"email"
/>
{
/* <br /> */
}
<
Input
{
/* <Input
label="Password"
name="email"
type="password"
/>
<
Button
size=
{
"
md
"
}
>
Confirm
</
Button
>
/>
*/
}
<
Button
size=
{
"
sm
"
}
>
Confirm
</
Button
>
</
form
>
</
section
>
</
div
>
...
...
src/components/TopLevel/Login/styles.module.css
View file @
58c584aa
...
...
@@ -31,9 +31,6 @@
background-color
:
rgba
(
0
,
0
,
0
,
0.6
);
border-radius
:
10px
;
padding
:
3%
5%
;
max-height
:
70%
;
max-width
:
70%
;
min-height
:
max
(
550px
,
30vh
);
box-sizing
:
border-box
;
z-index
:
1
;
color
:
white
;
...
...
@@ -55,7 +52,7 @@
.title
{
font-family
:
'Inter-Medium'
;
font-size
:
clamp
(
1rem
,
2vw
,
3
rem
);
font-size
:
clamp
(
1rem
,
2vw
,
2
rem
);
color
:
#f1f1f1
c4
;
padding
:
1%
0
;
}
...
...
@@ -64,7 +61,7 @@
font-family
:
'Inter-Medium'
;
font-size
:
16px
;
color
:
#bdbcbc97
;
font-size
:
clamp
(
0.5rem
,
3vw
,
1
.5
rem
);
font-size
:
clamp
(
0.5rem
,
3vw
,
1rem
);
padding
:
1%
0
;
}
...
...
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