add by files
This commit is contained in:
68
src/App.jsx
68
src/App.jsx
@@ -707,6 +707,44 @@ export default function App() {
|
||||
reader.readAsDataURL(file);
|
||||
};
|
||||
|
||||
const handleItemImageUpload = (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
const canvas = document.createElement('canvas');
|
||||
const MAX_SIZE = 800; // Tamanho maior para roupas
|
||||
let width = img.width;
|
||||
let height = img.height;
|
||||
|
||||
if (width > height) {
|
||||
if (width > MAX_SIZE) {
|
||||
height *= MAX_SIZE / width;
|
||||
width = MAX_SIZE;
|
||||
}
|
||||
} else {
|
||||
if (height > MAX_SIZE) {
|
||||
width *= MAX_SIZE / height;
|
||||
height = MAX_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0, width, height);
|
||||
const base64Data = canvas.toDataURL('image/jpeg', 0.8);
|
||||
|
||||
setImageUrlDraft(base64Data);
|
||||
};
|
||||
img.src = event.target.result;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
};
|
||||
|
||||
const saveProfile = async (e) => {
|
||||
e.preventDefault();
|
||||
setSavingProfile(true);
|
||||
@@ -1011,7 +1049,7 @@ export default function App() {
|
||||
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black/80 via-transparent opacity-0 group-hover:opacity-100 transition-all duration-300 flex flex-col justify-end p-6 pb-[136px] text-white z-10 pointer-events-none">
|
||||
<div className="grid grid-cols-2 gap-2 pointer-events-auto">
|
||||
<button onClick={() => { setEditingItem(item); setImageUrlDraft(''); setView('edit'); }} className="py-3 px-2 bg-white text-primary-600 rounded-xl font-black text-[9px] uppercase flex items-center justify-center gap-1.5 hover:bg-primary-50"><Edit2 size={14} /> {t('edit')}</button>
|
||||
<button onClick={() => { setEditingItem(item); setImageUrlDraft(item.imageUrl || ''); setView('edit'); }} className="py-3 px-2 bg-white text-primary-600 rounded-xl font-black text-[9px] uppercase flex items-center justify-center gap-1.5 hover:bg-primary-50"><Edit2 size={14} /> {t('edit')}</button>
|
||||
<button onClick={() => handleItemAction('laundry', item)} className="py-3 px-2 bg-blue-600 text-white rounded-xl font-black text-[9px] uppercase flex items-center justify-center gap-1.5 hover:bg-blue-700"><Droplets size={14} /> {t('makeDirty')}</button>
|
||||
<button onClick={() => handleItemAction('trash', item)} className="py-3 px-2 bg-red-600/20 text-red-100 backdrop-blur-md rounded-xl font-black text-[9px] uppercase hover:bg-red-600 transition-colors col-span-2">{t('moveToTrash')}</button>
|
||||
</div>
|
||||
@@ -1289,8 +1327,8 @@ export default function App() {
|
||||
<div className="space-y-8">
|
||||
<h3 className="text-5xl font-black tracking-tighter text-inherit">{editingItem ? t('edit') : t('newItem')}</h3>
|
||||
<Card className="aspect-[3/4] overflow-hidden shadow-2xl relative" darkMode={darkMode}>
|
||||
{editingItem?.imageUrl || imageUrlDraft.startsWith('http') ? (
|
||||
<img src={imageUrlDraft || editingItem?.imageUrl} className="w-full h-full object-cover" alt="" />
|
||||
{imageUrlDraft ? (
|
||||
<img src={imageUrlDraft} className="w-full h-full object-cover" alt="" />
|
||||
) : (
|
||||
<div className="h-full flex flex-col items-center justify-center opacity-10">
|
||||
<ImageIcon size={100} />
|
||||
@@ -1336,7 +1374,29 @@ export default function App() {
|
||||
<input type="hidden" name="color" value={itemColors.join(', ')} />
|
||||
{itemColors.length === 0 && <p className="text-[10px] text-red-500 uppercase tracking-widest font-black mt-2">Selecione pelo menos uma cor</p>}
|
||||
</div>
|
||||
<Input label={t('imageUrl')} name="imageUrl" defaultValue={editingItem?.imageUrl} onChange={(v) => setImageUrlDraft(v)} />
|
||||
<div className="space-y-4">
|
||||
<label className="text-[10px] font-black uppercase opacity-40 tracking-widest ml-1 text-inherit flex items-center gap-2"><ImageIcon size={12}/> {t('imageUrl')} ou Upload</label>
|
||||
<div className="flex flex-col gap-3">
|
||||
<input
|
||||
type="text"
|
||||
name="imageUrl"
|
||||
value={imageUrlDraft}
|
||||
onChange={(e) => setImageUrlDraft(e.target.value)}
|
||||
placeholder="https://..."
|
||||
className={`w-full p-5 rounded-2xl border-none outline-none focus:ring-4 focus:ring-primary-500/10 font-bold transition-all ${darkMode ? 'bg-gray-700 text-white' : 'bg-gray-100 text-gray-900'}`}
|
||||
/>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="h-px bg-gray-200 dark:bg-gray-700 flex-1"></div>
|
||||
<span className="text-[10px] font-black uppercase tracking-widest opacity-30">OU</span>
|
||||
<div className="h-px bg-gray-200 dark:bg-gray-700 flex-1"></div>
|
||||
</div>
|
||||
<label className={`flex items-center justify-center gap-3 p-5 rounded-2xl cursor-pointer transition-all font-black text-[10px] uppercase tracking-widest border-2 border-dashed ${darkMode ? 'bg-gray-800 border-gray-700 hover:border-primary-500 hover:text-primary-400' : 'bg-gray-50 border-gray-200 hover:border-primary-400 hover:text-primary-600'}`}>
|
||||
<ImageIcon size={16} />
|
||||
<span>Upload da Galeria / Ficheiros</span>
|
||||
<input type="file" accept="image/*" className="hidden" onChange={handleItemImageUpload} />
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Campo de Secções */}
|
||||
<div className="space-y-3">
|
||||
|
||||
Reference in New Issue
Block a user