From 27571a4ab6cbbcfc96a7067aca2dd188c7900607 Mon Sep 17 00:00:00 2001 From: Leonid Pershin Date: Sat, 25 Jul 2026 10:10:36 +0300 Subject: [PATCH] Refactor ChannelDetail component: replace Card components with CollapsibleCard for improved UI organization and user experience. Introduce CollapsibleCard functionality to manage expandable content sections. Update AirPage to enhance time display formatting for better readability. --- .../features/admin/channels/ChannelDetail.tsx | 97 ++++++++++--------- frontend/src/features/streaming/AirPage.tsx | 2 +- 2 files changed, 52 insertions(+), 47 deletions(-) diff --git a/frontend/src/features/admin/channels/ChannelDetail.tsx b/frontend/src/features/admin/channels/ChannelDetail.tsx index 82c91a3..4987efc 100644 --- a/frontend/src/features/admin/channels/ChannelDetail.tsx +++ b/frontend/src/features/admin/channels/ChannelDetail.tsx @@ -1,8 +1,8 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { Link } from '@tanstack/react-router' -import { useEffect, useState } from 'react' +import { type ReactNode, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' -import { ChevronLeft, RefreshCw } from 'lucide-react' +import { ChevronDown, ChevronLeft, RefreshCw } from 'lucide-react' import { HttpError } from '@/shared/api/client' import type { AdInsertion, @@ -16,7 +16,7 @@ import type { } from '@/shared/api/types' import { Badge } from '@/shared/ui/badge' import { Button } from '@/shared/ui/button' -import { Card, CardContent, CardHeader, CardTitle } from '@/shared/ui/card' +import { Card, CardContent, CardTitle } from '@/shared/ui/card' import { Input } from '@/shared/ui/input' import { Label } from '@/shared/ui/label' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/shared/ui/select' @@ -118,11 +118,7 @@ export function ChannelDetail({ channelId }: { channelId: string }) { {/* Шоу канала */} - - - {t('admin.channels.shows')} - - + ({ id: s.id, name: s.name }))} @@ -158,15 +154,10 @@ export function ChannelDetail({ channelId }: { channelId: string }) { )} - - + {/* Реклама */} - - - {t('admin.channels.ads')} - - + {t('admin.channels.noAds')} )} - - + {/* Джинглы-отбивки (статичные заставки) */} - - - {t('admin.channels.jingles')} - - +

{t('admin.channels.jinglesHint')}

{t('admin.channels.noJingles')} )} -
-
+ {/* Override'ы / марафоны */} - - - {t('admin.channels.overrides')} - - + ({ id: cs.showId, name: cs.showName }))} @@ -255,22 +236,47 @@ export function ChannelDetail({ channelId }: { channelId: string }) {
  • {t('admin.channels.noOverrides')}
  • )} -
    -
    + {/* Предпросмотр расписания */} - - - {t('admin.channels.schedule')} - - - - - + + + ) } +/** Карточка со сворачиваемым содержимым: клик по заголовку скрывает/раскрывает блок. */ +function CollapsibleCard({ + title, + defaultOpen = false, + contentClassName, + children, +}: { + title: string + defaultOpen?: boolean + contentClassName?: string + children: ReactNode +}) { + const [open, setOpen] = useState(defaultOpen) + return ( + + + {open && {children}} + + ) +} + function SettingsCard({ channel, readyAssets, @@ -323,11 +329,11 @@ function SettingsCard({ }) return ( - - - {t('admin.channels.settings')} - - +
    setName(e.target.value)} /> @@ -408,8 +414,7 @@ function SettingsCard({ {t('common.save')}
    -
    -
    + ) } diff --git a/frontend/src/features/streaming/AirPage.tsx b/frontend/src/features/streaming/AirPage.tsx index 4be4a2e..595f03f 100644 --- a/frontend/src/features/streaming/AirPage.tsx +++ b/frontend/src/features/streaming/AirPage.tsx @@ -179,7 +179,7 @@ export function AirPage() {