Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions .claude/skills/changelog/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Gera automaticamente uma entrada no changelog da documentação Mintlify com bas
| `pages/v2/changelog.mdx` | Corridas |
| `pages/v2/changelog-entregas.mdx` | Entregas |

Cada arquivo define seus próprios componentes (`Entry`, `ChangeSection`, `ParamBadge`, `EndpointBadge`) no topo via `export const`. As entradas `<Entry>` são inseridas diretamente no arquivo, dentro do `<div>` principal, em ordem cronológica decrescente.
Os componentes (`Entry`, `ChangeSection`, `ParamBadge`, `EndpointBadge`) são compartilhados e vivem em `snippets/changelog-components.mdx`; cada arquivo de changelog os importa no topo via `import { Entry, ChangeSection, ParamBadge, EndpointBadge } from '/snippets/changelog-components.mdx';`. O layout responsivo fica nas classes `cl-*` do `custom.css` da raiz. As entradas `<Entry>` são inseridas diretamente no arquivo, dentro do `<div className="cl-container">`, em ordem cronológica decrescente.

## Arquivos OpenAPI da v2

Expand Down Expand Up @@ -224,9 +224,9 @@ Repetir os passos abaixo para **cada arquivo** determinado na etapa 4:
4. Se a nova entrada for a **mais recente** de todas, inserir logo após o bloco de cabeçalho:

