90 lines
2.7 KiB
TypeScript
90 lines
2.7 KiB
TypeScript
import { useState } from 'react';
|
|
import { Modal, Button, Input, Form, toast } from "@heroui/react";
|
|
import { api } from '../api/client';
|
|
import { useSWRConfig } from 'swr';
|
|
|
|
export function CreateResourceModal({ isOpen, onOpenChange }: { isOpen: boolean, onOpenChange: (isOpen: boolean) => void }) {
|
|
const [title, setTitle] = useState('');
|
|
const [description, setDescription] = useState('');
|
|
const [url, setUrl] = useState('');
|
|
const [category, setCategory] = useState('');
|
|
const [loading, setLoading] = useState(false);
|
|
const { mutate } = useSWRConfig();
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
setLoading(true);
|
|
try {
|
|
await api.resources.post({
|
|
title,
|
|
description,
|
|
url,
|
|
category
|
|
});
|
|
mutate('/resources');
|
|
onOpenChange(false);
|
|
setTitle('');
|
|
setDescription('');
|
|
setUrl('');
|
|
setCategory('');
|
|
} catch (err) {
|
|
console.error(err);
|
|
toast.danger('创建失败');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
|
|
<Modal.Backdrop />
|
|
<Modal.Container>
|
|
<Modal.Dialog>
|
|
<Modal.Header>
|
|
<Modal.Heading>添加新资源</Modal.Heading>
|
|
<Modal.CloseTrigger />
|
|
</Modal.Header>
|
|
<Modal.Body>
|
|
<Form validationBehavior="native" onSubmit={handleSubmit} className="flex flex-col gap-4">
|
|
<Input
|
|
isRequired
|
|
label="标题"
|
|
placeholder="资源名称"
|
|
value={title}
|
|
onValueChange={setTitle}
|
|
/>
|
|
<Input
|
|
label="描述"
|
|
placeholder="简短描述"
|
|
value={description}
|
|
onValueChange={setDescription}
|
|
/>
|
|
<Input
|
|
isRequired
|
|
label="链接"
|
|
placeholder="https://..."
|
|
value={url}
|
|
onValueChange={setUrl}
|
|
/>
|
|
<Input
|
|
label="分类"
|
|
placeholder="如: 工具, 文档"
|
|
value={category}
|
|
onValueChange={setCategory}
|
|
/>
|
|
<Button color="primary" type="submit" isLoading={loading}>
|
|
提交
|
|
</Button>
|
|
</Form>
|
|
</Modal.Body>
|
|
<Modal.Footer>
|
|
<Button color="danger" variant="ghost" onPress={() => onOpenChange(false)}>
|
|
取消
|
|
</Button>
|
|
</Modal.Footer>
|
|
</Modal.Dialog>
|
|
</Modal.Container>
|
|
</Modal>
|
|
);
|
|
}
|