Phase 0.2: migrate remaining SVGs to lucide-react icons

This commit is contained in:
Agent Zero
2026-07-23 03:21:05 +02:00
parent e9a5eee524
commit 4f8cda1566
41 changed files with 228 additions and 564 deletions
@@ -6,6 +6,8 @@ import { EmptyState } from '@/components/ui/EmptyState';
import { Modal } from '@/components/ui/Modal';
import { Input } from '@/components/ui/Input';
import { useToast } from '@/components/ui/Toast';
import { Loader2 } from 'lucide-react';
import {
type UnifiedContact,
type ContactPerson,
@@ -145,10 +147,7 @@ export function ContactDetail({ contact, loading, onEdit, onDeleted }: ContactDe
if (loading) {
return (
<div className="flex items-center justify-center py-12" data-testid="contact-detail-loading">
<svg className="animate-spin h-5 w-5 text-secondary-400" fill="none" viewBox="0 0 24 24" aria-hidden="true">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
</svg>
<Loader2 className="animate-spin h-5 w-5 text-secondary-400" aria-hidden="true" />
<span className="ml-2 text-sm text-secondary-500">{t('common.loading')}</span>
</div>
);
@@ -9,6 +9,7 @@ import {
useMoveContactToFolder,
} from '@/api/hooks';
import { buildFolderTree, type ContactFolderTreeNode } from '@/api/contactFolders';
import { ChevronRight, Folder, Pencil, Plus, Tag, Trash2, Users } from 'lucide-react';
export type ContactFilter = 'all' | 'company' | 'person' | `tag:${string}` | `folder:${string}`;
@@ -22,28 +23,21 @@ export interface ContactFolderTreeProps {
// Icons
const icon = (path: string, cls = 'w-4 h-4') => (
<svg className={cls} fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d={path} />
</svg>
const icon = (IconComp: React.ElementType, cls = 'w-4 h-4') => (
<IconComp className={cls} aria-hidden="true" strokeWidth={2} />
);
const chevron = (open: boolean) => (
<svg
className={clsx('w-3.5 h-3.5 transition-transform flex-shrink-0', open && 'rotate-90')}
fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
<ChevronRight className={clsx('w-3.5 h-3.5 transition-transform flex-shrink-0', open && 'rotate-90')} aria-hidden="true" strokeWidth={2} />
);
const ICONS = {
all: 'M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6-3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z',
folder: 'M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z',
tag: 'M7 7h.01M7 3h5a1.99 1.99 0 01.832.184l4 2A2 2 0 0118 7v10a2 2 0 01-2 2H7a2 2 0 01-2-2V5a2 2 0 012-2z',
edit: 'M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z',
trash: 'M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16',
plus: 'M12 4v16m8-8H4',
all: Users,
folder: Folder,
tag: Tag,
edit: Pencil,
trash: Trash2,
plus: Plus,
};
// Context Menu
@@ -6,6 +6,8 @@ import { Pagination } from '@/components/ui/Pagination';
import { EmptyState } from '@/components/ui/EmptyState';
import type { UnifiedContact } from '@/api/hooks';
import { Loader2 } from 'lucide-react';
export type ContactViewMode = 'list' | 'table' | 'cards';
export interface ContactListProps {
@@ -77,10 +79,7 @@ export function ContactList({
if (loading) {
return (
<div className="flex items-center justify-center py-12" data-testid="contact-list-loading">
<svg className="animate-spin h-5 w-5 text-secondary-400" fill="none" viewBox="0 0 24 24" aria-hidden="true">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
</svg>
<Loader2 className="animate-spin h-5 w-5 text-secondary-400" aria-hidden="true" />
<span className="ml-2 text-sm text-secondary-500">{t('common.loading')}</span>
</div>
);