Add interstitial endpoints and enhance media and template functionalities: implement MapInterstitialEndpoints in Program.cs, add preview functionality for media assets in MediaEndpoints, and introduce template preview capabilities in TemplateEndpoints. Remove obsolete bumper settings from Channel and related classes to streamline configuration.
build / backend (push) Successful in 5m58s
build / frontend (push) Successful in 47s
tests / backend-tests (push) Successful in 5m57s

This commit is contained in:
Leonid Pershin
2026-07-26 14:03:53 +03:00
parent 66040a8841
commit 7b12a06d1b
53 changed files with 4076 additions and 469 deletions
@@ -3,12 +3,10 @@ import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import type { BumperFont, BumperSelection, BumperSettings, ChannelDto } from '@/shared/api/types'
import { Button } from '@/shared/ui/button'
import { Input } from '@/shared/ui/input'
import { Label } from '@/shared/ui/label'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/shared/ui/select'
import { toast } from '@/shared/ui/toast-store'
import { addBumperTemplate, updateChannelSettings } from '../api'
import { clampChance } from '../lib/format'
import { BumperTemplateEditor } from './BumperTemplateEditor'
import { CollapsibleCard } from './CollapsibleCard'
@@ -76,8 +74,8 @@ export function BumperCard({
</span>
</label>
{/* Общие настройки */}
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
{/* Общие настройки. Как часто ставить заставку — не здесь: это условие элемента стыка. */}
<div className="grid gap-4 sm:grid-cols-2">
<div className="flex flex-col gap-1.5">
<Label>{t('admin.channels.bumperSelection')}</Label>
<Select value={bumper.selection} onValueChange={(v) => setField('selection', v as BumperSelection)}>
@@ -85,7 +83,6 @@ export function BumperCard({
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="Rotation">{t('admin.channels.bumperSelectionRotation')}</SelectItem>
<SelectItem value="Random">{t('admin.channels.bumperSelectionRandom')}</SelectItem>
<SelectItem value="WeightedRandom">
{t('admin.channels.bumperSelectionWeighted')}
@@ -108,45 +105,8 @@ export function BumperCard({
</SelectContent>
</Select>
</div>
<div className="flex flex-col gap-1.5">
<Label>{t('admin.channels.bumperMinInterval')}</Label>
<Input
type="number"
min={0}
max={1440}
value={bumper.minIntervalMinutes}
onChange={(e) => setField('minIntervalMinutes', Number(e.target.value))}
/>
</div>
<div className="flex flex-col gap-1.5">
<Label>{t('admin.channels.bumperShowChangeChance')}</Label>
<Input
type="number"
min={0}
max={1}
step={0.05}
value={bumper.showChangeChance}
onChange={(e) => setField('showChangeChance', clampChance(e.target.value))}
/>
<span className="text-xs text-muted-foreground">
{t('admin.channels.bumperShowChangeChanceHint')}
</span>
</div>
<div className="flex flex-col gap-1.5">
<Label>{t('admin.channels.bumperEpisodeChangeChance')}</Label>
<Input
type="number"
min={0}
max={1}
step={0.05}
value={bumper.episodeChangeChance}
onChange={(e) => setField('episodeChangeChance', clampChance(e.target.value))}
/>
<span className="text-xs text-muted-foreground">
{t('admin.channels.bumperEpisodeChangeChanceHint')}
</span>
</div>
</div>
<p className="text-xs text-muted-foreground">{t('admin.channels.bumperConditionsHint')}</p>
<div className="flex justify-end">
<Button size="sm" disabled={save.isPending} onClick={() => save.mutate()}>
{t('common.save')}