mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 23:53:05 +00:00
docs(C222): plano + design hi-fi — Central de Conteúdos — apagar uma peça (Related #1330)
This commit is contained in:
parent
c9ab467f23
commit
a81f2c2672
2 changed files with 669 additions and 0 deletions
561
docs/plans/central-conteudos-apagar-peca-ui-design.html
Normal file
561
docs/plans/central-conteudos-apagar-peca-ui-design.html
Normal file
|
|
@ -0,0 +1,561 @@
|
|||
<!doctype html>
|
||||
<html lang="pt-BR" data-theme="campaign">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
||||
<title>Design — C222 · Central de Conteúdos — apagar uma peça</title>
|
||||
<style type="text/tailwindcss">
|
||||
@theme inline {
|
||||
--font-sans: Inter, ui-sans-serif, system-ui, sans-serif;
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--color-card: var(--card);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-border: var(--border);
|
||||
--color-input: var(--input);
|
||||
--color-ring: var(--ring);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--radius-sm: 0.25rem;
|
||||
--radius-md: 0.375rem;
|
||||
--radius-lg: 0.5rem;
|
||||
--radius-xl: 0.75rem;
|
||||
}
|
||||
|
||||
[data-theme='campaign'] {
|
||||
--radius: 0.5rem;
|
||||
--background: #ffffff;
|
||||
--foreground: #1c1917;
|
||||
--card: #ffffff;
|
||||
--card-foreground: #1c1917;
|
||||
--popover: #ffffff;
|
||||
--popover-foreground: #1c1917;
|
||||
--primary: #c51414;
|
||||
--primary-foreground: #ffffff;
|
||||
--secondary: #f5f5f4;
|
||||
--secondary-foreground: #292524;
|
||||
--muted: #f4f4f5;
|
||||
--muted-foreground: #6b7280;
|
||||
--accent: #f4f4f5;
|
||||
--accent-foreground: #1c1917;
|
||||
--destructive: #b42318;
|
||||
--border: rgb(28 25 23 / 12%);
|
||||
--input: rgb(28 25 23 / 16%);
|
||||
--ring: #c51414;
|
||||
--sidebar: #fafaf9;
|
||||
--sidebar-foreground: #1c1917;
|
||||
--sidebar-accent: #f5f5f4;
|
||||
--sidebar-border: rgb(28 25 23 / 12%);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
font-family: Inter, ui-sans-serif, system-ui, sans-serif;
|
||||
}
|
||||
button,
|
||||
a {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.board {
|
||||
background-color: #efeeec;
|
||||
background-image: radial-gradient(rgb(28 25 23 / 8%) 0.7px, transparent 0.7px);
|
||||
background-size: 16px 16px;
|
||||
}
|
||||
.scene-shadow {
|
||||
box-shadow: 0 18px 52px rgb(28 25 23 / 10%);
|
||||
}
|
||||
.dialog-shadow {
|
||||
box-shadow: 0 24px 80px rgb(28 25 23 / 25%);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="board min-h-screen bg-background text-foreground antialiased">
|
||||
<!-- Ícones inline seguem o grid e o stroke do Lucide. Não há SVG próprio. -->
|
||||
<main class="mx-auto max-w-[1480px] space-y-16 px-4 py-10 md:px-8 md:py-14">
|
||||
<header class="max-w-3xl">
|
||||
<div
|
||||
class="inline-flex min-h-6 items-center rounded-full bg-primary px-2.5 text-xs font-semibold text-primary-foreground"
|
||||
>
|
||||
C222 · design do gate
|
||||
</div>
|
||||
<h1 class="mt-4 text-3xl font-semibold tracking-tight">Apagar sem competir com o trabalho</h1>
|
||||
<p class="mt-2 max-w-2xl text-sm leading-6 text-muted-foreground">
|
||||
A saída definitiva fica disponível na lista e na ficha, mas permanece visualmente abaixo
|
||||
da próxima ação. A confirmação cresce apenas quando existe um link público.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<nav aria-label="Índice de cenas" class="flex flex-wrap gap-2 text-xs">
|
||||
<a href="#lista-desktop" class="rounded-full border border-border bg-card px-3 py-1.5 font-medium"
|
||||
>A · Lista desktop</a
|
||||
>
|
||||
<a href="#lista-mobile" class="rounded-full border border-border bg-card px-3 py-1.5 font-medium"
|
||||
>B · Lista mobile</a
|
||||
>
|
||||
<a href="#detalhe" class="rounded-full border border-border bg-card px-3 py-1.5 font-medium"
|
||||
>C–D · Detalhe</a
|
||||
>
|
||||
<a href="#confirmacoes" class="rounded-full border border-border bg-card px-3 py-1.5 font-medium"
|
||||
>E–F · Confirmações</a
|
||||
>
|
||||
<a href="#feedback" class="rounded-full border border-border bg-card px-3 py-1.5 font-medium"
|
||||
>G–H · Erro e envio</a
|
||||
>
|
||||
</nav>
|
||||
|
||||
<!-- CENA A — LISTA DESKTOP -->
|
||||
<section id="lista-desktop" aria-labelledby="lista-desktop-title">
|
||||
<div class="mb-3 flex items-end justify-between gap-4">
|
||||
<div>
|
||||
<p class="text-xs font-medium text-muted-foreground">Cena A · desktop ~1280</p>
|
||||
<h2 id="lista-desktop-title" class="mt-1 text-base font-semibold">
|
||||
“Apagar” acompanha cada próxima ação sem virar o foco da linha
|
||||
</h2>
|
||||
</div>
|
||||
<p class="hidden max-w-md text-right text-xs leading-5 text-muted-foreground md:block">
|
||||
Abrir continua outline; Reprocessar continua primário. Apagar é ghost, destrutivo e
|
||||
separado por respiro.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto pb-4">
|
||||
<div
|
||||
class="scene-shadow mx-auto h-[780px] w-[1280px] overflow-hidden rounded-xl border border-border bg-background"
|
||||
>
|
||||
<div class="flex h-full">
|
||||
<aside class="flex w-56 shrink-0 flex-col border-r border-sidebar-border bg-sidebar p-3">
|
||||
<div class="flex h-12 items-center gap-2 px-2">
|
||||
<div
|
||||
class="grid size-8 place-items-center rounded-lg bg-primary text-sm font-bold text-primary-foreground"
|
||||
>
|
||||
S
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-semibold">Solla</p>
|
||||
<p class="text-xs text-muted-foreground">Campanha</p>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="mt-4 space-y-1 text-sm" aria-label="Navegação ilustrativa">
|
||||
<div class="flex h-9 items-center gap-2 rounded-md bg-sidebar-accent px-3 font-semibold">
|
||||
<svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="m3 11 18-5v12L3 14v-3Z" />
|
||||
<path d="M11.6 16.9 13 22H7l-1.3-7" />
|
||||
</svg>
|
||||
Comunicação
|
||||
</div>
|
||||
<div class="ml-4 border-l border-sidebar-border pl-3">
|
||||
<div
|
||||
class="mt-1 flex h-9 items-center rounded-md bg-card px-3 font-semibold text-primary ring-1 ring-border"
|
||||
>
|
||||
Conteúdos
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<p class="mt-auto border-t border-sidebar-border px-2 pt-4 text-xs text-muted-foreground">
|
||||
Assessoria de comunicação
|
||||
</p>
|
||||
</aside>
|
||||
|
||||
<div class="min-w-0 flex-1">
|
||||
<header class="flex h-16 items-center justify-between border-b border-border px-6">
|
||||
<div>
|
||||
<p class="text-xs text-muted-foreground">Comunicação</p>
|
||||
<p class="text-sm font-medium">Central de Conteúdos</p>
|
||||
</div>
|
||||
<div class="size-8 rounded-full bg-secondary ring-1 ring-border"></div>
|
||||
</header>
|
||||
|
||||
<div class="p-6">
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold">Conteúdos</h3>
|
||||
<p class="mt-1 text-sm text-muted-foreground">
|
||||
Peças que alimentam a Central pública. Rascunhos não aparecem no site.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-3 text-sm font-medium"
|
||||
>
|
||||
Adicionar por link
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex min-h-11 items-center justify-center rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground"
|
||||
>
|
||||
Enviar peças
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex items-center gap-3">
|
||||
<div class="relative flex-1">
|
||||
<svg aria-hidden="true" class="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<circle cx="11" cy="11" r="8" />
|
||||
<path d="m21 21-4.3-4.3" />
|
||||
</svg>
|
||||
<input
|
||||
readonly
|
||||
aria-label="Buscar conteúdos"
|
||||
placeholder="Buscar por título, tema ou cidade…"
|
||||
class="h-11 w-full rounded-md border border-input bg-background pl-9 pr-3 text-sm outline-none placeholder:text-muted-foreground"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex h-11 items-center justify-center rounded-lg border border-border bg-background px-3 text-sm font-medium"
|
||||
>
|
||||
Filtros
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="mt-5 overflow-hidden rounded-xl border border-border">
|
||||
<table class="w-full table-fixed text-left text-sm">
|
||||
<caption class="sr-only">
|
||||
Quatro peças com estados de processamento, publicação, circulação e ações.
|
||||
</caption>
|
||||
<thead class="bg-stone-50 text-xs text-muted-foreground">
|
||||
<tr class="border-b border-border">
|
||||
<th class="w-[23%] p-3 font-medium">Peça</th>
|
||||
<th class="w-[14%] p-3 font-medium">Processamento</th>
|
||||
<th class="w-[12%] p-3 font-medium">Publicação</th>
|
||||
<th class="w-[25%] p-3 font-medium">Circulação</th>
|
||||
<th class="w-[26%] p-3 text-right font-medium">Próxima ação</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-border">
|
||||
<tr>
|
||||
<td class="p-3 align-middle">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="grid h-14 w-20 shrink-0 place-items-center rounded-md bg-gradient-to-br from-stone-200 to-stone-100 text-stone-500">
|
||||
<svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="m16 13 5 3-5 3v-6Z" /><rect x="3" y="6" width="13" height="14" rx="2" />
|
||||
</svg>
|
||||
</span>
|
||||
<div class="min-w-0">
|
||||
<p class="font-semibold">Peça publicada</p>
|
||||
<p class="mt-1 truncate text-xs text-muted-foreground">Vídeo · 02:14</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="p-3">
|
||||
<span class="inline-flex min-h-5 items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-semibold text-green-800">Pronto</span>
|
||||
</td>
|
||||
<td class="p-3">
|
||||
<span class="inline-flex min-h-5 items-center rounded-full bg-rose-50 px-2 py-0.5 text-xs font-semibold text-rose-900 ring-1 ring-rose-200">Publicado</span>
|
||||
</td>
|
||||
<td class="p-3">
|
||||
<div class="grid grid-cols-2 gap-x-3 gap-y-1 text-xs">
|
||||
<span class="text-muted-foreground">Visualizações</span><b class="text-right">—</b>
|
||||
<span class="text-muted-foreground">Downloads</span><b class="text-right">—</b>
|
||||
</div>
|
||||
</td>
|
||||
<td class="p-3">
|
||||
<div class="flex items-center justify-end gap-2">
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-3 text-sm font-medium">Abrir</button>
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg px-2.5 text-sm font-medium text-destructive hover:bg-red-50">
|
||||
<svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>
|
||||
Apagar
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="p-3"><p class="font-semibold">Peça em rascunho</p><p class="mt-1 text-xs text-muted-foreground">Card</p></td>
|
||||
<td class="p-3"><span class="inline-flex min-h-5 items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-semibold text-green-800">Pronto</span></td>
|
||||
<td class="p-3"><span class="inline-flex min-h-5 items-center rounded-full bg-muted px-2 py-0.5 text-xs font-semibold text-muted-foreground">Rascunho</span></td>
|
||||
<td class="p-3"><span class="text-xs text-muted-foreground">Ainda não publicada</span></td>
|
||||
<td class="p-3">
|
||||
<div class="flex items-center justify-end gap-2">
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-3 text-sm font-medium">Abrir</button>
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg px-2.5 text-sm font-medium text-destructive hover:bg-red-50">
|
||||
<svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="p-3"><p class="font-semibold">Peça com falha</p><p class="mt-1 text-xs text-muted-foreground">Áudio</p></td>
|
||||
<td class="p-3"><span class="inline-flex min-h-5 items-center rounded-full bg-red-100 px-2 py-0.5 text-xs font-semibold text-red-700">Falhou</span></td>
|
||||
<td class="p-3"><span class="inline-flex min-h-5 items-center rounded-full bg-muted px-2 py-0.5 text-xs font-semibold text-muted-foreground">Rascunho</span></td>
|
||||
<td class="p-3"><span class="text-xs text-muted-foreground">Ainda não publicada</span></td>
|
||||
<td class="p-3">
|
||||
<div class="flex items-center justify-end gap-2">
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground">
|
||||
<svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6v6h-6" /><path d="M20 12a8 8 0 1 0-2.34 5.66" /></svg>Reprocessar
|
||||
</button>
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg px-2.5 text-sm font-medium text-destructive hover:bg-red-50">
|
||||
<svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="p-3"><p class="font-semibold">Peça em processamento</p><p class="mt-1 text-xs text-muted-foreground">Vídeo enviado</p></td>
|
||||
<td class="p-3"><span class="inline-flex min-h-5 items-center rounded-full bg-amber-100 px-2 py-0.5 text-xs font-semibold text-amber-900">Processando</span><p class="mt-1 text-xs text-muted-foreground">Transcrevendo…</p></td>
|
||||
<td class="p-3"><span class="inline-flex min-h-5 items-center rounded-full bg-muted px-2 py-0.5 text-xs font-semibold text-muted-foreground">Rascunho</span></td>
|
||||
<td class="p-3"><span class="text-xs text-muted-foreground">Ainda não publicada</span></td>
|
||||
<td class="p-3">
|
||||
<div class="flex items-center justify-end gap-2">
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-3 text-sm font-medium">Abrir</button>
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg px-2.5 text-sm font-medium text-destructive hover:bg-red-50">
|
||||
<svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="mt-3 text-xs text-muted-foreground">4 peças</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CENA B — LISTA MOBILE -->
|
||||
<section id="lista-mobile" aria-labelledby="lista-mobile-title">
|
||||
<div class="mb-3">
|
||||
<p class="text-xs font-medium text-muted-foreground">Cena B · mobile ~390</p>
|
||||
<h2 id="lista-mobile-title" class="mt-1 text-base font-semibold">
|
||||
Nos cards, apagar fica ao lado da ação rotineira — nunca acima dela
|
||||
</h2>
|
||||
</div>
|
||||
<div
|
||||
class="scene-shadow mx-auto w-full max-w-[390px] overflow-hidden rounded-[28px] border-[6px] border-stone-800 bg-background"
|
||||
>
|
||||
<div class="flex h-14 items-center justify-between bg-primary px-4 text-primary-foreground">
|
||||
<button aria-label="Abrir menu" class="grid size-10 place-items-center rounded-lg">
|
||||
<svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 6h16M4 12h16M4 18h16" /></svg>
|
||||
</button>
|
||||
<span class="text-sm font-semibold">Conteúdos</span>
|
||||
<div class="size-10"></div>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<button type="button" class="inline-flex min-h-11 w-full items-center justify-center rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground">Enviar peças</button>
|
||||
<button type="button" class="mt-2 inline-flex min-h-11 w-full items-center justify-center rounded-lg border border-border bg-background px-3 text-sm font-medium">Adicionar por link</button>
|
||||
<input readonly aria-label="Buscar conteúdos" placeholder="Buscar conteúdos…" class="mt-3 h-11 w-full rounded-md border border-input bg-background px-3 text-base outline-none placeholder:text-muted-foreground" />
|
||||
|
||||
<div class="mt-4 space-y-3">
|
||||
<article class="rounded-xl border border-border bg-card p-4">
|
||||
<div class="flex items-start justify-between gap-3"><p class="text-sm font-semibold">Peça publicada</p><span class="inline-flex min-h-5 shrink-0 items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-semibold text-green-800">Pronto</span></div>
|
||||
<div class="mt-1 flex flex-wrap items-center gap-2 text-xs text-muted-foreground"><span class="inline-flex min-h-5 items-center rounded-full bg-rose-50 px-2 py-0.5 font-semibold text-rose-900 ring-1 ring-rose-200">Publicado</span><span>Vídeo · 02:14</span></div>
|
||||
<div class="mt-3 grid grid-cols-[1fr_auto] gap-2">
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-3 text-sm font-medium">Abrir</button>
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg px-3 text-sm font-medium text-destructive hover:bg-red-50"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar</button>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="rounded-xl border border-border bg-card p-4">
|
||||
<div class="flex items-start justify-between gap-3"><p class="text-sm font-semibold">Peça em rascunho</p><span class="inline-flex min-h-5 shrink-0 items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-semibold text-green-800">Pronto</span></div>
|
||||
<div class="mt-1 flex flex-wrap items-center gap-2 text-xs text-muted-foreground"><span class="inline-flex min-h-5 items-center rounded-full bg-muted px-2 py-0.5 font-semibold">Rascunho</span><span>Card</span></div>
|
||||
<div class="mt-3 grid grid-cols-[1fr_auto] gap-2"><button type="button" class="min-h-11 rounded-lg border border-border text-sm font-medium">Abrir</button><button type="button" class="inline-flex min-h-11 items-center gap-1.5 rounded-lg px-3 text-sm font-medium text-destructive"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar</button></div>
|
||||
</article>
|
||||
|
||||
<article class="rounded-xl border border-border bg-card p-4">
|
||||
<div class="flex items-start justify-between gap-3"><p class="text-sm font-semibold">Peça com falha</p><span class="inline-flex min-h-5 shrink-0 items-center rounded-full bg-red-100 px-2 py-0.5 text-xs font-semibold text-red-700">Falhou</span></div>
|
||||
<div class="mt-1 flex flex-wrap items-center gap-2 text-xs text-muted-foreground"><span class="inline-flex min-h-5 items-center rounded-full bg-muted px-2 py-0.5 font-semibold">Rascunho</span><span>Áudio</span></div>
|
||||
<button type="button" class="mt-3 inline-flex min-h-11 w-full items-center justify-center gap-1.5 rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6v6h-6" /><path d="M20 12a8 8 0 1 0-2.34 5.66" /></svg>Reprocessar</button>
|
||||
<button type="button" class="mt-2 inline-flex min-h-11 w-full items-center justify-center gap-1.5 rounded-lg text-sm font-medium text-destructive"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar</button>
|
||||
</article>
|
||||
|
||||
<article class="rounded-xl border border-border bg-card p-4">
|
||||
<div class="flex items-start justify-between gap-3"><p class="text-sm font-semibold">Peça em processamento</p><span class="inline-flex min-h-5 shrink-0 items-center rounded-full bg-amber-100 px-2 py-0.5 text-xs font-semibold text-amber-900">Processando</span></div>
|
||||
<div class="mt-3 h-2 overflow-hidden rounded-full bg-muted"><div class="h-full w-1/2 rounded-full bg-primary"></div></div>
|
||||
<p class="mt-2 text-xs text-muted-foreground">Transcrevendo…</p>
|
||||
<div class="mt-3 grid grid-cols-[1fr_auto] gap-2"><button type="button" class="min-h-11 rounded-lg border border-border text-sm font-medium">Abrir</button><button type="button" class="inline-flex min-h-11 items-center gap-1.5 rounded-lg px-3 text-sm font-medium text-destructive"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar</button></div>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CENAS C–D — DETALHE DESKTOP E MOBILE -->
|
||||
<section id="detalhe" aria-labelledby="detalhe-title">
|
||||
<div class="mb-3 flex items-end justify-between gap-4">
|
||||
<div>
|
||||
<p class="text-xs font-medium text-muted-foreground">Cenas C–D · detalhe desktop e mobile</p>
|
||||
<h2 id="detalhe-title" class="mt-1 text-base font-semibold">
|
||||
A ação definitiva fecha a fila de ações do topo
|
||||
</h2>
|
||||
</div>
|
||||
<p class="hidden max-w-md text-right text-xs leading-5 text-muted-foreground md:block">
|
||||
Publicar, Despublicar ou Reprocessar preservam seu peso contextual. Anexar é secundário;
|
||||
Apagar permanece ghost destrutivo.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto pb-4">
|
||||
<div class="scene-shadow mx-auto w-[1280px] overflow-hidden rounded-xl border border-border bg-background">
|
||||
<div class="flex h-16 items-center justify-between border-b border-border px-8">
|
||||
<div><p class="text-xs text-muted-foreground">Comunicação</p><p class="text-sm font-medium">Peça publicada</p></div>
|
||||
<div class="size-8 rounded-full bg-secondary ring-1 ring-border"></div>
|
||||
</div>
|
||||
<div class="mx-auto max-w-5xl p-8">
|
||||
<a href="#" class="inline-flex min-h-10 items-center gap-1 text-xs font-semibold text-primary">
|
||||
<svg aria-hidden="true" class="size-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m15 18-6-6 6-6" /></svg>Conteúdos
|
||||
</a>
|
||||
<div class="mt-2 flex items-start justify-between gap-5 border-b border-border pb-5">
|
||||
<div class="min-w-0">
|
||||
<h3 class="text-xl font-semibold">Peça publicada</h3>
|
||||
<div class="mt-2 flex gap-2"><span class="inline-flex min-h-5 items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-semibold text-green-800">Pronto</span><span class="inline-flex min-h-5 items-center rounded-full bg-rose-50 px-2 py-0.5 text-xs font-semibold text-rose-900 ring-1 ring-rose-200">Publicado</span></div>
|
||||
</div>
|
||||
<div class="flex shrink-0 flex-wrap items-center justify-end gap-2">
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg border border-border bg-background px-3 text-sm font-medium"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M13.5 3H12H8C6.9 3 6 3.9 6 5v14c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V8.5L13.5 3Z" /><path d="M13 3v6h6" /><path d="M12 18v-6" /><path d="m9 15 3 3 3-3" /></svg>Anexar</button>
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg border border-border bg-background px-3 text-sm font-medium"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 3l18 18" /><path d="M10.6 10.6A3 3 0 0 0 15 15" /><path d="M9.9 4.2A10.6 10.6 0 0 1 12 4c5.5 0 10 8 10 8a18 18 0 0 1-2 2.8" /><path d="M6.6 6.6C3.9 8.4 2 12 2 12s4.5 8 10 8a9.8 9.8 0 0 0 5.4-1.6" /></svg>Despublicar</button>
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg px-3 text-sm font-medium text-destructive hover:bg-red-50"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 grid grid-cols-[300px_1fr] gap-8">
|
||||
<div><div class="grid aspect-video place-items-center rounded-xl border border-border bg-gradient-to-br from-stone-200 to-stone-100 text-xs font-semibold text-muted-foreground">Prévia da peça</div><dl class="mt-4 space-y-2 text-xs"><div class="flex justify-between"><dt class="text-muted-foreground">Origem</dt><dd>Arquivo</dd></div><div class="flex justify-between"><dt class="text-muted-foreground">Duração</dt><dd>02:14</dd></div></dl></div>
|
||||
<div><div class="rounded-xl border border-border p-5"><p class="text-sm font-semibold">Circulação</p><div class="mt-4 grid grid-cols-4 gap-3"><div class="h-16 rounded-lg bg-muted"></div><div class="h-16 rounded-lg bg-muted"></div><div class="h-16 rounded-lg bg-muted"></div><div class="h-16 rounded-lg bg-muted"></div></div></div><div class="mt-6 border-t border-border pt-6"><div class="h-11 rounded-md border border-input"></div><div class="mt-3 h-24 rounded-md border border-input"></div></div></div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid grid-cols-2 gap-4 border-t border-border pt-6">
|
||||
<div class="rounded-xl border border-border bg-card p-4">
|
||||
<p class="text-xs font-semibold">Variante · pronto e rascunho</p>
|
||||
<div class="mt-3 flex items-center gap-2"><button type="button" class="inline-flex min-h-11 items-center rounded-lg border border-border px-3 text-sm font-medium">Anexar</button><button type="button" class="inline-flex min-h-11 items-center rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground">Publicar</button><button type="button" class="inline-flex min-h-11 items-center rounded-lg px-3 text-sm font-medium text-destructive">Apagar</button></div>
|
||||
</div>
|
||||
<div class="rounded-xl border border-border bg-card p-4">
|
||||
<p class="text-xs font-semibold">Variante · falhou</p>
|
||||
<div class="mt-3 flex items-center gap-2"><button type="button" class="inline-flex min-h-11 items-center rounded-lg border border-border px-3 text-sm font-medium">Anexar</button><button type="button" class="inline-flex min-h-11 items-center gap-1.5 rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6v6h-6" /><path d="M20 12a8 8 0 1 0-2.34 5.66" /></svg>Reprocessar</button><button type="button" class="inline-flex min-h-11 items-center rounded-lg px-3 text-sm font-medium text-destructive">Apagar</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid items-start gap-8 lg:grid-cols-2">
|
||||
<div>
|
||||
<p class="mb-2 text-center text-xs font-medium text-muted-foreground">Mobile · publicado</p>
|
||||
<div class="scene-shadow mx-auto w-full max-w-[390px] overflow-hidden rounded-[28px] border-[6px] border-stone-800 bg-background">
|
||||
<div class="flex h-14 items-center justify-between bg-primary px-4 text-primary-foreground"><button aria-label="Abrir menu" class="grid size-10 place-items-center rounded-lg"><svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 6h16M4 12h16M4 18h16" /></svg></button><span class="max-w-[230px] truncate text-sm font-semibold">Peça publicada</span><div class="size-10"></div></div>
|
||||
<div class="p-4">
|
||||
<a href="#" class="inline-flex min-h-11 items-center gap-1 text-xs font-semibold text-primary"><svg aria-hidden="true" class="size-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m15 18-6-6 6-6" /></svg>Conteúdos</a>
|
||||
<h3 class="mt-1 text-xl font-semibold">Peça publicada</h3>
|
||||
<div class="mt-2 flex gap-2"><span class="inline-flex min-h-5 items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-semibold text-green-800">Pronto</span><span class="inline-flex min-h-5 items-center rounded-full bg-rose-50 px-2 py-0.5 text-xs font-semibold text-rose-900 ring-1 ring-rose-200">Publicado</span></div>
|
||||
<div class="mt-4 grid grid-cols-2 gap-2"><button type="button" class="min-h-11 rounded-lg border border-border text-sm font-medium">Anexar</button><button type="button" class="min-h-11 rounded-lg border border-border text-sm font-medium">Despublicar</button><button type="button" class="col-span-2 inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg text-sm font-medium text-destructive"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar</button></div>
|
||||
<div class="mt-5 grid aspect-video place-items-center rounded-xl border border-border bg-gradient-to-br from-stone-200 to-stone-100 text-xs font-semibold text-muted-foreground">Prévia da peça</div>
|
||||
<div class="mt-5 h-28 rounded-xl border border-border"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="mb-2 text-center text-xs font-medium text-muted-foreground">Mobile · falhou</p>
|
||||
<div class="scene-shadow mx-auto w-full max-w-[390px] overflow-hidden rounded-[28px] border-[6px] border-stone-800 bg-background">
|
||||
<div class="flex h-14 items-center justify-between bg-primary px-4 text-primary-foreground"><button aria-label="Abrir menu" class="grid size-10 place-items-center rounded-lg"><svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 6h16M4 12h16M4 18h16" /></svg></button><span class="max-w-[230px] truncate text-sm font-semibold">Peça com falha</span><div class="size-10"></div></div>
|
||||
<div class="p-4">
|
||||
<a href="#" class="inline-flex min-h-11 items-center gap-1 text-xs font-semibold text-primary"><svg aria-hidden="true" class="size-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m15 18-6-6 6-6" /></svg>Conteúdos</a>
|
||||
<h3 class="mt-1 text-xl font-semibold">Peça com falha</h3>
|
||||
<div class="mt-2 flex gap-2"><span class="inline-flex min-h-5 items-center rounded-full bg-red-100 px-2 py-0.5 text-xs font-semibold text-red-700">Falhou</span><span class="inline-flex min-h-5 items-center rounded-full bg-muted px-2 py-0.5 text-xs font-semibold text-muted-foreground">Rascunho</span></div>
|
||||
<button type="button" class="mt-4 inline-flex min-h-11 w-full items-center justify-center gap-1.5 rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6v6h-6" /><path d="M20 12a8 8 0 1 0-2.34 5.66" /></svg>Reprocessar</button>
|
||||
<button type="button" class="mt-2 min-h-11 w-full rounded-lg border border-border text-sm font-medium">Anexar</button>
|
||||
<button type="button" class="mt-2 inline-flex min-h-11 w-full items-center justify-center gap-1.5 rounded-lg text-sm font-medium text-destructive"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar</button>
|
||||
<div class="mt-5 grid aspect-video place-items-center rounded-xl border border-border bg-muted text-xs font-semibold text-muted-foreground">Sem prévia disponível</div>
|
||||
<div class="mt-5 rounded-lg border border-red-200 bg-red-50 p-3 text-xs leading-5 text-red-800">O processamento não foi concluído. O arquivo foi preservado.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CENAS E–F — CONFIRMAÇÕES -->
|
||||
<section id="confirmacoes" aria-labelledby="confirmacoes-title">
|
||||
<div class="mb-3">
|
||||
<p class="text-xs font-medium text-muted-foreground">Cenas E–F · diálogos sempre visíveis</p>
|
||||
<h2 id="confirmacoes-title" class="mt-1 text-base font-semibold">
|
||||
O link público é nomeado somente quando será quebrado
|
||||
</h2>
|
||||
</div>
|
||||
<div class="grid gap-6 lg:grid-cols-2">
|
||||
<div class="relative flex min-h-[430px] items-center justify-center overflow-hidden rounded-xl border border-border bg-stone-200 p-4">
|
||||
<div class="absolute inset-0 bg-foreground/35"></div>
|
||||
<span class="absolute left-4 top-4 rounded-full bg-white/90 px-2.5 py-1 text-xs font-medium">Publicado</span>
|
||||
<div role="dialog" aria-modal="true" aria-labelledby="published-title" class="dialog-shadow relative grid w-full max-w-sm gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10">
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="grid size-9 shrink-0 place-items-center rounded-full bg-red-50 text-destructive"><svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10" /><path d="M12 8v4" /><path d="M12 16h.01" /></svg></div>
|
||||
<div class="min-w-0"><h3 id="published-title" class="text-base font-medium">Apagar esta peça?</h3><p class="mt-2 text-sm leading-6 text-muted-foreground">O link público <span class="font-medium text-foreground">/conteudos/<slug></span> deixa de funcionar para quem já recebeu. Esta ação não pode ser desfeita.</p></div>
|
||||
</div>
|
||||
<div class="-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t border-border bg-muted/50 p-4 sm:flex-row sm:justify-end">
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-4 text-sm font-medium">Cancelar</button>
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg bg-destructive px-4 text-sm font-medium text-white">Apagar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative flex min-h-[430px] items-center justify-center overflow-hidden rounded-xl border border-border bg-stone-200 p-4">
|
||||
<div class="absolute inset-0 bg-foreground/35"></div>
|
||||
<span class="absolute left-4 top-4 rounded-full bg-white/90 px-2.5 py-1 text-xs font-medium">Rascunho · processando · falhou</span>
|
||||
<div role="dialog" aria-modal="true" aria-labelledby="draft-title" class="dialog-shadow relative grid w-full max-w-sm gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10">
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="grid size-9 shrink-0 place-items-center rounded-full bg-red-50 text-destructive"><svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10" /><path d="M12 8v4" /><path d="M12 16h.01" /></svg></div>
|
||||
<div class="min-w-0"><h3 id="draft-title" class="text-base font-medium">Apagar esta peça?</h3><p class="mt-2 text-sm leading-6 text-muted-foreground">Esta ação não pode ser desfeita.</p></div>
|
||||
</div>
|
||||
<div class="-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t border-border bg-muted/50 p-4 sm:flex-row sm:justify-end">
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-4 text-sm font-medium">Cancelar</button>
|
||||
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg bg-destructive px-4 text-sm font-medium text-white">Apagar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CENAS G–H — FEEDBACK -->
|
||||
<section id="feedback" aria-labelledby="feedback-title">
|
||||
<div class="mb-3">
|
||||
<p class="text-xs font-medium text-muted-foreground">Cenas G–H · estados críticos do diálogo</p>
|
||||
<h2 id="feedback-title" class="mt-1 text-base font-semibold">
|
||||
Falha permanece no contexto; envio bloqueia os dois gestos
|
||||
</h2>
|
||||
</div>
|
||||
<div class="grid gap-6 lg:grid-cols-2">
|
||||
<div class="relative flex min-h-[470px] items-center justify-center overflow-hidden rounded-xl border border-border bg-stone-200 p-4">
|
||||
<div class="absolute inset-0 bg-foreground/35"></div>
|
||||
<span class="absolute left-4 top-4 rounded-full bg-white/90 px-2.5 py-1 text-xs font-medium">Erro ao apagar</span>
|
||||
<div role="dialog" aria-modal="true" aria-labelledby="error-title" class="dialog-shadow relative grid w-full max-w-sm gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10">
|
||||
<div class="flex items-start gap-3"><div class="grid size-9 shrink-0 place-items-center rounded-full bg-red-50 text-destructive"><svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10" /><path d="M12 8v4" /><path d="M12 16h.01" /></svg></div><div><h3 id="error-title" class="text-base font-medium">Apagar esta peça?</h3><p class="mt-2 text-sm leading-6 text-muted-foreground">Esta ação não pode ser desfeita.</p></div></div>
|
||||
<div role="alert" class="grid w-full grid-cols-[auto_1fr] gap-x-2 rounded-lg border border-border bg-card px-2.5 py-2 text-left text-destructive"><svg aria-hidden="true" class="mt-0.5 size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10" /><path d="M12 8v4" /><path d="M12 16h.01" /></svg><p class="text-xs">Não foi possível apagar a peça.</p></div>
|
||||
<div class="-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t border-border bg-muted/50 p-4 sm:flex-row sm:justify-end"><button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-4 text-sm font-medium">Cancelar</button><button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg bg-destructive px-4 text-sm font-medium text-white">Apagar</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative flex min-h-[470px] items-center justify-center overflow-hidden rounded-xl border border-border bg-stone-200 p-4">
|
||||
<div class="absolute inset-0 bg-foreground/35"></div>
|
||||
<span class="absolute left-4 top-4 rounded-full bg-white/90 px-2.5 py-1 text-xs font-medium">Enviando</span>
|
||||
<div role="dialog" aria-modal="true" aria-labelledby="submitting-title" class="dialog-shadow relative grid w-full max-w-sm gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10">
|
||||
<div class="flex items-start gap-3"><div class="grid size-9 shrink-0 place-items-center rounded-full bg-red-50 text-destructive"><svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10" /><path d="M12 8v4" /><path d="M12 16h.01" /></svg></div><div><h3 id="submitting-title" class="text-base font-medium">Apagar esta peça?</h3><p class="mt-2 text-sm leading-6 text-muted-foreground">O link público <span class="font-medium text-foreground">/conteudos/<slug></span> deixa de funcionar para quem já recebeu. Esta ação não pode ser desfeita.</p></div></div>
|
||||
<div class="-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t border-border bg-muted/50 p-4 sm:flex-row sm:justify-end">
|
||||
<button disabled type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-4 text-sm font-medium opacity-50">Cancelar</button>
|
||||
<button disabled type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg bg-destructive px-4 text-sm font-medium text-white opacity-70"><svg aria-hidden="true" class="size-4 animate-spin motion-reduce:animate-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12a9 9 0 1 1-6.2-8.6" /></svg>Apagar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
108
docs/plans/central-conteudos-apagar-peca.md
Normal file
108
docs/plans/central-conteudos-apagar-peca.md
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
# C222 — Central de Conteúdos — apagar uma peça
|
||||
|
||||
Status: rascunho
|
||||
Atualizado em: 2026-09-24
|
||||
Issue: #1330
|
||||
Priority: P2
|
||||
Impeccable: B — encaixe na Central de Conteúdos (lista + detalhe): ação de apagar com confirmação
|
||||
Design UI: docs/plans/central-conteudos-apagar-peca-ui-design.html
|
||||
Appetite: ~1 dia eng; um outcome verificável
|
||||
Responsável: —
|
||||
|
||||
## Intenção
|
||||
|
||||
A Central de Conteúdos (C211) resolveu o garimpo: a assessoria envia, cataloga e publica as peças de campanha em `/campanha/comunicacao/conteudos`. Mas deixou um beco declarado — não existe nenhuma superfície de apagar; o `delete` ficou restrito ao admin do Payload como anti-goal aceito ("campanha nunca perde um arquivo por acidente"). Consequência: uma peça errada, duplicada ou que ninguém vai usar fica na Central e na pública para sempre; só um admin do Payload consegue removê-la, e a assessoria, que é quem sabe que a peça não presta, não tem como limpar a própria mesa.
|
||||
|
||||
O pedido humano reabre esse anti-goal de propósito — exatamente como o C183 (#1105, `docs/plans/biblioteca-cortes-apagar-e-falhas.md`) reabriu o "deletar corte não existe na UI" dos cortes do acervo. O pedido é direto: poder apagar uma peça de conteúdo, com confirmação explícita.
|
||||
|
||||
## Persona e fluxo
|
||||
|
||||
- **Persona / contexto:** assessoria de comunicação (`communicator`) e coordenação/candidatura, em `/campanha/comunicacao/conteudos`, na mesa ou no celular, sob prazo — quem não é da vertical (`advisor`, `leader`) segue negado.
|
||||
- **Job principal:** "tirar da Central uma peça que não serve mais — errada, duplicada ou vencida — sem depender do admin do Payload".
|
||||
- **Fluxo desejado:** abre a Central → vê a peça que não serve na lista (ou no detalhe) → "Apagar" → a confirmação avisa o efeito (se publicada, o link público morre para quem já recebeu) → confirma → a peça some da lista interna, some da Central pública e o arquivo privado sai junto.
|
||||
- **Anti-goals de produto:** não virar lixeira/desfazer (soft delete) nem restauração; sem lote; sem editor de peça; sem métricas/telemetria de exclusão; sem dashboard nova; não mexer no kill switch de publicação (despublicar continua o gesto reversível e existente).
|
||||
- **Reabertura de anti-goal (produto):** o C211 (`docs/plans/central-conteudos-ingestao.md`) declarou "sem delete na Central; só admin do Payload" como guardrail aceito. O pedido humano reabre de propósito. Ao apagar, respeitar o contrato público: uma peça publicada tem link `/conteudos/<slug>` já distribuível, então apagar é ação explícita e avisada — nunca em silêncio.
|
||||
|
||||
### Esboço de fluxo (B)
|
||||
|
||||
```text
|
||||
[Central de Conteúdos: lista] → peça que não serve (na lista ou no detalhe)
|
||||
→ [Apagar] → confirmação: "Apagar esta peça?" (avisa o link público se publicada)
|
||||
→ confirma → some da lista interna, some da Central pública, arquivo privado sai junto
|
||||
[outcome: Central limpa, sem peça fantasma e sem arquivo órfão]
|
||||
```
|
||||
|
||||
### Design UI (B)
|
||||
|
||||
- Design UI (gate): `docs/plans/central-conteudos-apagar-peca-ui-design.html` — encaixe na lista (ação por linha, junto de Abrir/Reprocessar) e no detalhe; a distribuição exata das cenas é do design.
|
||||
|
||||
## Objetivo e aceite
|
||||
|
||||
- A Central (lista e detalhe) permite apagar uma peça, com confirmação explícita; após apagar, a peça some da Central e não aparece na pública.
|
||||
- Apagar peça publicada avisa, no diálogo, que o link `/conteudos/<slug>` deixa de funcionar para quem já recebeu; despublicar continua a alternativa reversível (não é pré-requisito).
|
||||
- "Apagar" existe em qualquer estado — inclusive `processando` (saída de quem quer cancelar um processamento travado) e `falhou`. _(assumido — validar no gate)_
|
||||
- O arquivo privado da peça sai junto (mídia exclusiva da peça, sem resíduo no storage); os contadores de circulação morrem com a peça — não há dashboard a limpar. _(assumido — validar no gate)_
|
||||
- **Quem pode apagar:** a mesma audiência da vertical que hoje cria/edita/publica (`communicator`, `coordinator`, `candidate`) + admin do Payload; `advisor`/`leader` negados (fail-closed).
|
||||
- Apagar é definitivo (hard delete, sem lixeira/desfazer) e por peça, sem lote na v1.
|
||||
|
||||
## Dados (intenção)
|
||||
|
||||
- **Vou apresentar dados?** Não — é uma decisão de estado do item (apagar), não um painel.
|
||||
- **Decisões desbloqueadas:** a assessoria decide o que sai da Central; nenhuma leitura agregada nova.
|
||||
- **Forma:** _adiada ao plano de implementação_ — restrição de produto: sem contador de exclusão, sem auditoria exposta, sem telemetria de "peças apagadas".
|
||||
|
||||
## Dados da decisão (literais)
|
||||
|
||||
- **Ação:** `Apagar` (na lista e no detalhe).
|
||||
- **Diálogo:** título `Apagar esta peça?` · botões `Cancelar` / `Apagar`.
|
||||
- **Corpo (peça publicada):** `O link público /conteudos/<slug> deixa de funcionar para quem já recebeu. Esta ação não pode ser desfeita.`
|
||||
- **Corpo (rascunho/em processamento/falhou):** `Esta ação não pode ser desfeita.`
|
||||
- **Estados:** processamento `processando` | `pronto` | `falhou`; publicação `rascunho` | `publicado` — apagar disponível em todos.
|
||||
- **Rotas internas:** `/campanha/comunicacao/conteudos` (lista) e `/campanha/comunicacao/conteudos/[id]` (detalhe).
|
||||
- **Contrato público:** peça publicada aparece em `/conteudos/<slug>` (S27) e serve a mídia em `/conteudos/<slug>/midia`; apagar quebra esses links para quem já recebeu — daí o aviso.
|
||||
- **Acesso:** `communicator`, `coordinator`, `candidate` apagam; `advisor` e `leader` negados (fail-closed); admin do Payload mantém o delete.
|
||||
|
||||
## Direção no codebase (hipótese)
|
||||
|
||||
- **Áreas prováveis:** lista `src/app/(campaign)/campanha/(app)/comunicacao/conteudos/page.tsx` (`src/components/campaign/content/ContentPieceTable.tsx`, `ContentPieceCardList.tsx`) e detalhe `.../conteudos/[id]/page.tsx`; access em `src/collections/ContentPiece.ts` (o `delete` a reabrir) e predicados em `src/utilities/access/contentPieces.ts`; leitura pública em `src/utilities/content/contentPieceReads.ts`; mídia privada `src/collections/ContentMedia.ts`.
|
||||
- **Precedente a olhar:** C183 — `src/components/campaign/speech/SpeechCutDeleteDialog.tsx` (AlertDialog, aviso do link público, botão destructive) e `docs/plans/biblioteca-cortes-apagar-e-falhas.md`; cascata de mídia própria em `src/collections/Speech.ts` (`deleteSpeechAssets`).
|
||||
- **Risco de acoplamento:** a lista pública é cacheada (tag `contentPieces`) e hoje só o `afterChange` a busta — apagar precisa refletir na pública sem peça fantasma; o job de processamento tolera a row sumida (cancelar em `processando` não pode derrubar o worker); eventos de circulação (`ContentEvent`, C213) referenciam a peça por `subjectId` texto, sem FK — órfãos inertes, não limpar.
|
||||
|
||||
## Dependências
|
||||
|
||||
- Nenhuma — o C211 está entregue; o S27 é o contrato público a respeitar.
|
||||
|
||||
## Fora de escopo
|
||||
|
||||
- Lote (apagar várias peças), lixeira/desfazer e restauração (soft delete).
|
||||
- Limpar eventos órfãos de circulação (C213) — são inertes e não aparecem em lugar nenhum após a peça sumir.
|
||||
- Métricas/telemetria de exclusão e dashboard nova.
|
||||
- Apagar mídia compartilhada de outra peça (não existe) e qualquer mudança na página pública além de a peça sumir.
|
||||
- Mexer no kill switch de publicação: despublicar continua o gesto reversível; editor de peça fica de fora.
|
||||
|
||||
## Rabbit holes de produto
|
||||
|
||||
- **"Já que apaga, deixa uma lixeira pra desfazer."** Se alguém "só completar": soft delete, retenção e restauração. **Corte neste item:** apagar é definitivo, com confirmação; sem lixeira.
|
||||
- **"Já que apaga, apaga em lote."** Se alguém "só completar": seleção múltipla, confirmação em massa, progresso. **Corte neste item:** uma peça por vez (v1); lote é item próprio se o uso pedir.
|
||||
- **"Já que apaga, limpa os eventos órfãos."** Se alguém "só completar": varredura/reconciliação de `ContentEvent`. **Corte neste item:** eventos órfãos são inertes; sem faxina de analytics.
|
||||
|
||||
## Questões em aberto (produto)
|
||||
|
||||
- **Apagar em qualquer estado ou bloquear `processando`?** **Opções:** A) qualquer estado, inclusive `processando` (cancelar job travado) | B) só depois de `pronto`/`falhou`. **Recomendação:** A — quem quer cancelar um processamento travado precisa da saída; o job tolera a row sumida. _(assumido — validar no gate)_
|
||||
- **Ação na lista ou só no detalhe?** **Opções:** A) só no detalhe | B) na lista (junto de Abrir/Reprocessar) e no detalhe. **Recomendação:** B — a limpeza acontece na lista e a confirmação evita o clique errado. _(assumido — validar no gate)_
|
||||
- **Arquivo privado sai junto ou fica órfão adiado?** **Opções:** A) sai junto com a peça | B) fica órfão, como no C183. **Recomendação:** A — aqui a mídia é exclusiva da peça (o público serve o mesmo objeto), então resíduo não faz sentido; o "como" fica para o plano de implementação. _(assumido — validar no gate)_
|
||||
- **Publicada, apagar é definitivo ou redireciona para "Despublicar"?** **Opções:** A) apaga de vez com aviso | B) só despublica. **Recomendação:** A — despublicar é reversível e já existe; quem quer apagar quer remover de vez. _(assumido — validar no gate)_
|
||||
|
||||
## Referências
|
||||
|
||||
- GitHub Issue: #1330
|
||||
- Design UI (gate): `docs/plans/central-conteudos-apagar-peca-ui-design.html`
|
||||
- Precedente: `docs/plans/biblioteca-cortes-apagar-e-falhas.md` (C183, #1105) · `src/components/campaign/speech/SpeechCutDeleteDialog.tsx`
|
||||
- Planos irmãos: `docs/plans/central-conteudos-ingestao.md` (C211, anti-goal reaberto) · `docs/plans/central-conteudos-publica.md` (S27, contrato do link) · `docs/plans/central-conteudos-analytics.md` (C213, eventos)
|
||||
- Arquivos-pista: `src/collections/ContentPiece.ts` · `src/collections/ContentMedia.ts` · `src/utilities/access/contentPieces.ts` · `src/utilities/content/contentPieceReads.ts` · `src/components/campaign/content/ContentPieceTable.tsx` · `src/components/campaign/content/ContentPieceCardList.tsx` · `src/app/(campaign)/campanha/(app)/comunicacao/conteudos/page.tsx` e `[id]/page.tsx`
|
||||
- Testes a tocar: `tests/int/contentPiece.int.spec.ts` · `tests/e2e/campaignSpeechAcervo.e2e.spec.ts` (seção C211) · `tests/unit/speechCutDeleteDialog.unit.spec.tsx` (molde do diálogo)
|
||||
- `AGENTS.md` — vertical Comunicação, fail-closed, mídia privada/S3
|
||||
|
||||
## Self-score (shaping)
|
||||
|
||||
5/5 — (1) fatia = um outcome verificável (apagar uma peça e ela sumir da Central e da pública, sem resíduo de arquivo); (2) appetite ~1 dia declarado e o escopo cabe (encaixe na lista/detalhe, sem lote/lixeira/telemetria); (3) persona, job e aceite em linguagem de usuário, com a reabertura do anti-goal e o contrato do link público explícitos; (4) direção no codebase é hipótese com precedente nomeado, sem contrato; (5) zero decisão dura de engenharia (formato da ação, cascata de mídia e bust de cache ficam para o plano de implementação — aqui só se declara quem pode apagar e o efeito de produto).
|
||||
Loading…
Reference in a new issue