import { useState } from 'react' import { Button, Form, Input, InputNumber, Modal, Popconfirm, Select, Space, Switch, Typography, message } from 'antd' import type { ColumnsType } from 'antd/es/table' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { useTranslation } from 'react-i18next' import DataTable from '../../components/DataTable' import apiClient, { isEnvelope } from '../../api/client' interface Backend { id: number name: string scheme: string address: string port: number health_check_path?: string | null active: boolean created_at: string updated_at: string } interface BackendFormValues { name: string scheme: 'http' | 'https' address: string port: number health_check_path?: string active: boolean } async function listBackends(): Promise { const r = await apiClient.get('/backends') if (!isEnvelope(r.data)) return [] const payload = r.data.data as { backends?: Backend[] } return payload.backends ?? [] } export default function BackendsPage() { const { t } = useTranslation() const qc = useQueryClient() const { data, isLoading } = useQuery({ queryKey: ['backends'], queryFn: listBackends }) const [editing, setEditing] = useState(null) const [creating, setCreating] = useState(false) const [form] = Form.useForm() const create = useMutation({ mutationFn: async (v: BackendFormValues) => { await apiClient.post('/backends', v) }, onSuccess: () => { message.success(t('common.save')) setCreating(false) form.resetFields() void qc.invalidateQueries({ queryKey: ['backends'] }) }, }) const update = useMutation({ mutationFn: async ({ id, v }: { id: number; v: BackendFormValues }) => { await apiClient.put(`/backends/${id}`, v) }, onSuccess: () => { message.success(t('common.save')) setEditing(null) form.resetFields() void qc.invalidateQueries({ queryKey: ['backends'] }) }, }) const del = useMutation({ mutationFn: async (id: number) => { await apiClient.delete(`/backends/${id}`) }, onSuccess: () => { void qc.invalidateQueries({ queryKey: ['backends'] }) }, }) const columns: ColumnsType = [ { title: t('backends.name'), dataIndex: 'name', key: 'name' }, { title: t('backends.scheme'), dataIndex: 'scheme', key: 'scheme' }, { title: t('backends.target'), key: 'target', render: (_, row) => `${row.address}:${row.port}`, }, { title: t('backends.healthCheck'), dataIndex: 'health_check_path', key: 'hc', render: (v?: string) => v ?? '—' }, { title: t('backends.active'), dataIndex: 'active', key: 'active', render: (v: boolean) => v ? t('common.yes') : t('common.no') }, { title: t('backends.actions'), key: 'actions', render: (_, row) => ( del.mutate(row.id)} > ), }, ] return (
{t('backends.title')} { setEditing(null); setCreating(false) }} onOk={() => { void form.submit() }} confirmLoading={create.isPending || update.isPending} >
{ if (editing) update.mutate({ id: editing.id, v }) else create.mutate(v) }} >
) }