Files
imgPub/src/components/UploadStep.jsx

144 lines
4.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 coverImageId = useAppStore((state) => state.coverImageId);
const setCoverImageId = useAppStore((state) => state.setCoverImageId);
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 handleCoverToggle = (imageId) => {
const nextId = coverImageId === imageId ? null : imageId;
setCoverImageId(nextId);
};
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>
<Button
variant={image.id === coverImageId ? 'contained' : 'outlined'}
size="small"
fullWidth
sx={{ mt: 1 }}
onClick={(event) => {
event.stopPropagation();
handleCoverToggle(image.id);
}}
>
{image.id === coverImageId ? 'Kapak seçildi' : 'Kapak olarak işaretle'}
</Button>
</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;