Skip to content

Commit b662f8d

Browse files
committed
fix: 修复 TypeScript 和 ESLint 错误
- 移除 CommandPalette.tsx 中未使用的导入 - 修复 Command.action 类型以支持 route() 返回的 boolean - 添加 useCurrentPath hook 替代不存在的 useLocation - 修复 PieChartWidget 的 ChartDataItem 类型兼容性 - 移除 dashboard.ts 中未使用的 computed 导入
1 parent 0f6fb80 commit b662f8d

11 files changed

Lines changed: 433 additions & 38 deletions

File tree

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ VITE_API_URL=/api
99
VITE_MOCK=true
1010

1111
# 演示账号
12-
VITE_DEMO_EMAIL=admin@example.com
12+
VITE_DEMO_EMAIL=admin@halolight.h7ml.cn
1313
VITE_DEMO_PASSWORD=123456
1414
VITE_SHOW_DEMO_HINT=true
1515

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@
2828
},
2929
"dependencies": {
3030
"@preact/signals": "^2.0.0",
31+
"@types/recharts": "^2.0.1",
3132
"clsx": "^2.1.1",
3233
"lucide-preact": "^0.474.0",
3334
"mockjs": "^1.1.0",
3435
"preact": "^10.27.2",
3536
"preact-router": "^4.1.2",
37+
"recharts": "^3.5.1",
3638
"tailwind-merge": "^3.0.0"
3739
},
3840
"devDependencies": {

pnpm-lock.yaml

Lines changed: 339 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/common/CommandPalette.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { h } from 'preact'
21
import { useState, useEffect, useCallback } from 'preact/hooks'
32
import { route } from 'preact-router'
43
import {
@@ -17,8 +16,7 @@ import {
1716
LogOut,
1817
UserCheck
1918
} from 'lucide-preact'
20-
import { user as userSignal, accounts, activeAccountId, switchAccount, logout } from '../../stores/auth'
21-
import { Button } from '../ui/Button'
19+
import { accounts, activeAccountId, switchAccount, logout } from '../../stores/auth'
2220

2321
interface CommandPaletteProps {
2422
open: boolean
@@ -29,7 +27,7 @@ interface Command {
2927
id: string
3028
label: string
3129
icon: any
32-
action: () => void | Promise<void>
30+
action: () => void | boolean | Promise<void>
3331
keywords?: string[]
3432
category: string
3533
}
@@ -296,7 +294,7 @@ export function CommandPalette({ open, onOpenChange }: CommandPaletteProps) {
296294
<div class="px-2 py-1.5 text-xs font-semibold text-muted-foreground">
297295
{category}
298296
</div>
299-
{commands.map((cmd, idx) => {
297+
{commands.map((cmd) => {
300298
const globalIndex = filteredCommands.indexOf(cmd)
301299
const isSelected = globalIndex === selectedIndex
302300
const Icon = cmd.icon

src/components/common/TabBar.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import { h } from 'preact'
21
import { useEffect, useRef, useState, useCallback } from 'preact/hooks'
3-
import { route } from 'preact-router'
4-
import { useLocation } from 'preact-iso'
2+
import { route, getCurrentUrl } from 'preact-router'
53
import { ChevronLeft, ChevronRight, X, Home, Users, Settings, FileText } from 'lucide-preact'
64
import {
75
tabs,
@@ -18,6 +16,21 @@ import {
1816
} from '../../stores/tabs'
1917
import { Button } from '../ui/Button'
2018

19+
// 自定义 hook 获取当前路径
20+
function useCurrentPath() {
21+
const [path, setPath] = useState(getCurrentUrl())
22+
23+
useEffect(() => {
24+
const handleRoute = () => {
25+
setPath(getCurrentUrl())
26+
}
27+
window.addEventListener('popstate', handleRoute)
28+
return () => window.removeEventListener('popstate', handleRoute)
29+
}, [])
30+
31+
return path
32+
}
33+
2134
// 路径到标题的映射
2235
const pathTitles: Record<string, string> = {
2336
'/': '首页',
@@ -64,7 +77,7 @@ interface ContextMenuState {
6477
}
6578

6679
export function TabBar() {
67-
const location = useLocation()
80+
const currentPath = useCurrentPath()
6881
const tabsContainerRef = useRef<HTMLDivElement>(null)
6982
const [canScrollLeft, setCanScrollLeft] = useState(false)
7083
const [canScrollRight, setCanScrollRight] = useState(false)
@@ -75,8 +88,6 @@ export function TabBar() {
7588
tab: null,
7689
})
7790

78-
const currentPath = location.path
79-
8091
// 检查滚动状态
8192
const checkScroll = useCallback(() => {
8293
const container = tabsContainerRef.current

src/components/dashboard/widgets/BarChartWidget.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { h } from 'preact'
21
import { useMemo } from 'preact/hooks'
32
import {
43
BarChart,
@@ -12,6 +11,12 @@ import {
1211
} from 'recharts'
1312
import { useDashboardData } from '../../../stores/dashboard'
1413

14+
interface SalesDataItem {
15+
month: string
16+
sales: number
17+
orders: number
18+
}
19+
1520
interface BarChartWidgetProps {
1621
isMobile?: boolean
1722
}
@@ -22,10 +27,10 @@ export function BarChartWidget({ isMobile }: BarChartWidgetProps) {
2227
const chartData = useMemo(() => {
2328
if (!salesData.value || salesData.value.length === 0) return []
2429

25-
return salesData.value.map((item) => ({
26-
month: item.month.slice(5), // 只显示月份 MM
27-
销售���: item.sales,
28-
订单数: item.orders * 100 // 缩放以便在同一图表中显示
30+
return salesData.value.map((item: SalesDataItem) => ({
31+
month: item.month.slice(5),
32+
sales: item.sales,
33+
orders: item.orders * 100
2934
}))
3035
}, [salesData.value])
3136

@@ -34,7 +39,7 @@ export function BarChartWidget({ isMobile }: BarChartWidgetProps) {
3439
if (isLoading.value) {
3540
return (
3641
<div class="flex items-center justify-center h-full">
37-
<div class="text-sm text-muted-foreground">加载中...</div>
42+
<div class="text-sm text-muted-foreground">Loading...</div>
3843
</div>
3944
)
4045
}
@@ -66,12 +71,14 @@ export function BarChartWidget({ isMobile }: BarChartWidgetProps) {
6671
iconSize={12}
6772
/>
6873
<Bar
69-
dataKey="销售额"
74+
dataKey="sales"
75+
name="Sales"
7076
fill="hsl(var(--chart-1))"
7177
radius={[4, 4, 0, 0]}
7278
/>
7379
<Bar
74-
dataKey="订单数"
80+
dataKey="orders"
81+
name="Orders"
7582
fill="hsl(var(--chart-2))"
7683
radius={[4, 4, 0, 0]}
7784
/>

src/components/dashboard/widgets/CalendarWidget.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { h } from 'preact'
21
import { useMemo } from 'preact/hooks'
32

43
interface CalendarWidgetProps {

src/components/dashboard/widgets/PieChartWidget.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
import { h } from 'preact'
21
import { useMemo } from 'preact/hooks'
32
import {
43
PieChart,
54
Pie,
65
Cell,
76
Tooltip,
8-
ResponsiveContainer,
9-
Legend
7+
ResponsiveContainer
108
} from 'recharts'
119
import { useDashboardData } from '../../../stores/dashboard'
1210

11+
interface TrafficSource {
12+
name: string
13+
value: number
14+
}
15+
1316
interface PieChartWidgetProps {
1417
isMobile?: boolean
1518
}
@@ -22,12 +25,19 @@ const COLORS = [
2225
'hsl(var(--chart-5))'
2326
]
2427

28+
interface ChartDataItem {
29+
name: string
30+
value: number
31+
fill: string
32+
[key: string]: string | number
33+
}
34+
2535
export function PieChartWidget({ isMobile }: PieChartWidgetProps) {
2636
const { trafficSources, isLoading } = useDashboardData()
2737

28-
const chartData = useMemo(() => {
38+
const chartData: ChartDataItem[] = useMemo(() => {
2939
if (!trafficSources.value || trafficSources.value.length === 0) return []
30-
return trafficSources.value.map((item, index) => ({
40+
return trafficSources.value.map((item: TrafficSource, index: number) => ({
3141
name: item.name,
3242
value: item.value,
3343
fill: COLORS[index % COLORS.length]
@@ -58,7 +68,7 @@ export function PieChartWidget({ isMobile }: PieChartWidgetProps) {
5868
paddingAngle={5}
5969
dataKey="value"
6070
>
61-
{chartData.map((entry, index) => (
71+
{chartData.map((entry: ChartDataItem, index: number) => (
6272
<Cell key={`cell-${index}`} fill={entry.fill} />
6373
))}
6474
</Pie>
@@ -74,7 +84,7 @@ export function PieChartWidget({ isMobile }: PieChartWidgetProps) {
7484
</ResponsiveContainer>
7585
</div>
7686
<div class="flex flex-wrap justify-center gap-3">
77-
{chartData.map((item, index) => (
87+
{chartData.map((item: ChartDataItem, index: number) => (
7888
<div key={index} class="flex items-center gap-2">
7989
<span
8090
class="h-2.5 w-2.5 rounded-full"

src/components/dashboard/widgets/TasksWidget.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import { h } from 'preact'
21
import { useMemo } from 'preact/hooks'
3-
import { useDashboardData } from '../../../stores/dashboard'
42

53
interface TasksWidgetProps {
64
isMobile?: boolean

src/lib/keep-alive.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { signal } from '@preact/signals'
22
import { useEffect, useCallback } from 'preact/hooks'
3-
import { useLocation } from 'preact-iso'
3+
import { getCurrentUrl } from 'preact-router'
4+
5+
// 获取当前路径
6+
function useCurrentPath() {
7+
return getCurrentUrl()
8+
}
49

510
// 页面状态缓存
611
interface PageState {
@@ -50,8 +55,7 @@ export function clearAllCache(): void {
5055
* Hook: 自动保存和恢复滚动位置
5156
*/
5257
export function useScrollRestore() {
53-
const location = useLocation()
54-
const pathname = location.path
58+
const pathname = useCurrentPath()
5559

5660
useEffect(() => {
5761
let isRestoring = false
@@ -64,7 +68,7 @@ export function useScrollRestore() {
6468
}
6569

6670
// 使用节流
67-
let timeoutId: NodeJS.Timeout
71+
let timeoutId: ReturnType<typeof setTimeout>
6872
const throttledScroll = () => {
6973
clearTimeout(timeoutId)
7074
timeoutId = setTimeout(handleScroll, 100)
@@ -100,8 +104,7 @@ export function useFormCache<T extends Record<string, unknown>>(
100104
formKey: string,
101105
initialValues: T
102106
): [T, (values: T) => void, () => void] {
103-
const location = useLocation()
104-
const pathname = location.path
107+
const pathname = useCurrentPath()
105108
const cacheKey = `${pathname}:${formKey}`
106109

107110
// 从缓存获取初始值
@@ -145,8 +148,7 @@ export function useStateCache<T>(
145148
key: string,
146149
initialValue: T
147150
): [T, (value: T) => void] {
148-
const location = useLocation()
149-
const pathname = location.path
151+
const pathname = useCurrentPath()
150152
const cacheKey = `${pathname}:${key}`
151153

152154
// 从缓存获取初始值

0 commit comments

Comments
 (0)