Files
TeleWave/frontend/src/features/admin/shows/CreateShowDialog.tsx
T
Leonid Pershin 281d081e6b
ci / build-backend (push) Successful in 2m23s
ci / build-frontend (push) Successful in 54s
ci / tests (push) Successful in 2m18s
ci / sonar (push) Successful in 5m51s
Refactor admin panels to utilize CreateNameDialog for creating new entities
Updated the BumpersPanel, ChannelsPanel, CollectionsPanel, GroupsPanel, ClipGroupPanel, and ShowsPanel components to replace direct input fields with a CreateNameDialog for creating new items. This change enhances user experience by centralizing the creation process and improving UI consistency. Localization strings were also updated to reflect new dialog titles and labels in both English and Russian.
2026-07-29 23:26:32 +03:00

124 lines
4.5 KiB
TypeScript

import { useMutation } from '@tanstack/react-query'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import {
AUDIENCE_UNSET,
SHOW_AUDIENCES,
type ShowAudience,
type ShowKind,
} from '@/shared/api/types'
import { useApiError } from '@/shared/lib/use-api-error'
import { Button } from '@/shared/ui/button'
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/shared/ui/dialog'
import { Input } from '@/shared/ui/input'
import { Label } from '@/shared/ui/label'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/shared/ui/select'
import { createShow } from './api'
/**
* Заведение шоу. Отдельным окном, а не строкой над таблицей: поля создания стояли вплотную к полям
* фильтра, и в них постоянно начинали искать.
*/
export function CreateShowDialog({
onClose,
onCreated,
}: Readonly<{ onClose: () => void; onCreated: () => void }>) {
const { t } = useTranslation()
const onError = useApiError()
const [name, setName] = useState('')
const [originalName, setOriginalName] = useState('')
const [kind, setKind] = useState<ShowKind>('Series')
// Новое шоу заводится без рейтинга: проставят метаданные либо админ руками.
const [audience, setAudience] = useState<ShowAudience | null>(null)
const createMutation = useMutation({
mutationFn: () =>
createShow({
name: name.trim(),
kind,
originalName: originalName.trim() || undefined,
audience,
}),
onSuccess: () => {
onCreated()
onClose()
},
onError,
})
const submit = () => {
if (name.trim() && !createMutation.isPending) createMutation.mutate()
}
return (
<Dialog open onOpenChange={(open) => !open && onClose()}>
<DialogContent className="max-w-lg">
<DialogHeader>
<DialogTitle>{t('admin.shows.createTitle')}</DialogTitle>
</DialogHeader>
<div className="flex flex-col gap-3">
<div className="flex flex-col gap-1.5">
<Label>{t('admin.shows.name')}</Label>
<Input
autoFocus
value={name}
onChange={(e) => setName(e.target.value)}
// Enter в единственном обязательном поле — самый быстрый путь: форма короткая.
onKeyDown={(e) => e.key === 'Enter' && submit()}
/>
</div>
<div className="flex flex-col gap-1.5">
<Label>{t('admin.shows.originalName')}</Label>
<Input value={originalName} onChange={(e) => setOriginalName(e.target.value)} />
</div>
<div className="flex flex-col gap-1.5">
<Label>{t('admin.shows.kind')}</Label>
<Select value={kind} onValueChange={(v) => setKind(v as ShowKind)}>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="Series">{t('admin.shows.kinds.Series')}</SelectItem>
<SelectItem value="Single">{t('admin.shows.kinds.Single')}</SelectItem>
</SelectContent>
</Select>
</div>
<div className="flex flex-col gap-1.5">
<Label>{t('admin.shows.audience')}</Label>
<Select
value={audience ?? AUDIENCE_UNSET}
onValueChange={(v) => setAudience(v === AUDIENCE_UNSET ? null : (v as ShowAudience))}
>
<SelectTrigger className="whitespace-nowrap">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value={AUDIENCE_UNSET}>{t('admin.shows.audienceUnset')}</SelectItem>
{SHOW_AUDIENCES.map((value) => (
<SelectItem key={value} value={value}>
{t(`admin.shows.audiences.${value}`)}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
<DialogFooter>
<Button size="sm" variant="outline" onClick={onClose}>
{t('common.cancel')}
</Button>
<Button size="sm" disabled={!name.trim() || createMutation.isPending} onClick={submit}>
{t('common.create')}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}