generated from kevisual/vite-react-template
update
This commit is contained in:
130
src/pages/repos/modules/CreateRepoDialog.tsx
Normal file
130
src/pages/repos/modules/CreateRepoDialog.tsx
Normal file
@@ -0,0 +1,130 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import { useRepoStore } from '../store'
|
||||
import { useShallow } from 'zustand/shallow'
|
||||
|
||||
interface CreateRepoDialogProps {
|
||||
open: boolean
|
||||
onOpenChange: (open: boolean) => void
|
||||
}
|
||||
|
||||
interface FormData {
|
||||
path: string
|
||||
license: string
|
||||
description: string
|
||||
visibility: string
|
||||
}
|
||||
|
||||
export function CreateRepoDialog({ open, onOpenChange }: CreateRepoDialogProps) {
|
||||
const { createRepo, refresh } = useRepoStore(useShallow((state) => ({
|
||||
createRepo: state.createRepo,
|
||||
refresh: state.refresh,
|
||||
})))
|
||||
const { register, handleSubmit, reset } = useForm<FormData>()
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
// 重置表单
|
||||
reset({
|
||||
path: '',
|
||||
license: '',
|
||||
description: '',
|
||||
visibility: 'public'
|
||||
})
|
||||
}
|
||||
}, [open, reset])
|
||||
|
||||
const onSubmit = async (data: FormData) => {
|
||||
setIsSubmitting(true)
|
||||
try {
|
||||
const submitData = {
|
||||
...data,
|
||||
}
|
||||
|
||||
await createRepo(submitData)
|
||||
onOpenChange(false)
|
||||
refresh()
|
||||
} finally {
|
||||
setIsSubmitting(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="sm:max-w-150">
|
||||
<DialogHeader>
|
||||
<DialogTitle>新建仓库</DialogTitle>
|
||||
<DialogDescription>
|
||||
填写仓库信息以创建新的代码仓库
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="path">仓库路径 *</Label>
|
||||
<Input
|
||||
id="path"
|
||||
placeholder="例如: username/repository"
|
||||
{...register('path', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="description">描述</Label>
|
||||
<Textarea
|
||||
id="description"
|
||||
placeholder="简短描述你的仓库..."
|
||||
rows={3}
|
||||
{...register('description')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="visibility">可见性</Label>
|
||||
<Input
|
||||
id="visibility"
|
||||
placeholder="public 或 private"
|
||||
{...register('visibility')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="topics">主题标签</Label>
|
||||
<Input
|
||||
id="license"
|
||||
placeholder="例如: MIT, Apache-2.0"
|
||||
{...register('license')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={() => onOpenChange(false)}
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
<Button type="submit" disabled={isSubmitting}>
|
||||
{isSubmitting ? '创建中...' : '创建仓库'}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user