fix: disable mobile drag, replace window.location.reload with router.refresh, use semantic icons
- Disable Muuri drag on mobile devices to prevent scroll conflicts - Replace all remaining window.location.reload() with router.refresh() in settings/data, settings/general, and note-editor - Replace duplicate X icons with semantic icons (Trash2 for fused badge, LogOut for leave share) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,9 +6,11 @@ import { Button } from '@/components/ui/button'
|
|||||||
import { Download, Upload, Trash2, Loader2 } from 'lucide-react'
|
import { Download, Upload, Trash2, Loader2 } from 'lucide-react'
|
||||||
import { toast } from 'sonner'
|
import { toast } from 'sonner'
|
||||||
import { useLanguage } from '@/lib/i18n'
|
import { useLanguage } from '@/lib/i18n'
|
||||||
|
import { useRouter } from 'next/navigation'
|
||||||
|
|
||||||
export default function DataSettingsPage() {
|
export default function DataSettingsPage() {
|
||||||
const { t } = useLanguage()
|
const { t } = useLanguage()
|
||||||
|
const router = useRouter()
|
||||||
const [isExporting, setIsExporting] = useState(false)
|
const [isExporting, setIsExporting] = useState(false)
|
||||||
const [isImporting, setIsImporting] = useState(false)
|
const [isImporting, setIsImporting] = useState(false)
|
||||||
const [isDeleting, setIsDeleting] = useState(false)
|
const [isDeleting, setIsDeleting] = useState(false)
|
||||||
@@ -54,7 +56,7 @@ export default function DataSettingsPage() {
|
|||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const result = await response.json()
|
const result = await response.json()
|
||||||
toast.success(t('dataManagement.import.success', { count: result.count }))
|
toast.success(t('dataManagement.import.success', { count: result.count }))
|
||||||
window.location.reload()
|
router.refresh()
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Import failed')
|
throw new Error('Import failed')
|
||||||
}
|
}
|
||||||
@@ -77,7 +79,7 @@ export default function DataSettingsPage() {
|
|||||||
const response = await fetch('/api/notes/delete-all', { method: 'POST' })
|
const response = await fetch('/api/notes/delete-all', { method: 'POST' })
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
toast.success(t('dataManagement.delete.success'))
|
toast.success(t('dataManagement.delete.success'))
|
||||||
window.location.reload()
|
router.refresh()
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Delete error:', error)
|
console.error('Delete error:', error)
|
||||||
|
|||||||
@@ -5,9 +5,11 @@ import { SettingsNav, SettingsSection, SettingToggle, SettingSelect } from '@/co
|
|||||||
import { useLanguage } from '@/lib/i18n'
|
import { useLanguage } from '@/lib/i18n'
|
||||||
import { updateAISettings, getAISettings } from '@/app/actions/ai-settings'
|
import { updateAISettings, getAISettings } from '@/app/actions/ai-settings'
|
||||||
import { toast } from 'sonner'
|
import { toast } from 'sonner'
|
||||||
|
import { useRouter } from 'next/navigation'
|
||||||
|
|
||||||
export default function GeneralSettingsPage() {
|
export default function GeneralSettingsPage() {
|
||||||
const { t, setLanguage: setContextLanguage } = useLanguage()
|
const { t, setLanguage: setContextLanguage } = useLanguage()
|
||||||
|
const router = useRouter()
|
||||||
const [language, setLanguage] = useState('auto')
|
const [language, setLanguage] = useState('auto')
|
||||||
const [emailNotifications, setEmailNotifications] = useState(false)
|
const [emailNotifications, setEmailNotifications] = useState(false)
|
||||||
const [desktopNotifications, setDesktopNotifications] = useState(false)
|
const [desktopNotifications, setDesktopNotifications] = useState(false)
|
||||||
@@ -45,8 +47,8 @@ export default function GeneralSettingsPage() {
|
|||||||
toast.success(t('profile.languageUpdateSuccess') || "Language updated")
|
toast.success(t('profile.languageUpdateSuccess') || "Language updated")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Force reload to ensure all components update (server components, metadata, etc.)
|
// 3. Refresh server components to ensure all components update (metadata, etc.)
|
||||||
setTimeout(() => window.location.reload(), 500)
|
setTimeout(() => router.refresh(), 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleEmailNotificationsChange = async (enabled: boolean) => {
|
const handleEmailNotificationsChange = async (enabled: boolean) => {
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ export function MasonryGrid({ notes, onEdit }: MasonryGridProps) {
|
|||||||
|
|
||||||
|
|
||||||
const layoutOptions = {
|
const layoutOptions = {
|
||||||
dragEnabled: true,
|
dragEnabled: !isMobile,
|
||||||
// Use drag handle for mobile devices to allow smooth scrolling
|
// Use drag handle for mobile devices to allow smooth scrolling
|
||||||
// On desktop, whole card is draggable (no handle needed)
|
// On desktop, whole card is draggable (no handle needed)
|
||||||
dragHandle: isMobile ? '.muuri-drag-handle' : undefined,
|
dragHandle: isMobile ? '.muuri-drag-handle' : undefined,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@/components/ui/dropdown-menu'
|
} from '@/components/ui/dropdown-menu'
|
||||||
import { Pin, Bell, GripVertical, X, Link2, FolderOpen, StickyNote, LucideIcon, Folder, Briefcase, FileText, Zap, BarChart3, Globe, Sparkles, Book, Heart, Crown, Music, Building2 } from 'lucide-react'
|
import { Pin, Bell, GripVertical, X, Link2, FolderOpen, StickyNote, LucideIcon, Folder, Briefcase, FileText, Zap, BarChart3, Globe, Sparkles, Book, Heart, Crown, Music, Building2, LogOut, Trash2 } from 'lucide-react'
|
||||||
import { useState, useEffect, useTransition, useOptimistic, memo } from 'react'
|
import { useState, useEffect, useTransition, useOptimistic, memo } from 'react'
|
||||||
import { useSession } from 'next-auth/react'
|
import { useSession } from 'next-auth/react'
|
||||||
import { useRouter, useSearchParams } from 'next/navigation'
|
import { useRouter, useSearchParams } from 'next/navigation'
|
||||||
@@ -444,7 +444,7 @@ export const NoteCard = memo(function NoteCard({
|
|||||||
className="ml-1 opacity-0 group-hover/badge:opacity-100 hover:opacity-100 transition-opacity"
|
className="ml-1 opacity-0 group-hover/badge:opacity-100 hover:opacity-100 transition-opacity"
|
||||||
title={t('notes.remove') || 'Remove'}
|
title={t('notes.remove') || 'Remove'}
|
||||||
>
|
>
|
||||||
<X className="h-2.5 w-2.5" />
|
<Trash2 className="h-2.5 w-2.5" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -499,7 +499,7 @@ export const NoteCard = memo(function NoteCard({
|
|||||||
handleLeaveShare()
|
handleLeaveShare()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<X className="h-3 w-3 mr-1" />
|
<LogOut className="h-3 w-3 mr-1" />
|
||||||
{t('notes.leaveShare')}
|
{t('notes.leaveShare')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -528,9 +528,8 @@ export function NoteEditor({ note, readOnly = false, onClose }: NoteEditorProps)
|
|||||||
size: size,
|
size: size,
|
||||||
})
|
})
|
||||||
toast.success(t('notes.copySuccess'))
|
toast.success(t('notes.copySuccess'))
|
||||||
|
triggerRefresh()
|
||||||
onClose()
|
onClose()
|
||||||
// Force refresh to show the new note
|
|
||||||
window.location.reload()
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to copy note:', error)
|
console.error('Failed to copy note:', error)
|
||||||
toast.error(t('notes.copyFailed'))
|
toast.error(t('notes.copyFailed'))
|
||||||
|
|||||||
Reference in New Issue
Block a user