Spaces:
Build error
Build error
File size: 4,864 Bytes
f62c9f6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | import React, { useState, useCallback } from 'react';
import PokemonCard from './PokemonCard';
const LocalDropZone = () => {
const [dragActive, setDragActive] = useState(false);
const [cards, setCards] = useState([]);
const handleDrag = useCallback((e) => {
e.preventDefault();
e.stopPropagation();
}, []);
const handleDragEnter = useCallback((e) => {
e.preventDefault();
e.stopPropagation();
setDragActive(true);
}, []);
const handleDragLeave = useCallback((e) => {
e.preventDefault();
e.stopPropagation();
setDragActive(false);
}, []);
const handleDragOver = useCallback((e) => {
e.preventDefault();
e.stopPropagation();
e.dataTransfer.dropEffect = 'copy';
}, []);
const handleDrop = useCallback((e) => {
e.preventDefault();
e.stopPropagation();
setDragActive(false);
const files = e.dataTransfer.files;
if (files && files.length > 0) {
Array.from(files).forEach(file => {
if (file.type.startsWith('image/')) {
const imageUrl = URL.createObjectURL(file);
const newCard = {
id: Math.random().toString(36).substr(2, 9),
name: file.name.replace(/\.[^/.]+$/, ""),
image: imageUrl,
type: 'custom',
size: (file.size / 1024).toFixed(2) + ' KB'
};
setCards(prevCards => [...prevCards, newCard]);
}
});
}
}, []);
const handleFileSelect = (e) => {
const files = e.target.files;
if (files && files.length > 0) {
Array.from(files).forEach(file => {
if (file.type.startsWith('image/')) {
const imageUrl = URL.createObjectURL(file);
const newCard = {
id: Math.random().toString(36).substr(2, 9),
name: file.name.replace(/\.[^/.]+$/, ""),
image: imageUrl,
type: 'custom',
size: (file.size / 1024).toFixed(2) + ' KB'
};
setCards(prevCards => [...prevCards, newCard]);
}
});
}
};
const handleRemoveCard = (id) => {
setCards(prevCards => prevCards.filter(card => card.id !== id));
};
return (
<div className="w-full max-w-4xl mx-auto p-6">
<h1 className="text-4xl font-extrabold text-gray-800 mb-2 text-center">Pokemon Card Drop Monitor</h1>
<p className="text-gray-500 mb-8 text-center">Drag and drop images to create custom Pokemon cards</p>
<div className={`relative border-4 border-dashed rounded-2xl p-12 text-center transition-all duration-300 ease-in-out mb-8
${dragActive ? 'border-blue-500 bg-blue-50' : 'border-gray-300 bg-gray-50 hover:border-blue-400'}`}>
<input
type="file"
multiple
accept="image/*"
onChange={handleFileSelect}
className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
id="fileInput"
/>
<div className="pointer-events-none">
<svg
className="mx-auto h-16 w-16 text-gray-400 mb-4"
stroke="currentColor"
fill="none"
viewBox="0 0 48 48"
aria-hidden="true"
>
<path
d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
<p className="text-lg text-gray-600 font-medium">
{dragActive ? 'Drop images here!' : 'Drag & Drop images here, or click to upload'}
</p>
<p className="text-sm text-gray-400 mt-2">Supports PNG, JPG, GIF, WEBP</p>
</div>
</div>
{cards.length === 0 && (
<div className="text-center text-gray-400 py-8">
<p>No cards added yet. Start dropping images above!</p>
</div>
)}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
{cards.map(card => (
<div key={card.id} className="relative group">
<PokemonCard pokemon={card} />
<button
onClick={() => handleRemoveCard(card.id)}
className="absolute top-2 right-2 bg-red-500 hover:bg-red-600 text-white rounded-full p-1.5 shadow-lg opacity-0 group-hover:opacity-100 transition-opacity duration-200"
aria-label="Remove card"
>
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
))}
</div>
</div>
);
};
export default LocalDropZone; |