source: components/BuildCard.tsx@ 6270fa4

main
Last change on this file since 6270fa4 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
RevLine 
[8a7f936]1import React, {useEffect, useState} from 'react';
[958bc89]2import {Card, CardContent, CardMedia, Typography, Box, Chip, CircularProgress} from '@mui/material';
[1bf6e1f]3import StarIcon from '@mui/icons-material/Star';
[8a7f936]4import {onGetBuildDetails} from "../pages/+Layout.telefunc";
[1bf6e1f]5
[8a7f936]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);
[958bc89]9 const [details, setDetails] = useState<any>(null);
[8a7f936]10
11 const formattedPrice = new Intl.NumberFormat('en-US', {
12 style: 'currency',
13 currency: 'EUR'
14 }).format(build.total_price || 0);
15
16 useEffect(() => {
[958bc89]17 setImageLoading(true);
[8a7f936]18 onGetBuildDetails({buildId: build.id})
[958bc89]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 );
[8a7f936]27 })
[958bc89]28 .catch((error) => {
29 console.error("Failed to load build details:", error);
30 setDetails(null);
[8a7f936]31 })
[958bc89]32 .finally(() => {
33 setImageLoading(false);
34 });
[8a7f936]35 }, [build.id]);
[1bf6e1f]36
[958bc89]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
[1bf6e1f]45 return (
46 <Card
47 onClick={onClick}
[8a7f936]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 }}
[1bf6e1f]61 >
[8a7f936]62 <Box sx={{position: 'relative', paddingTop: '75%'}}>
63 <CardMedia
64 component="img"
[958bc89]65 image={caseImage}
[8a7f936]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>
[1bf6e1f]79
[8a7f936]80 <CardContent sx={{flexGrow: 1, display: 'flex', flexDirection: 'column', justifyContent: 'space-between'}}>
[958bc89]81 <Box sx={{mb: 1}}>
82 <Typography variant="h6" component="div" fontWeight="bold">
[8a7f936]83 {build.name}
84 </Typography>
[1bf6e1f]85 </Box>
86
[958bc89]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
[8a7f936]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'}}>
[958bc89]106 <StarIcon sx={{color: '#faaf00', fontSize: 20, ml: 1}}/>
[1bf6e1f]107 <Typography variant="body2" fontWeight="bold">
[958bc89]108 {Number(build.avgRating || 0).toFixed(1)}
[1bf6e1f]109 </Typography>
110 </Box>
111 </Box>
112 </CardContent>
113 </Card>
114 );
[8a7f936]115}
Note: See TracBrowser for help on using the repository browser.