From 7e164b637dd439b2c653bbc5554af5a37667aa11 Mon Sep 17 00:00:00 2001 From: Francisco Solla Date: Fri, 18 Sep 2026 21:34:29 -0300 Subject: [PATCH] =?UTF-8?q?fix(C194):=20port=20fiel=20ao=20artefato=20ap?= =?UTF-8?q?=C3=B3s=20cr=C3=ADtica=20do=20designer=20(#1153)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - player mobile 226px (CTA do detalhe acima da dobra), 330px a partir de lg - painel de downloads no mobile: CTA primário primeiro, 'Outros arquivos' depois - cards mobile só com título/funcionalidade; data e 'Abrir reel' a partir de lg - despublicado: aviso + publicação antes da mídia bloqueada; 'Sobre o reel' depois - feature sem '(#cards)' na UI e data de publicação só com o dia - 'Abrir reel' aria-hidden (o card inteiro é o link) Design tier: openai/gpt-5.6-sol — crítica final certificada (v3, 10 capturas). --- .../(app)/comunicacao/reels/[id]/page.tsx | 26 +++++++++------- .../campaign/reels/ReelDownloadPanel.tsx | 30 ++++++++++++------- .../campaign/reels/ReelLibraryCard.tsx | 9 ++++-- src/components/campaign/reels/ReelPlayer.tsx | 4 +-- src/lib/reel.ts | 14 +++++++-- tests/int/reelLibrary.int.spec.ts | 2 +- tests/unit/reel.unit.spec.ts | 4 +-- 7 files changed, 58 insertions(+), 31 deletions(-) diff --git a/src/app/(campaign)/campanha/(app)/comunicacao/reels/[id]/page.tsx b/src/app/(campaign)/campanha/(app)/comunicacao/reels/[id]/page.tsx index ab1219bc..6cb607a7 100644 --- a/src/app/(campaign)/campanha/(app)/comunicacao/reels/[id]/page.tsx +++ b/src/app/(campaign)/campanha/(app)/comunicacao/reels/[id]/page.tsx @@ -59,6 +59,7 @@ export default async function ReelDetailPage({ params }: ReelDetailPageProps) { if (error instanceof ReelNotFoundError) notFound() throw error }) + const blocked = !reel.canServeMedia return ( @@ -85,22 +86,25 @@ export default async function ReelDetailPage({ params }: ReelDetailPageProps) { + {blocked ? ( +
+
+

Fora da lista

+

+ Este reel não aparece na biblioteca. O registro e os arquivos continuam guardados, + mas nenhuma mídia é servida enquanto ele não estiver publicado. +

+
+ +
+ ) : null} +
- {reel.canServeMedia ? null : ( -
-

Fora da lista

-

- Este reel não aparece na biblioteca. O registro e os arquivos continuam guardados, - mas nenhuma mídia é servida enquanto ele não estiver publicado. -

-
- )} - {reel.transcript ? ( @@ -125,7 +129,7 @@ export default async function ReelDetailPage({ params }: ReelDetailPageProps) { - + {blocked ? null : }

Nada é publicado no Instagram por esta tela. diff --git a/src/components/campaign/reels/ReelDownloadPanel.tsx b/src/components/campaign/reels/ReelDownloadPanel.tsx index ece42c84..e67aa034 100644 --- a/src/components/campaign/reels/ReelDownloadPanel.tsx +++ b/src/components/campaign/reels/ReelDownloadPanel.tsx @@ -27,20 +27,30 @@ export const ReelDownloadPanel = ({ reel }: { reel: ReelDetailViewModel }) => { const secondary = reel.downloads.filter((item) => !item.primary) return ( -

-
-
-

Downloads

-

- Arquivos deste reel para finalizar e publicar fora do Teqo. -

+
+
+
+
+

Downloads

+

Outros arquivos

+

+ Arquivos deste reel para finalizar e publicar fora do Teqo. +

+
+
-
- {primary ? : null} + {primary ? ( +
+ +
+ ) : null} -
+
{secondary.map((item) => ( ))} diff --git a/src/components/campaign/reels/ReelLibraryCard.tsx b/src/components/campaign/reels/ReelLibraryCard.tsx index a2f0011d..ee868497 100644 --- a/src/components/campaign/reels/ReelLibraryCard.tsx +++ b/src/components/campaign/reels/ReelLibraryCard.tsx @@ -32,9 +32,14 @@ export const ReelLibraryCard = ({ reel }: { reel: ReelLibraryItemViewModel }) =>

{reel.title}

{reel.featureLabel}

{reel.publishedAtLabel ? ( -

Publicado em {reel.publishedAtLabel}

+

+ Publicado em {reel.publishedAtLabel} +

) : null} - +
diff --git a/src/components/campaign/reels/ReelPlayer.tsx b/src/components/campaign/reels/ReelPlayer.tsx index dfd60afb..2a16e29b 100644 --- a/src/components/campaign/reels/ReelPlayer.tsx +++ b/src/components/campaign/reels/ReelPlayer.tsx @@ -9,7 +9,7 @@ import type { ReelDetailViewModel } from '@/lib/reel' export const ReelPlayer = ({ reel }: { reel: ReelDetailViewModel }) => { if (!reel.videoSourceUrl) { return ( -
+
Player indisponível

{reel.mediaBlockedLabel}

@@ -23,7 +23,7 @@ export const ReelPlayer = ({ reel }: { reel: ReelDetailViewModel }) => { preload="metadata" poster={reel.videoPosterUrl} src={reel.videoSourceUrl} - className="mx-auto aspect-[9/16] w-full max-w-[330px] rounded-xl border bg-black" + className="mx-auto aspect-[9/16] w-full max-w-[226px] rounded-xl border bg-black lg:max-w-[330px]" /> ) } diff --git a/src/lib/reel.ts b/src/lib/reel.ts index 12bc54d1..f8dd5ac4 100644 --- a/src/lib/reel.ts +++ b/src/lib/reel.ts @@ -6,7 +6,7 @@ */ import { campaignReelDetailHref } from '@/lib/campaignPaths' -import { formatBahiaDateTimeLabel } from '@/lib/campaignTime' +import { formatBahiaCivilDate } from '@/lib/campaignTime' /** Upload collection of the artifacts; also its local disk directory in dev. */ export const REEL_MEDIA_SLUG = 'reelMedia' @@ -33,10 +33,16 @@ export const isReelStatus = (value: unknown): value is ReelStatus => export const REEL_FEATURES = ['cards'] as const export type ReelFeature = (typeof REEL_FEATURES)[number] +/** Admin/select wording: keeps the public anchor the tutorial teaches. */ export const reelFeatureLabels: Record = { cards: 'Cards de apoio (#cards)', } +/** Library UI wording: the anchor belongs to the admin context, not the card. */ +const reelFeatureDisplayLabels: Record = { + cards: 'Cards de apoio', +} + /** * The artifacts a reel can carry, each mapping to exactly one upload field. * `video` is the primary file (silent); the others are optional variants. @@ -179,11 +185,13 @@ const mediaAlt = (value: ReelMediaRef, fallback: string): string => { return alt ? alt : fallback } +/** Date-only (`dd/mm/aaaa`) publication label — the library never shows the hour. */ const publishedAtLabel = (iso: string | null | undefined): string | null => { if (!iso) return null const instant = new Date(iso) if (Number.isNaN(instant.getTime())) return null - return formatBahiaDateTimeLabel(iso) + const [year, month, day] = formatBahiaCivilDate(instant).split('-') + return `${day}/${month}/${year}` } const reelCover = (record: ReelRecordForView): { coverUrl: string; coverAlt: string } => ({ @@ -199,7 +207,7 @@ export const toReelLibraryItemViewModel = (record: ReelRecordForView): ReelLibra id: record.id, title: record.title, featureLabel: isReelFeature(record.feature) - ? reelFeatureLabels[record.feature] + ? reelFeatureDisplayLabels[record.feature] : record.feature, status, statusLabel: reelStatusLabels[status], diff --git a/tests/int/reelLibrary.int.spec.ts b/tests/int/reelLibrary.int.spec.ts index 8e94290f..1911b604 100644 --- a/tests/int/reelLibrary.int.spec.ts +++ b/tests/int/reelLibrary.int.spec.ts @@ -153,7 +153,7 @@ describe('reel library data (C194)', () => { const newest = data.rows.find((row) => row.id === newer.id) expect(newest).toMatchObject({ title: 'Reel novo', - featureLabel: 'Cards de apoio (#cards)', + featureLabel: 'Cards de apoio', status: 'published', statusLabel: 'Publicado', coverUrl: `/campanha/comunicacao/reels/${newer.id}/media/cover`, diff --git a/tests/unit/reel.unit.spec.ts b/tests/unit/reel.unit.spec.ts index 8533403a..d8d60a6a 100644 --- a/tests/unit/reel.unit.spec.ts +++ b/tests/unit/reel.unit.spec.ts @@ -159,12 +159,12 @@ describe('reel view models (C194)', () => { expect(item).toEqual({ id: 42, title: 'Como criar seu card de apoio', - featureLabel: 'Cards de apoio (#cards)', + featureLabel: 'Cards de apoio', status: 'published', statusLabel: 'Publicado', coverUrl: '/campanha/comunicacao/reels/42/media/cover', coverAlt: 'Capa do tutorial', - publishedAtLabel: '18/09/2026 às 14:00', + publishedAtLabel: '18/09/2026', detailHref: '/campanha/comunicacao/reels/42', }) })