diff --git a/client/src/api/authUrl.ts b/client/src/api/authUrl.ts index cebd2f921..53c9935dc 100644 --- a/client/src/api/authUrl.ts +++ b/client/src/api/authUrl.ts @@ -50,7 +50,7 @@ export async function fetchImageAsBlob(url: string): Promise { } if (active < MAX_CONCURRENT) { active++ - run() + void run() } else { queue.push(run) } diff --git a/client/src/api/websocket.ts b/client/src/api/websocket.ts index 0f5974648..6a27abe5c 100644 --- a/client/src/api/websocket.ts +++ b/client/src/api/websocket.ts @@ -93,7 +93,7 @@ function scheduleReconnect(): void { reconnectTimer = setTimeout(() => { reconnectTimer = null if (shouldReconnect) { - connectInternal(true) + void connectInternal(true) } }, reconnectDelay) reconnectDelay = Math.min(reconnectDelay * 2, MAX_RECONNECT_DELAY) @@ -141,7 +141,7 @@ async function connectInternal(_isReconnect = false): Promise { // Flush queued mutations first so local writes land before server read-back. // If the hook fails, still refetch to keep the UI correct. if (preReconnectHook) { - preReconnectHook().catch(console.error).then(doRefetch) + void preReconnectHook().catch(console.error).then(doRefetch) } else { doRefetch() } @@ -170,7 +170,7 @@ export function connect(): void { clearTimeout(reconnectTimer) reconnectTimer = null } - connectInternal(false) + void connectInternal(false) } export function disconnect(): void { diff --git a/client/src/components/Admin/AddonManager.tsx b/client/src/components/Admin/AddonManager.tsx index 5a9a2d5b5..9f556753e 100644 --- a/client/src/components/Admin/AddonManager.tsx +++ b/client/src/components/Admin/AddonManager.tsx @@ -114,7 +114,7 @@ export default function AddonManager({ bagTrackingEnabled, onToggleBagTracking, const [loading, setLoading] = useState(true) useEffect(() => { - loadAddons().finally(() => setLoading(false)) + void loadAddons().finally(() => setLoading(false)) }, []) const loadAddons = async () => { @@ -410,7 +410,7 @@ function LlmParsingConfig({ addon }: { addon: Addon }) { // Load installed models when the local provider is active. useEffect(() => { - if (provider === 'local') loadModels() + if (provider === 'local') void loadModels() // eslint-disable-next-line react-hooks/exhaustive-deps }, [provider]) diff --git a/client/src/components/Admin/BackupPanel.tsx b/client/src/components/Admin/BackupPanel.tsx index 28ce06181..90b6896bc 100644 --- a/client/src/components/Admin/BackupPanel.tsx +++ b/client/src/components/Admin/BackupPanel.tsx @@ -73,7 +73,7 @@ export default function BackupPanel() { } catch {} } - useEffect(() => { loadBackups(); loadAutoSettings() }, []) + useEffect(() => { void loadBackups(); void loadAutoSettings() }, []) const handleCreate = async () => { setIsCreating(true) diff --git a/client/src/components/Admin/CategoryManager.tsx b/client/src/components/Admin/CategoryManager.tsx index db20979ac..67b072eb3 100644 --- a/client/src/components/Admin/CategoryManager.tsx +++ b/client/src/components/Admin/CategoryManager.tsx @@ -25,7 +25,7 @@ export default function CategoryManager() { const toast = useToast() const { t } = useTranslation() - useEffect(() => { loadCategories() }, []) + useEffect(() => { void loadCategories() }, []) const loadCategories = async () => { setIsLoading(true) diff --git a/client/src/components/Admin/DefaultUserSettingsTab.tsx b/client/src/components/Admin/DefaultUserSettingsTab.tsx index e235ab767..7a15ccd6c 100644 --- a/client/src/components/Admin/DefaultUserSettingsTab.tsx +++ b/client/src/components/Admin/DefaultUserSettingsTab.tsx @@ -218,7 +218,7 @@ export default function DefaultUserSettingsTab(): React.ReactElement { setMapboxStyle(nextStyle) patch[styleSettingKey(nextProvider)] = nextStyle } - save(patch) + void save(patch) } return ( @@ -320,7 +320,7 @@ export default function DefaultUserSettingsTab(): React.ReactElement { { if (value) save({ default_currency: value }) }} + onChange={(value: string) => { if (value) void save({ default_currency: value }) }} placeholder={t('settings.currency')} searchable options={currenciesWith(defaults.default_currency).map(c => ({ value: c, label: SYMBOLS[c] ? `${c} ${SYMBOLS[c]}` : c }))} @@ -356,7 +356,7 @@ export default function DefaultUserSettingsTab(): React.ReactElement { { if (value) { setMapTileUrl(value); save({ map_tile_url: value }) } }} + onChange={(value: string) => { if (value) { setMapTileUrl(value); void save({ map_tile_url: value }) } }} placeholder={t('settings.mapTemplatePlaceholder.select')} options={MAP_PRESETS.map(p => ({ value: p.url, label: p.name }))} size="sm" @@ -473,7 +473,7 @@ export default function DefaultUserSettingsTab(): React.ReactElement { { if (value) { setMapboxStyle(value); save({ [styleKey]: value }) } }} + onChange={(value: string) => { if (value) { setMapboxStyle(value); void save({ [styleKey]: value }) } }} placeholder={t('admin.defaultSettings.mapboxStylePlaceholder')} options={glStylePresets.map(p => ({ value: p.url, label: p.name }))} size="sm" @@ -486,7 +486,7 @@ export default function DefaultUserSettingsTab(): React.ReactElement { onBlur={() => { const nextStyle = normalizeStyleForProvider(mapProvider, mapboxStyle) setMapboxStyle(nextStyle) - save({ [styleKey]: nextStyle }) + void save({ [styleKey]: nextStyle }) }} placeholder={defaultStyleForProvider(mapProvider)} className="w-full px-3 py-2 border border-slate-300 rounded-lg text-sm focus:ring-2 focus:ring-slate-400 focus:border-transparent" diff --git a/client/src/components/Admin/GitHubPanel.tsx b/client/src/components/Admin/GitHubPanel.tsx index fb54eb708..90ad9b570 100644 --- a/client/src/components/Admin/GitHubPanel.tsx +++ b/client/src/components/Admin/GitHubPanel.tsx @@ -53,7 +53,7 @@ export default function GitHubPanel({ isPrerelease = false }: { isPrerelease?: b useEffect(() => { setLoading(true); - fetchReleases(1).finally(() => setLoading(false)); + void fetchReleases(1).finally(() => setLoading(false)); }, []); const handleLoadMore = async () => { diff --git a/client/src/components/Admin/PackingTemplateManager.tsx b/client/src/components/Admin/PackingTemplateManager.tsx index df4197d77..3be66bbc3 100644 --- a/client/src/components/Admin/PackingTemplateManager.tsx +++ b/client/src/components/Admin/PackingTemplateManager.tsx @@ -46,7 +46,7 @@ export default function PackingTemplateManager() { const toast = useToast() const { t } = useTranslation() - useEffect(() => { loadTemplates() }, []) + useEffect(() => { void loadTemplates() }, []) const loadTemplates = async () => { setIsLoading(true) @@ -178,7 +178,7 @@ export default function PackingTemplateManager() {
setCreateName(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') handleCreateTemplate(); if (e.key === 'Escape') setShowCreate(false) }} + onKeyDown={e => { if (e.key === 'Enter') void handleCreateTemplate(); if (e.key === 'Escape') setShowCreate(false) }} placeholder={t('admin.packingTemplates.namePlaceholder')} className={inputStyle} /> @@ -203,7 +203,7 @@ export default function PackingTemplateManager() { {editingTemplate === tmpl.id ? ( setEditTemplateName(e.target.value)} onBlur={() => handleRenameTemplate(tmpl.id)} - onKeyDown={e => { if (e.key === 'Enter') handleRenameTemplate(tmpl.id); if (e.key === 'Escape') setEditingTemplate(null) }} + onKeyDown={e => { if (e.key === 'Enter') void handleRenameTemplate(tmpl.id); if (e.key === 'Escape') setEditingTemplate(null) }} className="flex-1 px-2 py-0.5 border border-slate-300 rounded text-sm" /> ) : ( @@ -230,7 +230,7 @@ export default function PackingTemplateManager() { <> setEditCatName(e.target.value)} onBlur={() => handleRenameCategory(cat.id)} - onKeyDown={e => { if (e.key === 'Enter') handleRenameCategory(cat.id); if (e.key === 'Escape') setEditingCatId(null) }} + onKeyDown={e => { if (e.key === 'Enter') void handleRenameCategory(cat.id); if (e.key === 'Escape') setEditingCatId(null) }} className="flex-1 px-2 py-0.5 border border-slate-300 rounded text-sm font-semibold" /> ) : ( @@ -253,7 +253,7 @@ export default function PackingTemplateManager() { {editingItemId === item.id ? ( <> setEditItemName(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') handleRenameItem(item.id); if (e.key === 'Escape') setEditingItemId(null) }} + onKeyDown={e => { if (e.key === 'Enter') void handleRenameItem(item.id); if (e.key === 'Escape') setEditingItemId(null) }} className="flex-1 px-2 py-1 border border-slate-200 rounded-lg text-sm" /> @@ -277,7 +277,7 @@ export default function PackingTemplateManager() { {addingItemToCatId === cat.id && (
setNewItemName(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter' && newItemName.trim()) handleAddItem(cat.id); if (e.key === 'Escape') { setAddingItemToCatId(null); setNewItemName('') } }} + onKeyDown={e => { if (e.key === 'Enter' && newItemName.trim()) void handleAddItem(cat.id); if (e.key === 'Escape') { setAddingItemToCatId(null); setNewItemName('') } }} placeholder={t('admin.packingTemplates.itemName')} className="flex-1 px-2 py-1 border border-slate-200 rounded-lg text-sm" /> diff --git a/client/src/components/Admin/PermissionsPanel.tsx b/client/src/components/Admin/PermissionsPanel.tsx index 6b2b149b7..f0d32b7da 100644 --- a/client/src/components/Admin/PermissionsPanel.tsx +++ b/client/src/components/Admin/PermissionsPanel.tsx @@ -38,7 +38,7 @@ export default function PermissionsPanel(): React.ReactElement { const [dirty, setDirty] = useState(false) useEffect(() => { - loadPermissions() + void loadPermissions() }, []) const loadPermissions = async () => { diff --git a/client/src/components/Budget/BudgetPanelCategoryTable.tsx b/client/src/components/Budget/BudgetPanelCategoryTable.tsx index e68346e48..7ac16aef7 100644 --- a/client/src/components/Budget/BudgetPanelCategoryTable.tsx +++ b/client/src/components/Budget/BudgetPanelCategoryTable.tsx @@ -79,7 +79,7 @@ export default function BudgetCategoryTable({ cat, grouped, categoryColor, canEd const toIdx = newOrder.indexOf(cat) newOrder.splice(fromIdx, 1) newOrder.splice(toIdx, 0, dragCat) - reorderBudgetCategories(tripId, newOrder) + void reorderBudgetCategories(tripId, newOrder) } setDragCat(null); setDragOverCat(null) }} @@ -103,8 +103,8 @@ export default function BudgetCategoryTable({ cat, grouped, categoryColor, canEd autoFocus value={editingCat.value} onChange={e => setEditingCat({ ...editingCat, value: e.target.value })} - onBlur={() => { handleRenameCategory(cat, editingCat.value); setEditingCat(null) }} - onKeyDown={e => { if (e.key === 'Enter') { handleRenameCategory(cat, editingCat.value); setEditingCat(null) } if (e.key === 'Escape') setEditingCat(null) }} + onBlur={() => { void handleRenameCategory(cat, editingCat.value); setEditingCat(null) }} + onKeyDown={e => { if (e.key === 'Enter') { void handleRenameCategory(cat, editingCat.value); setEditingCat(null) } if (e.key === 'Escape') setEditingCat(null) }} style={{ fontWeight: 600, fontSize: 'calc(13px * var(--fs-scale-body, 1))', background: 'rgba(255,255,255,0.15)', border: 'none', borderRadius: 4, color: '#fff', padding: '1px 6px', outline: 'none', fontFamily: 'inherit', width: '100%' }} /> ) : ( @@ -180,7 +180,7 @@ export default function BudgetCategoryTable({ cat, grouped, categoryColor, canEd const toIdx = ids.indexOf(item.id) ids.splice(fromIdx, 1) ids.splice(toIdx, 0, dragItem) - reorderBudgetItems(tripId, ids) + void reorderBudgetItems(tripId, ids) setDragItem(null); setDragOverItem(null); setDragItemCat(null) } }} diff --git a/client/src/components/Collab/CollabNotesAuthedImg.tsx b/client/src/components/Collab/CollabNotesAuthedImg.tsx index 799eb9820..e5386f51d 100644 --- a/client/src/components/Collab/CollabNotesAuthedImg.tsx +++ b/client/src/components/Collab/CollabNotesAuthedImg.tsx @@ -4,7 +4,7 @@ import { getAuthUrl } from '../../api/authUrl' export function AuthedImg({ src, style, onClick, onMouseEnter, onMouseLeave, alt }: { src: string; style?: React.CSSProperties; onClick?: () => void; onMouseEnter?: React.MouseEventHandler; onMouseLeave?: React.MouseEventHandler; alt?: string }) { const [authSrc, setAuthSrc] = useState('') useEffect(() => { - getAuthUrl(src, 'download').then(setAuthSrc) + void getAuthUrl(src, 'download').then(setAuthSrc) }, [src]) if (!authSrc) return null // A clickable thumbnail gets a real button around the image so it is diff --git a/client/src/components/Collab/CollabNotesCard.tsx b/client/src/components/Collab/CollabNotesCard.tsx index 3c625cf75..ce64c0bfd 100644 --- a/client/src/components/Collab/CollabNotesCard.tsx +++ b/client/src/components/Collab/CollabNotesCard.tsx @@ -53,7 +53,7 @@ export function NoteCard({ note, canEdit, onUpdate, onDelete, onEdit, onView, on const menu = useContextMenu() const handleTogglePin = useCallback(() => { - onUpdate(note.id, { pinned: !note.pinned }) + void onUpdate(note.id, { pinned: !note.pinned }) }, [note.id, note.pinned, onUpdate]) const handleDelete = useCallback(() => { diff --git a/client/src/components/Collab/CollabNotesFilePreviewPortal.tsx b/client/src/components/Collab/CollabNotesFilePreviewPortal.tsx index 49cda7ee1..e88407ff8 100644 --- a/client/src/components/Collab/CollabNotesFilePreviewPortal.tsx +++ b/client/src/components/Collab/CollabNotesFilePreviewPortal.tsx @@ -25,7 +25,7 @@ export function FilePreviewPortal({ file, onClose }: FilePreviewPortalProps) { useEffect(() => { setAuthUrl('') if (!rawUrl) return - getAuthUrl(rawUrl, 'download').then(setAuthUrl) + void getAuthUrl(rawUrl, 'download').then(setAuthUrl) }, [rawUrl]) const isImage = !!file?.mime_type?.startsWith('image/') diff --git a/client/src/components/Collections/AddPlaceToCollectionModal.tsx b/client/src/components/Collections/AddPlaceToCollectionModal.tsx index 230207e00..2955fb184 100644 --- a/client/src/components/Collections/AddPlaceToCollectionModal.tsx +++ b/client/src/components/Collections/AddPlaceToCollectionModal.tsx @@ -205,7 +205,7 @@ export default function AddPlaceToCollectionModal({ isOpen, collectionId, collec type="text" value={query} onChange={e => { setQuery(e.target.value); setNoResults(false) }} - onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); search() } }} + onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); void search() } }} aria-label={t('collections.addPlaceSearch')} placeholder={t('collections.addPlaceSearch')} className={`${INPUT} pl-8`} diff --git a/client/src/components/Collections/LabelManager.tsx b/client/src/components/Collections/LabelManager.tsx index a122e1da7..56fd53430 100644 --- a/client/src/components/Collections/LabelManager.tsx +++ b/client/src/components/Collections/LabelManager.tsx @@ -150,7 +150,7 @@ export default function LabelManager({ isOpen, labels, onCreate, onUpdate, onDel setNewName(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') add() }} + onKeyDown={e => { if (e.key === 'Enter') void add() }} maxLength={60} placeholder={t('collections.labels.namePlaceholder')} className={`${INPUT} flex-1`} diff --git a/client/src/components/Collections/ListEditorModal.tsx b/client/src/components/Collections/ListEditorModal.tsx index 415614c82..ca57fff5b 100644 --- a/client/src/components/Collections/ListEditorModal.tsx +++ b/client/src/components/Collections/ListEditorModal.tsx @@ -219,7 +219,7 @@ export default function ListEditorModal({ target, onClose, onCreated, onRequestD setCoverQuery(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); searchCover() } }} + onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); void searchCover() } }} aria-label={t('dashboard.unsplashSearchPlaceholder')} placeholder={t('dashboard.unsplashSearchPlaceholder')} className={`${INPUT} flex-1`} diff --git a/client/src/components/Collections/MSaveToCollectionSheet.tsx b/client/src/components/Collections/MSaveToCollectionSheet.tsx index 8afd008b0..9d99d6924 100644 --- a/client/src/components/Collections/MSaveToCollectionSheet.tsx +++ b/client/src/components/Collections/MSaveToCollectionSheet.tsx @@ -56,7 +56,7 @@ export default function MSaveToCollectionSheet() { let cancelled = false setLoading(true) setMembership(null) - Promise.all([ + void Promise.all([ collectionsApi.list().catch(() => ({ collections: [], incomingInvites: [] })), membershipQuery ? collectionsApi.membership(membershipQuery).catch(() => ({ saved: false, lists: [] as CollectionMembership['lists'] })) diff --git a/client/src/components/Collections/SaveToCollectionModal.tsx b/client/src/components/Collections/SaveToCollectionModal.tsx index 6dbcfcce4..2f1d686cf 100644 --- a/client/src/components/Collections/SaveToCollectionModal.tsx +++ b/client/src/components/Collections/SaveToCollectionModal.tsx @@ -59,7 +59,7 @@ export default function SaveToCollectionModal(): React.ReactElement | null { let cancelled = false setLoading(true) setMembership(null) - Promise.all([collectionsApi.list().catch(() => ({ collections: [], incomingInvites: [] })), membershipQuery ? collectionsApi.membership(membershipQuery).catch(() => ({ saved: false, lists: [] as CollectionMembership['lists'] })) : Promise.resolve({ saved: false, lists: [] as CollectionMembership['lists'] })]) + void Promise.all([collectionsApi.list().catch(() => ({ collections: [], incomingInvites: [] })), membershipQuery ? collectionsApi.membership(membershipQuery).catch(() => ({ saved: false, lists: [] as CollectionMembership['lists'] })) : Promise.resolve({ saved: false, lists: [] as CollectionMembership['lists'] })]) .then(([listRes, m]) => { if (cancelled) return setLists(listRes.collections) diff --git a/client/src/components/Dashboard/CollectionsWidget.tsx b/client/src/components/Dashboard/CollectionsWidget.tsx index ea8963c2f..7ed605957 100644 --- a/client/src/components/Dashboard/CollectionsWidget.tsx +++ b/client/src/components/Dashboard/CollectionsWidget.tsx @@ -21,7 +21,7 @@ export default function CollectionsWidget({ onOpen }: { onOpen: () => void }): R useEffect(() => { let cancelled = false - ;(async () => { + ;void (async () => { try { const data = await collectionsApi.list() if (!cancelled) setLists(data.collections) diff --git a/client/src/components/Files/FileManagerAssignModal.tsx b/client/src/components/Files/FileManagerAssignModal.tsx index a2a41cfa2..326467bfa 100644 --- a/client/src/components/Files/FileManagerAssignModal.tsx +++ b/client/src/components/Files/FileManagerAssignModal.tsx @@ -36,7 +36,7 @@ export function AssignModal(S: FileManagerState) { const val = e.target.value.trim() const file = files.find(f => f.id === assignFileId) if (file && val !== (file.description || '')) { - handleAssign(file.id, { description: val } as any) + void handleAssign(file.id, { description: val } as any) } }} onKeyDown={e => { if (e.key === 'Enter') (e.target as HTMLInputElement).blur() }} diff --git a/client/src/components/Files/FileManagerAuthedImg.tsx b/client/src/components/Files/FileManagerAuthedImg.tsx index bdc883909..0a64d6b9f 100644 --- a/client/src/components/Files/FileManagerAuthedImg.tsx +++ b/client/src/components/Files/FileManagerAuthedImg.tsx @@ -5,7 +5,7 @@ import { getAuthUrl } from '../../api/authUrl' export function AuthedImg({ src, style }: { src: string; style?: React.CSSProperties }) { const [authSrc, setAuthSrc] = useState('') useEffect(() => { - getAuthUrl(src, 'download').then(setAuthSrc) + void getAuthUrl(src, 'download').then(setAuthSrc) }, [src]) return authSrc ? : null } diff --git a/client/src/components/Files/FileManagerImageLightbox.tsx b/client/src/components/Files/FileManagerImageLightbox.tsx index 26156e5a4..e66b6dee4 100644 --- a/client/src/components/Files/FileManagerImageLightbox.tsx +++ b/client/src/components/Files/FileManagerImageLightbox.tsx @@ -168,7 +168,7 @@ function ThumbImg({ file, active, onClick }: { file: TripFile & { url: string }; useEffect(() => { if (!visible || fileIsVideo) return let current = true - getAuthUrl(file.url, 'download').then(u => { if (current) setSrc(u) }) + void getAuthUrl(file.url, 'download').then(u => { if (current) setSrc(u) }) return () => { current = false } }, [file.url, fileIsVideo, visible]) diff --git a/client/src/components/Files/useFileManager.ts b/client/src/components/Files/useFileManager.ts index 590a8702f..28f50db37 100644 --- a/client/src/components/Files/useFileManager.ts +++ b/client/src/components/Files/useFileManager.ts @@ -64,7 +64,7 @@ export function useFileManager({ files = [], onUpload, onDelete, onUpdate, place // onUpdate doubles as the "files changed" signal towards the parent; the arguments carry no payload. const refreshFiles = useCallback(async () => { - if (onUpdate) onUpdate(0, {} as any) + if (onUpdate) void onUpdate(0, {} as any) }, [onUpdate]) const handleStar = async (fileId: number) => { @@ -185,7 +185,7 @@ export function useFileManager({ files = [], onUpload, onDelete, onUpdate, place useEffect(() => { if (previewFile) { - getAuthUrl(previewFile.url, 'download').then(setPreviewFileUrl) + void getAuthUrl(previewFile.url, 'download').then(setPreviewFileUrl) } else { setPreviewFileUrl('') } diff --git a/client/src/components/Journey/JourneyDetailPageEntryEditor.tsx b/client/src/components/Journey/JourneyDetailPageEntryEditor.tsx index 3321c9fc5..8d0a7fa5b 100644 --- a/client/src/components/Journey/JourneyDetailPageEntryEditor.tsx +++ b/client/src/components/Journey/JourneyDetailPageEntryEditor.tsx @@ -232,7 +232,7 @@ export function EntryEditor({ entry, journeyId, tripDates, galleryPhotos, trips, // The discovery is not tied to the open tab, so the result is applied even if // the user left the tab meanwhile — dropping it would leave providersLoading // stuck and block every later run of this effect. - ;(async () => { + ;void (async () => { try { const addonsData = await addonsApi.enabled() const enabled = (addonsData.addons || []).filter((a: any) => a.type === 'photo_provider' && a.enabled) diff --git a/client/src/components/Journey/JourneyDetailPageProviderPicker.tsx b/client/src/components/Journey/JourneyDetailPageProviderPicker.tsx index 681460e99..435e5af3a 100644 --- a/client/src/components/Journey/JourneyDetailPageProviderPicker.tsx +++ b/client/src/components/Journey/JourneyDetailPageProviderPicker.tsx @@ -184,18 +184,18 @@ export function ProviderPicker({ // load on mount / filter change useEffect(() => { if (filter === 'day' && initialDate) { - searchPhotos(initialDate, initialDate); + void searchPhotos(initialDate, initialDate); } else if (filter === 'trip' && tripRange.from && tripRange.to) { - searchPhotos(tripRange.from, tripRange.to); + void searchPhotos(tripRange.from, tripRange.to); } else if (filter === 'all') { - searchPhotos('', ''); + void searchPhotos('', ''); } else if (filter === 'album' && albums.length === 0) { - loadAlbums(); + void loadAlbums(); } }, [filter]); const handleCustomSearch = () => { - if (customFrom && customTo) searchPhotos(customFrom, customTo); + if (customFrom && customTo) void searchPhotos(customFrom, customTo); }; // Sorted here rather than in the two fetches above. contextLocation is live @@ -224,7 +224,7 @@ export function ProviderPicker({ const loadMorePhotos = () => { if (loadingMore || !canLoadMore) return; - searchPhotos(searchFrom, searchTo, searchPage + 1, true); + void searchPhotos(searchFrom, searchTo, searchPage + 1, true); }; const selectionEntry = (asset: PickerAsset | undefined): SelectedAsset => ({ @@ -462,7 +462,7 @@ export function ProviderPicker({ onClick={() => { setSelectedAlbum(a.id); setSelectedAlbumPassphrase(a.passphrase); - loadAlbumPhotos(a); + void loadAlbumPhotos(a); }} className={`flex-shrink-0 rounded-lg border px-2.5 py-1 text-[11px] font-medium whitespace-nowrap ${ selectedAlbum === a.id diff --git a/client/src/components/Journey/JourneyDetailPageSettingsDialog.tsx b/client/src/components/Journey/JourneyDetailPageSettingsDialog.tsx index c22542ff6..f723e4228 100644 --- a/client/src/components/Journey/JourneyDetailPageSettingsDialog.tsx +++ b/client/src/components/Journey/JourneyDetailPageSettingsDialog.tsx @@ -308,7 +308,7 @@ export function JourneySettingsDialog({ journey, onClose, onSaved, onOpenInvite, { if (!savingTracks) handleTracksToggle() }} + onToggle={() => { if (!savingTracks) void handleTracksToggle() }} label={t('journey.settings.showTripTracks')} />
@@ -345,7 +345,7 @@ export function JourneySettingsDialog({ journey, onClose, onSaved, onOpenInvite, {label} { if (savingField === null) handleFieldToggle(field) }} + onToggle={() => { if (savingField === null) void handleFieldToggle(field) }} label={label} />
diff --git a/client/src/components/Layout/OfflineBanner.tsx b/client/src/components/Layout/OfflineBanner.tsx index bdb89e9b8..1fe915c17 100644 --- a/client/src/components/Layout/OfflineBanner.tsx +++ b/client/src/components/Layout/OfflineBanner.tsx @@ -41,7 +41,7 @@ export default function OfflineBanner(): React.ReactElement | null { setConflictCount(conflicts) } } - poll() + void poll() const id = setInterval(poll, POLL_MS) return () => { cancelled = true; clearInterval(id) } }, []) diff --git a/client/src/components/Packing/PackingListPanelBagModal.tsx b/client/src/components/Packing/PackingListPanelBagModal.tsx index ee44623c9..355a680d8 100644 --- a/client/src/components/Packing/PackingListPanelBagModal.tsx +++ b/client/src/components/Packing/PackingListPanelBagModal.tsx @@ -78,7 +78,7 @@ export function BagModal(S: PackingState) { {canEdit && (showAddBag ? (
setNewBagName(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') handleCreateBag(); if (e.key === 'Escape') { setShowAddBag(false); setNewBagName('') } }} + onKeyDown={e => { if (e.key === 'Enter') void handleCreateBag(); if (e.key === 'Escape') { setShowAddBag(false); setNewBagName('') } }} placeholder={t('packing.bagName')} style={{ flex: 1, padding: '8px 12px', borderRadius: 10, border: '1px solid var(--border-primary)', fontSize: 'calc(13px * var(--fs-scale-body, 1))', fontFamily: 'inherit', outline: 'none' }} /> diff --git a/client/src/components/Todo/TodoListPanel.tsx b/client/src/components/Todo/TodoListPanel.tsx index f2cef6dd2..d69377337 100644 --- a/client/src/components/Todo/TodoListPanel.tsx +++ b/client/src/components/Todo/TodoListPanel.tsx @@ -485,7 +485,7 @@ function NewTaskPane({ tripId, categories, members, defaultCategory, onCreated,
setName(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter' && name.trim()) create() }} + onKeyDown={e => { if (e.key === 'Enter' && name.trim()) void create() }} style={{ ...taskInputStyle, fontSize: 'calc(15px * var(--fs-scale-subtitle, 1))', fontWeight: 600 }} placeholder={t('todo.namePlaceholder')} /> setFields(f => ({ ...f, ...patch }))} categories={categories} members={members} /> diff --git a/client/src/components/Trips/TripFormModal.tsx b/client/src/components/Trips/TripFormModal.tsx index de7224c30..83198335f 100644 --- a/client/src/components/Trips/TripFormModal.tsx +++ b/client/src/components/Trips/TripFormModal.tsx @@ -258,7 +258,7 @@ export default function TripFormModal({ isOpen, onClose, onSave, trip, onCoverUp setPendingUnsplashUrl(null) if (isEditing && trip?.id) { // Existing trip: upload immediately - uploadCoverNow(normalized) + void uploadCoverNow(normalized) } else { // New trip: stage for upload after creation setPendingCoverFile(normalized) @@ -269,7 +269,7 @@ export default function TripFormModal({ isOpen, onClose, onSave, trip, onCoverUp } const handleCoverChange = (e: React.ChangeEvent) => { - handleCoverSelect(e.target.files?.[0]) + void handleCoverSelect(e.target.files?.[0]) e.target.value = '' } @@ -361,7 +361,7 @@ export default function TripFormModal({ isOpen, onClose, onSave, trip, onCoverUp if (item.type.startsWith('image/')) { e.preventDefault() const file = item.getAsFile() - if (file) handleCoverSelect(file) + if (file) void handleCoverSelect(file) return } } @@ -488,7 +488,7 @@ export default function TripFormModal({ isOpen, onClose, onSave, trip, onCoverUp
diff --git a/client/src/mobile/screens/admin/MAdminGitHubPanel.tsx b/client/src/mobile/screens/admin/MAdminGitHubPanel.tsx index 3c9e2d0ee..b78e17c80 100644 --- a/client/src/mobile/screens/admin/MAdminGitHubPanel.tsx +++ b/client/src/mobile/screens/admin/MAdminGitHubPanel.tsx @@ -77,7 +77,7 @@ export default function MAdminGitHubPanel({ isPrerelease = false }: { isPrerelea useEffect(() => { setLoading(true) - loadFrom(1, false).finally(() => setLoading(false)) + void loadFrom(1, false).finally(() => setLoading(false)) }, []) const handleLoadMore = async () => { diff --git a/client/src/mobile/screens/admin/MAdminPackingTemplateManager.tsx b/client/src/mobile/screens/admin/MAdminPackingTemplateManager.tsx index 406f26da7..f58c09d33 100644 --- a/client/src/mobile/screens/admin/MAdminPackingTemplateManager.tsx +++ b/client/src/mobile/screens/admin/MAdminPackingTemplateManager.tsx @@ -84,7 +84,7 @@ export default function MAdminPackingTemplateManager() { const toast = useToast() const { t } = useTranslation() - useEffect(() => { loadTemplates() }, []) + useEffect(() => { void loadTemplates() }, []) const loadTemplates = async () => { setIsLoading(true) @@ -216,7 +216,7 @@ export default function MAdminPackingTemplateManager() { autoFocus value={createName} onChange={e => setCreateName(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') handleCreateTemplate(); if (e.key === 'Escape') setShowCreate(false) }} + onKeyDown={e => { if (e.key === 'Enter') void handleCreateTemplate(); if (e.key === 'Escape') setShowCreate(false) }} placeholder={t('admin.packingTemplates.namePlaceholder')} />
@@ -254,7 +254,7 @@ export default function MAdminPackingTemplateManager() { value={editTemplateName} onChange={e => setEditTemplateName(e.target.value)} onBlur={() => handleRenameTemplate(tmpl.id)} - onKeyDown={e => { if (e.key === 'Enter') handleRenameTemplate(tmpl.id); if (e.key === 'Escape') setEditingTemplate(null) }} + onKeyDown={e => { if (e.key === 'Enter') void handleRenameTemplate(tmpl.id); if (e.key === 'Escape') setEditingTemplate(null) }} /> ) : ( @@ -292,7 +292,7 @@ export default function MAdminPackingTemplateManager() { value={editCatName} onChange={e => setEditCatName(e.target.value)} onBlur={() => handleRenameCategory(cat.id)} - onKeyDown={e => { if (e.key === 'Enter') handleRenameCategory(cat.id); if (e.key === 'Escape') setEditingCatId(null) }} + onKeyDown={e => { if (e.key === 'Enter') void handleRenameCategory(cat.id); if (e.key === 'Escape') setEditingCatId(null) }} /> ) : ( @@ -329,7 +329,7 @@ export default function MAdminPackingTemplateManager() { autoFocus value={editItemName} onChange={e => setEditItemName(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') handleRenameItem(item.id); if (e.key === 'Escape') setEditingItemId(null) }} + onKeyDown={e => { if (e.key === 'Enter') void handleRenameItem(item.id); if (e.key === 'Escape') setEditingItemId(null) }} /> handleRenameItem(item.id)}> @@ -361,7 +361,7 @@ export default function MAdminPackingTemplateManager() { ref={addItemRef} value={newItemName} onChange={e => setNewItemName(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter' && newItemName.trim()) handleAddItem(cat.id); if (e.key === 'Escape') { setAddingItemToCatId(null); setNewItemName('') } }} + onKeyDown={e => { if (e.key === 'Enter' && newItemName.trim()) void handleAddItem(cat.id); if (e.key === 'Escape') { setAddingItemToCatId(null); setNewItemName('') } }} placeholder={t('admin.packingTemplates.itemName')} className={inlineFieldCls} /> @@ -383,7 +383,7 @@ export default function MAdminPackingTemplateManager() { autoFocus value={newCatName} onChange={e => setNewCatName(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') handleAddCategory(); if (e.key === 'Escape') { setAddingCategory(false); setNewCatName('') } }} + onKeyDown={e => { if (e.key === 'Enter') void handleAddCategory(); if (e.key === 'Escape') { setAddingCategory(false); setNewCatName('') } }} placeholder={t('admin.packingTemplates.categoryName')} /> diff --git a/client/src/mobile/screens/admin/MAdminPermissionsPanel.tsx b/client/src/mobile/screens/admin/MAdminPermissionsPanel.tsx index fff021a89..4a6a98299 100644 --- a/client/src/mobile/screens/admin/MAdminPermissionsPanel.tsx +++ b/client/src/mobile/screens/admin/MAdminPermissionsPanel.tsx @@ -38,7 +38,7 @@ export default function MAdminPermissionsPanel(): React.ReactElement { const [dirty, setDirty] = useState(false) useEffect(() => { - loadPermissions() + void loadPermissions() }, []) const loadPermissions = async () => { diff --git a/client/src/mobile/screens/admin/MAdminSheets.tsx b/client/src/mobile/screens/admin/MAdminSheets.tsx index e3e743d6d..10460d7d4 100644 --- a/client/src/mobile/screens/admin/MAdminSheets.tsx +++ b/client/src/mobile/screens/admin/MAdminSheets.tsx @@ -178,7 +178,7 @@ export default function MAdminSheets({ admin, t }: MAdminSheetsProps) { onClick={() => { const user = editingUser setEditingUser(null) - handleDeleteUser(user) + void handleDeleteUser(user) }} > diff --git a/client/src/mobile/screens/atlas/MAtlasBucketSheet.tsx b/client/src/mobile/screens/atlas/MAtlasBucketSheet.tsx index 7eb6ea80a..15ad2865e 100644 --- a/client/src/mobile/screens/atlas/MAtlasBucketSheet.tsx +++ b/client/src/mobile/screens/atlas/MAtlasBucketSheet.tsx @@ -152,8 +152,8 @@ export default function MAtlasBucketSheet({ atlas, open, onClose }: MAtlasBucket }} onKeyDown={(e) => { if (e.key !== 'Enter') return - if (bucketForm.name) handleAddBucketItem() - else handleBucketPoiSearch() + if (bucketForm.name) void handleAddBucketItem() + else void handleBucketPoiSearch() }} placeholder={t('atlas.bucketNamePlaceholder')} className={`${inputCls} min-w-0 flex-1`} diff --git a/client/src/mobile/screens/collections/MCollAddSheet.tsx b/client/src/mobile/screens/collections/MCollAddSheet.tsx index e2ce4a006..1141a59e2 100644 --- a/client/src/mobile/screens/collections/MCollAddSheet.tsx +++ b/client/src/mobile/screens/collections/MCollAddSheet.tsx @@ -161,7 +161,7 @@ export default function MCollAddSheet({ open, collectionId, collectionName, list setQuery(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); search() } }} + onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); void search() } }} placeholder={t('collections.addPlaceSearch')} className="min-w-0 flex-1 bg-transparent py-2 font-[inherit] text-[0.8125rem] text-m-ink outline-none placeholder:text-m-faint" /> diff --git a/client/src/mobile/screens/collections/MCollEditSheet.tsx b/client/src/mobile/screens/collections/MCollEditSheet.tsx index 3105c297c..ab11a344d 100644 --- a/client/src/mobile/screens/collections/MCollEditSheet.tsx +++ b/client/src/mobile/screens/collections/MCollEditSheet.tsx @@ -204,7 +204,7 @@ export default function MCollEditSheet({ target, onClose, onCreated, onRequestDe setCoverQuery(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); searchCover() } }} + onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); void searchCover() } }} placeholder={t('dashboard.unsplashSearchPlaceholder')} className="min-w-0 flex-1 rounded-[12px] border border-[color:var(--m-rowbr)] bg-[color:var(--m-sheet)] px-3 py-[10px] font-geist text-[0.71875rem] text-m-ink outline-none placeholder:text-m-faint" /> diff --git a/client/src/mobile/screens/collections/MCollLabelsSheet.tsx b/client/src/mobile/screens/collections/MCollLabelsSheet.tsx index 9be1bbc84..2e376a654 100644 --- a/client/src/mobile/screens/collections/MCollLabelsSheet.tsx +++ b/client/src/mobile/screens/collections/MCollLabelsSheet.tsx @@ -101,7 +101,7 @@ export default function MCollLabelsSheet({ setName(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') submit() }} + onKeyDown={e => { if (e.key === 'Enter') void submit() }} placeholder={t('collections.labels.namePlaceholder')} className={INPUT_CLS} /> diff --git a/client/src/mobile/screens/collections/MCollShareSheet.tsx b/client/src/mobile/screens/collections/MCollShareSheet.tsx index 66d23fdd0..af43f00cf 100644 --- a/client/src/mobile/screens/collections/MCollShareSheet.tsx +++ b/client/src/mobile/screens/collections/MCollShareSheet.tsx @@ -98,7 +98,7 @@ export default function MCollShareSheet({ if (collectionId == null) return const current = member.role ?? 'editor' const next = COLLECTION_ROLES[(COLLECTION_ROLES.indexOf(current) + 1) % COLLECTION_ROLES.length] - run(member.user_id, () => setMemberRole(collectionId, member.user_id, next)) + void run(member.user_id, () => setMemberRole(collectionId, member.user_id, next)) } const handleInvite = async () => { diff --git a/client/src/mobile/screens/dashboard/MNewTripSheet.tsx b/client/src/mobile/screens/dashboard/MNewTripSheet.tsx index ba13b88d5..5f89b172e 100644 --- a/client/src/mobile/screens/dashboard/MNewTripSheet.tsx +++ b/client/src/mobile/screens/dashboard/MNewTripSheet.tsx @@ -356,7 +356,7 @@ export default function MNewTripSheet({ open, trip, onClose, onSave, onCoverUpda type="file" accept="image/*" className="hidden" - onChange={e => { handleCoverFile(e.target.files?.[0]); e.target.value = '' }} + onChange={e => { void handleCoverFile(e.target.files?.[0]); e.target.value = '' }} /> {coverPreview ? (
@@ -398,7 +398,7 @@ export default function MNewTripSheet({ open, trip, onClose, onSave, onCoverUpda setSearchQuery(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); handleSearch() } }} + onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); void handleSearch() } }} placeholder={t('dashboard.unsplashSearchPlaceholder')} className={`${inputCls} pt-0 text-[0.8125rem] font-medium`} /> diff --git a/client/src/mobile/screens/journey/MJourneyDetail.tsx b/client/src/mobile/screens/journey/MJourneyDetail.tsx index cf43f4771..326fd1a8f 100644 --- a/client/src/mobile/screens/journey/MJourneyDetail.tsx +++ b/client/src/mobile/screens/journey/MJourneyDetail.tsx @@ -262,7 +262,7 @@ export default function MJourneyDetail() { useEffect(() => { let active = true - ;(async () => { + ;void (async () => { try { const addonsData = await addonsApi.enabled() const enabled = (addonsData.addons || []).filter( diff --git a/client/src/mobile/screens/journey/MJourneyEntrySheet.tsx b/client/src/mobile/screens/journey/MJourneyEntrySheet.tsx index 2a54d0f19..101da4edc 100644 --- a/client/src/mobile/screens/journey/MJourneyEntrySheet.tsx +++ b/client/src/mobile/screens/journey/MJourneyEntrySheet.tsx @@ -160,7 +160,7 @@ export default function MJourneyEntrySheet({ if (!addonsLoaded) return if (photoProviders.length === 0) { setProviders([]); return } let active = true - ;(async () => { + ;void (async () => { const connected: { id: string; name: string }[] = [] for (const provider of photoProviders) { try { diff --git a/client/src/mobile/screens/settings/MSettingsAccount.tsx b/client/src/mobile/screens/settings/MSettingsAccount.tsx index 835fff019..f95ae217b 100644 --- a/client/src/mobile/screens/settings/MSettingsAccount.tsx +++ b/client/src/mobile/screens/settings/MSettingsAccount.tsx @@ -647,7 +647,7 @@ function MPasskeysCard({ demoMode }: { demoMode?: boolean }): React.ReactElement value={renameVal} onChange={(e) => setRenameVal(e.target.value)} onKeyDown={(e) => { - if (e.key === 'Enter') handleRename(c.id) + if (e.key === 'Enter') void handleRename(c.id) if (e.key === 'Escape') setRenamingId(null) }} /> diff --git a/client/src/mobile/screens/settings/MSettingsMcp.tsx b/client/src/mobile/screens/settings/MSettingsMcp.tsx index 873837007..d9664069a 100644 --- a/client/src/mobile/screens/settings/MSettingsMcp.tsx +++ b/client/src/mobile/screens/settings/MSettingsMcp.tsx @@ -164,7 +164,7 @@ export default function MSettingsMcp() { }` const handleCopy = (text: string, key: string) => { - navigator.clipboard.writeText(text).then(() => { + void navigator.clipboard.writeText(text).then(() => { setCopiedKey(key) if (copyTimerRef.current) clearTimeout(copyTimerRef.current) copyTimerRef.current = setTimeout(() => setCopiedKey(null), 2000) diff --git a/client/src/mobile/screens/settings/MSettingsPlugins.tsx b/client/src/mobile/screens/settings/MSettingsPlugins.tsx index 4dee05e96..4e0171940 100644 --- a/client/src/mobile/screens/settings/MSettingsPlugins.tsx +++ b/client/src/mobile/screens/settings/MSettingsPlugins.tsx @@ -117,7 +117,7 @@ function PluginSettingsForm({ id, name, icon }: { id: string; name: string; icon const runAction = (a: PluginAction) => { // Danger actions confirm first (native sheet in place of window.confirm). if (a.danger) { setConfirmAction(a); return } - performAction(a) + void performAction(a) } const save = async () => { @@ -258,7 +258,7 @@ function PluginSettingsForm({ id, name, icon }: { id: string; name: string; icon confirmLabel={confirmAction?.label} cancelLabel={t('common.cancel')} danger - onConfirm={() => { const a = confirmAction; setConfirmAction(null); if (a) performAction(a) }} + onConfirm={() => { const a = confirmAction; setConfirmAction(null); if (a) void performAction(a) }} /> ) diff --git a/client/src/mobile/screens/trip/sheets/ImpListStep.tsx b/client/src/mobile/screens/trip/sheets/ImpListStep.tsx index 2e7c77c9f..1f882417a 100644 --- a/client/src/mobile/screens/trip/sheets/ImpListStep.tsx +++ b/client/src/mobile/screens/trip/sheets/ImpListStep.tsx @@ -94,7 +94,7 @@ export default function ImpListStep({ planner, onBack, onDone }: ImpListStepProp onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault() - handleImport() + void handleImport() } }} placeholder={provider === 'google' ? 'https://maps.app.goo.gl/…' : 'https://naver.me/…'} diff --git a/client/src/mobile/screens/trip/sheets/MPlaceEditSheet.tsx b/client/src/mobile/screens/trip/sheets/MPlaceEditSheet.tsx index 7acdaa165..9bd2eba64 100644 --- a/client/src/mobile/screens/trip/sheets/MPlaceEditSheet.tsx +++ b/client/src/mobile/screens/trip/sheets/MPlaceEditSheet.tsx @@ -482,7 +482,7 @@ export default function MPlaceEditSheet({ planner, onOpenExpense }: MPlaceEditSh placeId={sheetPlace?.id} hintKey="places.createExpenseHint" createDisabled={!form.name.trim() || isSaving} - onCreate={() => { expenseIntentRef.current = true; handleSubmit() }} + onCreate={() => { expenseIntentRef.current = true; void handleSubmit() }} onEdit={item => onOpenExpense({ editItem: item })} /> )} diff --git a/client/src/mobile/screens/trip/sheets/MPlaceSheet.tsx b/client/src/mobile/screens/trip/sheets/MPlaceSheet.tsx index 9d02048a7..b8d29f0dd 100644 --- a/client/src/mobile/screens/trip/sheets/MPlaceSheet.tsx +++ b/client/src/mobile/screens/trip/sheets/MPlaceSheet.tsx @@ -146,12 +146,12 @@ export default function MPlaceSheet({ planner, shell }: MTripSheetsProps) { const removeParticipant = (userId: number) => { let next = allJoined ? members.filter(m => m.id !== userId).map(m => m.id) : participantIds.filter(id => id !== userId) if (next.length === members.length) next = [] - setParticipants(next) + void setParticipants(next) } const addParticipant = (userId: number) => { const next = [...participantIds, userId] - setParticipants(next.length === members.length ? [] : next) + void setParticipants(next.length === members.length ? [] : next) setParticipantPickerOpen(false) } diff --git a/client/src/mobile/screens/trip/sheets/MTransportSheet.tsx b/client/src/mobile/screens/trip/sheets/MTransportSheet.tsx index c14791d6c..e3188702f 100644 --- a/client/src/mobile/screens/trip/sheets/MTransportSheet.tsx +++ b/client/src/mobile/screens/trip/sheets/MTransportSheet.tsx @@ -144,7 +144,7 @@ export default function MTransportSheet({ planner, shell }: MTripSheetsProps) { } const deleteTransport = () => { - planner.handleDeleteReservation(res.id) + void planner.handleDeleteReservation(res.id) shell.closeSheet() } diff --git a/client/src/mobile/screens/trip/sheets/PlCategoryPicker.tsx b/client/src/mobile/screens/trip/sheets/PlCategoryPicker.tsx index 6b6738a70..f50fd0ae8 100644 --- a/client/src/mobile/screens/trip/sheets/PlCategoryPicker.tsx +++ b/client/src/mobile/screens/trip/sheets/PlCategoryPicker.tsx @@ -84,7 +84,7 @@ export default function PlCategoryPicker({ planner, value, onChange }: PlCategor onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault() - handleCreate() + void handleCreate() } }} placeholder={t('places.categoryNamePlaceholder')} diff --git a/client/src/mobile/screens/trip/sheets/PlPlaceSearch.tsx b/client/src/mobile/screens/trip/sheets/PlPlaceSearch.tsx index 6b6785307..5455201de 100644 --- a/client/src/mobile/screens/trip/sheets/PlPlaceSearch.tsx +++ b/client/src/mobile/screens/trip/sheets/PlPlaceSearch.tsx @@ -301,7 +301,7 @@ export default function PlPlaceSearch({ planner, locationBias, onPick, onResolvi onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault() - handleSearch() + void handleSearch() } }} onBlur={() => setTimeout(() => setSuggestions([]), 150)} diff --git a/client/src/mobile/screens/trip/tabs/MBookingsTab.tsx b/client/src/mobile/screens/trip/tabs/MBookingsTab.tsx index c21348538..30fba55ae 100644 --- a/client/src/mobile/screens/trip/tabs/MBookingsTab.tsx +++ b/client/src/mobile/screens/trip/tabs/MBookingsTab.tsx @@ -247,8 +247,8 @@ function BookingCard({ res, planner, canEdit, compact }: { key={f.id} role="button" tabIndex={0} - onClick={e => { e.stopPropagation(); openFile(f.url, f.original_name) }} - onKeyDown={e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); e.stopPropagation(); openFile(f.url, f.original_name) } }} + onClick={e => { e.stopPropagation(); void openFile(f.url, f.original_name) }} + onKeyDown={e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); e.stopPropagation(); void openFile(f.url, f.original_name) } }} className="flex items-center gap-[6px] rounded-[10px] border border-[color:var(--m-rowbr)] bg-m-card px-[10px] py-[7px]" > diff --git a/client/src/mobile/screens/trip/tabs/MCostsTab.tsx b/client/src/mobile/screens/trip/tabs/MCostsTab.tsx index c1299ff22..d48f793fe 100644 --- a/client/src/mobile/screens/trip/tabs/MCostsTab.tsx +++ b/client/src/mobile/screens/trip/tabs/MCostsTab.tsx @@ -599,7 +599,7 @@ export default function MCostsTab({ planner, shell }: MTabScreenProps) { onConfirm={() => { const item = confirmDelete setConfirmDelete(null) - if (item) handleDeleteExpense(item) + if (item) void handleDeleteExpense(item) }} /> diff --git a/client/src/mobile/screens/trip/tabs/MFileLightbox.tsx b/client/src/mobile/screens/trip/tabs/MFileLightbox.tsx index ef27fd758..c17f350c8 100644 --- a/client/src/mobile/screens/trip/tabs/MFileLightbox.tsx +++ b/client/src/mobile/screens/trip/tabs/MFileLightbox.tsx @@ -42,7 +42,7 @@ export default function MFileLightbox({ files, index, onIndexChange, onClose, t let cancelled = false setImgSrc('') if (fileUrl && !isVideo(fileMimeType)) { - getAuthUrl(fileUrl, 'download').then(url => { if (!cancelled) setImgSrc(url) }) + void getAuthUrl(fileUrl, 'download').then(url => { if (!cancelled) setImgSrc(url) }) } return () => { cancelled = true } }, [fileUrl, fileMimeType]) diff --git a/client/src/mobile/screens/trip/tabs/MPackingListTab.tsx b/client/src/mobile/screens/trip/tabs/MPackingListTab.tsx index 72854539c..e6a9dc7f6 100644 --- a/client/src/mobile/screens/trip/tabs/MPackingListTab.tsx +++ b/client/src/mobile/screens/trip/tabs/MPackingListTab.tsx @@ -387,7 +387,7 @@ export default function MPackingListTab({ planner }: { planner: TripPlanner }) { autoFocus value={saveTemplateName} onChange={e => setSaveTemplateName(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') saveAsTemplate() }} + onKeyDown={e => { if (e.key === 'Enter') void saveAsTemplate() }} placeholder={t('packing.templateName')} className={`${FIELD_CLS} flex-1`} /> @@ -417,7 +417,7 @@ export default function MPackingListTab({ planner }: { planner: TripPlanner }) { value={newCategoryName} onChange={e => setNewCategoryName(e.target.value)} onKeyDown={e => { - if (e.key === 'Enter') addNewCategory() + if (e.key === 'Enter') void addNewCategory() if (e.key === 'Escape') { setAddingCategory(false); setNewCategoryName('') } }} placeholder={t('packing.newCategoryPlaceholder')} @@ -538,7 +538,7 @@ export default function MPackingListTab({ planner }: { planner: TripPlanner }) { confirmLabel={t('common.delete')} cancelLabel={t('common.cancel')} danger - onConfirm={() => { setConfirmClear(false); clearChecked() }} + onConfirm={() => { setConfirmClear(false); void clearChecked() }} /> { const target = deleteCategoryTarget setDeleteCategoryTarget(null) - if (target) deleteCategoryItems(target.items) + if (target) void deleteCategoryItems(target.items) }} /> @@ -996,7 +996,7 @@ function PackingItemRow({ item, planner, currentUserId, editMode, canEdit, bagTr autoFocus value={newBagName} onChange={e => setNewBagName(e.target.value)} - onKeyDown={e => { if (e.key === 'Enter') submitNewBag(); if (e.key === 'Escape') { setCreatingBag(false); setNewBagName('') } }} + onKeyDown={e => { if (e.key === 'Enter') void submitNewBag(); if (e.key === 'Escape') { setCreatingBag(false); setNewBagName('') } }} placeholder={t('packing.bagName')} className={`${FIELD_CLS} flex-1 py-[6px] text-[0.75rem]`} /> diff --git a/client/src/mobile/screens/trip/tabs/MTransportsTab.tsx b/client/src/mobile/screens/trip/tabs/MTransportsTab.tsx index 70e9fe0fc..3840fb8ec 100644 --- a/client/src/mobile/screens/trip/tabs/MTransportsTab.tsx +++ b/client/src/mobile/screens/trip/tabs/MTransportsTab.tsx @@ -265,8 +265,8 @@ function TransportCard({ res, planner, shell, canEdit, compact }: { key={f.id} role="button" tabIndex={0} - onClick={e => { e.stopPropagation(); openFile(f.url, f.original_name) }} - onKeyDown={e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); e.stopPropagation(); openFile(f.url, f.original_name) } }} + onClick={e => { e.stopPropagation(); void openFile(f.url, f.original_name) }} + onKeyDown={e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); e.stopPropagation(); void openFile(f.url, f.original_name) } }} className="flex items-center gap-[6px] rounded-[10px] border border-[color:var(--m-rowbr)] bg-m-card px-[10px] py-[7px]" > diff --git a/client/src/mobile/screens/vacay/useMVacay.ts b/client/src/mobile/screens/vacay/useMVacay.ts index 52258eff7..7d5460f60 100644 --- a/client/src/mobile/screens/vacay/useMVacay.ts +++ b/client/src/mobile/screens/vacay/useMVacay.ts @@ -64,7 +64,7 @@ export function useMVacay() { // Trip-overlap dots: collect every day of the year covered by an own trip. useEffect(() => { let cancelled = false - ;(async () => { + ;void (async () => { try { const data = await tripsApi.list() const dates = new Set() diff --git a/client/src/pages/AtlasPage.tsx b/client/src/pages/AtlasPage.tsx index 75be38ba7..0901e0772 100644 --- a/client/src/pages/AtlasPage.tsx +++ b/client/src/pages/AtlasPage.tsx @@ -644,7 +644,7 @@ function SidebarContent({ data, stats, regionsVisited, countryRegions, onOpenPla
{ const v = e.target.value; if (bucketForm.name) setBucketForm({ ...bucketForm, name: v }); else setBucketSearch(v) }} - onKeyDown={e => { if (e.key === 'Enter' && !bucketForm.name) onSearchBucket(); else if (e.key === 'Enter') onAddBucket(); if (e.key === 'Escape') setShowBucketAdd(false) }} + onKeyDown={e => { if (e.key === 'Enter' && !bucketForm.name) void onSearchBucket(); else if (e.key === 'Enter') void onAddBucket(); if (e.key === 'Escape') setShowBucketAdd(false) }} placeholder={t('atlas.bucketNamePlaceholder')} autoFocus className="border border-edge text-content bg-surface-input" diff --git a/client/src/pages/admin/useAdmin.ts b/client/src/pages/admin/useAdmin.ts index 717062185..ffb51b7be 100644 --- a/client/src/pages/admin/useAdmin.ts +++ b/client/src/pages/admin/useAdmin.ts @@ -210,9 +210,9 @@ export function useAdmin() { const [rotatingJwt, setRotatingJwt] = useState(false) useEffect(() => { - loadData() - loadAppConfig() - loadApiKeys() + void loadData() + void loadAppConfig() + void loadApiKeys() // Skipped rather than caught when the route is closed to us: the request // still reaches the network, still answers 403, and still prints a red line // in the console of every admin who opens this page. Swallowing the promise @@ -441,7 +441,7 @@ export function useAdmin() { setInviteForm({ max_uses: 1, expires_in_days: 7, trip_id: '' }) // Copy link to clipboard const link = `${window.location.origin}/register?invite=${data.invite.token}` - navigator.clipboard.writeText(link).then(() => toast.success(t('admin.invite.copied'))) + void navigator.clipboard.writeText(link).then(() => toast.success(t('admin.invite.copied'))) } catch (err: unknown) { toast.error(getApiErrorMessage(err, t('admin.invite.createError'))) } @@ -459,7 +459,7 @@ export function useAdmin() { const copyInviteLink = (token: string) => { const link = `${window.location.origin}/register?invite=${token}` - navigator.clipboard.writeText(link).then(() => toast.success(t('admin.invite.copied'))) + void navigator.clipboard.writeText(link).then(() => toast.success(t('admin.invite.copied'))) } const handleEditUser = (user) => { diff --git a/client/src/pages/dashboard/useDashboard.ts b/client/src/pages/dashboard/useDashboard.ts index d804e7e58..b3fb8967e 100644 --- a/client/src/pages/dashboard/useDashboard.ts +++ b/client/src/pages/dashboard/useDashboard.ts @@ -63,7 +63,7 @@ export function useDashboard() { } }, [searchParams]) - useEffect(() => { loadTrips() }, []) + useEffect(() => { void loadTrips() }, []) // Travel stats + upcoming reservations power the atlas row and the sidebar. // Both are best-effort: a failure just leaves that section empty. @@ -91,7 +91,7 @@ export function useDashboard() { // the error banner (loadUser resets authCheckFailed on success). #1283 const retryLoad = () => { loadUser({ silent: true }) - loadTrips() + void loadTrips() } const today = localIsoToday() diff --git a/client/src/pages/files/useFiles.ts b/client/src/pages/files/useFiles.ts index f62bfe277..faa0ffa78 100644 --- a/client/src/pages/files/useFiles.ts +++ b/client/src/pages/files/useFiles.ts @@ -22,7 +22,7 @@ export function useFiles() { const [isLoading, setIsLoading] = useState(true) useEffect(() => { - loadData() + void loadData() }, [tripId]) const loadData = async (): Promise => { diff --git a/client/src/pages/journey/useJourney.ts b/client/src/pages/journey/useJourney.ts index af3d373da..90b540a52 100644 --- a/client/src/pages/journey/useJourney.ts +++ b/client/src/pages/journey/useJourney.ts @@ -42,7 +42,7 @@ export function useJourney() { // The bottom-nav "+" opens the new-journey modal via ?create=1. useEffect(() => { if (searchParams.get('create') === '1') { - openCreateModal() + void openCreateModal() setSearchParams(p => { p.delete('create'); return p }, { replace: true }) } }, [searchParams]) diff --git a/client/src/pages/oauthAuthorize/useOAuthAuthorize.ts b/client/src/pages/oauthAuthorize/useOAuthAuthorize.ts index 490df6ae7..724860fb1 100644 --- a/client/src/pages/oauthAuthorize/useOAuthAuthorize.ts +++ b/client/src/pages/oauthAuthorize/useOAuthAuthorize.ts @@ -48,7 +48,7 @@ export function useOAuthAuthorize() { useEffect(() => { if (authLoading) return - validateRequest() + void validateRequest() // eslint-disable-next-line react-hooks/exhaustive-deps }, [authLoading, isAuthenticated]) diff --git a/client/src/pages/tripPlanner/useDayAdd.ts b/client/src/pages/tripPlanner/useDayAdd.ts index b82387f4a..eab6f99ee 100644 --- a/client/src/pages/tripPlanner/useDayAdd.ts +++ b/client/src/pages/tripPlanner/useDayAdd.ts @@ -48,7 +48,7 @@ export function useDayAdd(options: DayAddOptions): DayAdd { if (inFlight.current) return inFlight.current = true setBusy(true) - add().finally(() => { + void add().finally(() => { inFlight.current = false setBusy(false) }) diff --git a/client/src/pages/tripPlanner/useTripPlanner.ts b/client/src/pages/tripPlanner/useTripPlanner.ts index 2e8f8c7d1..3f2bcf401 100644 --- a/client/src/pages/tripPlanner/useTripPlanner.ts +++ b/client/src/pages/tripPlanner/useTripPlanner.ts @@ -2849,7 +2849,7 @@ export function useTripPlanner() { if (!receipt) return void (async () => { const files = inMemory && inMemory.length ? inMemory : await getImportFiles(jobId) - deleteImportFiles(jobId) + void deleteImportFiles(jobId) setReceiptExpense(receiptToPrefill(receipt, canUploadFiles ? files : [])) })() } else if (task && task.items && task.items.length > 0) { @@ -2863,7 +2863,7 @@ export function useTripPlanner() { // Prefer the in-memory files (immediate path); after a reload they live in IndexedDB. void (async () => { const files = inMemory && inMemory.length ? inMemory : await getImportFiles(jobId) - deleteImportFiles(jobId) + void deleteImportFiles(jobId) startImportReview(items, files, kind) })() } diff --git a/client/src/repo/budgetRepo.ts b/client/src/repo/budgetRepo.ts index c2f0fa318..b0af41694 100644 --- a/client/src/repo/budgetRepo.ts +++ b/client/src/repo/budgetRepo.ts @@ -8,7 +8,7 @@ export const budgetRepo = { return onlineThenCache( async () => { const result = await budgetApi.list(tripId) - upsertBudgetItems(result.items) + void upsertBudgetItems(result.items) return result }, async () => ({ diff --git a/client/src/repo/dayRepo.ts b/client/src/repo/dayRepo.ts index 337118675..0424fe59d 100644 --- a/client/src/repo/dayRepo.ts +++ b/client/src/repo/dayRepo.ts @@ -14,7 +14,7 @@ export const dayRepo = { return onlineThenCache( async () => { const result = await daysApi.list(tripId) - upsertDays(result.days) + void upsertDays(result.days) return result }, async () => ({ diff --git a/client/src/repo/fileRepo.ts b/client/src/repo/fileRepo.ts index 8c75c863e..7f85160df 100644 --- a/client/src/repo/fileRepo.ts +++ b/client/src/repo/fileRepo.ts @@ -8,7 +8,7 @@ export const fileRepo = { return onlineThenCache( async () => { const result = await filesApi.list(tripId) - upsertTripFiles(result.files) + void upsertTripFiles(result.files) return result }, async () => ({ diff --git a/client/src/repo/packingRepo.ts b/client/src/repo/packingRepo.ts index 38ba2da7d..ce06a9550 100644 --- a/client/src/repo/packingRepo.ts +++ b/client/src/repo/packingRepo.ts @@ -10,7 +10,7 @@ export const packingRepo = { return onlineThenCache( async () => { const result = await packingApi.list(tripId) - upsertPackingItems(result.items) + void upsertPackingItems(result.items) return result }, async () => ({ diff --git a/client/src/repo/placeRepo.ts b/client/src/repo/placeRepo.ts index 6b86063dc..121ed1154 100644 --- a/client/src/repo/placeRepo.ts +++ b/client/src/repo/placeRepo.ts @@ -10,7 +10,7 @@ export const placeRepo = { return onlineThenCache( async () => { const result = await placesApi.list(tripId, params) - upsertPlaces(result.places) + void upsertPlaces(result.places) return result }, async () => ({ diff --git a/client/src/repo/reservationRepo.ts b/client/src/repo/reservationRepo.ts index 0394adb1d..ac5b766ec 100644 --- a/client/src/repo/reservationRepo.ts +++ b/client/src/repo/reservationRepo.ts @@ -8,7 +8,7 @@ export const reservationRepo = { return onlineThenCache( async () => { const result = await reservationsApi.list(tripId) - upsertReservations(result.reservations) + void upsertReservations(result.reservations) return result }, async () => ({ diff --git a/client/src/repo/todoRepo.ts b/client/src/repo/todoRepo.ts index 60b47aff8..bdfb40091 100644 --- a/client/src/repo/todoRepo.ts +++ b/client/src/repo/todoRepo.ts @@ -8,7 +8,7 @@ export const todoRepo = { return onlineThenCache( async () => { const result = await todoApi.list(tripId) - upsertTodoItems(result.items) + void upsertTodoItems(result.items) return result }, async () => ({ diff --git a/client/src/repo/tripRepo.ts b/client/src/repo/tripRepo.ts index 76d2798de..b300cde14 100644 --- a/client/src/repo/tripRepo.ts +++ b/client/src/repo/tripRepo.ts @@ -75,7 +75,7 @@ export const tripRepo = { return onlineThenCache( async () => { const result = await tripsApi.get(tripId) - upsertTrip(result.trip) + void upsertTrip(result.trip) return result }, async () => { diff --git a/client/src/services/photoService.ts b/client/src/services/photoService.ts index 24eaba81f..860db5138 100644 --- a/client/src/services/photoService.ts +++ b/client/src/services/photoService.ts @@ -115,14 +115,14 @@ export function fetchPhoto( callback?.(entry) notify(cacheKey, entry) // Generate base64 thumb in background - urlToBase64(photoId).then(thumb => { + void urlToBase64(photoId).then(thumb => { if (thumb) { entry.thumbDataUrl = thumb; notifyThumb(cacheKey, thumb) } }) return } inFlight.add(cacheKey) - acquireRequestSlot().then(() => + void acquireRequestSlot().then(() => mapsApi.placePhoto(photoId, lat, lng, name) .then(async (data: { photoUrl?: string }) => { const photoUrl = data.photoUrl || null diff --git a/client/src/store/slices/remoteEventHandler.ts b/client/src/store/slices/remoteEventHandler.ts index da9702484..38acd8e3c 100644 --- a/client/src/store/slices/remoteEventHandler.ts +++ b/client/src/store/slices/remoteEventHandler.ts @@ -173,7 +173,7 @@ function writeToDexie( payload: Record, state: TripStoreState, ): void { - ;(async () => { + ;void (async () => { try { await DEXIE_WRITERS[type as TrekWsTripEventName]?.(payload, state) } catch { diff --git a/client/src/sync/tripSyncManager.ts b/client/src/sync/tripSyncManager.ts index fcfef99c6..9d325b6ec 100644 --- a/client/src/sync/tripSyncManager.ts +++ b/client/src/sync/tripSyncManager.ts @@ -265,8 +265,8 @@ export const tripSyncManager = { // Cache global user data (tags + categories) — fire-and-forget, so the // gate has to be re-read when the response lands, not when it was issued: // a logout in between would put these rows in the anonymous database. - tagsApi.list().then(d => { if (isAuthed()) upsertTags(d.tags) }).catch(() => {}) - categoriesApi.list().then(d => { if (isAuthed()) upsertCategories(d.categories) }).catch(() => {}) + tagsApi.list().then(d => { if (isAuthed()) void upsertTags(d.tags) }).catch(() => {}) + categoriesApi.list().then(d => { if (isAuthed()) void upsertCategories(d.categories) }).catch(() => {}) // Cache file blobs + map tiles in background (don't block syncAll) const cacheTiles = getOfflinePrefs().cacheTiles diff --git a/server/src/nest/memories/trek-photo-cache.service.ts b/server/src/nest/memories/trek-photo-cache.service.ts index 291d403e3..ddfca8774 100644 --- a/server/src/nest/memories/trek-photo-cache.service.ts +++ b/server/src/nest/memories/trek-photo-cache.service.ts @@ -91,7 +91,7 @@ export class TrekPhotoCacheService { setInFlight(key: string, promise: Promise): void { inFlight.set(key, promise); - promise.finally(() => inFlight.delete(key)); + void promise.finally(() => inFlight.delete(key)); } async sweepExpired(): Promise {