feat: atalhos de navegação Q/E e correções no i18n
This commit is contained in:
118
add_shortcuts.cjs
Normal file
118
add_shortcuts.cjs
Normal file
@@ -0,0 +1,118 @@
|
||||
const fs = require('fs');
|
||||
|
||||
let content = fs.readFileSync('src/App.jsx', 'utf8');
|
||||
|
||||
// 1. State
|
||||
content = content.replace(
|
||||
/const \[isPrivate, setIsPrivate\] = useState\(false\);/,
|
||||
`const [isPrivate, setIsPrivate] = useState(false);\n const [shortcutsEnabled, setShortcutsEnabled] = useState(false);`
|
||||
);
|
||||
|
||||
// 2. Toggle and Nav handle
|
||||
const toggleInsert = `
|
||||
const handlePrivacyToggle = (newVal) => {
|
||||
setIsPrivate(newVal);
|
||||
saveUserSetting('isPrivate', newVal);
|
||||
};
|
||||
|
||||
const handleShortcutsToggle = (newVal) => {
|
||||
setShortcutsEnabled(newVal);
|
||||
saveUserSetting('shortcutsEnabled', newVal);
|
||||
};
|
||||
|
||||
const handleNavShortcut = (direction) => {
|
||||
const navItems = ['dashboard', 'closet', 'wishlist', 'laundry', 'outfits', 'planner', 'community', 'settings'];
|
||||
const currentIndex = navItems.indexOf(view);
|
||||
if (currentIndex === -1) return;
|
||||
|
||||
let nextIndex;
|
||||
if (direction === 'up') {
|
||||
nextIndex = currentIndex === 0 ? navItems.length - 1 : currentIndex - 1;
|
||||
} else {
|
||||
nextIndex = currentIndex === navItems.length - 1 ? 0 : currentIndex + 1;
|
||||
}
|
||||
setView(navItems[nextIndex]);
|
||||
if (window.innerWidth < 768) setSidebarOpen(false);
|
||||
};
|
||||
`;
|
||||
|
||||
content = content.replace(
|
||||
/const handlePrivacyToggle = \(newVal\) => \{[\s\S]*?saveUserSetting\('isPrivate', newVal\);\n \};/,
|
||||
toggleInsert.trim()
|
||||
);
|
||||
|
||||
// 3. Load from Firebase
|
||||
content = content.replace(
|
||||
/if \(data\.settings\.isPrivate !== undefined\) setIsPrivate\(data\.settings\.isPrivate\);/,
|
||||
`if (data.settings.isPrivate !== undefined) setIsPrivate(data.settings.isPrivate);\n if (data.settings.shortcutsEnabled !== undefined) setShortcutsEnabled(data.settings.shortcutsEnabled);`
|
||||
);
|
||||
|
||||
// 4. UseEffect
|
||||
const useEffectInsert = `
|
||||
useEffect(() => {
|
||||
if (!shortcutsEnabled) return;
|
||||
|
||||
const handleKeyDown = (e) => {
|
||||
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
|
||||
|
||||
if (e.key.toLowerCase() === 'q') {
|
||||
handleNavShortcut('up');
|
||||
} else if (e.key.toLowerCase() === 'e') {
|
||||
handleNavShortcut('down');
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
return () => window.removeEventListener('keydown', handleKeyDown);
|
||||
}, [shortcutsEnabled, view]);
|
||||
|
||||
useEffect(() => {
|
||||
if (editingItem && editingItem.color) {`;
|
||||
|
||||
content = content.replace(
|
||||
/useEffect\(\(\) => \{\n if \(editingItem && editingItem\.color\) \{/,
|
||||
useEffectInsert.trim()
|
||||
);
|
||||
|
||||
// 5. Settings UI
|
||||
const settingsUI = `
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="font-bold text-inherit flex items-center gap-2">Atalhos de Teclado</p>
|
||||
<p className="text-[10px] uppercase tracking-widest opacity-50 text-inherit">Ativar navegação com Q e E</p>
|
||||
</div>
|
||||
<button onClick={() => handleShortcutsToggle(!shortcutsEnabled)} className={\`w-14 h-8 rounded-full transition-colors relative \${shortcutsEnabled ? 'bg-primary-600' : 'bg-gray-200'}\`}>
|
||||
<div className={\`w-6 h-6 rounded-full bg-white absolute top-1 transition-all \${shortcutsEnabled ? 'left-7' : 'left-1'}\`}></div>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
content = content.replace(
|
||||
/(<div className="flex items-center justify-between">[\s\S]*?t\('lookReminders'\)}<\/p>[\s\S]*?<\/div>[\s\S]*?<\/button>[\s\S]*?<\/div>)/,
|
||||
`$1\n${settingsUI}`
|
||||
);
|
||||
|
||||
// 6. Sidebar UI Top
|
||||
const sidebarTop = `
|
||||
{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> Cima
|
||||
</button>
|
||||
)}
|
||||
<nav className="flex-1 space-y-3">
|
||||
`;
|
||||
content = content.replace(/<nav className="flex-1 space-y-3">/, sidebarTop.trim());
|
||||
|
||||
// 7. Sidebar UI Bottom
|
||||
const sidebarBottom = `
|
||||
))}
|
||||
</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> Baixo
|
||||
</button>
|
||||
)}
|
||||
`;
|
||||
content = content.replace(/ \}\)\}\n <\/nav>/, sidebarBottom.trim());
|
||||
|
||||
fs.writeFileSync('src/App.jsx', content);
|
||||
console.log('Shortcuts feature added successfully.');
|
||||
Reference in New Issue
Block a user