remoção de frase e sintonia de idioma
This commit is contained in:
50
src/App.jsx
50
src/App.jsx
@@ -1060,7 +1060,7 @@ export default function App() {
|
||||
<Droplets size={40} />
|
||||
</div>
|
||||
<h3 className="text-4xl font-black tracking-tight">{t('laundryBasket')}</h3>
|
||||
<p className="opacity-60 font-medium">{t('laundryMsg')}</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8">
|
||||
@@ -1117,12 +1117,12 @@ export default function App() {
|
||||
<Tag size={12} /> {t('assignSections')}
|
||||
</label>
|
||||
<button type="button" onClick={() => setShowSectionManager(true)} className="text-[10px] font-black uppercase tracking-widest text-primary-600 hover:text-primary-700 flex items-center gap-1">
|
||||
<Plus size={10} /> Criar Secção
|
||||
<Plus size={10} /> {t('createSection')}
|
||||
</button>
|
||||
</div>
|
||||
{sections.length === 0 ? (
|
||||
<div className="p-4 border-2 border-dashed border-gray-200 dark:border-gray-800 rounded-2xl text-center">
|
||||
<p className="text-[10px] font-black uppercase tracking-widest opacity-40">Ainda não tem secções criadas</p>
|
||||
<p className="text-[10px] font-black uppercase tracking-widest opacity-40">{t('noSectionsCreated')}</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
@@ -1209,7 +1209,7 @@ export default function App() {
|
||||
>
|
||||
{copiedLookId === look.id ? <Check size={18} /> : <Share2 size={18} />}
|
||||
<span className="absolute -top-8 left-1/2 -translate-x-1/2 bg-gray-900 text-white text-[9px] font-black uppercase tracking-widest px-2 py-1 rounded-lg whitespace-nowrap opacity-0 group-hover/share:opacity-100 transition-opacity pointer-events-none">
|
||||
{copiedLookId === look.id ? 'Link copiado!' : 'Partilhar'}
|
||||
{copiedLookId === look.id ? t('linkCopied') : t('share')}
|
||||
</span>
|
||||
</button>
|
||||
<button onClick={() => { setEditingLook(look); setSelectedForLook(look.items); }} className="p-2 text-gray-300 hover:text-primary-500 transition-colors"><Edit2 size={18} /></button>
|
||||
@@ -1237,7 +1237,7 @@ export default function App() {
|
||||
<div className="flex items-center gap-2 mt-2 px-3 py-2 bg-blue-50 dark:bg-blue-900/20 rounded-xl">
|
||||
<Droplets size={14} className="text-blue-500 shrink-0" />
|
||||
<p className="text-[10px] font-black uppercase tracking-widest text-blue-500">
|
||||
{look.items.filter(id => { const it = clothes.find(c => c.id === id); return it?.status === 'laundry'; }).length} peça(s) na lavandaria
|
||||
{look.items.filter(id => { const it = clothes.find(c => c.id === id); return it?.status === 'laundry'; }).length} {t('piecesInLaundry')}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
@@ -1251,14 +1251,14 @@ export default function App() {
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center gap-3 px-2">
|
||||
<div className="w-2.5 h-2.5 rounded-full bg-green-500"></div>
|
||||
<h3 className="text-2xl font-black tracking-tighter text-inherit">{t('lookHistory')} <span className="text-sm font-bold opacity-40">— Disponíveis ({availableLooks.length})</span></h3>
|
||||
<h3 className="text-2xl font-black tracking-tighter text-inherit">{t('lookHistory')} <span className="text-sm font-bold opacity-40">— {t('availableLooks')} ({availableLooks.length})</span></h3>
|
||||
</div>
|
||||
{availableLooks.length > 0 ? (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
{availableLooks.map(renderLookCard)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="py-12 text-center opacity-20 font-black uppercase tracking-[0.3em] text-sm">Nenhum look disponível</div>
|
||||
<div className="py-12 text-center opacity-20 font-black uppercase tracking-[0.3em] text-sm">{t('noLooksAvailable')}</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1267,7 +1267,7 @@ export default function App() {
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center gap-3 px-2">
|
||||
<div className="w-2.5 h-2.5 rounded-full bg-blue-400"></div>
|
||||
<h3 className="text-2xl font-black tracking-tighter text-inherit">A ser lavados <span className="text-sm font-bold opacity-40">— Indisponíveis ({laundryLooks.length})</span></h3>
|
||||
<h3 className="text-2xl font-black tracking-tighter text-inherit">A ser lavados <span className="text-sm font-bold opacity-40">— {t('unavailable')} ({laundryLooks.length})</span></h3>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
{laundryLooks.map(renderLookCard)}
|
||||
@@ -1312,8 +1312,8 @@ export default function App() {
|
||||
<label className="flex items-center gap-3 p-4 rounded-xl border border-gray-100 dark:border-gray-800 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors">
|
||||
<input type="checkbox" name="isWishlist" defaultChecked={editingItem?.status === 'wishlist'} className="w-5 h-5 text-primary-600 focus:ring-primary-500 rounded-lg" />
|
||||
<div>
|
||||
<span className="font-bold text-sm text-inherit">{t('wishlist') || 'Lista de Desejos'}</span>
|
||||
<p className="text-[10px] uppercase tracking-widest opacity-50">Adicionar peça como compra futura</p>
|
||||
<span className="font-bold text-sm text-inherit">{t('wishlist') || t('wishlistDesc')}</span>
|
||||
<p className="text-[10px] uppercase tracking-widest opacity-50">{t('addFuturePurchase')}</p>
|
||||
</div>
|
||||
</label>
|
||||
<div className="space-y-2">
|
||||
@@ -1345,12 +1345,12 @@ export default function App() {
|
||||
<Tag size={12} /> {t('assignSections')}
|
||||
</label>
|
||||
<button type="button" onClick={() => setShowSectionManager(true)} className="text-[10px] font-black uppercase tracking-widest text-primary-600 hover:text-primary-700 flex items-center gap-1">
|
||||
<Plus size={10} /> Criar Secção
|
||||
<Plus size={10} /> {t('createSection')}
|
||||
</button>
|
||||
</div>
|
||||
{sections.length === 0 ? (
|
||||
<div className="p-4 border-2 border-dashed border-gray-200 dark:border-gray-800 rounded-2xl text-center">
|
||||
<p className="text-[10px] font-black uppercase tracking-widest opacity-40">Ainda não tem secções criadas</p>
|
||||
<p className="text-[10px] font-black uppercase tracking-widest opacity-40">{t('noSectionsCreated')}</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
@@ -1434,7 +1434,7 @@ export default function App() {
|
||||
</div>
|
||||
</div>
|
||||
<Input label={`${t('bio')} ${t('optional')}`} name="bio" defaultValue={userProfile?.bio || ''} placeholder="..." />
|
||||
<Input label="Localidade" name="location" defaultValue={userProfile?.location || ''} placeholder="Ex: Lisboa, Portugal" />
|
||||
<Input label={t('location')} name="location" defaultValue={userProfile?.location || ''} placeholder={t('locationEx')} />
|
||||
</div>
|
||||
<button disabled={savingProfile} type="submit" className="w-full py-4 bg-primary-600 text-white rounded-xl font-black uppercase text-[10px] tracking-widest shadow-xl shadow-primary-600/30 disabled:opacity-50 hover:scale-[1.01] transition-all">
|
||||
{savingProfile ? t('saving') : t('save')}
|
||||
@@ -1548,7 +1548,7 @@ export default function App() {
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
setToastMessage('Mensagem enviada com sucesso!');
|
||||
setToastMessage(t('msgSentSuccess'));
|
||||
setTimeout(() => setToastMessage(null), 4000);
|
||||
e.target.reset();
|
||||
} else {
|
||||
@@ -1556,7 +1556,7 @@ export default function App() {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Erro ao enviar feedback:", error);
|
||||
setToastMessage('Erro ao enviar mensagem. Verifica a tua ligação.');
|
||||
setToastMessage(t('msgSendError'));
|
||||
setTimeout(() => setToastMessage(null), 4000);
|
||||
}
|
||||
}} className="space-y-4">
|
||||
@@ -1570,7 +1570,7 @@ export default function App() {
|
||||
<span className="font-bold text-sm text-inherit">Bug / Erro</span>
|
||||
</label>
|
||||
</div>
|
||||
<textarea name="message" required placeholder="Escreva aqui a sua mensagem..." rows={4} className={`w-full p-4 rounded-xl border-none outline-none focus:ring-2 focus:ring-primary-500 font-bold resize-none ${darkMode ? 'bg-gray-800 text-white' : 'bg-gray-50'}`}></textarea>
|
||||
<textarea name="message" required placeholder={t('writeMessage')} rows={4} className={`w-full p-4 rounded-xl border-none outline-none focus:ring-2 focus:ring-primary-500 font-bold resize-none ${darkMode ? 'bg-gray-800 text-white' : 'bg-gray-50'}`}></textarea>
|
||||
<button type="submit" className="w-full py-4 bg-primary-600 text-white rounded-xl font-black uppercase text-[10px] tracking-widest shadow-xl shadow-primary-600/30 hover:scale-[1.01] transition-all">
|
||||
Enviar Mensagem
|
||||
</button>
|
||||
@@ -1631,12 +1631,12 @@ export default function App() {
|
||||
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowNotificationsModal(false)}>
|
||||
<Card className="w-full max-w-md p-8 animate-in zoom-in-95 flex flex-col max-h-[80vh]" 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"><Bell size={24} className="text-primary-600" /> Notificações</h3>
|
||||
<h3 className="text-2xl font-black text-inherit flex items-center gap-3"><Bell size={24} className="text-primary-600" /> {t('notificationsModal')}</h3>
|
||||
<button onClick={() => setShowNotificationsModal(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>
|
||||
<div className="flex-1 overflow-y-auto space-y-4 custom-scrollbar">
|
||||
{notifications.length === 0 ? (
|
||||
<div className="py-12 text-center opacity-30 font-black uppercase tracking-[0.3em] text-sm">Sem Notificações</div>
|
||||
<div className="py-12 text-center opacity-30 font-black uppercase tracking-[0.3em] text-sm">{t('noNotifications')}</div>
|
||||
) : notifications.map(notif => (
|
||||
<div key={notif.id} className={`p-4 rounded-2xl flex items-start gap-4 ${!notif.read ? 'bg-primary-50 dark:bg-primary-900/20' : 'bg-gray-50 dark:bg-gray-800'}`}>
|
||||
<div className={`p-3 rounded-full ${!notif.read ? 'bg-primary-100 text-primary-600 dark:bg-primary-900/40 dark:text-primary-400' : 'bg-gray-200 text-gray-500 dark:bg-gray-700'}`}>
|
||||
@@ -1645,7 +1645,7 @@ export default function App() {
|
||||
<div className="flex-1">
|
||||
<p className="font-bold text-sm text-inherit">
|
||||
{notif.type === 'look_copied' && (
|
||||
<>O utilizador <span className="text-primary-600">{notif.copiedByEmail}</span> guardou o seu look "{notif.lookName}" no armário dele!</>
|
||||
<>O utilizador <span className="text-primary-600">{notif.copiedByEmail}</span> guardou o seu look "{notif.lookName}" {t('inTheirCloset')}</>
|
||||
)}
|
||||
</p>
|
||||
<p className="text-[10px] uppercase font-black tracking-widest opacity-40 mt-2">
|
||||
@@ -1864,7 +1864,7 @@ export default function App() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Modal de Look Partilhado */}
|
||||
{/* Modal de {t('sharedLookTitle')} */}
|
||||
{showSharedLookModal && sharedLookData && (
|
||||
<div className="fixed inset-0 z-[300] flex items-center justify-center bg-black/70 backdrop-blur-md p-6" onClick={() => { setShowSharedLookModal(false); setSharedLookData(null); }}>
|
||||
<div
|
||||
@@ -1879,16 +1879,16 @@ export default function App() {
|
||||
<div className="p-2 bg-white/20 rounded-xl backdrop-blur-sm">
|
||||
<Share2 size={20} className="text-white" />
|
||||
</div>
|
||||
<span className="text-white/80 font-black uppercase text-[10px] tracking-widest">Look Partilhado</span>
|
||||
<span className="text-white/80 font-black uppercase text-[10px] tracking-widest">{t('sharedLookTitle')}</span>
|
||||
</div>
|
||||
<h2 className="text-3xl font-black text-white tracking-tight">{sharedLookData.lookName}</h2>
|
||||
<p className="text-white/60 text-sm font-bold mt-1">{sharedLookData.items.length} peça{sharedLookData.items.length !== 1 ? 's' : ''} • Partilhado por {sharedLookData.ownerEmail?.split('@')[0] || 'alguém'}</p>
|
||||
<p className="text-white/60 text-sm font-bold mt-1">{sharedLookData.items.length} peça{sharedLookData.items.length !== 1 ? 's' : ''} • {t('sharedBy')} {sharedLookData.ownerEmail?.split('@')[0] || t('someone')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Peças do look */}
|
||||
<div className={`p-8 ${darkMode ? 'bg-gray-900' : 'bg-white'}`}>
|
||||
<p className="text-[10px] font-black uppercase tracking-widest opacity-40 mb-4">Peças incluídas</p>
|
||||
<p className="text-[10px] font-black uppercase tracking-widest opacity-40 mb-4">{t('includedPieces')}</p>
|
||||
<div className="flex flex-wrap gap-3 mb-8">
|
||||
{sharedLookData.items.map((item, idx) => (
|
||||
<div key={idx} className="relative group/item">
|
||||
@@ -1927,9 +1927,9 @@ export default function App() {
|
||||
style={{ background: 'linear-gradient(135deg, hsl(var(--primary-600)), hsl(var(--primary-500)))' }}
|
||||
>
|
||||
{sharedLookCopying ? (
|
||||
<><Loader2 size={16} className="animate-spin" /> A copiar...</>
|
||||
<><Loader2 size={16} className="animate-spin" /> {t('copying')}</>
|
||||
) : (
|
||||
<><Check size={16} /> Copiar para o meu armário</>
|
||||
<><Check size={16} /> {t('copyToMyCloset')}</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user