Files
hfb_jysh/frontend/src/features/crash/CrashListPage.tsx
T

110 lines
4.1 KiB
TypeScript

import { useState } from 'react'
import { Alert, Button, Card, Empty, Image, Pagination, Segmented, Space, Tag, Typography } from 'antd'
import { Link, useNavigate } from 'react-router-dom'
import { useCrashCategories, useCrashProducts } from '@/features/crash/api'
import { useSessionStore } from '@/stores/session'
import { formatMoney } from '@/shared/utils/format'
export function CrashListPage() {
const navigate = useNavigate()
const user = useSessionStore(state => state.user)
const [categoryId, setCategoryId] = useState<number | undefined>()
const [page, setPage] = useState(1)
const categoriesQuery = useCrashCategories()
const productsQuery = useCrashProducts({ category_id: categoryId, page, page_size: 12 })
const items = productsQuery.data?.items ?? []
return (
<div className="wallet-page">
<section className="wallet-hero wallet-hero--compact">
<div>
<Typography.Text className="wallet-eyebrow">JIEYOU · 撞车商城</Typography.Text>
<Typography.Title level={1} className="brand-title wallet-title">
摸红商城
</Typography.Title>
<Typography.Paragraph className="wallet-desc">
明码标价、下单即锁库存;支付后由客服接单处理,订单可在「我的撞车订单」查看。
</Typography.Paragraph>
</div>
<div className="wallet-hero__action">
<span>共</span>
<strong>{productsQuery.data?.total ?? 0}</strong>
<Space size={8} wrap>
<Button onClick={() => navigate('/crash/orders')}>我的撞车订单</Button>
</Space>
</div>
</section>
<Segmented
value={categoryId ?? 0}
options={[
{ value: 0, label: '全部' },
...(categoriesQuery.data ?? []).map(item => ({ value: item.id, label: item.name })),
]}
onChange={value => {
setCategoryId(Number(value) || undefined)
setPage(1)
}}
/>
{productsQuery.isError ? <Alert type="error" showIcon message="商品加载失败" /> : null}
{items.length === 0 && !productsQuery.isPending ? (
<Card>
<Empty description="暂无商品" />
</Card>
) : (
<div
style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, minmax(220px, 1fr))',
gap: 14,
}}
>
{items.map(item => (
<Card key={item.id} styles={{ body: { padding: 12 } }}>
<Link to={`/crash/${item.id}`}>
{item.cover_url ? (
<Image src={item.cover_url} alt={item.title} height={140} width="100%" style={{ objectFit: 'cover', borderRadius: 8 }} preview={false} />
) : null}
<div className="admin-stack" style={{ marginTop: 10 }}>
<strong>{item.title}</strong>
<Space size={6} wrap>
<Typography.Text strong>{formatMoney(item.price_cent)}</Typography.Text>
{item.original_price_cent > 0 ? (
<Typography.Text delete type="secondary">
{formatMoney(item.original_price_cent)}
</Typography.Text>
) : null}
<Tag bordered={false}>{item.category_name || '未分类'}</Tag>
<Tag bordered={false} color={item.stock < 0 ? 'green' : item.stock > 0 ? 'blue' : 'default'}>
{item.stock < 0 ? '不限量' : `库存 ${item.stock}`}
</Tag>
</Space>
</div>
</Link>
</Card>
))}
</div>
)}
{(productsQuery.data?.total ?? 0) > 12 ? (
<Pagination
current={page}
pageSize={12}
total={productsQuery.data?.total ?? 0}
showSizeChanger={false}
onChange={next => setPage(next)}
style={{ textAlign: 'center' }}
/>
) : null}
{!user ? (
<Typography.Text type="secondary">登录后可下单;下单需要完成实名认证。</Typography.Text>
) : null}
</div>
)
}