'use client' import {Suspense, useCallback, useEffect, useState} from 'react' import {useStatus} from '@/lib/states' import {PageRecord} from '@/lib/api' import {Channel} from '@/lib/models' import Page from '@/components/page' import DataTable from '@/components/data-table' import {toast} from 'sonner' import {listChannels} from '@/actions/channel' import {format, isBefore} from 'date-fns' import {Form, FormField} from '@/components/ui/form' import {z} from 'zod' import {useForm} from 'react-hook-form' import {zodResolver} from '@hookform/resolvers/zod' import DatePicker from '@/components/date-picker' import {Button} from '@/components/ui/button' import {EraserIcon, SearchIcon} from 'lucide-react' import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue} from '@/components/ui/select' import {Badge} from '@/components/ui/badge' import Addr from '../_components/addr' export type ChannelsPageProps = {} export default function ChannelsPage(props: ChannelsPageProps) { // ====================== // data // ====================== const [status, setStatus] = useStatus() const [data, setData] = useState>({ page: 1, size: 10, total: 0, list: [], }) // ====================== // filter // ====================== const filterSchema = z.object({ auth_type: z.enum(['0', '1', '2']), expired_status: z.enum(['all', 'active']).default('all'), expire_after: z.date().optional(), expire_before: z.date().optional(), }) type FilterSchema = z.infer const filterForm = useForm({ resolver: zodResolver(filterSchema), defaultValues: { auth_type: '0', expired_status: 'all', expire_after: undefined, expire_before: undefined, }, }) const refresh = useCallback(async (page: number, size: number) => { try { setStatus('load') // 筛选条件 const filter = filterForm.getValues() const auth_type = filter.auth_type ? parseInt(filter.auth_type) : undefined // 请求数据 const resp = await listChannels({ page, size, ...filter, auth_type, }) if (!resp.success) { throw new Error(resp.message) } // 更新数据 setData(resp.data) setStatus('done') } catch (e) { setStatus('fail') console.error(e) toast.error('获取提取结果失败', { description: (e as Error).message, }) } }, [setStatus, filterForm]) useEffect(() => { refresh(data.page, data.size).then() }, [data.page, data.size, refresh]) const filterHandler = filterForm.handleSubmit(async (value) => { await refresh(1, data.size) }) // ====================== // render // ====================== return (
name="expired_status" label={状态}> {({field}) => ( )} name="auth_type" label={认证方式}> {({field}) => ( )}
过期时间
name="expire_after"> {({field}) => ( )} - name="expire_before"> {({field}) => ( )}
refresh(page, data.size), onSizeChange: size => refresh(1, size), }} columns={[ { header: '代理地址', cell: ({row}) => , }, { header: '认证方式', cell: ({row}) => { const channel = row.original const hasWhitelist = channel.whitelists && channel.whitelists.trim() !== '' const hasAuth = channel.username && channel.password return (
{hasWhitelist ? (
白名单
{channel.whitelists.split(',').map((ip, index) => ( {ip.trim()} ))}
) : hasAuth ? (
账号密码 {channel.username}:{channel.password}
) : ( 无认证 )}
) }, }, { header: '提取时间', cell: ({row}) => format(row.original.created_at, 'yyyy-MM-dd HH:mm'), }, { header: '过期时间', cell: ({row}) => format(row.original.expired_at, 'yyyy-MM-dd HH:mm:ss'), }, ]} />
) }