glam-web/src/pages/ModelPage/index.tsx

114 lines
4.4 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogTitle } from '@/components/ui/dialog';
import type { Body_create_model_api_models_create_post } from '@/api/models/Body_create_model_api_models_create_post';
import type { Body_update_model_api_models__model_id__put } from '@/api/models/Body_update_model_api_models__model_id__put';
import ModelForm from './components/ModelForm';
import { api } from '@/lib/api';
import { ConfirmDialog } from '@/components/block/confirm-dialog';
interface ModelItem {
id: number;
tag: Record<string, string>;
cover_url: string;
status: number;
create_time: string;
}
const ModelPage: React.FC = () => {
const [models, setModels] = useState<ModelItem[]>([]);
const [_, setLoading] = useState(false);
const [selected, setSelected] = useState<ModelItem | null>(null);
const [open, setOpen] = useState(false);
const [editMode, setEditMode] = useState(false);
const fetchModels = async () => {
setLoading(true);
try {
const res = await api.Service.getModelsListApiModelsListGet({});
setModels(res.data || []);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchModels();
}, []);
const handleAdd = () => {
setEditMode(false);
setSelected(null);
setOpen(true);
};
const handleEdit = (item: ModelItem) => {
setEditMode(true);
setSelected(item);
setOpen(true);
};
const handleDelete = async (id: number) => {
ConfirmDialog.confirm({
content: '确定要删除该模特吗?',
onConfirm: async () => {
await api.Service.deleteModelApiModelsModelIdDelete({ modelId: id });
fetchModels();
},
});
};
const handleFormSubmit = async (data: Body_create_model_api_models_create_post | Body_update_model_api_models__model_id__put, id?: number) => {
console.log(data);
if (editMode && id) {
await api.Service.updateModelApiModelsModelIdPut({ modelId: id, formData: data as Body_update_model_api_models__model_id__put });
} else {
await api.Service.createModelApiModelsCreatePost({ formData: data as Body_create_model_api_models_create_post });
}
setOpen(false);
fetchModels();
};
return (
<div className='p-6'>
<div className='flex justify-between items-center mb-4'>
<h1 className='text-2xl font-bold'></h1>
<Button onClick={handleAdd}></Button>
</div>
<div className='grid gap-6 grid-cols-[repeat(auto-fit,minmax(500px,500px))]'>
{models.map(item => (
<div key={item.id} className='w-[500px] bg-white dark:bg-zinc-900 rounded-lg shadow p-4 flex gap-3'>
<img src={item.cover_url} alt='cover' className='w-[200px] object-cover rounded aspect-[9/16]' />
<div className='flex-1 flex flex-col gap-2'>
<div className='flex-1 flex flex-col gap-1'>
<div className='text-sm text-muted-foreground'>ID: {item.id}</div>
<div className='text-sm truncate'>: {Object.values(item.tag).join('_')}</div>
<div className='text-sm'>
: <span className={item.status === 1 ? 'text-green-600' : 'text-red-500'}>{item.status === 1 ? '启用' : '禁用'}</span>
</div>
<div className='text-xs text-muted-foreground'>: {item.create_time}</div>
</div>
<div className='mt-4 flex flex-col gap-2'>
<Button variant='outline' onClick={() => handleEdit(item)} className='flex-1'>
</Button>
<Button variant='destructive' onClick={() => handleDelete(item.id)} className='flex-1' disabled={item.status === 1}>
</Button>
</div>
</div>
</div>
))}
</div>
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent style={{ width: '650px', maxWidth: '650px' }}>
<DialogTitle>{editMode ? '编辑模特' : '新建模特'}</DialogTitle>
<ModelForm initialData={selected} onSubmit={handleFormSubmit} onCancel={() => setOpen(false)} editMode={editMode} />
</DialogContent>
</Dialog>
</div>
);
};
export default ModelPage;