diff --git a/src/App.jsx b/src/App.jsx index 1332199..b138809 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -6,7 +6,7 @@ import { Edit2, Image as ImageIcon, Check, RotateCcw, Trash, PanelLeftClose, PanelLeftOpen, Sparkles, CloudSun, ArrowRight, Droplets, CheckCircle2, PieChart, History, - X, Download, Bell, Globe, Filter + X, Download, Bell, Globe, Filter, ShoppingBag } from 'lucide-react'; import { @@ -34,6 +34,7 @@ export default function App() { const [darkMode, setDarkMode] = useState(false); const [searchTerm, setSearchTerm] = useState(''); const [imageUrlDraft, setImageUrlDraft] = useState(''); + const [itemColors, setItemColors] = useState([]); const [sidebarOpen, setSidebarOpen] = useState(true); const [authMode, setAuthMode] = useState('login'); const [authError, setAuthError] = useState(''); @@ -98,6 +99,14 @@ export default function App() { saveUserSetting('weatherAlerts', newVal); }; + useEffect(() => { + if (editingItem && editingItem.color) { + setItemColors(editingItem.color.split(',').map(c => c.trim()).filter(Boolean)); + } else { + setItemColors([]); + } + }, [editingItem]); + useEffect(() => { document.documentElement.classList.remove('theme-indigo', 'theme-rose', 'theme-emerald', 'theme-amber', 'theme-slate'); document.documentElement.classList.add(theme); @@ -193,11 +202,15 @@ export default function App() { const activeClothes = useMemo(() => clothes.filter(c => c.status === 'active'), [clothes]); const laundryClothes = useMemo(() => clothes.filter(c => c.status === 'laundry'), [clothes]); const trashClothes = useMemo(() => clothes.filter(c => c.status === 'trash'), [clothes]); + const wishlistClothes = useMemo(() => clothes.filter(c => c.status === 'wishlist'), [clothes]); + const availableForLooks = useMemo(() => clothes.filter(c => c.status === 'active' || c.status === 'wishlist'), [clothes]); + + const baseClothes = view === 'wishlist' ? wishlistClothes : activeClothes; const availableColors = useMemo(() => { - const colors = new Set(activeClothes.map(c => c.color).filter(Boolean)); + const colors = new Set(baseClothes.map(c => c.color).filter(Boolean)); return Array.from(colors); - }, [activeClothes]); + }, [baseClothes]); const colorStats = useMemo(() => { if (!activeClothes.length) return []; @@ -222,11 +235,11 @@ export default function App() { }, [activeClothes]); const filteredClothes = useMemo(() => { - return activeClothes.filter(c => { + return baseClothes.filter(c => { const matchesSearch = (c.name || "").toLowerCase().includes(searchTerm.toLowerCase()) || (c.color || "").toLowerCase().includes(searchTerm.toLowerCase()); const matchesCategory = categoryFilter === 'Todos' || categoryFilter === t('all') || c.category === categoryFilter; - const matchesColor = !colorFilter || c.color === colorFilter; + const matchesColor = !colorFilter || (c.color && c.color.includes(colorFilter)); let matchesAge = true; if (ageFilter !== 'any') { @@ -240,7 +253,7 @@ export default function App() { return matchesSearch && matchesCategory && matchesColor && matchesAge; }); - }, [activeClothes, searchTerm, categoryFilter, colorFilter, ageFilter, t]); + }, [baseClothes, searchTerm, categoryFilter, colorFilter, ageFilter, t]); // Ações de Itens const handleItemAction = async (action, item) => { @@ -260,14 +273,21 @@ export default function App() { const saveItem = async (e) => { e.preventDefault(); if (!user) return; - setLoading(true); + const formData = new FormData(e.target); + const colorVal = formData.get('color'); + if (!colorVal || colorVal.trim() === '') { + alert('Por favor selecione pelo menos uma cor.'); + return; + } + + setLoading(true); const itemData = { name: formData.get('name'), category: formData.get('category'), color: formData.get('color'), imageUrl: formData.get('imageUrl') || 'https://images.unsplash.com/photo-1521572267360-ee0c2909d518?q=80&w=500&auto=format&fit=crop', - status: 'active', + status: formData.get('isWishlist') ? 'wishlist' : (editingItem && editingItem.status === 'wishlist' ? 'active' : (editingItem ? editingItem.status : 'active')), favorite: editingItem ? (editingItem.favorite || false) : false, updatedAt: new Date().getTime() }; @@ -279,7 +299,11 @@ export default function App() { // Navegação instantânea (Optimistic UI Update) setEditingItem(null); setImageUrlDraft(''); - setView('closet'); + setCategoryFilter('Todos'); + setColorFilter(''); + setAgeFilter('any'); + setSearchTerm(''); + setView(formData.get('isWishlist') ? 'wishlist' : 'closet'); if (currentEditId) { const docRef = doc(db, 'artifacts', appId, 'users', user.uid, 'clothes', currentEditId); @@ -328,6 +352,21 @@ export default function App() { await deleteDoc(docRef); }; + const sendLookToLaundry = async (look) => { + if (!window.confirm(t('confirmSendLookToLaundry') || 'Enviar todas as peças deste look para a lavandaria?')) return; + setLoading(true); + try { + const batch = writeBatch(db); + look.items.forEach(itemId => { + const docRef = doc(db, 'artifacts', appId, 'users', user.uid, 'clothes', itemId); + batch.update(docRef, { status: 'laundry' }); + }); + await batch.commit(); + alert(t('lookSentToLaundry') || 'Peças enviadas para a lavandaria!'); + } catch (e) { console.error(e); } + finally { setLoading(false); } + }; + const handleAuth = async (e) => { e.preventDefault(); setAuthError(''); @@ -513,6 +552,7 @@ export default function App() { {[ { id: 'dashboard', label: t('dashboard'), icon: LayoutDashboard }, { id: 'closet', label: t('closet'), icon: Shirt }, + { id: 'wishlist', label: t('wishlist') || 'Lista de Desejos', icon: ShoppingBag }, { id: 'laundry', label: t('laundry'), icon: Droplets }, { id: 'outfits', label: t('outfits'), icon: Sparkles }, { id: 'settings', label: t('settings'), icon: Settings }, @@ -561,6 +601,7 @@ export default function App() {

{view === 'dashboard' && t('overview')} {view === 'closet' && t('myCloset')} + {view === 'wishlist' && (t('wishlist') || 'Lista de Desejos')} {view === 'laundry' && t('laundry')} {view === 'outfits' && t('outfitsAndStyle')} {view === 'settings' && t('settings')} @@ -653,8 +694,8 @@ export default function App() { )} - {/* ARMÁRIO */} - {view === 'closet' && ( + {/* ARMÁRIO & WISHLIST */} + {(view === 'closet' || view === 'wishlist') && (
@@ -785,9 +826,10 @@ export default function App() {

{t('closetLabel')}

- {activeClothes.map(c => ( + {availableForLooks.map(c => ( ))} @@ -807,6 +849,7 @@ export default function App() {
+
@@ -849,14 +892,38 @@ export default function App() {
-
-
- - +
+ + +
+ +
+ +
+ {['Vermelho', 'Azul', 'Amarelo', 'Verde', 'Laranja', 'Roxo', 'Branco', 'Preto', 'Cinzento', 'Bege'].map(c => ( + + ))} +
+ + {itemColors.length === 0 &&

Selecione pelo menos uma cor

}
setImageUrlDraft(v)} />