11import StarIcon from "@mui/icons-material/Star" ;
2- import { Typography } from "@mui/material" ;
2+ import { Typography , TypographyProps } from "@mui/material" ;
33import Box , { BoxProps } from "@mui/material/Box" ;
44import CircularProgress from "@mui/material/CircularProgress" ;
55import Stack from "@mui/material/Stack" ;
@@ -14,19 +14,20 @@ import { setCurrentBuilding } from "../redux/currentBuildingSlice";
1414import { useDispatch } from "../redux/hooks" ;
1515import { getNumFreerooms } from "../utils/utils" ;
1616import StatusDot from "./StatusDot" ;
17+ import BuildingRating from "./Rating/BuildingRating" ;
18+
19+ import { useMediaQuery } from "@mui/material" ;
1720
1821const INITIALISING = - 2 ;
1922const FAILED = - 1 ;
2023
2124const MainBox = styled ( Box ) < BoxProps > ( ( { theme } ) => ( {
22- position : "relative" ,
23- flex : 1 ,
24- backgroundColor : theme . palette . primary . main ,
25- height : 385 ,
26- borderRadius : 10 ,
27- "&:hover" : {
28- cursor : "pointer" ,
29- } ,
25+ display : "flex" ,
26+ flexDirection : "column" ,
27+ height : 379 ,
28+ borderRadius : 12 ,
29+ border : "1px solid #F3D0C5" ,
30+ overflow : "hidden" ,
3031 [ theme . breakpoints . down ( "lg" ) ] : {
3132 height : 300 ,
3233 } ,
@@ -35,8 +36,16 @@ const MainBox = styled(Box)<BoxProps>(({ theme }) => ({
3536 } ,
3637} ) ) ;
3738
39+ const ImageBox = styled ( Box ) < BoxProps > ( ( { theme } ) => ( {
40+ position : "relative" ,
41+ height : 249 ,
42+ borderTopLeftRadius : 12 ,
43+ borderTopRightRadius : 12 ,
44+ cursor : "pointer" ,
45+ //width: "100%",
46+ } ) ) ;
47+
3848const StyledImage = styled ( Image ) < ImageProps > ( ( { theme } ) => ( {
39- borderRadius : 10 ,
4049 transition : "all 0.1s ease-in-out" ,
4150 "&:hover" : {
4251 opacity : 0.7 ,
@@ -47,39 +56,66 @@ const StatusBox = styled(Box)<BoxProps>(({ theme }) => ({
4756 display : "flex" ,
4857 justifyContent : "center" ,
4958 alignItems : "center" ,
50- borderRadius : 15 ,
59+ borderRadius : 100 ,
5160 position : "absolute" ,
5261 top : 0 ,
5362 right : 0 ,
54- padding : 10 ,
55- paddingLeft : 15 ,
56- paddingRight : 15 ,
63+ padding : 6 ,
64+ paddingLeft : 12 ,
65+ paddingRight : 12 ,
5766 margin : 10 ,
67+ gap : 6 ,
5868 pointerEvents : "none" ,
5969 backgroundColor : theme . palette . background . default ,
6070} ) ) ;
6171
62- const TitleBox = styled ( Box ) < BoxProps > ( ( { theme } ) => ( {
72+ const InfoBox = styled ( Box ) < BoxProps > ( ( { theme } ) => ( {
73+ display : "flex" ,
74+ flexDirection : "column" ,
75+ borderBottomLeftRadius : 12 ,
76+ borderBottomRightRadius : 12 ,
77+ padding : 12 ,
78+ gap : 4 ,
79+ //width: "100%",
80+ } ) ) ;
81+
82+ const InfoFooterBox = styled ( Box ) < BoxProps > ( ( { theme } ) => ( {
6383 display : "flex" ,
64- borderRadius : 10 ,
65- position : "absolute" ,
6684 justifyContent : "space-between" ,
67- bottom : 0 ,
68- left : 0 ,
69- right : 0 ,
70- backgroundColor : theme . palette . primary . main ,
71- color : "white" ,
72- padding : 15 ,
73- paddingLeft : 20 ,
74- paddingRight : 20 ,
75- margin : 10 ,
76- pointerEvents : "none" ,
85+ paddingTop : 8 ,
86+ } ) ) ;
87+
88+ const DetailPill = styled ( Box ) < BoxProps > ( ( { theme } ) => ( {
89+ borderRadius : 100 ,
90+ gap : 6 ,
91+ padding : 6 ,
92+ paddingLeft : 12 ,
93+ paddingRight : 12 ,
94+ backgroundColor : "#FDE7E1" ,
95+ } ) ) ;
96+
97+ const DetailPillText = styled ( Typography ) < TypographyProps > ( ( ) => ( {
98+ fontFamily : "TT Commons Pro Trial Variable" ,
99+ fontSize : 12 ,
100+ fontWeight : 400 ,
101+ color : "#D4613C" ,
102+ paddingBottom : "2px" ,
103+ gap : 10 ,
104+ } ) ) ;
105+
106+ // Show only building name and rating for smaller screens
107+ const NameRatingBox = styled ( Box ) < BoxProps > ( ( { theme } ) => ( {
108+ display : "flex" ,
109+ flexDirection : "row" ,
110+ justifyContent : "space-between" ,
111+ alignItems : "center" ,
77112} ) ) ;
78113
79114const BuildingCard : React . FC < {
80115 buildingId : string ;
81116} > = ( { buildingId } ) => {
82117 const dispatch = useDispatch ( ) ;
118+ const isCompact = useMediaQuery ( "(max-width:900px)" ) ;
83119
84120 const { building } = useBuilding ( buildingId ) ;
85121 const { status } = useBuildingStatus ( buildingId ) ;
@@ -91,49 +127,144 @@ const BuildingCard: React.FC<{
91127
92128 return (
93129 < MainBox onClick = { ( ) => dispatch ( setCurrentBuilding ( building ) ) } >
94- < StyledImage
95- alt = { `Image of ${ buildingId } ` }
96- src = { `/assets/building_photos/${ buildingId } .webp` }
97- fill = { true }
98- style = { { objectFit : "cover" } }
99- priority = { true }
100- />
101- < StatusBox >
102- { freerooms > INITIALISING ? (
130+ < ImageBox >
131+ < StyledImage
132+ alt = { `Image of ${ buildingId } ` }
133+ src = { `/assets/building_photos/${ buildingId } .webp` }
134+ fill = { true }
135+ style = { { objectFit : "cover" } }
136+ priority = { true }
137+ />
138+ < StatusBox >
139+ { freerooms > INITIALISING ? (
140+ < >
141+ { freerooms !== FAILED ? (
142+ < StatusDot
143+ colour = {
144+ freerooms >= 5
145+ ? "green"
146+ : freerooms !== 0
147+ ? "orange"
148+ : "red"
149+ }
150+ />
151+ ) : null }
152+ < Typography
153+ sx = { {
154+ fontFamily : "TT Commons Pro Trial Variable" ,
155+ fontWeight : 400 ,
156+ fontSize : 12 ,
157+ paddingBottom : "2px" ,
158+ } }
159+ >
160+ { freerooms !== FAILED
161+ ? `${ freerooms } room${ freerooms === 1 ? "" : "s" } available`
162+ : "Data Unavailable" }
163+ </ Typography >
164+ </ >
165+ ) : (
166+ < CircularProgress size = { 20 } thickness = { 5 } disableShrink />
167+ ) }
168+ </ StatusBox >
169+ </ ImageBox >
170+
171+ < InfoBox >
172+ { isCompact ? (
173+ < NameRatingBox >
174+ < Typography
175+ sx = { {
176+ fontFamily : "TT Commons Pro Trial Variable" ,
177+ fontWeight : 700 ,
178+ fontSize : 20 ,
179+ color : "#632410" ,
180+ textTransform : "uppercase" ,
181+ overflow : "hidden" ,
182+ textOverflow : "ellipsis" ,
183+ whiteSpace : "nowrap" ,
184+ } }
185+ >
186+ { building . name }
187+ </ Typography >
188+
189+ < Stack
190+ direction = "row"
191+ alignItems = "center"
192+ spacing = "1px"
193+ aria-label = "star-info"
194+ >
195+ < Typography
196+ sx = { {
197+ fontFamily : "TT Commons Pro Trial Variable" ,
198+ fontWeight : 400 ,
199+ fontSize : 12 ,
200+ color : "#D4613C" ,
201+ } }
202+ >
203+ { ratings ?. overallRating }
204+ </ Typography >
205+
206+ < StarIcon sx = { { color : "#D4613C" } } />
207+ </ Stack >
208+ </ NameRatingBox >
209+ ) : (
103210 < >
104- { freerooms !== FAILED ? (
105- < StatusDot
106- colour = {
107- freerooms >= 5 ? "green" : freerooms !== 0 ? "orange" : "red"
108- }
109- />
110- ) : null }
111- < Typography sx = { { fontSize : 12 , fontWeight : 500 } } >
112- { freerooms !== FAILED
113- ? `${ freerooms } room${ freerooms === 1 ? "" : "s" } available`
114- : "Data Unavailable" }
211+ < Typography
212+ sx = { {
213+ fontFamily : "TT Commons Pro Trial Variable" ,
214+ fontWeight : 400 ,
215+ fontSize : 12 ,
216+ color : "#D4613C" ,
217+ } }
218+ >
219+ { `Building ID ${ buildingId } ` }
220+ </ Typography >
221+
222+ < Typography
223+ sx = { {
224+ fontFamily : "TT Commons Pro Trial Variable" ,
225+ fontWeight : 700 ,
226+ fontSize : 20 ,
227+ color : "#632410" ,
228+ textTransform : "uppercase" ,
229+ overflow : "hidden" ,
230+ textOverflow : "ellipsis" ,
231+ whiteSpace : "nowrap" ,
232+ } }
233+ >
234+ { building . name }
115235 </ Typography >
236+
237+ < Stack
238+ direction = "row"
239+ alignItems = "center"
240+ gap = "1px"
241+ aria-label = "star-info"
242+ >
243+ < BuildingRating overallRating = { ratings ?. overallRating ?? 0 } />
244+ </ Stack >
245+
246+ < InfoFooterBox >
247+ < Stack direction = "row" gap = "8px" >
248+ < DetailPill >
249+ < DetailPillText > Category</ DetailPillText >
250+ </ DetailPill >
251+
252+ < DetailPill >
253+ < DetailPillText > TODO</ DetailPillText >
254+ </ DetailPill >
255+ </ Stack >
256+
257+ < Image
258+ alt = "Arrow up right icon"
259+ src = "/assets/icons/arrow-up-right.svg"
260+ width = { 24 }
261+ height = { 24 }
262+ style = { { cursor : "pointer" } }
263+ />
264+ </ InfoFooterBox >
116265 </ >
117- ) : (
118- < CircularProgress size = { 20 } thickness = { 5 } disableShrink />
119266 ) }
120- </ StatusBox >
121- < TitleBox >
122- < Typography sx = { { fontSize : 16 , fontWeight : 500 } } >
123- { building . name }
124- </ Typography >
125- < Stack
126- direction = "row"
127- alignItems = "center"
128- spacing = { 0.3 }
129- aria-label = "star-info"
130- >
131- < Typography sx = { { fontSize : 16 , fontWeight : 500 } } >
132- { ratings ?. overallRating }
133- </ Typography >
134- < StarIcon sx = { { color : "rgb(255, 169, 12)" } } />
135- </ Stack >
136- </ TitleBox >
267+ </ InfoBox >
137268 </ MainBox >
138269 ) ;
139270} ;
0 commit comments