feat: RTL/i18n, AI translate+undo, no-refresh saves, settings perf

- RTL: force dir=rtl on LabelFilter, NotesViewToggle, LabelManagementDialog
- i18n: add missing keys (notifications, privacy, edit/preview, AI translate/undo)
- Settings pages: convert to Server Components (general, appearance) + loading skeleton
- AI menu: add Translate option (10 languages) + Undo AI button in toolbar
- Fix: saveInline uses REST API instead of Server Action → eliminates all implicit refreshes in list mode
- Fix: NotesTabsView notes sync effect preserves selected note on content changes
- Fix: auto-tag suggestions now filter already-assigned labels
- Fix: color change in card view uses local state (no refresh)
- Fix: nav links use <Link> for prefetching (Settings, Admin)
- Fix: suppress duplicate label suggestions already on note
- Route: add /api/ai/translate endpoint
This commit is contained in:
Sepehr Ramezani
2026-04-15 23:48:28 +02:00
parent 39671c6472
commit b6a548acd8
68 changed files with 5014 additions and 485 deletions

View File

@@ -24,7 +24,7 @@ interface LabelFilterProps {
export function LabelFilter({ selectedLabels, onFilterChange, className }: LabelFilterProps) {
const { labels, loading } = useLabels()
const { t } = useLanguage()
const { t, language } = useLanguage()
const [allLabelNames, setAllLabelNames] = useState<string[]>([])
useEffect(() => {
@@ -47,10 +47,11 @@ export function LabelFilter({ selectedLabels, onFilterChange, className }: Label
if (loading || allLabelNames.length === 0) return null
return (
<div className={cn("flex items-center gap-2", className ? "" : "")}>
<DropdownMenu>
<div dir={language === 'fa' || language === 'ar' ? 'rtl' : 'ltr'} className={cn("flex items-center gap-2", className ? "" : "")}>
<DropdownMenu dir={language === 'fa' || language === 'ar' ? 'rtl' : 'ltr'}>
<DropdownMenuTrigger asChild>
<Button
dir={language === 'fa' || language === 'ar' ? 'rtl' : 'ltr'}
variant="outline"
size="sm"
className={cn(