- {/* 最近使用 */}
{showRecent && (
@@ -30,12 +13,12 @@ export default function Index() {
{recentFeatures.map(({ key, feature }) => {
- const IconComponent = feature!.icon!;
+ const IconComponent = feature.icon;
return (
);
})}
@@ -52,40 +35,45 @@ export default function Index() {
)}
- {/* 全部工具 — 紧凑 Grid */}
{'全部工具'}
-
- {visibleFeatures.map(({ key, feature }) => {
- const IconComponent = feature!.icon!;
- return (
-
+ );
+ })}
+
+ )}
);
diff --git a/src/pages/Dashboard/useDashboard.ts b/src/pages/Dashboard/useDashboard.ts
new file mode 100644
index 0000000..1fdc0d0
--- /dev/null
+++ b/src/pages/Dashboard/useDashboard.ts
@@ -0,0 +1,31 @@
+import { useMemo } from 'react';
+import { useRouter } from '@/providers/RouterProvider';
+import type { PageType } from '@/types/storage';
+import { resolveDashboardFeatures, type DashboardFeatureItem } from './dashboardFeatures';
+
+export type { DashboardFeatureItem } from './dashboardFeatures';
+
+export interface UseDashboardReturn {
+ visibleFeatures: DashboardFeatureItem[];
+ recentFeatures: DashboardFeatureItem[];
+ showRecent: boolean;
+ navigateTo: (page: PageType) => void;
+}
+
+export function useDashboard(): UseDashboardReturn {
+ const { navigateTo, visiblePages, pageOrder, recentlyUsedTools } = useRouter();
+
+ const visibleFeatures = useMemo(
+ () => resolveDashboardFeatures(pageOrder, visiblePages),
+ [pageOrder, visiblePages],
+ );
+
+ const recentFeatures = useMemo(
+ () => resolveDashboardFeatures(recentlyUsedTools, visiblePages),
+ [recentlyUsedTools, visiblePages],
+ );
+
+ const showRecent = recentFeatures.length > 0;
+
+ return { visibleFeatures, recentFeatures, showRecent, navigateTo };
+}
diff --git a/src/pages/QrCode/index.tsx b/src/pages/QrCode/index.tsx
index adb1dde..39ef556 100644
--- a/src/pages/QrCode/index.tsx
+++ b/src/pages/QrCode/index.tsx
@@ -9,7 +9,6 @@ import type { QrCodeMode } from './types';
export default function Index() {
const qrCode = useQrCode();
- // 模式选项驱动骨架
const modeOptions = [
{ value: 'generate' as QrCodeMode, label: '文本转二维码' },
{ value: 'parse' as QrCodeMode, label: '二维码转文本' },
diff --git a/src/pages/README.md b/src/pages/README.md
index c3a15a2..1125899 100644
--- a/src/pages/README.md
+++ b/src/pages/README.md
@@ -22,10 +22,9 @@ pages/FeatureName/
仪表盘首页,以卡片网格展示所有可见工具,支持点击导航。
-| 文件 | 用途 |
-| -------------- | -------------------------------------------- |
-| `index.tsx` | 页面组件,渲染工具卡片网格 |
-| `ToolCard.tsx` | 工具卡片组件,展示图标、标题、描述和实时数据 |
+| 文件 | 用途 |
+| ----------- | -------------------------- |
+| `index.tsx` | 页面组件,渲染工具卡片网格 |
### Timestamp/
diff --git a/src/utils/__tests__/base64Converter.test.ts b/src/utils/__tests__/base64Converter.test.ts
index 95ff976..2d8c8a4 100644
--- a/src/utils/__tests__/base64Converter.test.ts
+++ b/src/utils/__tests__/base64Converter.test.ts
@@ -316,7 +316,7 @@ describe('base64ToBlob', () => {
});
it('应该对非法 Base64 抛出 Invalid Base64 string', () => {
- expect(() => base64ToBlob('这不是 base64!')).toThrow('Invalid Base64 string');
+ expect(() => base64ToBlob('这不是 base64!')).toThrow('无效的 Base64 字符串');
});
it('应该返回原始 Base64(已去除 data URI 前缀)', () => {
diff --git a/src/utils/__tests__/jsonToToml.test.ts b/src/utils/__tests__/jsonToToml.test.ts
index c4bff22..9b82c85 100644
--- a/src/utils/__tests__/jsonToToml.test.ts
+++ b/src/utils/__tests__/jsonToToml.test.ts
@@ -76,14 +76,6 @@ describe('jsonToToml', () => {
expect(() => jsonToToml('{invalid}')).toThrow(SyntaxError);
});
- it('should throw Error for non-object top-level value', () => {
- expect(() => jsonToToml('"hello"')).toThrow(
- 'TOML requires the top-level value to be an object',
- );
- expect(() => jsonToToml('[1,2]')).toThrow('TOML requires the top-level value to be an object');
- expect(() => jsonToToml('null')).toThrow('TOML requires the top-level value to be an object');
- });
-
it('should escape special characters in strings', () => {
const result = jsonToToml('{"path":"C:\\\\Users\\\\test"}');
expect(result.output).toContain('"C:\\\\Users\\\\test"');
diff --git a/src/utils/__tests__/jsonToYaml.test.ts b/src/utils/__tests__/jsonToYaml.test.ts
index 7090424..c06351e 100644
--- a/src/utils/__tests__/jsonToYaml.test.ts
+++ b/src/utils/__tests__/jsonToYaml.test.ts
@@ -86,11 +86,6 @@ describe('jsonToYaml', () => {
expect(() => jsonToYaml('{invalid}')).toThrow(SyntaxError);
});
- it('should handle keys with special characters', () => {
- const result = jsonToYaml('{"key with spaces":"value"}');
- expect(result.output).toContain('"key with spaces"');
- });
-
it('should handle nested arrays in objects', () => {
const result = jsonToYaml('{"items":[1,2,3]}');
expect(result.output).toContain('items:');
diff --git a/src/utils/__tests__/qrCodeParser.test.ts b/src/utils/__tests__/qrCodeParser.test.ts
index 65573f7..8d9782d 100644
--- a/src/utils/__tests__/qrCodeParser.test.ts
+++ b/src/utils/__tests__/qrCodeParser.test.ts
@@ -2,7 +2,6 @@ import { describe, expect, it, vi } from 'vitest';
import { parseQrCodeFromFile } from '@/utils/qrCodeParser';
import QrScanner from 'qr-scanner';
-// Mock qr-scanner
vi.mock('qr-scanner', () => ({
default: {
scanImage: vi.fn(),
diff --git a/src/utils/qrCodeParser.ts b/src/utils/qrCodeParser.ts
index 63ef41c..7cfd5b3 100644
--- a/src/utils/qrCodeParser.ts
+++ b/src/utils/qrCodeParser.ts
@@ -8,7 +8,6 @@ interface QrCodeParseResult {
/**
* 从文件中解析二维码
- * 使用 qr-scanner 替代 jsqr 以减小体积并提高性能
*/
export async function parseQrCodeFromFile(file: File): Promise
{
try {