save rq
This commit is contained in:
2
.env
2
.env
@@ -8,5 +8,3 @@ VITE_FIREBASE_APP_ID="1:219982610263:web:0ebe67d9cf0e7d2753c812"
|
||||
VITE_APP_ID=my-closet-app
|
||||
VITE_INITIAL_AUTH_TOKEN=
|
||||
VITE_FIREBASE_VAPID_KEY=BM55REBdX3g7x4JT7C6sN0uBDLATqsCnvgvx3mJnVmgU2dFvZL1przcV-V-Kl50Ao6-i8OA-5PZFWTuhETL9-v4
|
||||
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
1
dist/assets/index-DFJLltIj.css
vendored
1
dist/assets/index-DFJLltIj.css
vendored
File diff suppressed because one or more lines are too long
1
dist/assets/index-DUBk-k5k.css
vendored
Normal file
1
dist/assets/index-DUBk-k5k.css
vendored
Normal file
File diff suppressed because one or more lines are too long
4
dist/index.html
vendored
4
dist/index.html
vendored
@@ -5,8 +5,8 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>MyCloset</title>
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<script type="module" crossorigin src="/assets/index-SfxBfoF_.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-DFJLltIj.css">
|
||||
<script type="module" crossorigin src="/assets/index-C3FJNYuR.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-DUBk-k5k.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
88
src/App.jsx
88
src/App.jsx
@@ -70,6 +70,9 @@ export default function App() {
|
||||
const [weatherData, setWeatherData] = useState(null);
|
||||
const [isPrivate, setIsPrivate] = useState(false);
|
||||
const [shortcutsEnabled, setShortcutsEnabled] = useState(false);
|
||||
const [shortcutUpKey, setShortcutUpKey] = useState('q');
|
||||
const [shortcutDownKey, setShortcutDownKey] = useState('e');
|
||||
const [recordingKey, setRecordingKey] = useState(null);
|
||||
const [userStatus, setUserStatus] = useState('online');
|
||||
|
||||
// Estado da Comunidade
|
||||
@@ -117,6 +120,16 @@ export default function App() {
|
||||
|
||||
const t = (key) => translations[language]?.[key] || translations['PT'][key] || key;
|
||||
|
||||
const formatKeyName = (key) => {
|
||||
if (!key) return '';
|
||||
if (key === ' ') return t('spaceKey') || 'Espaço';
|
||||
if (key === 'ArrowUp') return '↑';
|
||||
if (key === 'ArrowDown') return '↓';
|
||||
if (key === 'ArrowLeft') return '←';
|
||||
if (key === 'ArrowRight') return '→';
|
||||
return key.toUpperCase();
|
||||
};
|
||||
|
||||
// Mapeamento de nomes de cor (PT) para valores CSS
|
||||
const COLOR_MAP = {
|
||||
'Vermelho': '#ef4444',
|
||||
@@ -299,16 +312,42 @@ export default function App() {
|
||||
const handleKeyDown = (e) => {
|
||||
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
|
||||
|
||||
if (e.key.toLowerCase() === 'q') {
|
||||
if (e.key.toLowerCase() === shortcutUpKey.toLowerCase()) {
|
||||
handleNavShortcut('up');
|
||||
} else if (e.key.toLowerCase() === 'e') {
|
||||
} else if (e.key.toLowerCase() === shortcutDownKey.toLowerCase()) {
|
||||
handleNavShortcut('down');
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
return () => window.removeEventListener('keydown', handleKeyDown);
|
||||
}, [shortcutsEnabled, view]);
|
||||
}, [shortcutsEnabled, view, shortcutUpKey, shortcutDownKey]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!recordingKey) return;
|
||||
|
||||
const handleCapture = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if (['control', 'shift', 'alt', 'meta'].includes(e.key.toLowerCase())) {
|
||||
return;
|
||||
}
|
||||
|
||||
const key = e.key;
|
||||
if (recordingKey === 'up') {
|
||||
setShortcutUpKey(key);
|
||||
saveUserSetting('shortcutUpKey', key);
|
||||
} else if (recordingKey === 'down') {
|
||||
setShortcutDownKey(key);
|
||||
saveUserSetting('shortcutDownKey', key);
|
||||
}
|
||||
setRecordingKey(null);
|
||||
};
|
||||
|
||||
window.addEventListener('keydown', handleCapture, true);
|
||||
return () => window.removeEventListener('keydown', handleCapture, true);
|
||||
}, [recordingKey]);
|
||||
|
||||
useEffect(() => {
|
||||
if (editingItem && editingItem.color) {
|
||||
@@ -454,6 +493,8 @@ export default function App() {
|
||||
}
|
||||
if (data.settings.isPrivate !== undefined) setIsPrivate(data.settings.isPrivate);
|
||||
if (data.settings.shortcutsEnabled !== undefined) setShortcutsEnabled(data.settings.shortcutsEnabled);
|
||||
if (data.settings.shortcutUpKey !== undefined) setShortcutUpKey(data.settings.shortcutUpKey);
|
||||
if (data.settings.shortcutDownKey !== undefined) setShortcutDownKey(data.settings.shortcutDownKey);
|
||||
if (data.settings.status !== undefined) setUserStatus(data.settings.status);
|
||||
}
|
||||
}
|
||||
@@ -1476,7 +1517,7 @@ export default function App() {
|
||||
|
||||
{shortcutsEnabled && (
|
||||
<button onClick={() => handleNavShortcut('up')} className="w-full flex items-center justify-center gap-2 p-2 bg-gray-100 dark:bg-gray-800 rounded-xl mb-3 text-xs font-bold hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors">
|
||||
<span className="px-2 py-1 bg-white dark:bg-gray-900 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">Q</span> {t('up')}
|
||||
<span className="px-2 py-1 bg-white dark:bg-gray-900 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">{formatKeyName(shortcutUpKey)}</span> {t('up')}
|
||||
</button>
|
||||
)}
|
||||
<nav className="flex-1 space-y-3">
|
||||
@@ -1505,7 +1546,7 @@ export default function App() {
|
||||
</nav>
|
||||
{shortcutsEnabled && (
|
||||
<button onClick={() => handleNavShortcut('down')} className="w-full flex items-center justify-center gap-2 p-2 bg-gray-100 dark:bg-gray-800 rounded-xl mt-3 text-xs font-bold hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors">
|
||||
<span className="px-2 py-1 bg-white dark:bg-gray-900 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">E</span> {t('down')}
|
||||
<span className="px-2 py-1 bg-white dark:bg-gray-900 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">{formatKeyName(shortcutDownKey)}</span> {t('down')}
|
||||
</button>
|
||||
)}
|
||||
|
||||
@@ -2736,6 +2777,43 @@ export default function App() {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{shortcutsEnabled && (
|
||||
<div className="pl-4 border-l-2 border-primary-500 dark:border-primary-400 flex flex-col gap-3 my-2 transition-all">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-xs font-bold text-inherit">{t('shortcutUp') || 'Navegar para Cima'}</p>
|
||||
<p className="text-[10px] opacity-50 text-inherit">{t('shortcutUpDesc') || 'Tecla para navegar para cima no menu'}</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setRecordingKey(recordingKey === 'up' ? null : 'up')}
|
||||
className={`px-3 py-1.5 rounded-xl text-xs font-black uppercase tracking-widest border transition-all ${
|
||||
recordingKey === 'up'
|
||||
? 'bg-primary-100 dark:bg-primary-950 border-primary-500 text-primary-600 ring-2 ring-primary-500 animate-pulse'
|
||||
: 'bg-gray-100 dark:bg-gray-800 border-transparent text-gray-500 hover:bg-gray-200 dark:hover:bg-gray-700'
|
||||
}`}
|
||||
>
|
||||
{recordingKey === 'up' ? t('pressAnyKey') || 'Pressione uma tecla...' : formatKeyName(shortcutUpKey)}
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-xs font-bold text-inherit">{t('shortcutDown') || 'Navegar para Baixo'}</p>
|
||||
<p className="text-[10px] opacity-50 text-inherit">{t('shortcutDownDesc') || 'Tecla para navegar para baixo no menu'}</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setRecordingKey(recordingKey === 'down' ? null : 'down')}
|
||||
className={`px-3 py-1.5 rounded-xl text-xs font-black uppercase tracking-widest border transition-all ${
|
||||
recordingKey === 'down'
|
||||
? 'bg-primary-100 dark:bg-primary-950 border-primary-500 text-primary-600 ring-2 ring-primary-500 animate-pulse'
|
||||
: 'bg-gray-100 dark:bg-gray-800 border-transparent text-gray-500 hover:bg-gray-200 dark:hover:bg-gray-700'
|
||||
}`}
|
||||
>
|
||||
{recordingKey === 'down' ? t('pressAnyKey') || 'Pressione uma tecla...' : formatKeyName(shortcutDownKey)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
|
||||
<div>
|
||||
<p className="font-bold text-inherit flex items-center gap-2">{t('dailyOutfitNotification')}</p>
|
||||
|
||||
@@ -225,6 +225,12 @@ export const translations = {
|
||||
userOutfits: "Outfits do Utilizador",
|
||||
userCloset: "Armário",
|
||||
usernameTaken: "Este nome de utilizador já está em uso.",
|
||||
shortcutUp: "Navegar para Cima",
|
||||
shortcutDown: "Navegar para Baixo",
|
||||
shortcutUpDesc: "Tecla para navegar para cima no menu",
|
||||
shortcutDownDesc: "Tecla para navegar para baixo no menu",
|
||||
pressAnyKey: "Pressione uma tecla...",
|
||||
spaceKey: "Espaço",
|
||||
},
|
||||
EN: {
|
||||
loginModeIntro: "The Future of Your Style",
|
||||
@@ -452,6 +458,12 @@ export const translations = {
|
||||
userOutfits: "User's Outfits",
|
||||
userCloset: "Closet",
|
||||
usernameTaken: "This username is already taken.",
|
||||
shortcutUp: "Navigate Up",
|
||||
shortcutDown: "Navigate Down",
|
||||
shortcutUpDesc: "Key to navigate up in the menu",
|
||||
shortcutDownDesc: "Key to navigate down in the menu",
|
||||
pressAnyKey: "Press a key...",
|
||||
spaceKey: "Space",
|
||||
},
|
||||
ES: {
|
||||
loginModeIntro: "El Futuro de Tu Estilo",
|
||||
@@ -679,6 +691,12 @@ export const translations = {
|
||||
userOutfits: "Outfits del Usuario",
|
||||
userCloset: "Armario",
|
||||
usernameTaken: "Este nombre de usuario ya está en uso.",
|
||||
shortcutUp: "Navegar hacia Arriba",
|
||||
shortcutDown: "Navegar hacia Abajo",
|
||||
shortcutUpDesc: "Tecla para navegar hacia arriba en el menú",
|
||||
shortcutDownDesc: "Tecla para navegar hacia abajo en el menú",
|
||||
pressAnyKey: "Presione una tecla...",
|
||||
spaceKey: "Espacio",
|
||||
},
|
||||
FR: {
|
||||
loginModeIntro: "Le Futur de Ton Style",
|
||||
@@ -906,6 +924,12 @@ export const translations = {
|
||||
userOutfits: "Outfits de l'Utilisateur",
|
||||
userCloset: "Placard",
|
||||
usernameTaken: "Ce nom d'utilisateur est déjà utilisé.",
|
||||
shortcutUp: "Naviguer vers le Haut",
|
||||
shortcutDown: "Naviguer vers le Bas",
|
||||
shortcutUpDesc: "Touche pour naviguer vers le haut dans le menu",
|
||||
shortcutDownDesc: "Touche pour naviguer vers le bas dans le menu",
|
||||
pressAnyKey: "Appuyez sur une touche...",
|
||||
spaceKey: "Espace",
|
||||
},
|
||||
DE: {
|
||||
loginModeIntro: "Die Zukunft deines Stils",
|
||||
@@ -1133,5 +1157,11 @@ export const translations = {
|
||||
userOutfits: "Outfits des Benutzers",
|
||||
userCloset: "Kleiderschrank",
|
||||
usernameTaken: "Dieser Benutzername ist bereits vergeben.",
|
||||
shortcutUp: "Nach oben navigieren",
|
||||
shortcutDown: "Nach unten navigieren",
|
||||
shortcutUpDesc: "Taste zum Navigieren nach oben im Menü",
|
||||
shortcutDownDesc: "Taste zum Navigieren nach unten im Menü",
|
||||
pressAnyKey: "Taste drücken...",
|
||||
spaceKey: "Leertaste",
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user