更新样式匹配新设计方案

This commit is contained in:
2025-04-26 17:56:32 +08:00
parent f46660fafd
commit b20ec85db9
10 changed files with 66 additions and 112 deletions

View File

@@ -5,7 +5,7 @@ export type ExtractPageProps = {}
export default async function ExtractPage(props: ExtractPageProps) {
return (
<Page className={`p-0`}>
<Page>
<Extract className={`p-8`}/>
</Page>
)

View File

@@ -312,9 +312,6 @@ export default function ResourcesPage(props: ResourcesPageProps) {
),
},
]}
classNames={{
dataRow: `h-14`,
}}
/>
</Page>
)

View File

@@ -24,6 +24,7 @@ import {
import {Pagination} from '@/components/ui/pagination'
import {Checkbox} from '@/components/ui/checkbox'
import Page from '@/components/page'
import DataTable from '@/components/data-table'
const schema = z.object({
host: z.string().min(1, {message: 'IP地址不能为空'}),
@@ -72,17 +73,6 @@ export default function WhitelistPage(props: WhitelistPageProps) {
}
}
// 处理分页
const changePage = (newPage: number) => {
refresh(newPage, data.size).then()
}
// 处理每页数量变化
const changeSize = (newSize: number) => {
refresh(1, newSize).then()
}
// ======================
// 弹窗
// ======================
@@ -254,80 +244,49 @@ export default function WhitelistPage(props: WhitelistPageProps) {
</section>
{/* 数据表 */}
<div className="rounded-md border overflow-hidden">
<Table>
<TableHeader>
<TableRow>
<TableHead className={`w-12 text-center px-0`}>
<Checkbox checked={selection.size === data.list.length} onClick={() => toggleSelectAll()}/>
</TableHead>
<TableHead>IP</TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{wait && data.list.length === 0 ? (
<TableRow>
<TableCell colSpan={5} className="h-24 text-center">
<Loader2 className="w-6 h-6 animate-spin mx-auto"/>
</TableCell>
</TableRow>
) : data.list.length === 0 ? (
<TableRow>
<TableCell colSpan={5} className="h-24 text-center">
</TableCell>
</TableRow>
) : (
data.list.map(item => (
<TableRow key={item.id}>
<TableCell className={`w-12 text-center px-0`}>
<Checkbox checked={selection.has(item.id)} onClick={() => toggleSelect(item.id)}/>
</TableCell>
<TableCell className="font-medium">{item.host}</TableCell>
<TableCell>{item.createdAt}</TableCell>
<TableCell>{item.remark || '无'}</TableCell>
<TableCell className="text-right">
<div className="flex justify-end gap-2">
<Button
className={`h-9 w-9`}
theme="outline"
onClick={() => openDialog('edit', item)}
disabled={wait}
>
<Edit className="w-4 h-4"/>
</Button>
<Button
className={`h-9 w-9`}
onClick={() => confirmRemove(item.id)}
theme={`error`}
disabled={wait}
>
<Trash2 className="w-4 h-4"/>
</Button>
</div>
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</div>
{/* 分页器 */}
{data.total > 0 && (
<Pagination
page={data.page}
size={data.size}
total={data.total}
sizeOptions={[10, 20, 50, 100]}
onPageChange={changePage}
onSizeChange={changeSize}
/>
)}
<DataTable
status={status}
data={data.list}
pagination={{
total: data.total,
page: data.page,
size: data.size,
onPageChange: (page: number) => refresh(page, data.size),
onSizeChange: (size: number) => refresh(1, size),
}}
columns={[
{
accessorKey: 'host', header: `IP 地址`,
}, {
accessorKey: 'createdAt', header: `添加时间`,
}, {
accessorKey: 'remark', header: `备注`,
}, {
id: 'actions',
header: `操作`,
cell: ({row}) => (
<div className="flex justify-end gap-2">
<Button
className={`h-9 w-9`}
theme="outline"
onClick={() => openDialog('edit', row.original)}
disabled={wait}
>
<Edit className="w-4 h-4"/>
</Button>
<Button
className={`h-9 w-9`}
onClick={() => confirmRemove(row.original.id)}
theme={`error`}
disabled={wait}
>
<Trash2 className="w-4 h-4"/>
</Button>
</div>
),
},
]}
/>
{/* 编辑表单 */}
<Dialog open={dialogVisible} onOpenChange={toggleDialog}>

View File

@@ -131,10 +131,6 @@ export default function Extract(props: ExtractProps) {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
// ======================
// form 中间变量
// ======================
// ======================
// render
// ======================

View File

@@ -6,20 +6,20 @@ export default async function Purchase(props: PurchaseProps) {
return (
<div className="flex flex-col gap-4">
<ul role={`tablist`} className={`flex justify-center items-stretch bg-white rounded-lg`}>
<li role={`tab`}>
<button className={`h-14 px-8 text-lg`}></button>
</li>
<li role={`tab`}>
<button className={`h-14 px-8 text-lg`}></button>
</li>
<li role={`tab`}>
<button className={`h-14 px-8 text-lg`}></button>
</li>
<li role={`tab`}>
<button className={`h-14 px-8 text-lg`}></button>
</li>
</ul>
{/*<ul role={`tablist`} className={`flex justify-center items-stretch bg-white rounded-lg`}>*/}
{/* <li role={`tab`}>*/}
{/* <button className={`h-14 px-8 text-lg`}>短效动态套餐</button>*/}
{/* </li>*/}
{/* <li role={`tab`}>*/}
{/* <button className={`h-14 px-8 text-lg`}>长效静态套餐</button>*/}
{/* </li>*/}
{/* <li role={`tab`}>*/}
{/* <button className={`h-14 px-8 text-lg`}>固定套餐</button>*/}
{/* </li>*/}
{/* <li role={`tab`}>*/}
{/* <button className={`h-14 px-8 text-lg`}>定制套餐</button>*/}
{/* </li>*/}
{/*</ul>*/}
<PurchaseForm/>
</div>
)

View File

@@ -35,7 +35,7 @@ export default function DataTable<T extends Record<string, unknown>>(props: Data
return (<>
{/* 数据表*/}
<div className={`border rounded-md relative`}>
<div className={`border rounded-md relative bg-card`}>
<TableRoot>
<TableHeader>
{table.getHeaderGroups().map(group => (
@@ -61,7 +61,7 @@ export default function DataTable<T extends Record<string, unknown>>(props: Data
<TableCell colSpan={props.columns.length} className={`text-center`}></TableCell>
</TableRow>
) : table.getRowModel().rows.map(row => (
<TableRow key={row.id} data-state={row.getIsSelected() && 'selected'} className={merge(props.classNames?.dataRow)}>
<TableRow key={row.id} data-state={row.getIsSelected() && 'selected'} className={merge('h-14', props.classNames?.dataRow)}>
{row.getVisibleCells().map(cell => (
<TableCell key={cell.id}>
{flexRender(

View File

@@ -12,7 +12,7 @@ const buttonVariants = cva(
destructive:
"bg-fail text-fail-foreground shadow-sm hover:bg-destructive/90",
outline:
"border border-input bg-background shadow-sm hover:bg-secondary hover:text-secondary-foreground",
"border border-input shadow-sm hover:bg-secondary hover:text-secondary-foreground bg-card",
secondary:
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
ghost: "hover:bg-secondary hover:text-secondary-foreground",

View File

@@ -8,11 +8,11 @@ function Input({className, type, ...props}: React.ComponentProps<'input'>) {
type={type}
data-slot="input"
className={merge(
`transition-[color,box-shadow] duration-200 ease-in-out`,
`transition-[color] duration-200 ease-in-out`,
`h-10 min-w-0 w-full`,
'placeholder:text-muted-foreground',
'selection:bg-primary selection:text-primary-foreground',
'flex rounded-md border bg-transparent px-3 py-1 text-base shadow-xs',
'flex rounded-md border bg-card px-3 py-1 text-base',
'outline-none focus-visible:ring-4 ring-ring/50',
'disabled:cursor-not-allowed disabled:opacity-50',
'aria-invalid:ring-fail/20 aria-invalid:border-fail dark:aria-invalid:ring-fail/40 dark:bg-input/30',

View File

@@ -217,6 +217,7 @@ function PaginationLink({
data-active={isActive}
className={merge(
'inline-flex items-center justify-center text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 h-9 w-9 rounded-md border border-input hover:bg-secondary hover:text-secondary-foreground',
`bg-card`,
isActive && 'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground',
className,
)}

View File

@@ -42,6 +42,7 @@ function SelectTrigger({
'aria-invalid:border-fail dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 ',
'rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap transition-[color] ',
'outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 ',
'bg-card',
{
sm: 'h-9',
default: 'h-10',