source: components/BuildCard.tsx@ c586cbd

main
Last change on this file since c586cbd was 958bc89, checked in by Mihail <mihail2.naumov@…>, 6 months ago

Added add component button, fixed several things

  • Property mode set to 100644
File size: 4.2 KB
Line 
1import React, {useEffect, useState} from 'react';
2import {Card, CardContent, CardMedia, Typography, Box, Chip, CircularProgress} from '@mui/material';
3import StarIcon from '@mui/icons-material/Star';
4import {onGetBuildDetails} from "../pages/+Layout.telefunc";
5
6export default function BuildCard({build, onClick}: { build: any, onClick?: () => void }) {
7 const [caseImage, setCaseImage] = useState<string>("https://placehold.co/600x400?text=PC+Build");
8 const [imageLoading, setImageLoading] = useState(true);
9 const [details, setDetails] = useState<any>(null);
10
11 const formattedPrice = new Intl.NumberFormat('en-US', {
12 style: 'currency',
13 currency: 'EUR'
14 }).format(build.total_price || 0);
15
16 useEffect(() => {
17 setImageLoading(true);
18 onGetBuildDetails({buildId: build.id})
19 .then(fullDetails => {
20 setDetails(fullDetails);
21
22 const caseComponent = fullDetails.components?.find((c: any) => c.type === 'case');
23 setCaseImage(
24 caseComponent?.imgUrl ||
25 "https://placehold.co/600x400?text=PC+Build"
26 );
27 })
28 .catch((error) => {
29 console.error("Failed to load build details:", error);
30 setDetails(null);
31 })
32 .finally(() => {
33 setImageLoading(false);
34 });
35 }, [build.id]);
36
37 if (imageLoading) {
38 return (
39 <Card sx={{width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center'}}>
40 <CircularProgress />
41 </Card>
42 );
43 }
44
45 return (
46 <Card
47 onClick={onClick}
48 sx={{
49 width: '100%',
50 height: '100%',
51 display: 'flex',
52 flexDirection: 'column',
53 cursor: onClick ? 'pointer' : 'default',
54 transition: 'transform 0.2s, box-shadow 0.2s',
55 '&:hover': onClick ? {
56 transform: 'translateY(-4px)',
57 boxShadow: 6
58 } : {},
59 position: 'relative'
60 }}
61 >
62 <Box sx={{position: 'relative', paddingTop: '75%'}}>
63 <CardMedia
64 component="img"
65 image={caseImage}
66 alt={build.name}
67 sx={{
68 position: 'absolute',
69 top: 0,
70 left: 0,
71 width: '100%',
72 height: '100%',
73 objectFit: 'contain',
74 p: 2,
75 bgcolor: '#f5f5f5'
76 }}
77 />
78 </Box>
79
80 <CardContent sx={{flexGrow: 1, display: 'flex', flexDirection: 'column', justifyContent: 'space-between'}}>
81 <Box sx={{mb: 1}}>
82 <Typography variant="h6" component="div" fontWeight="bold">
83 {build.name}
84 </Typography>
85 </Box>
86
87 <Box sx={{mb: 2}}>
88 <Typography
89 variant="body2"
90 color="text.secondary"
91 sx={{fontStyle: 'italic', fontSize: '0.875rem'}}
92 >
93 {details?.description || "No description provided."}
94 </Typography>
95 </Box>
96
97 <Box sx={{display: 'flex', justifyContent: 'space-between', alignItems: 'center', mt: 'auto'}}>
98 <Chip
99 label={formattedPrice}
100 color="primary"
101 variant="outlined"
102 size="small"
103 sx={{fontWeight: 'bold'}}
104 />
105 <Box sx={{display: 'flex', alignItems: 'center'}}>
106 <StarIcon sx={{color: '#faaf00', fontSize: 20, ml: 1}}/>
107 <Typography variant="body2" fontWeight="bold">
108 {Number(build.avgRating || 0).toFixed(1)}
109 </Typography>
110 </Box>
111 </Box>
112 </CardContent>
113 </Card>
114 );
115}
Note: See TracBrowser for help on using the repository browser.