generated from kevisual/vite-react-template
- repos 页面:标题和按钮移动端换行显示,响应式布局优化 - config 页面:移动端无边框,全屏宽度,按钮垂直堆叠 - gitea config 页面:同 config 页面优化 - BuildConfig、RepoCard、Dialog 等组件响应式优化
132 lines
3.6 KiB
TypeScript
132 lines
3.6 KiB
TypeScript
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="w-[90vw] max-w-lg sm:max-w-[525px]">
|
|
<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={2}
|
|
{...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 className="flex-col sm:flex-row gap-2 sm:gap-0">
|
|
<Button
|
|
type="button"
|
|
variant="outline"
|
|
onClick={() => onOpenChange(false)}
|
|
disabled={isSubmitting}
|
|
className="w-full sm:w-auto"
|
|
>
|
|
取消
|
|
</Button>
|
|
<Button type="submit" disabled={isSubmitting} className="w-full sm:w-auto">
|
|
{isSubmitting ? '创建中...' : '创建仓库'}
|
|
</Button>
|
|
</DialogFooter>
|
|
</form>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|