mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-29 03:26:37 +08:00
89 lines
3.0 KiB
TypeScript
89 lines
3.0 KiB
TypeScript
import { FormEvent, useState } from 'react'
|
|
import toast from 'react-hot-toast'
|
|
|
|
import { playProfilesAPI, type PlayProfileInput } from '../api/play_profiles'
|
|
import type { Library, PlayProfile } from '../types'
|
|
import {
|
|
ProfileFormActions,
|
|
ProfileIdentityFields,
|
|
ProfileLibraryAccessField,
|
|
ProfilePreferenceFields,
|
|
} from './ProfileFormSections'
|
|
|
|
type ProfileFormModalProps = {
|
|
editing: PlayProfile | null
|
|
libraries: Library[]
|
|
defaultUserID: string
|
|
onClose: () => void
|
|
onSaved: () => void | Promise<void>
|
|
}
|
|
|
|
export function ProfileFormModal({
|
|
editing,
|
|
libraries,
|
|
defaultUserID,
|
|
onClose,
|
|
onSaved,
|
|
}: ProfileFormModalProps) {
|
|
const [form, setForm] = useState<PlayProfileInput>(() => ({
|
|
user_id: editing?.user_id ?? defaultUserID,
|
|
name: editing?.name ?? '',
|
|
is_default: editing?.is_default ?? false,
|
|
content_rating_limit: editing?.content_rating_limit ?? '',
|
|
allow_adult: editing?.allow_adult ?? false,
|
|
require_pin: editing?.require_pin ?? false,
|
|
pin: '',
|
|
preferred_subtitle_lang: editing?.preferred_subtitle_lang ?? '',
|
|
preferred_audio_lang: editing?.preferred_audio_lang ?? '',
|
|
autoplay_next: editing?.autoplay_next ?? true,
|
|
skip_intro: editing?.skip_intro ?? false,
|
|
allowed_library_ids: editing?.allowed_library_ids ?? [],
|
|
}))
|
|
const [saving, setSaving] = useState(false)
|
|
|
|
const update = (patch: Partial<PlayProfileInput>) => setForm((current) => ({ ...current, ...patch }))
|
|
|
|
const toggleLib = (id: string) => {
|
|
const next = form.allowed_library_ids.includes(id)
|
|
? form.allowed_library_ids.filter((item) => item !== id)
|
|
: [...form.allowed_library_ids, id]
|
|
update({ allowed_library_ids: next })
|
|
}
|
|
|
|
const onSubmit = async (event: FormEvent) => {
|
|
event.preventDefault()
|
|
setSaving(true)
|
|
try {
|
|
if (editing) {
|
|
await playProfilesAPI.update(editing.id, form)
|
|
} else {
|
|
await playProfilesAPI.create(form)
|
|
}
|
|
toast.success('已保存')
|
|
await onSaved()
|
|
} catch (err: unknown) {
|
|
const msg =
|
|
(err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? '保存失败'
|
|
toast.error(msg)
|
|
} finally {
|
|
setSaving(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4 backdrop-blur-sm">
|
|
<div className="glass-panel max-h-[calc(100dvh-2rem)] w-full max-w-lg overflow-y-auto !p-4 sm:!p-6">
|
|
<h2 className="mb-4 font-display text-xl font-semibold text-ink-600">
|
|
{editing ? '编辑 Profile' : '创建 Profile'}
|
|
</h2>
|
|
<form onSubmit={onSubmit} className="space-y-4">
|
|
<ProfileIdentityFields form={form} editing={editing} update={update} />
|
|
<ProfilePreferenceFields form={form} update={update} />
|
|
<ProfileLibraryAccessField form={form} libraries={libraries} onToggleLibrary={toggleLib} />
|
|
<ProfileFormActions saving={saving} onClose={onClose} />
|
|
</form>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|