fix: resolve all 69 ESLint warnings across 40 files
- Remove unused imports (Mail, CalendarIcon, Plus, Circle, cn, Link, MessageCircle, User, Tag, FolderUp, useEffect, LogOut, GripVertical, Check, X, HoverActionsMode, HoverActionsCorner, asn1js, Convert, etc.) - Prefix unused variables/params with underscore to satisfy no-unused-vars - Add missing React hook dependencies (exhaustive-deps) - Wrap handleNavigateUp in useCallback and selectedGroupMembers in useMemo - Remove unused eslint-disable directives in jmap/client.ts - Replace as any with typed casts in filter-store and smime-store tests - Remove dead code (macOk assignment, unused now variable)
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import { useMemo, useRef, useEffect, useCallback } from "react";
|
||||
import { useTranslations, useFormatter } from "next-intl";
|
||||
import { format, parseISO, isToday, isTomorrow, startOfDay } from "date-fns";
|
||||
import { Calendar as CalendarIcon, MapPin, Users } from "lucide-react";
|
||||
import { MapPin, Users } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { parseDuration, getEventColor } from "./event-card";
|
||||
import { getEventDayBounds, getPrimaryCalendarId } from "@/lib/calendar-utils";
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useState, useRef, useEffect, useMemo } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Globe, ListTodo, Plus, RefreshCw, Share2, Trash2 } from "lucide-react";
|
||||
import { Globe, ListTodo, RefreshCw, Share2, Trash2 } from "lucide-react";
|
||||
import { cn, formatDateTime } from "@/lib/utils";
|
||||
import type { Calendar } from "@/lib/jmap/types";
|
||||
import { CalendarColorPicker } from "@/components/settings/calendar-management-settings";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { useMemo, useCallback, useState } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { format, parseISO, isPast, isToday, isTomorrow } from "date-fns";
|
||||
import { Check, Circle, Flag, CalendarDays, ListTodo, Plus } from "lucide-react";
|
||||
import { Check, Flag, CalendarDays, ListTodo, Plus } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { CalendarTask, Calendar } from "@/lib/jmap/types";
|
||||
import type { TaskViewFilter } from "@/stores/task-store";
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { X, Trash2, CalendarDays, Bell, Flag } from "lucide-react";
|
||||
import { format, parseISO } from "date-fns";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import type { CalendarTask, Calendar, CalendarEventAlert } from "@/lib/jmap/types";
|
||||
|
||||
interface TaskModalProps {
|
||||
@@ -43,7 +43,7 @@ export function TaskModal({
|
||||
onSave,
|
||||
onDelete,
|
||||
onClose,
|
||||
isMobile,
|
||||
isMobile: _isMobile,
|
||||
}: TaskModalProps) {
|
||||
const t = useTranslations("calendar");
|
||||
const isEdit = !!task;
|
||||
|
||||
@@ -66,7 +66,7 @@ describe('ContactForm', () => {
|
||||
const onSave = vi.fn().mockResolvedValue(undefined);
|
||||
render(<ContactForm onSave={onSave} onCancel={vi.fn()} />);
|
||||
|
||||
const inputs = screen.getAllByRole('textbox');
|
||||
const _inputs = screen.getAllByRole('textbox');
|
||||
const givenNameInput = screen.getByPlaceholderText('given_name');
|
||||
fireEvent.change(givenNameInput, { target: { value: 'Jane' } });
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { ContactList } from '../contact-list';
|
||||
import type { ContactCard } from '@/lib/jmap/types';
|
||||
@@ -22,7 +22,7 @@ const bob = makeContact({
|
||||
emails: { e0: { address: 'bob@example.com' } },
|
||||
});
|
||||
|
||||
const group = makeContact({
|
||||
const _group = makeContact({
|
||||
id: '3',
|
||||
kind: 'group',
|
||||
name: { components: [{ kind: 'given', value: 'Team' }], isOrdered: true },
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Mail, Phone, Building, MapPin, StickyNote, Pencil, Trash2, BookUser, Copy, Send, Globe, Cake, Tag, KeyRound, Link, Users, Briefcase, Heart, Languages, MessageCircle, User, Calendar, UserCircle, ShieldCheck, ShieldAlert, Download } from "lucide-react";
|
||||
import { Mail, Phone, Building, MapPin, StickyNote, Pencil, Trash2, BookUser, Copy, Send, Globe, Cake, Tag, KeyRound, Users, Briefcase, Heart, Languages, Calendar, UserCircle, ShieldCheck, ShieldAlert, Download } from "lucide-react";
|
||||
import { Avatar } from "@/components/ui/avatar";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@@ -132,7 +132,7 @@ export function EmailContextMenu({
|
||||
onEditDraft,
|
||||
}: EmailContextMenuProps) {
|
||||
const t = useTranslations("context_menu");
|
||||
const tColor = useTranslations("email_viewer.color_tag");
|
||||
const _tColor = useTranslations("email_viewer.color_tag");
|
||||
const emailKeywords = useSettingsStore((state) => state.emailKeywords);
|
||||
const isUnread = !email.keywords?.$seen;
|
||||
const isStarred = email.keywords?.$flagged;
|
||||
|
||||
@@ -6,7 +6,7 @@ import { formatDate } from "@/lib/utils";
|
||||
import { Email } from "@/lib/jmap/types";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Avatar } from "@/components/ui/avatar";
|
||||
import { Paperclip, Star, Circle, CheckSquare, Square, Tag, Reply, Forward } from "lucide-react";
|
||||
import { Paperclip, Star, Circle, CheckSquare, Square, Reply, Forward } from "lucide-react";
|
||||
import { useEmailStore } from "@/stores/email-store";
|
||||
import { useSettingsStore, KEYWORD_PALETTE } from "@/stores/settings-store";
|
||||
import { useAuthStore } from "@/stores/auth-store";
|
||||
|
||||
@@ -64,7 +64,7 @@ export function EmailList({
|
||||
const { client } = useAuthStore();
|
||||
const {
|
||||
selectedEmailIds,
|
||||
selectAllEmails,
|
||||
selectAllEmails: _selectAllEmails,
|
||||
clearSelection,
|
||||
batchMarkAsRead,
|
||||
batchDelete,
|
||||
|
||||
@@ -204,7 +204,7 @@ const getCurrentColor = (keywords: Record<string, boolean> | undefined) => {
|
||||
};
|
||||
|
||||
// Helper function to format recipients with contextual display
|
||||
const formatRecipients = (
|
||||
const _formatRecipients = (
|
||||
recipients: Array<{ name?: string; email: string }> | undefined,
|
||||
currentUserEmail: string | undefined,
|
||||
t: (key: string, params?: Record<string, string | number>) => string
|
||||
@@ -1751,6 +1751,7 @@ export function EmailViewer({
|
||||
smimeStore.autoImportSignerCerts,
|
||||
smimeStore.keyRecords,
|
||||
smimeStore.unlockedDecryptionKeys,
|
||||
smimeStore,
|
||||
]);
|
||||
|
||||
// TNEF (winmail.dat) detection and processing
|
||||
@@ -1928,7 +1929,7 @@ export function EmailViewer({
|
||||
if (decryptedCidAttachments.length > 0) {
|
||||
const urls: Record<string, string> = {};
|
||||
|
||||
decryptedCidAttachments.forEach((att, index) => {
|
||||
decryptedCidAttachments.forEach((att) => {
|
||||
const bytes = getAttachmentContentBytes(att);
|
||||
if (!bytes) return;
|
||||
const cidValue = att.contentId!.replace(/^<|>$/g, '');
|
||||
@@ -1985,7 +1986,7 @@ export function EmailViewer({
|
||||
cancelled = true;
|
||||
objectUrls.forEach(url => URL.revokeObjectURL(url));
|
||||
};
|
||||
}, [client, email?.id, smimeDecryptedAttachments]);
|
||||
}, [client, email?.id, smimeDecryptedAttachments, email?.attachments]);
|
||||
|
||||
const effectiveAttachments = useMemo<EffectiveAttachment[]>(() => {
|
||||
if (smimeDecryptedAttachments.length > 0) {
|
||||
|
||||
@@ -305,7 +305,7 @@ function EmailCard({
|
||||
cancelled = true;
|
||||
objectUrls.forEach(url => URL.revokeObjectURL(url));
|
||||
};
|
||||
}, [client, email?.id]);
|
||||
}, [client, email?.id, email?.attachments]);
|
||||
|
||||
// Sanitize and prepare email HTML content
|
||||
const emailContent = useMemo(() => {
|
||||
|
||||
@@ -453,13 +453,13 @@ export function FileBrowser({
|
||||
})),
|
||||
];
|
||||
|
||||
const handleNavigateUp = () => {
|
||||
const handleNavigateUp = useCallback(() => {
|
||||
if (currentPath === '/') return;
|
||||
const segments = currentPath.split('/').filter(Boolean);
|
||||
segments.pop();
|
||||
const parentPath = segments.length === 0 ? '/' : '/' + segments.join('/');
|
||||
onNavigate(parentPath, null);
|
||||
};
|
||||
}, [currentPath, onNavigate]);
|
||||
|
||||
const handleResourceClick = (resource: FileResource, e: React.MouseEvent) => {
|
||||
if (resource.isDirectory) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useCallback, useState } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Upload, FolderPlus, FilePlus, FolderUp } from "lucide-react";
|
||||
import { Upload, FolderPlus, FilePlus } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { getDroppedFilesAndFolders } from "@/lib/webdav/drop-utils";
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ function FolderTreeItem({
|
||||
}) {
|
||||
const isExpanded = expandedIds.has(node.id);
|
||||
const isSelected = currentPath === node.path;
|
||||
const isLoading = loadingIds.has(node.id);
|
||||
const _isLoading = loadingIds.has(node.id);
|
||||
const children = childrenCache.get(node.id);
|
||||
const hasChildren = children !== undefined && children.length > 0;
|
||||
const indentPx = depth * 16;
|
||||
|
||||
@@ -45,7 +45,7 @@ export function IdentityManagerModal({ isOpen, onClose }: IdentityManagerModalPr
|
||||
|
||||
const client = useAuthStore((state) => state.client);
|
||||
const identities = useIdentityStore((state) => state.identities);
|
||||
const preferredPrimaryId = useIdentityStore((state) => state.preferredPrimaryId);
|
||||
const _preferredPrimaryId = useIdentityStore((state) => state.preferredPrimaryId);
|
||||
const setPreferredPrimary = useIdentityStore((state) => state.setPreferredPrimary);
|
||||
const syncIdentities = useSyncIdentities();
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useMemo, useRef, useEffect, useCallback } from 'react';
|
||||
import { useState, useMemo, useRef, useCallback } from 'react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { icons as lucideIcons, type LucideIcon } from 'lucide-react';
|
||||
import { Search, X } from 'lucide-react';
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useState, useRef, useEffect, useCallback } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { Mail, Calendar, BookUser, HardDrive, Settings, LogOut, Keyboard, Plus } from "lucide-react";
|
||||
import { Mail, Calendar, BookUser, HardDrive, Settings, Keyboard, Plus } from "lucide-react";
|
||||
import { AccountSwitcher } from "./account-switcher";
|
||||
import { icons as lucideIcons, type LucideIcon } from "lucide-react";
|
||||
import { useConfig } from "@/hooks/use-config";
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { X, Plus, Pencil, Trash2, GripVertical, ExternalLink, PanelRight } from 'lucide-react';
|
||||
import { X, Plus, Pencil, Trash2, ExternalLink, PanelRight } from 'lucide-react';
|
||||
import { icons as lucideIcons, type LucideIcon } from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Button } from '@/components/ui/button';
|
||||
|
||||
@@ -429,7 +429,7 @@ export function Sidebar({
|
||||
className,
|
||||
}: SidebarProps) {
|
||||
const { sidebarCollapsed: isCollapsed, toggleSidebarCollapsed } = useUIStore();
|
||||
const { primaryIdentity } = useAuthStore();
|
||||
const { primaryIdentity: _primaryIdentity } = useAuthStore();
|
||||
const [expandedFolders, setExpandedFolders] = useState<Set<string>>(new Set());
|
||||
const [tagsExpanded, setTagsExpanded] = useState(() => {
|
||||
try {
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useCalendarStore } from '@/stores/calendar-store';
|
||||
import { useAuthStore } from '@/stores/auth-store';
|
||||
import { toast } from '@/stores/toast-store';
|
||||
import { SettingsSection } from './settings-section';
|
||||
import { Plus, Pencil, Trash2, Check, X, Calendar as CalendarIcon, Copy, Link, Upload, Globe, RefreshCw, Eraser } from 'lucide-react';
|
||||
import { Plus, Pencil, Trash2, Calendar as CalendarIcon, Copy, Link, Upload, Globe, RefreshCw, Eraser } from 'lucide-react';
|
||||
import { cn, formatDateTime } from '@/lib/utils';
|
||||
import { ICalImportModal } from '@/components/calendar/ical-import-modal';
|
||||
import { ICalSubscriptionModal } from '@/components/calendar/ical-subscription-modal';
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useState, useCallback } from 'react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { useConfig } from '@/hooks/use-config';
|
||||
import { useSettingsStore } from '@/stores/settings-store';
|
||||
import type { ArchiveMode, HoverAction, HoverActionsMode, HoverActionsCorner } from '@/stores/settings-store';
|
||||
import type { ArchiveMode, HoverAction } from '@/stores/settings-store';
|
||||
import { ALL_HOVER_ACTIONS } from '@/stores/settings-store';
|
||||
import { useAuthStore } from '@/stores/auth-store';
|
||||
import { useEmailStore } from '@/stores/email-store';
|
||||
|
||||
@@ -18,7 +18,7 @@ export function SmimeCertificateModal({
|
||||
isOpen,
|
||||
onClose,
|
||||
record,
|
||||
type,
|
||||
type: _type,
|
||||
}: SmimeCertificateModalProps) {
|
||||
const t = useTranslations("smime");
|
||||
const id = useId();
|
||||
|
||||
Reference in New Issue
Block a user