source: pages/index/+Page.tsx@ b348db4

main
Last change on this file since b348db4 was 5af32f0, checked in by Mihail <mihail2.naumov@…>, 6 months ago

Added styling to admin dashboard functions and highest ranking popup

  • Property mode set to 100644
File size: 9.4 KB
RevLine 
[8a7f936]1import React, {useEffect, useState} from 'react';
[40ac7a9]2import {
[5af32f0]3 Container, Box, Typography, Button, IconButton, Dialog, DialogTitle, DialogContent
[40ac7a9]4} from '@mui/material';
5import CloseIcon from '@mui/icons-material/Close';
6import AutoFixHighIcon from '@mui/icons-material/AutoFixHigh';
[1bf6e1f]7import ListIcon from '@mui/icons-material/List';
[40ac7a9]8
[1bf6e1f]9import BuildDetailsDialog from '../../components/BuildDetailsDialog';
10import BuildCard from '../../components/BuildCard';
[40ac7a9]11
[8a7f936]12import {onGetApprovedBuilds, onGetAuthState, onCloneBuild} from '../+Layout.telefunc';
[40ac7a9]13
14export default function HomePage() {
15 const [data, setData] = useState<any>(null);
[e599341]16 const [allRanked, setAllRanked] = useState<any[]>([]);
[40ac7a9]17
[1bf6e1f]18 const [selectedBuildId, setSelectedBuildId] = useState<number | null>(null);
[40ac7a9]19 const [openRankedPopup, setOpenRankedPopup] = useState(false);
20
21 useEffect(() => {
[1bf6e1f]22 async function loadSite() {
23 try {
[40ac7a9]24 const [
[e599341]25 authData,
26 highestRankedBuilds,
27 communityBuilds,
28 fullRankedList
[40ac7a9]29 ] = await Promise.all([
[67dfe57]30 onGetAuthState(),
[8a7f936]31 onGetApprovedBuilds({limit: 5, sort: 'rating_desc'}),
32 onGetApprovedBuilds({limit: 12}),
33 onGetApprovedBuilds({limit: 20, sort: 'rating_desc'})
[40ac7a9]34 ]);
35
36 setData({
37 isLoggedIn: authData.isLoggedIn,
38 userId: authData.userId,
39 prebuilts: highestRankedBuilds,
[1bf6e1f]40 communityBuilds: communityBuilds
[40ac7a9]41 });
[e599341]42 setAllRanked(fullRankedList);
[40ac7a9]43 } catch (error) {
44 console.error("Error loading homepage data:", error);
45 }
[1bf6e1f]46 }
[8a7f936]47
[1bf6e1f]48 loadSite();
49 }, []);
[40ac7a9]50
[1bf6e1f]51 const handleCloneWrapper = async (buildId: number) => {
[40ac7a9]52 if (!data?.isLoggedIn) return alert("Please login to clone builds!");
[1bf6e1f]53 if (confirm(`Clone this build to your dashboard?`)) {
[8a7f936]54 await onCloneBuild({buildId});
[40ac7a9]55 alert("Build cloned! Check your dashboard.");
[1bf6e1f]56 setSelectedBuildId(null);
[40ac7a9]57 }
58 };
59
[8a7f936]60 if (!data) return <Box sx={{p: 10, textAlign: 'center'}}>Loading Forge...</Box>;
[40ac7a9]61
62 return (
63 <Box>
64 <Box sx={{
65 position: 'relative', height: '500px',
66 display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white',
[1bf6e1f]67 '&::before': {
68 content: '""', position: 'absolute', top: 0, left: 0, width: '100%', height: '100%',
69 backgroundColor: 'rgba(0,0,0,0.6)'
70 }
[40ac7a9]71 }}>
[8a7f936]72 <Box sx={{position: 'relative', textAlign: 'center', zIndex: 1, p: 2}}>
[40ac7a9]73 <Typography variant="h2" fontWeight="bold" gutterBottom>Forge Your Ultimate Machine</Typography>
[8a7f936]74 <Typography variant="h5" sx={{maxWidth: '800px', mx: 'auto', mb: 1}}>
[40ac7a9]75 Build, share, discuss, and discover custom PC configurations.
76 </Typography>
[8a7f936]77 <Button variant="contained" size="large" href="/forge" startIcon={<AutoFixHighIcon/>}
78 sx={{fontSize: '1.2rem', px: 4, py: 1.5, mt: 2}}>
[40ac7a9]79 Start Forging
80 </Button>
81 </Box>
82 </Box>
83
[8a7f936]84 <Container maxWidth="xl" sx={{mt: 6, mb: 10}}>
[1bf6e1f]85 <Box sx={{
[8a7f936]86 mb: 2, borderLeft: '5px solid #ff8201', pl: 1,
[1bf6e1f]87 display: 'flex', justifyContent: 'space-between', alignItems: 'end'
88 }}>
[40ac7a9]89 <Box>
90 <Typography variant="h4" fontWeight="bold">Hall of Fame</Typography>
[1bf6e1f]91 <Typography variant="subtitle1" color="text.secondary">
92 The highest rated configurations from across the community.
93 </Typography>
[40ac7a9]94 </Box>
[8a7f936]95 <Button variant="outlined" startIcon={<ListIcon/>} onClick={() => setOpenRankedPopup(true)}>
[40ac7a9]96 Show All Top Ranked
97 </Button>
98 </Box>
[8a7f936]99 <Box
100 sx={{
101 display: 'grid',
102 gridTemplateColumns: {
103 xs: '1fr',
104 sm: 'repeat(2, 1fr)',
105 md: 'repeat(3, 1fr)',
106 lg: 'repeat(4, 1fr)',
107 xl: 'repeat(5, 1fr)',
108 },
109 gap: 3,
[5af32f0]110 width: '100%',
111 mb: 8
[8a7f936]112 }}
113 >
114 {data.prebuilts.map((build: any) => (
115 <BuildCard
116 key={build.id}
117 build={build}
118 onClick={() => setSelectedBuildId(build.id)}
119 />
[40ac7a9]120 ))}
[8a7f936]121 </Box>
[40ac7a9]122
[8a7f936]123 <Box sx={{
124 mb: 2, mt: 2, borderLeft: '5px solid #ff8201', pl: 1,
125 }}>
126 <Typography variant="h4" fontWeight="bold" color="text.primary">Community Forge</Typography>
[5af32f0]127 <Typography variant="subtitle1" color="text.secondary" sx={{mb: 2}}>Fresh builds from users around the world.</Typography>
[8a7f936]128 </Box>
129 <Box
130 sx={{
131 display: 'grid',
132 gridTemplateColumns: {
133 xs: '1fr',
134 sm: 'repeat(2, 1fr)',
135 md: 'repeat(3, 1fr)',
136 lg: 'repeat(4, 1fr)',
137 xl: 'repeat(5, 1fr)',
138 },
139 gap: 3,
[5af32f0]140 width: '100%',
[8a7f936]141 }}
142 >
[40ac7a9]143 {data.communityBuilds.map((build: any) => (
[8a7f936]144 <BuildCard
145 key={build.id}
146 build={build}
147 onClick={() => setSelectedBuildId(build.id)}
148 />
[40ac7a9]149 ))}
[8a7f936]150 </Box>
[40ac7a9]151
[8a7f936]152 <Box sx={{display: 'flex', justifyContent: 'center', mt: 6}}>
[40ac7a9]153 <Button variant="outlined" size="large" href="/completed-builds">View All Community Builds</Button>
154 </Box>
155 </Container>
156
[1bf6e1f]157 <BuildDetailsDialog
158 open={!!selectedBuildId}
159 buildId={selectedBuildId}
160 currentUser={data.userId}
161 onClose={() => setSelectedBuildId(null)}
162 onClone={handleCloneWrapper}
163 />
[40ac7a9]164
[5af32f0]165 <Dialog open={openRankedPopup} onClose={() => setOpenRankedPopup(false)} maxWidth="xl" fullWidth scroll="paper">
[8a7f936]166 <DialogTitle sx={{display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
[e599341]167 Hall of Fame (Top Rated)
[8a7f936]168 <IconButton onClick={() => setOpenRankedPopup(false)}><CloseIcon/></IconButton>
[40ac7a9]169 </DialogTitle>
[5af32f0]170 <DialogContent dividers sx={{p: 3}}>
171 <Box
172 sx={{
173 display: 'grid',
174 gridTemplateColumns: {
175 xs: '1fr',
176 sm: 'repeat(2, 1fr)',
177 md: 'repeat(3, 1fr)',
178 lg: 'repeat(4, 1fr)',
179 xl: 'repeat(5, 1fr)',
180 },
181 gap: 3,
182 width: '100%'
183 }}
184 >
[e599341]185 {allRanked.map((build: any, index: number) => (
[5af32f0]186 <Box key={`ranked-${build.id}`} sx={{position: 'relative', width: '100%'}}>
187 <Box sx={{
188 position: 'absolute',
189 top: -10,
190 left: -10,
191 zIndex: 1,
192 width: 35,
193 height: 35,
194 borderRadius: '50%',
195 bgcolor: index < 3 ? '#ff8201' : 'grey.800',
196 color: 'white',
197 display: 'flex',
198 alignItems: 'center',
199 justifyContent: 'center',
200 fontWeight: 'bold',
201 border: '2px solid white',
202 boxShadow: 2,
203 }}>
204 #{index + 1}
[e599341]205 </Box>
[5af32f0]206 <BuildCard
207 build={build}
208 onClick={() => {
209 setOpenRankedPopup(false);
210 setSelectedBuildId(build.id);
211 }}
212 />
213 </Box>
[40ac7a9]214 ))}
[5af32f0]215 </Box>
[40ac7a9]216 </DialogContent>
217 </Dialog>
218 </Box>
219 );
220}
Note: See TracBrowser for help on using the repository browser.