secçoes personalizadas !
This commit is contained in:
176
src/App.jsx
176
src/App.jsx
@@ -6,7 +6,8 @@ import {
|
|||||||
Edit2, Image as ImageIcon, Check, RotateCcw, Trash,
|
Edit2, Image as ImageIcon, Check, RotateCcw, Trash,
|
||||||
PanelLeftClose, PanelLeftOpen, Sparkles, CloudSun,
|
PanelLeftClose, PanelLeftOpen, Sparkles, CloudSun,
|
||||||
ArrowRight, Droplets, CheckCircle2, PieChart, History,
|
ArrowRight, Droplets, CheckCircle2, PieChart, History,
|
||||||
X, Download, Bell, Globe, Filter, ShoppingBag, Share2
|
X, Download, Bell, Globe, Filter, ShoppingBag, Share2,
|
||||||
|
FolderOpen, Tag
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -66,6 +67,14 @@ export default function App() {
|
|||||||
const [sharedLookCopying, setSharedLookCopying] = useState(false);
|
const [sharedLookCopying, setSharedLookCopying] = useState(false);
|
||||||
const [copiedLookId, setCopiedLookId] = useState(null);
|
const [copiedLookId, setCopiedLookId] = useState(null);
|
||||||
|
|
||||||
|
// Estado para Secções
|
||||||
|
const [sections, setSections] = useState([]);
|
||||||
|
const [activeSectionFilter, setActiveSectionFilter] = useState('all');
|
||||||
|
const [showSectionManager, setShowSectionManager] = useState(false);
|
||||||
|
const [newSectionName, setNewSectionName] = useState('');
|
||||||
|
const [newSectionEmoji, setNewSectionEmoji] = useState('');
|
||||||
|
const [itemSections, setItemSections] = useState([]);
|
||||||
|
|
||||||
const t = (key) => translations[language]?.[key] || translations['PT'][key] || key;
|
const t = (key) => translations[language]?.[key] || translations['PT'][key] || key;
|
||||||
|
|
||||||
// Mapeamento de nomes de cor (PT) para valores CSS
|
// Mapeamento de nomes de cor (PT) para valores CSS
|
||||||
@@ -151,6 +160,7 @@ export default function App() {
|
|||||||
} else {
|
} else {
|
||||||
setItemColors([]);
|
setItemColors([]);
|
||||||
}
|
}
|
||||||
|
setItemSections(editingItem?.sections || []);
|
||||||
}, [editingItem]);
|
}, [editingItem]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -179,6 +189,7 @@ export default function App() {
|
|||||||
setUser(null);
|
setUser(null);
|
||||||
setClothes([]);
|
setClothes([]);
|
||||||
setLooks([]);
|
setLooks([]);
|
||||||
|
setSections([]);
|
||||||
setUserProfile({});
|
setUserProfile({});
|
||||||
setDarkMode(false);
|
setDarkMode(false);
|
||||||
setTheme('theme-indigo');
|
setTheme('theme-indigo');
|
||||||
@@ -219,6 +230,12 @@ export default function App() {
|
|||||||
setLooks(snap.docs.map(d => ({ id: d.id, ...d.data() })));
|
setLooks(snap.docs.map(d => ({ id: d.id, ...d.data() })));
|
||||||
}, (err) => console.error(err));
|
}, (err) => console.error(err));
|
||||||
|
|
||||||
|
// Secções
|
||||||
|
const sectionsCol = collection(db, 'artifacts', appId, 'users', user.uid, 'sections');
|
||||||
|
const unsubSections = onSnapshot(sectionsCol, (snap) => {
|
||||||
|
setSections(snap.docs.map(d => ({ id: d.id, ...d.data() })).sort((a, b) => a.createdAt - b.createdAt));
|
||||||
|
}, (err) => console.error(err));
|
||||||
|
|
||||||
// Profile
|
// Profile
|
||||||
const profileDoc = doc(db, 'artifacts', appId, 'users', user.uid, 'profile', 'data');
|
const profileDoc = doc(db, 'artifacts', appId, 'users', user.uid, 'profile', 'data');
|
||||||
const unsubProfile = onSnapshot(profileDoc, (snap) => {
|
const unsubProfile = onSnapshot(profileDoc, (snap) => {
|
||||||
@@ -236,7 +253,7 @@ export default function App() {
|
|||||||
else setUserProfile({});
|
else setUserProfile({});
|
||||||
}, (err) => console.error(err));
|
}, (err) => console.error(err));
|
||||||
|
|
||||||
return () => { unsubClothes(); unsubLooks(); unsubProfile(); };
|
return () => { unsubClothes(); unsubLooks(); unsubSections(); unsubProfile(); };
|
||||||
}, [user]);
|
}, [user]);
|
||||||
|
|
||||||
// Fetch Weather Data
|
// Fetch Weather Data
|
||||||
@@ -278,6 +295,35 @@ export default function App() {
|
|||||||
const wishlistClothes = useMemo(() => clothes.filter(c => c.status === 'wishlist'), [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 availableForLooks = useMemo(() => clothes.filter(c => c.status === 'active' || c.status === 'wishlist'), [clothes]);
|
||||||
|
|
||||||
|
// CRUD de Secções
|
||||||
|
const saveSection = async () => {
|
||||||
|
if (!newSectionName.trim() || !user) return;
|
||||||
|
const sectionsCol = collection(db, 'artifacts', appId, 'users', user.uid, 'sections');
|
||||||
|
await addDoc(sectionsCol, {
|
||||||
|
name: newSectionName.trim(),
|
||||||
|
emoji: newSectionEmoji.trim() || '💼',
|
||||||
|
createdAt: new Date().getTime()
|
||||||
|
});
|
||||||
|
setNewSectionName('');
|
||||||
|
setNewSectionEmoji('');
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteSection = async (id) => {
|
||||||
|
if (!window.confirm(t('confirmDeleteSection'))) return;
|
||||||
|
const docRef = doc(db, 'artifacts', appId, 'users', user.uid, 'sections', id);
|
||||||
|
await deleteDoc(docRef);
|
||||||
|
// Remover a secção de todas as peças que a tinham
|
||||||
|
const batch = writeBatch(db);
|
||||||
|
clothes.forEach(item => {
|
||||||
|
if (item.sections && item.sections.includes(id)) {
|
||||||
|
const itemRef = doc(db, 'artifacts', appId, 'users', user.uid, 'clothes', item.id);
|
||||||
|
batch.update(itemRef, { sections: item.sections.filter(s => s !== id) });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await batch.commit();
|
||||||
|
if (activeSectionFilter === id) setActiveSectionFilter('all');
|
||||||
|
};
|
||||||
|
|
||||||
const baseClothes = view === 'wishlist' ? wishlistClothes : activeClothes;
|
const baseClothes = view === 'wishlist' ? wishlistClothes : activeClothes;
|
||||||
|
|
||||||
const availableColors = useMemo(() => {
|
const availableColors = useMemo(() => {
|
||||||
@@ -313,6 +359,7 @@ export default function App() {
|
|||||||
(c.color || "").toLowerCase().includes(searchTerm.toLowerCase());
|
(c.color || "").toLowerCase().includes(searchTerm.toLowerCase());
|
||||||
const matchesCategory = categoryFilter === 'Todos' || categoryFilter === t('all') || c.category === categoryFilter;
|
const matchesCategory = categoryFilter === 'Todos' || categoryFilter === t('all') || c.category === categoryFilter;
|
||||||
const matchesColor = !colorFilter || (c.color && c.color.includes(colorFilter));
|
const matchesColor = !colorFilter || (c.color && c.color.includes(colorFilter));
|
||||||
|
const matchesSection = activeSectionFilter === 'all' || (c.sections && c.sections.includes(activeSectionFilter));
|
||||||
|
|
||||||
let matchesAge = true;
|
let matchesAge = true;
|
||||||
if (ageFilter !== 'any') {
|
if (ageFilter !== 'any') {
|
||||||
@@ -324,9 +371,9 @@ export default function App() {
|
|||||||
else if (ageFilter === 'older') matchesAge = days > 365;
|
else if (ageFilter === 'older') matchesAge = days > 365;
|
||||||
}
|
}
|
||||||
|
|
||||||
return matchesSearch && matchesCategory && matchesColor && matchesAge;
|
return matchesSearch && matchesCategory && matchesColor && matchesAge && matchesSection;
|
||||||
});
|
});
|
||||||
}, [baseClothes, searchTerm, categoryFilter, colorFilter, ageFilter, t]);
|
}, [baseClothes, searchTerm, categoryFilter, colorFilter, ageFilter, t, activeSectionFilter]);
|
||||||
|
|
||||||
// Ações de Itens
|
// Ações de Itens
|
||||||
const handleItemAction = async (action, item) => {
|
const handleItemAction = async (action, item) => {
|
||||||
@@ -362,6 +409,7 @@ export default function App() {
|
|||||||
imageUrl: formData.get('imageUrl') || 'https://images.unsplash.com/photo-1521572267360-ee0c2909d518?q=80&w=500&auto=format&fit=crop',
|
imageUrl: formData.get('imageUrl') || 'https://images.unsplash.com/photo-1521572267360-ee0c2909d518?q=80&w=500&auto=format&fit=crop',
|
||||||
status: formData.get('isWishlist') ? 'wishlist' : (editingItem && editingItem.status === 'wishlist' ? 'active' : (editingItem ? editingItem.status : 'active')),
|
status: formData.get('isWishlist') ? 'wishlist' : (editingItem && editingItem.status === 'wishlist' ? 'active' : (editingItem ? editingItem.status : 'active')),
|
||||||
favorite: editingItem ? (editingItem.favorite || false) : false,
|
favorite: editingItem ? (editingItem.favorite || false) : false,
|
||||||
|
sections: itemSections,
|
||||||
updatedAt: new Date().getTime()
|
updatedAt: new Date().getTime()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -868,6 +916,33 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Barra de Secções */}
|
||||||
|
{view === 'closet' && (
|
||||||
|
<div className="flex items-center gap-3 overflow-x-auto pb-1 custom-scrollbar">
|
||||||
|
<button
|
||||||
|
onClick={() => setActiveSectionFilter('all')}
|
||||||
|
className={`shrink-0 flex items-center gap-2 px-5 py-2.5 rounded-2xl font-black text-[10px] uppercase tracking-widest transition-all ${activeSectionFilter === 'all' ? 'bg-primary-600 text-white shadow-lg shadow-primary-600/30' : (darkMode ? 'bg-gray-800 text-gray-400 hover:bg-gray-700' : 'bg-gray-100 text-gray-500 hover:bg-gray-200')}`}
|
||||||
|
>
|
||||||
|
<FolderOpen size={14} /> {t('allSections')}
|
||||||
|
</button>
|
||||||
|
{sections.map(sec => (
|
||||||
|
<button
|
||||||
|
key={sec.id}
|
||||||
|
onClick={() => setActiveSectionFilter(sec.id)}
|
||||||
|
className={`shrink-0 flex items-center gap-2 px-5 py-2.5 rounded-2xl font-black text-[10px] uppercase tracking-widest transition-all ${activeSectionFilter === sec.id ? 'bg-primary-600 text-white shadow-lg shadow-primary-600/30 scale-105' : (darkMode ? 'bg-gray-800 text-gray-400 hover:bg-gray-700' : 'bg-gray-100 text-gray-500 hover:bg-gray-200')}`}
|
||||||
|
>
|
||||||
|
<span>{sec.emoji}</span> {sec.name}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
<button
|
||||||
|
onClick={() => setShowSectionManager(true)}
|
||||||
|
className={`shrink-0 flex items-center gap-2 px-4 py-2.5 rounded-2xl font-black text-[10px] uppercase tracking-widest transition-all border-2 border-dashed ${darkMode ? 'border-gray-700 text-gray-500 hover:border-primary-500 hover:text-primary-400' : 'border-gray-200 text-gray-400 hover:border-primary-400 hover:text-primary-600'}`}
|
||||||
|
>
|
||||||
|
<Settings size={14} /> {t('manageSections')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-10">
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-10">
|
||||||
{filteredClothes.map(item => (
|
{filteredClothes.map(item => (
|
||||||
<div key={item.id} className="group">
|
<div key={item.id} className="group">
|
||||||
@@ -1149,6 +1224,33 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
<Input label={t('imageUrl')} name="imageUrl" defaultValue={editingItem?.imageUrl} onChange={(v) => setImageUrlDraft(v)} />
|
<Input label={t('imageUrl')} name="imageUrl" defaultValue={editingItem?.imageUrl} onChange={(v) => setImageUrlDraft(v)} />
|
||||||
|
|
||||||
|
{/* Campo de Secções */}
|
||||||
|
{sections.length > 0 && (
|
||||||
|
<div className="space-y-3">
|
||||||
|
<label className="text-[10px] font-black uppercase opacity-40 tracking-widest ml-1 text-inherit flex items-center gap-2">
|
||||||
|
<Tag size={12} /> {t('assignSections')}
|
||||||
|
</label>
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{sections.map(sec => (
|
||||||
|
<button
|
||||||
|
key={sec.id}
|
||||||
|
type="button"
|
||||||
|
onClick={() => {
|
||||||
|
if (itemSections.includes(sec.id))
|
||||||
|
setItemSections(itemSections.filter(s => s !== sec.id));
|
||||||
|
else
|
||||||
|
setItemSections([...itemSections, sec.id]);
|
||||||
|
}}
|
||||||
|
className={`flex items-center gap-2 px-4 py-2 rounded-xl text-xs font-bold transition-all border-2 ${itemSections.includes(sec.id) ? 'border-primary-600 bg-primary-600 text-white shadow-lg shadow-primary-600/30' : 'border-transparent bg-gray-100 dark:bg-gray-800 text-gray-500 hover:bg-gray-200 dark:hover:bg-gray-700'}`}
|
||||||
|
>
|
||||||
|
<span>{sec.emoji}</span> {sec.name}
|
||||||
|
{itemSections.includes(sec.id) && <Check size={12} />}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="flex gap-4 pt-6">
|
<div className="flex gap-4 pt-6">
|
||||||
<button type="button" onClick={() => { setEditingItem(null); setImageUrlDraft(''); setView('closet'); }} className="flex-1 font-black uppercase text-[10px] opacity-40 hover:opacity-100 tracking-widest transition-all text-inherit">{t('cancel')}</button>
|
<button type="button" onClick={() => { setEditingItem(null); setImageUrlDraft(''); setView('closet'); }} className="flex-1 font-black uppercase text-[10px] opacity-40 hover:opacity-100 tracking-widest transition-all text-inherit">{t('cancel')}</button>
|
||||||
<button type="submit" className="flex-1 py-5 bg-primary-600 text-white rounded-[2rem] font-black uppercase tracking-widest text-[10px] shadow-2xl shadow-primary-600/40 hover:scale-[1.02] active:scale-95 transition-all">
|
<button type="submit" className="flex-1 py-5 bg-primary-600 text-white rounded-[2rem] font-black uppercase tracking-widest text-[10px] shadow-2xl shadow-primary-600/40 hover:scale-[1.02] active:scale-95 transition-all">
|
||||||
@@ -1366,6 +1468,72 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
{/* Modal de Gestão de Secções */}
|
||||||
|
{showSectionManager && (
|
||||||
|
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowSectionManager(false)}>
|
||||||
|
<Card className="w-full max-w-lg p-8 animate-in zoom-in-95 flex flex-col max-h-[90vh]" darkMode={darkMode} onClick={e => e.stopPropagation()}>
|
||||||
|
<div className="flex items-center justify-between mb-8">
|
||||||
|
<h3 className="text-2xl font-black text-inherit flex items-center gap-3">
|
||||||
|
<FolderOpen size={24} className="text-primary-600" /> {t('manageSections')}
|
||||||
|
</h3>
|
||||||
|
<button onClick={() => setShowSectionManager(false)} className="p-2 bg-gray-100 dark:bg-gray-800 rounded-full hover:scale-110 transition-all text-inherit"><X size={20} /></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Criar nova secção */}
|
||||||
|
<div className={`flex gap-3 mb-8 p-4 rounded-2xl ${darkMode ? 'bg-gray-800' : 'bg-gray-50'}`}>
|
||||||
|
<input
|
||||||
|
value={newSectionEmoji}
|
||||||
|
onChange={e => setNewSectionEmoji(e.target.value)}
|
||||||
|
placeholder={t('emojiPlaceholder')}
|
||||||
|
maxLength={2}
|
||||||
|
className={`w-16 p-3 rounded-xl border-none outline-none font-bold text-center text-lg ${darkMode ? 'bg-gray-700 text-white' : 'bg-white'} shadow-sm`}
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
value={newSectionName}
|
||||||
|
onChange={e => setNewSectionName(e.target.value)}
|
||||||
|
placeholder={t('sectionPlaceholder')}
|
||||||
|
onKeyDown={e => e.key === 'Enter' && saveSection()}
|
||||||
|
className={`flex-1 p-3 rounded-xl border-none outline-none font-bold ${darkMode ? 'bg-gray-700 text-white' : 'bg-white'} shadow-sm`}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
onClick={saveSection}
|
||||||
|
disabled={!newSectionName.trim()}
|
||||||
|
className="px-5 py-3 bg-primary-600 text-white rounded-xl font-black text-[10px] uppercase tracking-widest shadow-lg shadow-primary-600/30 hover:scale-105 active:scale-95 transition-all disabled:opacity-30"
|
||||||
|
>
|
||||||
|
<Plus size={18} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Lista de secções */}
|
||||||
|
<div className="flex-1 overflow-y-auto space-y-3 custom-scrollbar">
|
||||||
|
{sections.length === 0 ? (
|
||||||
|
<div className="py-12 text-center opacity-30 font-black uppercase tracking-[0.3em] text-sm">{t('noSections')}</div>
|
||||||
|
) : sections.map(sec => (
|
||||||
|
<div key={sec.id} className={`flex items-center gap-4 p-4 rounded-2xl transition-all ${darkMode ? 'bg-gray-800' : 'bg-gray-50'}`}>
|
||||||
|
<span className="text-2xl w-10 text-center">{sec.emoji}</span>
|
||||||
|
<div className="flex-1">
|
||||||
|
<p className="font-black text-sm">{sec.name}</p>
|
||||||
|
<p className="text-[10px] opacity-40 font-bold uppercase tracking-widest">
|
||||||
|
{clothes.filter(c => c.sections && c.sections.includes(sec.id)).length} peça(s)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={() => deleteSection(sec.id)}
|
||||||
|
className="p-2 text-red-400 hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-xl transition-all"
|
||||||
|
>
|
||||||
|
<Trash size={16} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button onClick={() => setShowSectionManager(false)} className="mt-8 w-full py-4 font-black uppercase text-[10px] tracking-widest text-gray-500 hover:text-gray-900 dark:hover:text-white transition-colors">
|
||||||
|
{t('cancel')}
|
||||||
|
</button>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Modal de Filtros Avançados */}
|
{/* Modal de Filtros Avançados */}
|
||||||
{showClosetFilters && (
|
{showClosetFilters && (
|
||||||
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowClosetFilters(false)}>
|
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowClosetFilters(false)}>
|
||||||
|
|||||||
@@ -117,7 +117,20 @@ export const translations = {
|
|||||||
dob: "Data de Nascimento",
|
dob: "Data de Nascimento",
|
||||||
bio: "Bio / Sobre mim",
|
bio: "Bio / Sobre mim",
|
||||||
optional: "(Opcional)",
|
optional: "(Opcional)",
|
||||||
saving: "A guardar..."
|
saving: "A guardar...",
|
||||||
|
sections: "Secções",
|
||||||
|
manageSections: "Gerir Secções",
|
||||||
|
newSection: "Nova Secção",
|
||||||
|
sectionName: "Nome da Secção",
|
||||||
|
sectionEmoji: "Emoji",
|
||||||
|
noSections: "Nenhuma secção criada ainda.",
|
||||||
|
addSection: "Adicionar Secção",
|
||||||
|
deleteSection: "Apagar",
|
||||||
|
assignSections: "Atribuir a Secções",
|
||||||
|
allSections: "Todas",
|
||||||
|
confirmDeleteSection: "Apagar esta secção?",
|
||||||
|
sectionPlaceholder: "Ex: Trabalho, Festa...",
|
||||||
|
emojiPlaceholder: "Ex: 💼"
|
||||||
},
|
},
|
||||||
EN: {
|
EN: {
|
||||||
loginModeIntro: "The Future of Your Style",
|
loginModeIntro: "The Future of Your Style",
|
||||||
@@ -237,7 +250,20 @@ export const translations = {
|
|||||||
dob: "Date of Birth",
|
dob: "Date of Birth",
|
||||||
bio: "Bio / About me",
|
bio: "Bio / About me",
|
||||||
optional: "(Optional)",
|
optional: "(Optional)",
|
||||||
saving: "Saving..."
|
saving: "Saving...",
|
||||||
|
sections: "Sections",
|
||||||
|
manageSections: "Manage Sections",
|
||||||
|
newSection: "New Section",
|
||||||
|
sectionName: "Section Name",
|
||||||
|
sectionEmoji: "Emoji",
|
||||||
|
noSections: "No sections created yet.",
|
||||||
|
addSection: "Add Section",
|
||||||
|
deleteSection: "Delete",
|
||||||
|
assignSections: "Assign to Sections",
|
||||||
|
allSections: "All",
|
||||||
|
confirmDeleteSection: "Delete this section?",
|
||||||
|
sectionPlaceholder: "E.g.: Work, Party...",
|
||||||
|
emojiPlaceholder: "E.g.: 💼"
|
||||||
},
|
},
|
||||||
ES: {
|
ES: {
|
||||||
loginModeIntro: "El Futuro de Tu Estilo",
|
loginModeIntro: "El Futuro de Tu Estilo",
|
||||||
@@ -357,7 +383,20 @@ export const translations = {
|
|||||||
dob: "Fecha de Nacimiento",
|
dob: "Fecha de Nacimiento",
|
||||||
bio: "Bio / Sobre mí",
|
bio: "Bio / Sobre mí",
|
||||||
optional: "(Opcional)",
|
optional: "(Opcional)",
|
||||||
saving: "Guardando..."
|
saving: "Guardando...",
|
||||||
|
sections: "Secciones",
|
||||||
|
manageSections: "Gestionar Secciones",
|
||||||
|
newSection: "Nueva Sección",
|
||||||
|
sectionName: "Nombre de la Sección",
|
||||||
|
sectionEmoji: "Emoji",
|
||||||
|
noSections: "Aún no hay secciones creadas.",
|
||||||
|
addSection: "Añadir Sección",
|
||||||
|
deleteSection: "Eliminar",
|
||||||
|
assignSections: "Asignar a Secciones",
|
||||||
|
allSections: "Todas",
|
||||||
|
confirmDeleteSection: "¿Eliminar esta sección?",
|
||||||
|
sectionPlaceholder: "Ej: Trabajo, Fiesta...",
|
||||||
|
emojiPlaceholder: "Ej: 💼"
|
||||||
},
|
},
|
||||||
FR: {
|
FR: {
|
||||||
loginModeIntro: "Le Futur de Ton Style",
|
loginModeIntro: "Le Futur de Ton Style",
|
||||||
@@ -477,7 +516,20 @@ export const translations = {
|
|||||||
dob: "Date de Naissance",
|
dob: "Date de Naissance",
|
||||||
bio: "Bio / À propos",
|
bio: "Bio / À propos",
|
||||||
optional: "(Optionnel)",
|
optional: "(Optionnel)",
|
||||||
saving: "Enregistrement..."
|
saving: "Enregistrement...",
|
||||||
|
sections: "Sections",
|
||||||
|
manageSections: "Gérer les Sections",
|
||||||
|
newSection: "Nouvelle Section",
|
||||||
|
sectionName: "Nom de la Section",
|
||||||
|
sectionEmoji: "Emoji",
|
||||||
|
noSections: "Aucune section créée pour l'instant.",
|
||||||
|
addSection: "Ajouter une Section",
|
||||||
|
deleteSection: "Supprimer",
|
||||||
|
assignSections: "Attribuer aux Sections",
|
||||||
|
allSections: "Toutes",
|
||||||
|
confirmDeleteSection: "Supprimer cette section ?",
|
||||||
|
sectionPlaceholder: "Ex: Travail, Fête...",
|
||||||
|
emojiPlaceholder: "Ex: 💼"
|
||||||
},
|
},
|
||||||
DE: {
|
DE: {
|
||||||
loginModeIntro: "Die Zukunft deines Stils",
|
loginModeIntro: "Die Zukunft deines Stils",
|
||||||
@@ -597,6 +649,19 @@ export const translations = {
|
|||||||
dob: "Geburtsdatum",
|
dob: "Geburtsdatum",
|
||||||
bio: "Biografie / Über mich",
|
bio: "Biografie / Über mich",
|
||||||
optional: "(Optional)",
|
optional: "(Optional)",
|
||||||
saving: "Speichern..."
|
saving: "Speichern...",
|
||||||
|
sections: "Bereiche",
|
||||||
|
manageSections: "Bereiche verwalten",
|
||||||
|
newSection: "Neuer Bereich",
|
||||||
|
sectionName: "Bereichsname",
|
||||||
|
sectionEmoji: "Emoji",
|
||||||
|
noSections: "Noch keine Bereiche erstellt.",
|
||||||
|
addSection: "Bereich hinzufügen",
|
||||||
|
deleteSection: "Löschen",
|
||||||
|
assignSections: "Bereichen zuweisen",
|
||||||
|
allSections: "Alle",
|
||||||
|
confirmDeleteSection: "Diesen Bereich löschen?",
|
||||||
|
sectionPlaceholder: "Zb: Arbeit, Party...",
|
||||||
|
emojiPlaceholder: "Zb: 💼"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user