first commit

This commit is contained in:
2025-11-10 23:35:59 +03:00
commit 68165014ad
33 changed files with 2084 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
import { useCallback } from 'react';
import { useDropzone } from 'react-dropzone';
import {
Box,
Button,
Card,
CardActionArea,
CardContent,
CardMedia,
Grid,
Stack,
Typography,
} from '@mui/material';
import { useNavigate } from 'react-router-dom';
import { useAppStore } from '../store/useAppStore';
const dropzoneStyle = {
border: '2px dashed rgba(108, 155, 207, 0.7)',
borderRadius: 12,
padding: '32px',
textAlign: 'center',
backgroundColor: 'rgba(108, 155, 207, 0.08)',
cursor: 'pointer',
};
const UploadStep = () => {
const navigate = useNavigate();
const uploadedImages = useAppStore((state) => state.uploadedImages);
const setUploadedImages = useAppStore((state) => state.setUploadedImages);
const resetFromStep = useAppStore((state) => state.resetFromStep);
const onDrop = useCallback(
(acceptedFiles) => {
if (!acceptedFiles.length) return;
resetFromStep('upload');
const mapped = acceptedFiles.map((file, index) => ({
id: crypto.randomUUID(),
file,
previewUrl: URL.createObjectURL(file),
order: uploadedImages.length + index,
filename: file.name,
}));
setUploadedImages([...uploadedImages, ...mapped]);
},
[uploadedImages, resetFromStep, setUploadedImages],
);
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
accept: {
'image/png': ['.png'],
'image/jpeg': ['.jpg', '.jpeg'],
},
multiple: true,
});
return (
<Stack spacing={4}>
<Box {...getRootProps()} sx={dropzoneStyle}>
<input {...getInputProps()} />
<Typography variant="h5" gutterBottom>
Görselleri sürükleyip bırak veya tıkla
</Typography>
<Typography color="text.secondary" gutterBottom>
.png, .jpg, .jpeg formatlarında çoklu dosya yükleyebilirsin.
</Typography>
<Button variant="contained" color="primary">
Dosya seç
</Button>
{isDragActive && (
<Typography mt={2} fontWeight={600}>
Bırak ve yükleyelim!
</Typography>
)}
</Box>
<Box>
<Typography variant="h6" gutterBottom>
Yüklenen görseller ({uploadedImages.length})
</Typography>
{uploadedImages.length === 0 ? (
<Typography color="text.secondary">
Henüz görsel yüklenmedi.
</Typography>
) : (
<Grid container spacing={2}>
{uploadedImages.map((image) => (
<Grid item xs={12} sm={6} md={4} lg={3} key={image.id}>
<Card>
<CardActionArea>
<CardMedia
component="img"
height="160"
image={image.previewUrl}
alt={image.filename}
/>
<CardContent>
<Typography variant="body2" noWrap>
{image.filename}
</Typography>
</CardContent>
</CardActionArea>
</Card>
</Grid>
))}
</Grid>
)}
</Box>
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} justifyContent="flex-end">
<Button
variant="contained"
color="primary"
disabled={!uploadedImages.length}
onClick={() => navigate('/crop')}
>
Devam et
</Button>
</Stack>
</Stack>
);
};
export default UploadStep;