feat: optimize dashboard/search UX and simplify extension architecture

Redesign Dashboard with compact tool grid and recently used tools
Improve TopBar search UX with Cmd/Ctrl+K shortcut and better history navigation
Reorganize project structure into src/
Migrate i18n from react-i18next to chrome.i18n
Remove runtime language switch and settings page
Remove HTML/Markdown conversion tools
Clean up unused code, dead animations, redundant comments, and imports
Improve component consistency with shadcn/ui patterns
Replace hardcoded strings/colors with i18n tokens and theme tokens
Add comprehensive project documentation and coding standards
Fix CI artifact upload workflow and multiple TypeScript/test issues

Includes various refactors, UI polish, i18n cleanup, CI improvements,
and maintenance updates across the codebase.
This commit is contained in:
LingandRX
2026-05-28 22:39:25 +08:00
committed by GitHub
parent d4c29a1bf4
commit 945780def8
200 changed files with 1557 additions and 4380 deletions
@@ -0,0 +1,43 @@
import React from 'react';
import { CheckCircle, XCircle } from 'lucide-react';
import type { CleaningResult as CleaningResultType } from '@/types/storage';
import { formatCleaningResult } from '@/utils/storageCleaner';
import { useI18n } from '@/utils/chromeI18n';
import { cn } from '@/lib/utils';
interface CleaningResultProps extends React.HTMLAttributes<HTMLDivElement> {
result: CleaningResultType | null;
}
export default function CleaningResult({ result, className, ...props }: CleaningResultProps) {
const { t } = useI18n('storageCleaner');
if (!result) return null;
const isSuccess = result.success;
return (
<div className={cn('w-full', className)} {...props}>
<div
className={cn(
'flex items-start gap-3 rounded-xl py-2.5 px-3.5 border shadow-sm',
isSuccess
? 'bg-emerald-500/5 border-emerald-500/20 text-emerald-600 dark:text-emerald-400'
: 'bg-destructive/5 border-destructive/20 text-destructive',
)}
>
{isSuccess ? (
<CheckCircle className="h-4 w-4 shrink-0 mt-0.5 text-emerald-500" />
) : (
<XCircle className="h-4 w-4 shrink-0 mt-0.5 text-destructive" />
)}
<span className="text-xs sm:text-sm font-semibold leading-relaxed break-all">
{isSuccess
? formatCleaningResult(result, t)
: result.error || t('storageCleaner:partialFailure')}
</span>
</div>
</div>
);
}