```mdx
<div style={{ maxWidth: "860px", margin: "0 auto", padding: "40px 20px 80px" }}>
<div className="cl-container">

<div style={{ marginBottom: "56px" }}>
<div className="cl-page-header">
...
</div>

Expand All @@ -244,7 +244,9 @@ Após inserir, informar ao usuário:

## Componentes disponíveis nos arquivos

Ambos os arquivos de changelog definem os mesmos componentes no topo via `export const`. Nunca redefinir.
Os componentes são definidos uma única vez em `snippets/changelog-components.mdx` e importados pelos dois arquivos de changelog. Nunca redefinir componentes dentro dos changelogs nem remover o `import` do topo.

O layout responsivo (timeline em coluna no mobile, quebra de linha nos badges de endpoint) é controlado pelas classes `cl-*` (`cl-container`, `cl-entry`, `cl-endpoint` etc.) definidas no `custom.css` da raiz — qualquer ajuste visual estrutural deve ser feito lá, não com estilo inline nos componentes.

| Componente | Props | Descrição |
|------------------|--------------------------------------|------------------------------------------------|
Expand All @@ -257,10 +259,10 @@ O `EndpointBadge` suporta os métodos: `GET` (azul), `POST` (verde), `DELETE` (v

## Regras de qualidade

- **Nunca redefinir componentes** que já existem nos arquivos
- **Nunca redefinir componentes** — eles vivem em `snippets/changelog-components.mdx` e são importados; edições estruturais de layout vão para as classes `cl-*` no `custom.css`
- **Sempre incluir `href`** no `EndpointBadge` — buscar em `docs.json` antes de deixar vazio
- **Ordem cronológica decrescente sempre** — comparar datas numericamente antes de inserir; nunca prependar cegamente no topo nem appendar no final sem verificar
- **Sem `href` em `<a>` nulo** — se `href` não foi encontrado, usar `<div>` em vez de `<a>`
- **Sem `href` em `<a>` nulo** — o próprio `EndpointBadge` renderiza `<div>` quando `href` está ausente; basta omitir a prop (e deixar o comentário `{/* TODO: href */}`)
- **Data sempre em português** — `jan`, `fev`, `mar`, `abr`, `mai`, `jun`, `jul`, `ago`, `set`, `out`, `nov`, `dez`
- **Modalidade pelo arquivo openapi** — se `openapi.json` mudou → Corridas; se `openapi-entregas.json` mudou → Entregas; ambos → os dois changelogs
- **Não commitar** — a skill entrega apenas a edição no(s) arquivo(s); o commit é responsabilidade do autor
Expand Down
179 changes: 179 additions & 0 deletions custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,182 @@ html[data-current-path="/pages/v2/changelog-entregas"] .nav-tabs > a:nth-child(4
--cta-color: #e02020;
--cta-tint: rgba(241, 48, 48, 0.1);
}

/* ============================================================
Changelog (Corridas e Entregas) — layout da timeline
Componentes em snippets/changelog-components.mdx
============================================================ */

.cl-container {
max-width: 860px;
margin: 0 auto;
padding: 40px 20px 80px;
}

.cl-page-header {
margin-bottom: 56px;
}

.cl-page-title {
font-size: clamp(28px, 6vw, 40px);
font-weight: 800;
margin-bottom: 12px;
letter-spacing: -0.02em;
}

.cl-page-subtitle {
font-size: 17px;
opacity: 0.65;
line-height: 1.6;
}

.cl-entry {
display: flex;
gap: 32px;
margin-bottom: 56px;
position: relative;
}

/* Coluna de data + label */
.cl-entry-meta {
display: flex;
flex-direction: column;
align-items: center;
min-width: 140px;
padding-top: 4px;
}

.cl-entry-date {
font-size: 13px;
font-weight: 600;
color: var(--tw-prose-body);
opacity: 0.55;
white-space: nowrap;
letter-spacing: 0.02em;
}

.cl-entry-label {
margin-top: 8px;
padding: 3px 10px;
border-radius: 20px;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
white-space: nowrap;
}

/* Barra vertical da timeline com o ponto */
.cl-entry-line {
width: 2px;
background: rgba(22, 163, 74, 0.15);
border-radius: 2px;
flex-shrink: 0;
position: relative;
}

.cl-entry-dot {
Comment thread
tobiasfreire-gaudium marked this conversation as resolved.
position: absolute;
top: 6px;
left: 50%;
transform: translateX(-50%);
width: 10px;
height: 10px;
border-radius: 50%;
Comment thread
tobiasfreire-gaudium marked this conversation as resolved.
background: #16a34a;
border: 2px solid var(--tw-prose-bg, #fff);
box-shadow: 0 0 0 2px rgba(22, 163, 74, 0.27);
}

/* min-width: 0 permite o conteúdo encolher dentro do flex sem estourar */
.cl-entry-body {
flex: 1;
min-width: 0;
padding-bottom: 8px;
}

.cl-entry-body code {
overflow-wrap: anywhere;
}

/* Badge de endpoint (método + path) */
.cl-endpoint {
display: inline-flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
max-width: 100%;
background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 8px;
padding: 6px 12px;
margin-bottom: 16px;
margin-right: 8px;
font-family: monospace;
font-size: 13px;
text-decoration: none;
transition: border-color 0.15s, background 0.15s;
}

a.cl-endpoint[href]:hover {
border-color: rgba(22, 163, 74, 0.5);
background: rgba(22, 163, 74, 0.06);
}

.cl-endpoint-method {
color: #fff;
border-radius: 4px;
padding: 1px 7px;
font-weight: 700;
font-size: 11px;
letter-spacing: 0.05em;
flex-shrink: 0;
}

.cl-endpoint-path {
opacity: 0.8;
overflow-wrap: anywhere;
}

/* Mobile: empilha a entry em coluna, data + label lado a lado no topo,
oculta a barra vertical e libera 100% da largura para o conteúdo */
@media (max-width: 640px) {
.cl-container {
padding: 24px 16px 64px;
}

.cl-page-header {
margin-bottom: 40px;
}

.cl-entry {
flex-direction: column;
gap: 12px;
margin-bottom: 44px;
}

.cl-entry-meta {
flex-direction: row;
align-items: center;
gap: 10px;
min-width: 0;
padding-top: 0;
}

.cl-entry-label {
margin-top: 0;
}

.cl-entry-line {
display: none;
}

.cl-entry-body {
padding-bottom: 0;
}

/* h2 das entries usa fontSize inline de 22px — !important necessário */
Comment thread
tobiasfreire-gaudium marked this conversation as resolved.
.cl-entry-body h2 {
font-size: 19px !important;
}
}
149 changes: 5 additions & 144 deletions pages/v2/changelog-entregas.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,152 +4,13 @@ description: "Histórico de alterações e novidades da API de Entregas v2"
icon: "sparkles"
---

export const Entry = ({ date, label, labelColor = "#16A34A", children }) => (
<div style={{
display: "flex",
gap: "32px",
marginBottom: "56px",
position: "relative",
}}>
<div style={{
display: "flex",
flexDirection: "column",
alignItems: "center",
minWidth: "140px",
paddingTop: "4px",
}}>
<div style={{
fontSize: "13px",
fontWeight: "600",
color: "var(--tw-prose-body)",
opacity: 0.55,
whiteSpace: "nowrap",
letterSpacing: "0.02em",
}}>{date}</div>
{label && (
<div style={{
marginTop: "8px",
padding: "3px 10px",
borderRadius: "20px",
background: `${labelColor}22`,
border: `1px solid ${labelColor}55`,
color: labelColor,
fontSize: "11px",
fontWeight: "700",
letterSpacing: "0.06em",
textTransform: "uppercase",
}}>{label}</div>
)}
</div>

<div style={{
width: "2px",
background: "rgba(22, 163, 74, 0.15)",
borderRadius: "2px",
flexShrink: 0,
position: "relative",
}}>
<div style={{
position: "absolute",
top: "6px",
left: "50%",
transform: "translateX(-50%)",
width: "10px",
height: "10px",
borderRadius: "50%",
background: "#16A34A",
border: "2px solid var(--tw-prose-bg, #fff)",
boxShadow: "0 0 0 2px #16A34A44",
}} />
</div>

<div style={{ flex: 1, paddingBottom: "8px" }}>
{children}
</div>
</div>
);

export const ChangeSection = ({ type, children }) => {
const config = {
added: { label: "Adicionado", bg: "#16A34A14", border: "#16A34A44", dot: "#16A34A" },
changed: { label: "Alterado", bg: "#f59e0b14", border: "#f59e0b44", dot: "#f59e0b" },
fixed: { label: "Corrigido", bg: "#3b82f614", border: "#3b82f644", dot: "#3b82f6" },
removed: { label: "Removido", bg: "#ef444414", border: "#ef444444", dot: "#ef4444" },
};
const c = config[type] ?? config.added;
return (
<div style={{
marginBottom: "16px",
padding: "16px 20px",
borderRadius: "12px",
background: c.bg,
border: `1px solid ${c.border}`,
}}>
<div style={{
display: "flex",
alignItems: "center",
gap: "8px",
marginBottom: "10px",
}}>
<div style={{ width: "8px", height: "8px", borderRadius: "50%", background: c.dot, flexShrink: 0 }} />
<span style={{ fontSize: "12px", fontWeight: "700", letterSpacing: "0.07em", textTransform: "uppercase", color: c.dot }}>{c.label}</span>
</div>
<div style={{ fontSize: "14px", lineHeight: "1.65" }}>
{children}
</div>
</div>
);
};

export const ParamBadge = ({ name }) => (
<code style={{
background: "rgba(22, 163, 74, 0.12)",
border: "1px solid rgba(22, 163, 74, 0.25)",
color: "#16A34A",
borderRadius: "6px",
padding: "1px 6px",
fontSize: "13px",
fontWeight: "600",
}}>{name}</code>
);

export const EndpointBadge = ({ method, path, href }) => (
<a href={href} style={{
display: "inline-flex",
alignItems: "center",
gap: "8px",
background: "rgba(255,255,255,0.04)",
border: "1px solid rgba(255,255,255,0.1)",
borderRadius: "8px",
padding: "6px 12px",
marginBottom: "16px",
fontFamily: "monospace",
fontSize: "13px",
textDecoration: "none",
cursor: href ? "pointer" : "default",
transition: "border-color 0.15s, background 0.15s",
}}
onMouseEnter={e => { if (href) { e.currentTarget.style.borderColor = "rgba(22,163,74,0.5)"; e.currentTarget.style.background = "rgba(22,163,74,0.06)"; }}}
onMouseLeave={e => { e.currentTarget.style.borderColor = "rgba(255,255,255,0.1)"; e.currentTarget.style.background = "rgba(255,255,255,0.04)"; }}
>
<span style={{
background: method === "GET" ? "#3b82f6" : method === "POST" ? "#16A34A" : method === "DELETE" ? "#ef4444" : method === "PUT" ? "#f59e0b" : method === "PATCH" ? "#8b5cf6" : "#6b7280",
color: "#fff",
borderRadius: "4px",
padding: "1px 7px",
fontWeight: "700",
fontSize: "11px",
letterSpacing: "0.05em",
}}>{method}</span>
<span style={{ opacity: 0.8 }}>{path}</span>
</a>
);
import { Entry, ChangeSection, ParamBadge, EndpointBadge } from '/snippets/changelog-components.mdx';

<div style={{ maxWidth: "860px", margin: "0 auto", padding: "40px 20px 80px" }}>
<div className="cl-container">

<div style={{ marginBottom: "56px" }}>
<div style={{ fontSize: "40px", fontWeight: "800", marginBottom: "12px", letterSpacing: "-0.02em" }}>Entregas</div>
<p style={{ fontSize: "17px", opacity: 0.65, lineHeight: "1.6" }}>
<div className="cl-page-header">
<div className="cl-page-title">Entregas</div>
<p className="cl-page-subtitle">
Acompanhe todas as novidades, melhorias e alterações nos endpoints de Entregas da API v2.
</p>
</div>
Expand Down
Loading