Files
TeleWave/frontend/src/features/admin/channels/components/BumperBackgroundField.tsx
T
Leonid PershinandClaude Opus 5 0606ea3e6e Add Prettier to the frontend and gate formatting in CI
Форматтера у фронтенда не было: стиль держался вручную и успел разъехаться в 50 файлах.
Ставим Prettier с настройками под уже сложившийся стиль (без точек с запятой, одинарные кавычки,
ширина 100 — подобрана замером: при 100 расходится меньше файлов, чем при 96 или 110) и
прогоняем его по коду. `src/routeTree.gen.ts` исключён — его переписывает плагин роутера.

Чтобы форматирование больше не расходилось незаметно, добавлены проверки в CI: `csharpier check`
для бэкенда (его отсутствие и позволило накопиться 79 неотформатированным файлам) и
`prettier --check` для фронтенда. Версии форматтеров прибиты точно, без кареток: минорка меняет
вывод и красит CI на файлах, которых никто не трогал.

`.editorconfig` задаёт редакторам те же отступы и LF ещё до форматтера; значения совпадают с
настройками csharpier и Prettier намеренно — оба его читают.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 01:38:12 +03:00

81 lines
2.5 KiB
TypeScript

import { useMutation } from '@tanstack/react-query'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { imageUrl } from '@/features/admin/images/api'
import { ImageGallery } from '@/features/admin/images/ImageGallery'
import { Button } from '@/shared/ui/button'
import { Label } from '@/shared/ui/label'
import { clearBumperTemplateBackground, setBumperTemplateBackground } from '../api'
export function BumperBackgroundField({
channelId,
templateId,
backgroundImageId,
onChanged,
onError,
}: Readonly<{
channelId: string
templateId: string
backgroundImageId: string | null
onChanged: () => void
onError: (e: unknown) => void
}>) {
const { t } = useTranslation()
const [galleryOpen, setGalleryOpen] = useState(false)
const setBg = useMutation({
mutationFn: (imageId: string) => setBumperTemplateBackground(channelId, templateId, imageId),
onSuccess: onChanged,
onError,
})
const clearBg = useMutation({
mutationFn: () => clearBumperTemplateBackground(channelId, templateId),
onSuccess: onChanged,
onError,
})
return (
<div className="flex flex-col gap-1.5">
<Label>
{t('admin.channels.bumperBackground')}{' '}
<span className={backgroundImageId ? 'text-emerald-500' : 'text-muted-foreground'}>
{backgroundImageId
? ${t('admin.channels.bumperFileLoaded')}`
: ${t('admin.channels.bumperFileDefault')}`}
</span>
</Label>
<span className="text-xs text-muted-foreground">
{t('admin.channels.bumperBackgroundHint')}
</span>
<div className="flex items-center gap-2">
{backgroundImageId && (
<img
src={imageUrl(backgroundImageId)}
alt=""
className="h-10 w-16 shrink-0 rounded border border-border object-cover"
/>
)}
<Button size="sm" variant="outline" onClick={() => setGalleryOpen(true)}>
{t('admin.channels.bumperBackgroundPick')}
</Button>
{backgroundImageId && (
<Button
size="sm"
variant="ghost"
disabled={clearBg.isPending}
onClick={() => clearBg.mutate()}
>
{t('admin.channels.bumperReset')}
</Button>
)}
</div>
<ImageGallery
open={galleryOpen}
onOpenChange={setGalleryOpen}
category="BumperBackground"
onSelect={(img) => setBg.mutate(img.id)}
/>
</div>
)
}