feat(home): 添加市场数据概览
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
import { AlertTriangle, Database, RefreshCw } from "lucide-react"
|
||||
import { useState } from "react"
|
||||
|
||||
import { useHomeOverview } from "@/features/home/api/home.query"
|
||||
import { Button } from "@/shared/ui/button"
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/shared/ui/card"
|
||||
import { Skeleton } from "@/shared/ui/skeleton"
|
||||
|
||||
import { FailedStocksDialog } from "../components/failed-stocks-dialog"
|
||||
import { HomeShell } from "../components/home-shell"
|
||||
import { MarketDataOverviewCard } from "../components/market-data-overview-card"
|
||||
|
||||
export function HomePage() {
|
||||
const overview = useHomeOverview()
|
||||
const [failureDialogOpen, setFailureDialogOpen] = useState(false)
|
||||
const update = overview.data?.latest_update
|
||||
|
||||
return (
|
||||
<HomeShell>
|
||||
<div className="space-y-8">
|
||||
<section className="space-y-2">
|
||||
<p className="text-sm font-medium text-primary">欢迎回到知行量化</p>
|
||||
<h1 className="text-3xl font-semibold tracking-tight">首页</h1>
|
||||
<p className="max-w-2xl text-muted-foreground">
|
||||
从当前目标股票池和市场数据同步状态开始,快速判断研究数据是否准备就绪。
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{overview.isPending ? <OverviewLoading /> : null}
|
||||
|
||||
{overview.isError ? (
|
||||
<OverviewError onRetry={() => void overview.refetch()} />
|
||||
) : null}
|
||||
|
||||
{!overview.isPending &&
|
||||
!overview.isError &&
|
||||
overview.data?.status === "no_data" ? (
|
||||
<NoDataState stockPoolCount={overview.data.stock_pool_count} />
|
||||
) : null}
|
||||
|
||||
{!overview.isPending && !overview.isError && update ? (
|
||||
<MarketDataOverviewCard
|
||||
onShowFailures={() => setFailureDialogOpen(true)}
|
||||
stockPoolCount={overview.data.stock_pool_count}
|
||||
update={update}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{update ? (
|
||||
<FailedStocksDialog
|
||||
failures={update.failures}
|
||||
onOpenChange={setFailureDialogOpen}
|
||||
open={failureDialogOpen}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
</HomeShell>
|
||||
)
|
||||
}
|
||||
|
||||
function OverviewLoading() {
|
||||
return (
|
||||
<Card aria-label="正在加载市场数据概览">
|
||||
<CardHeader className="gap-3">
|
||||
<Skeleton className="h-6 w-48" />
|
||||
<Skeleton className="h-4 w-72 max-w-full" />
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{Array.from({ length: 5 }, (_, index) => (
|
||||
<Skeleton key={index} className="h-16 w-full" />
|
||||
))}
|
||||
</div>
|
||||
<Skeleton className="h-24 w-full" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
function OverviewError({ onRetry }: { onRetry: () => void }) {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2 text-xl">
|
||||
<AlertTriangle
|
||||
className="size-5 text-destructive"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
市场数据暂时不可用
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
概览请求失败,可能是服务或网络暂时异常。请稍后重试。
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Button onClick={onRetry} variant="outline">
|
||||
<RefreshCw aria-hidden="true" />
|
||||
重试
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
function NoDataState({ stockPoolCount }: { stockPoolCount: number }) {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2 text-xl">
|
||||
<Database className="size-5 text-primary" aria-hidden="true" />
|
||||
暂无市场数据
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
当前还没有同步批次,完成第一次同步后这里会显示更新详情。
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
当前目标股票池:
|
||||
<span className="font-semibold text-foreground">
|
||||
{stockPoolCount}
|
||||
</span>{" "}
|
||||
只
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user