Add audience categorization for shows: implement ShowAudience type, update related API endpoints, and enhance frontend components for audience selection and display. Modify data structures to support audience information in show creation and retrieval processes.
build / backend (push) Successful in 3m35s
build / frontend (push) Successful in 52s
tests / backend-tests (push) Successful in 3m27s

This commit is contained in:
Leonid Pershin
2026-07-26 02:06:08 +03:00
parent 525fd2ee01
commit 8962840654
19 changed files with 1900 additions and 8 deletions
@@ -3,7 +3,7 @@ import { Link } from '@tanstack/react-router'
import { useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { HttpError } from '@/shared/api/client'
import type { ShowKind } from '@/shared/api/types'
import type { ShowAudience, ShowKind } from '@/shared/api/types'
import { Badge } from '@/shared/ui/badge'
import { Button } from '@/shared/ui/button'
import { Input } from '@/shared/ui/input'
@@ -21,6 +21,7 @@ export function ShowsPanel() {
const [name, setName] = useState('')
const [originalName, setOriginalName] = useState('')
const [kind, setKind] = useState<ShowKind>('Series')
const [audience, setAudience] = useState<ShowAudience>('General')
const [query, setQuery] = useState('')
const [page, setPage] = useState(1)
const { sort, toggle } = useTableSort('name', false)
@@ -44,6 +45,7 @@ export function ShowsPanel() {
return sortRows(matched, sort, {
name: (s) => s.name.toLowerCase(),
kind: (s) => s.kind,
audience: (s) => s.audience,
seasons: (s) => s.seasonCount,
episodes: (s) => s.episodeCount,
})
@@ -56,7 +58,12 @@ export function ShowsPanel() {
const createMutation = useMutation({
mutationFn: () =>
createShow({ name: name.trim(), kind, originalName: originalName.trim() || undefined }),
createShow({
name: name.trim(),
kind,
originalName: originalName.trim() || undefined,
audience,
}),
onSuccess: () => {
setName('')
setOriginalName('')
@@ -92,6 +99,16 @@ export function ShowsPanel() {
<SelectItem value="Single">{t('admin.shows.kinds.Single')}</SelectItem>
</SelectContent>
</Select>
<Select value={audience} onValueChange={(v) => setAudience(v as ShowAudience)}>
<SelectTrigger className="w-40">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="General">{t('admin.shows.audiences.General')}</SelectItem>
<SelectItem value="Kids">{t('admin.shows.audiences.Kids')}</SelectItem>
<SelectItem value="Adult">{t('admin.shows.audiences.Adult')}</SelectItem>
</SelectContent>
</Select>
<Button
size="sm"
disabled={!name.trim() || createMutation.isPending}
@@ -127,6 +144,12 @@ export function ShowsPanel() {
sort={sort}
onToggle={sortColumn}
/>
<SortHeader
label={t('admin.shows.audience')}
sortKey="audience"
sort={sort}
onToggle={sortColumn}
/>
<SortHeader
label={t('admin.shows.seasons')}
sortKey="seasons"
@@ -145,7 +168,7 @@ export function ShowsPanel() {
<tbody>
{isLoading && (
<tr>
<td className="px-4 py-3 text-muted-foreground" colSpan={5}>
<td className="px-4 py-3 text-muted-foreground" colSpan={6}>
{t('common.loading')}
</td>
</tr>
@@ -164,6 +187,9 @@ export function ShowsPanel() {
<td className="px-4 py-2">
<Badge variant="muted">{t(`admin.shows.kinds.${show.kind}`)}</Badge>
</td>
<td className="px-4 py-2">
<Badge variant="muted">{t(`admin.shows.audiences.${show.audience}`)}</Badge>
</td>
<td className="px-4 py-2 text-muted-foreground">{show.seasonCount}</td>
<td className="px-4 py-2 text-muted-foreground">{show.episodeCount}</td>
<td className="px-4 py-2">