source: pages/index/+Page.tsx@ 5af32f0

main
Last change on this file since 5af32f0 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
Line 
1import React, {useEffect, useState} from 'react';
2import {
3 Container, Box, Typography, Button, IconButton, Dialog, DialogTitle, DialogContent
4} from '@mui/material';
5import CloseIcon from '@mui/icons-material/Close';
6import AutoFixHighIcon from '@mui/icons-material/AutoFixHigh';
7import ListIcon from '@mui/icons-material/List';
8
9import BuildDetailsDialog from '../../components/BuildDetailsDialog';
10import BuildCard from '../../components/BuildCard';
11
12import {onGetApprovedBuilds, onGetAuthState, onCloneBuild} from '../+Layout.telefunc';
13
14export default function HomePage() {
15 const [data, setData] = useState<any>(null);
16 const [allRanked, setAllRanked] = useState<any[]>([]);
17
18 const [selectedBuildId, setSelectedBuildId] = useState<number | null>(null);
19 const [openRankedPopup, setOpenRankedPopup] = useState(false);
20
21 useEffect(() => {
22 async function loadSite() {
23 try {
24 const [
25 authData,
26 highestRankedBuilds,
27 communityBuilds,
28 fullRankedList
29 ] = await Promise.all([
30 onGetAuthState(),
31 onGetApprovedBuilds({limit: 5, sort: 'rating_desc'}),
32 onGetApprovedBuilds({limit: 12}),
33 onGetApprovedBuilds({limit: 20, sort: 'rating_desc'})
34 ]);
35
36 setData({
37 isLoggedIn: authData.isLoggedIn,
38 userId: authData.userId,
39 prebuilts: highestRankedBuilds,
40 communityBuilds: communityBuilds
41 });
42 setAllRanked(fullRankedList);
43 } catch (error) {
44 console.error("Error loading homepage data:", error);
45 }
46 }
47
48 loadSite();
49 }, []);
50
51 const handleCloneWrapper = async (buildId: number) => {
52 if (!data?.isLoggedIn) return alert("Please login to clone builds!");
53 if (confirm(`Clone this build to your dashboard?`)) {
54 await onCloneBuild({buildId});
55 alert("Build cloned! Check your dashboard.");
56 setSelectedBuildId(null);
57 }
58 };
59
60 if (!data) return <Box sx={{p: 10, textAlign: 'center'}}>Loading Forge...</Box>;
61
62 return (
63 <Box>
64 <Box sx={{
65 position: 'relative', height: '500px',
66 display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white',
67 '&::before': {
68 content: '""', position: 'absolute', top: 0, left: 0, width: '100%', height: '100%',
69 backgroundColor: 'rgba(0,0,0,0.6)'
70 }
71 }}>
72 <Box sx={{position: 'relative', textAlign: 'center', zIndex: 1, p: 2}}>
73 <Typography variant="h2" fontWeight="bold" gutterBottom>Forge Your Ultimate Machine</Typography>
74 <Typography variant="h5" sx={{maxWidth: '800px', mx: 'auto', mb: 1}}>
75 Build, share, discuss, and discover custom PC configurations.
76 </Typography>
77 <Button variant="contained" size="large" href="/forge" startIcon={<AutoFixHighIcon/>}
78 sx={{fontSize: '1.2rem', px: 4, py: 1.5, mt: 2}}>
79 Start Forging
80 </Button>
81 </Box>
82 </Box>
83
84 <Container maxWidth="xl" sx={{mt: 6, mb: 10}}>
85 <Box sx={{
86 mb: 2, borderLeft: '5px solid #ff8201', pl: 1,
87 display: 'flex', justifyContent: 'space-between', alignItems: 'end'
88 }}>
89 <Box>
90 <Typography variant="h4" fontWeight="bold">Hall of Fame</Typography>
91 <Typography variant="subtitle1" color="text.secondary">
92 The highest rated configurations from across the community.
93 </Typography>
94 </Box>
95 <Button variant="outlined" startIcon={<ListIcon/>} onClick={() => setOpenRankedPopup(true)}>
96 Show All Top Ranked
97 </Button>
98 </Box>
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,
110 width: '100%',
111 mb: 8
112 }}
113 >
114 {data.prebuilts.map((build: any) => (
115 <BuildCard
116 key={build.id}
117 build={build}
118 onClick={() => setSelectedBuildId(build.id)}
119 />
120 ))}
121 </Box>
122
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>
127 <Typography variant="subtitle1" color="text.secondary" sx={{mb: 2}}>Fresh builds from users around the world.</Typography>
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,
140 width: '100%',
141 }}
142 >
143 {data.communityBuilds.map((build: any) => (
144 <BuildCard
145 key={build.id}
146 build={build}
147 onClick={() => setSelectedBuildId(build.id)}
148 />
149 ))}
150 </Box>
151
152 <Box sx={{display: 'flex', justifyContent: 'center', mt: 6}}>
153 <Button variant="outlined" size="large" href="/completed-builds">View All Community Builds</Button>
154 </Box>
155 </Container>
156
157 <BuildDetailsDialog
158 open={!!selectedBuildId}
159 buildId={selectedBuildId}
160 currentUser={data.userId}
161 onClose={() => setSelectedBuildId(null)}
162 onClone={handleCloneWrapper}
163 />
164
165 <Dialog open={openRankedPopup} onClose={() => setOpenRankedPopup(false)} maxWidth="xl" fullWidth scroll="paper">
166 <DialogTitle sx={{display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
167 Hall of Fame (Top Rated)
168 <IconButton onClick={() => setOpenRankedPopup(false)}><CloseIcon/></IconButton>
169 </DialogTitle>
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 >
185 {allRanked.map((build: any, index: number) => (
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}
205 </Box>
206 <BuildCard
207 build={build}
208 onClick={() => {
209 setOpenRankedPopup(false);
210 setSelectedBuildId(build.id);
211 }}
212 />
213 </Box>
214 ))}
215 </Box>
216 </DialogContent>
217 </Dialog>
218 </Box>
219 );
220}
Note: See TracBrowser for help on using the repository browser.