Skip to content
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Algoria

![](https://img.shields.io/badge/Versão-1.0.0-black?style=for-the-badge)
![](https://img.shields.io/badge/Versão-1.0.3-black?style=for-the-badge)

Plataforma em português para estudar **algoritmos e decisões em código** através de leitura guiada: catálogo de problemas com várias soluções (brute-force, óptima, alternativa), **code player** linha-a-linha com três níveis de explicação, mini-guias em **Conceitos**, **curso modular** com avaliações locais, hub de **inglês técnico para entrevistas** (conteúdo em inglês) e guias de **engenharia aplicada** (front, back, DevOps).

Expand Down
16 changes: 10 additions & 6 deletions app/changelog/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ArrowLeft } from "lucide-react";
import type { Metadata } from "next";
import Link from "next/link";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";

import { getChangelogHtml } from "@/lib/content/loader";
Expand Down Expand Up @@ -32,14 +33,17 @@ export default async function ChangelogPage() {
</Link>
</Button>
<main>
<header className="mb-10 border-l-4 border-primary pl-8">
<p className="text-[10px] font-black uppercase tracking-[0.35em] text-primary mb-2">
Atualizações
</p>
<h1 className="text-4xl font-black tracking-tighter uppercase mb-3">
<header className="mb-16 border-l-4 border-primary pl-8">
<Badge
variant="secondary"
className="mb-4 rounded-none bg-primary/10 px-1.5 py-0 font-mono text-[10px] uppercase text-primary"
>
Últimas Atualizações
</Badge>
<h1 className="mb-4 text-4xl font-black uppercase tracking-tighter md:text-6xl">
Novidades
</h1>
<p className="text-muted-foreground text-sm leading-relaxed">
<p className="max-w-2xl text-lg leading-relaxed tracking-tight text-muted-foreground">
Descobre as últimas melhorias, novos conteúdos e funcionalidades
desenhadas para levar o teu conhecimento técnico ao próximo nível.
</p>
Expand Down
61 changes: 42 additions & 19 deletions app/concepts/page.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import Link from 'next/link';
import type { Metadata } from 'next';
import type { Metadata } from "next";
import Link from "next/link";

import { ConceptsCatalogClient } from '@/components/concepts/concepts-catalog-client';
import { getAllConcepts } from '@/lib/content/loader';
import { buildPublicMetadata } from '@/lib/seo/build-metadata';
import { ConceptsCatalogClient } from "@/components/concepts/concepts-catalog-client";
import { Badge } from "@/components/ui/badge";
import { getAllConcepts } from "@/lib/content/loader";
import { buildPublicMetadata } from "@/lib/seo/build-metadata";

export const metadata: Metadata = buildPublicMetadata({
title: 'Conceitos de algoritmos e estruturas de dados',
title: "Conceitos de algoritmos e estruturas de dados",
description:
'Mini-guias sobre Big O, tabelas hash, duas ponteiros, janela deslizante e mais — base para ler as soluções com contexto.',
pathname: '/concepts',
"Mini-guias sobre Big O, tabelas hash, duas ponteiros, janela deslizante e mais — base para ler as soluções com contexto.",
pathname: "/concepts",
keywords: [
'Big O',
'complexidade algorítmica',
'hash table',
'two pointers',
'sliding window',
'fundamentos algoritmos',
'Algoria conceitos',
"Big O",
"complexidade algorítmica",
"hash table",
"two pointers",
"sliding window",
"fundamentos algoritmos",
"Algoria conceitos",
],
});

Expand All @@ -36,13 +37,35 @@ export default async function ConceptsPage() {
return (
<div className="relative bg-grid-pattern">
<div className="mx-auto max-w-7xl px-6 py-24">
<header className="mb-16 border-l-4 border-primary pl-8">
<Badge
variant="secondary"
className="mb-4 rounded-none bg-primary/10 px-1.5 py-0 font-mono text-[10px] uppercase text-primary"
>
Conceitos de algoritmos e estruturas de dados
</Badge>
<h1 className="mb-4 text-4xl font-black uppercase tracking-tighter md:text-6xl">
Conceitos fundamentais
</h1>
<p className="max-w-2xl text-lg leading-relaxed tracking-tight text-muted-foreground">
Os pilares fundamentais para entender problemas de algoritmos e
estruturas de dados.
</p>
</header>

<div className="mb-14 flex flex-col gap-6 rounded-xl border border-primary/35 bg-background/95 p-6 md:flex-row md:items-center md:justify-between">
<div className="max-w-xl space-y-2">
<p className="text-[10px] font-black uppercase tracking-[0.35em] text-primary">Nova trilha</p>
<h2 className="text-xl font-bold tracking-tight">Prefere um programa com ordem fixa?</h2>
<p className="text-[10px] font-black uppercase tracking-[0.35em] text-primary">
Nova trilha
</p>
<h2 className="text-xl font-bold tracking-tight">
Prefere um programa com ordem fixa?
</h2>
<p className="text-sm leading-relaxed text-muted-foreground">
O mesmo conteúdo abaixo entra também no curso de Fundamentos: progresso no browser, dois níveis nos exemplos
interativos e certificado próprio assim que resolveres a avaliação de cada módulo.
O mesmo conteúdo abaixo entra também no curso de Fundamentos:
progresso no browser, dois níveis nos exemplos interativos e
certificado próprio assim que resolveres a avaliação de cada
módulo.
</p>
</div>
<Link
Expand Down
35 changes: 15 additions & 20 deletions app/course/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { ArrowRight, Code2 } from 'lucide-react';

Check warning on line 1 in app/course/page.tsx

View workflow job for this annotation

GitHub Actions / verify

'Code2' is defined but never used
import type { Metadata } from 'next';
import Link from 'next/link';

import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { getCoursePackHydrated, listCourseSlugs } from '@/lib/courses/hydrate-course-pack';
import { buildPublicMetadata } from '@/lib/seo/build-metadata';

Expand All @@ -21,26 +22,20 @@
return (
<div className="relative bg-grid-pattern flex flex-col flex-1">
<div className="mx-auto w-full max-w-7xl px-6 py-12 md:py-20 flex-1">
<header className="mb-14 rounded-xl border border-primary/35 bg-background/95 p-6 md:p-8">
<div className="flex flex-col gap-6 md:flex-row md:items-start md:justify-between">
<div className="flex items-start gap-4">
<div className="flex h-12 w-12 shrink-0 items-center justify-center border-2 border-primary text-primary">
<Code2 className="h-6 w-6" aria-hidden />
</div>
<div className="space-y-3 max-w-2xl">
<p className="text-[10px] font-black uppercase tracking-[0.35em] text-primary">
Algoria.curriculum
</p>
<h1 className="text-2xl font-black uppercase tracking-tight md:text-3xl">
Cursos Guiados
</h1>
<p className="text-sm leading-relaxed text-muted-foreground">
Cada curso combina leitura, exemplos práticos e exercícios no browser.
Obtém certificados modulares ao concluir as avaliações de cada capítulo.
</p>
</div>
</div>
</div>
<header className="mb-16 border-l-4 border-primary pl-8">
<Badge
variant="secondary"
className="mb-4 rounded-none bg-primary/10 px-1.5 py-0 font-mono text-[10px] uppercase text-primary"
>
Trilhas de Aprendizagem
</Badge>
<h1 className="mb-4 text-4xl font-black uppercase tracking-tighter md:text-6xl">
Cursos Guiados
</h1>
<p className="max-w-2xl text-lg leading-relaxed tracking-tight text-muted-foreground">
Percursos estruturados com leitura curada, exercícios no browser e certificado modular
ao concluir cada avaliação.
</p>
</header>

<div className="grid gap-6">
Expand Down
139 changes: 85 additions & 54 deletions app/engineering-work/page.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,42 @@
import Link from 'next/link';
import type { Metadata } from 'next';
import type { ReactNode } from 'react';
import { Briefcase, Clock, MonitorSmartphone, Server, CloudCog } from 'lucide-react';
import { Clock, CloudCog, MonitorSmartphone, Server } from "lucide-react";
import type { Metadata } from "next";
import Link from "next/link";
import type { ReactNode } from "react";

import { Badge } from '@/components/ui/badge';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { ENGINEERING_WORK_PILLARS, type EngineeringWorkPillar } from '@/lib/content/schemas';
import { getAllEngineeringWorkGuides } from '@/lib/content/loader';
import { buildPublicMetadata } from '@/lib/seo/build-metadata';
import { Badge } from "@/components/ui/badge";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { getAllEngineeringWorkGuides } from "@/lib/content/loader";
import {
ENGINEERING_WORK_PILLARS,
type EngineeringWorkPillar,
} from "@/lib/content/schemas";
import { buildPublicMetadata } from "@/lib/seo/build-metadata";

export const metadata: Metadata = buildPublicMetadata({
title: 'Engenharia no trabalho — guias práticos',
title: "Engenharia no trabalho — guias práticos",
description:
'Guias em português sobre frontend e produto, backend e APIs, DevOps e operação — aplicáveis na sprint real, sem lista de buzzwords.',
pathname: '/engineering-work',
"Guias em português sobre frontend e produto, backend e APIs, DevOps e operação — aplicáveis na sprint real, sem lista de buzzwords.",
pathname: "/engineering-work",
keywords: [
'engenharia software prática',
'frontend produção',
'APIs backend',
'DevOps dia a dia',
'observabilidade',
'segurança aplicações',
'Algoria guias',
"engenharia software prática",
"frontend produção",
"APIs backend",
"DevOps dia a dia",
"observabilidade",
"segurança aplicações",
"Algoria guias",
],
});

const PILLAR_ORDER = new Map<EngineeringWorkPillar, number>(ENGINEERING_WORK_PILLARS.map((p, i) => [p, i]));
const PILLAR_ORDER = new Map<EngineeringWorkPillar, number>(
ENGINEERING_WORK_PILLARS.map((p, i) => [p, i]),
);

const PILLAR_ICON: Record<EngineeringWorkPillar, ReactNode> = {
frontend: <MonitorSmartphone className="h-6 w-6" aria-hidden />,
Expand All @@ -34,21 +45,26 @@ const PILLAR_ICON: Record<EngineeringWorkPillar, ReactNode> = {
};

const PILLAR_TITLE: Record<EngineeringWorkPillar, string> = {
frontend: 'Frontend e produto',
backend: 'Backend e APIs',
devops: 'DevOps e sistema',
frontend: "Frontend e produto",
backend: "Backend e APIs",
devops: "DevOps e sistema",
};

const PILLAR_TAGLINE: Record<EngineeringWorkPillar, string> = {
frontend: 'Performance real, segurança em superfícies web e SEO técnico honesto.',
backend: 'Identidade, permissões, contratos estáveis e resiliência sob carga.',
devops: 'Entrega contínua, observabilidade e segurança operacional sem teatro.',
frontend:
"Performance real, segurança em superfícies web e SEO técnico honesto.",
backend:
"Identidade, permissões, contratos estáveis e resiliência sob carga.",
devops:
"Entrega contínua, observabilidade e segurança operacional sem teatro.",
};

export default async function EngineeringWorkHubPage() {
const guides = await getAllEngineeringWorkGuides();
guides.sort((a, b) => {
const pd = (PILLAR_ORDER.get(a.meta.pillar) ?? 99) - (PILLAR_ORDER.get(b.meta.pillar) ?? 99);
const pd =
(PILLAR_ORDER.get(a.meta.pillar) ?? 99) -
(PILLAR_ORDER.get(b.meta.pillar) ?? 99);
if (pd !== 0) return pd;
return a.meta.title.localeCompare(b.meta.title);
});
Expand All @@ -61,48 +77,58 @@ export default async function EngineeringWorkHubPage() {
return (
<div className="relative bg-grid-pattern">
<div className="mx-auto max-w-7xl px-6 py-24">
<header className="mb-14 rounded-xl border border-primary/35 bg-background/95 p-6 md:p-8">
<div className="flex flex-col gap-6 md:flex-row md:items-start">
<div className="flex h-12 w-12 shrink-0 items-center justify-center border-2 border-primary text-primary">
<Briefcase className="h-6 w-6" aria-hidden />
</div>
<div className="max-w-3xl space-y-4">
<p className="text-[10px] font-black uppercase tracking-[0.35em] text-primary">Área aplicada</p>
<h1 className="text-2xl font-black uppercase tracking-tight md:text-4xl">Engenharia no trabalho</h1>
<p className="text-sm leading-relaxed text-muted-foreground md:text-base">
Material pensado para ler com calma e usar na segunda-feira: cada guia separa o que é conceito, o que é decisão de produto e o que é
checklist na prática. Sem pressupor cloud específica nem framework único — quando há exemplos, são ilustrativos.
</p>
<p className="text-xs leading-relaxed text-muted-foreground border-l-2 border-primary/25 pl-4">
Voltaste da página inicial? Os mesmos três pilares (front, back, DevOps) estão aqui expandidos em capítulos longos. Usa o tempo estimado
como bloco de foco — pausa entre guias para experimentar no teu projeto.
</p>
</div>
</div>
<header className="mb-16 border-l-4 border-primary pl-8">
<Badge
variant="secondary"
className="mb-4 rounded-none bg-primary/10 px-1.5 py-0 font-mono text-[10px] uppercase text-primary"
>
Conteúdo prático de engenharia
</Badge>
<h1 className="mb-4 text-4xl font-black uppercase tracking-tighter md:text-6xl">
Engenharia no trabalho
</h1>
<p className="max-w-2xl text-lg leading-relaxed tracking-tight text-muted-foreground">
Frontend, Backend e DevOps aplicados ao mundo real. Material pensado
para ler com calma e usar na segunda-feira.
</p>
</header>

<div className="space-y-20">
{byPillar.map(({ pillar, guides: list }) => (
<section key={pillar} aria-labelledby={`pillar-${pillar}`} className="scroll-mt-28">
<section
key={pillar}
aria-labelledby={`pillar-${pillar}`}
className="scroll-mt-28"
>
<div className="mb-8 flex flex-col gap-4 border-b border-border pb-8 md:flex-row md:items-end md:justify-between">
<div className="flex items-start gap-4">
<div className="flex h-11 w-11 shrink-0 items-center justify-center border border-primary/40 text-primary">
{PILLAR_ICON[pillar]}
</div>
<div>
<Badge variant="secondary" className="mb-2 rounded-none bg-primary/10 px-2 py-0 font-mono text-[9px] uppercase text-primary">
<Badge
variant="secondary"
className="mb-2 rounded-none bg-primary/10 px-2 py-0 font-mono text-[9px] uppercase text-primary"
>
Pilar · {pillar}
</Badge>
<h2 id={`pillar-${pillar}`} className="text-xl font-black uppercase tracking-tight md:text-2xl">
<h2
id={`pillar-${pillar}`}
className="text-xl font-black uppercase tracking-tight md:text-2xl"
>
{PILLAR_TITLE[pillar]}
</h2>
<p className="mt-2 max-w-xl text-sm text-muted-foreground">{PILLAR_TAGLINE[pillar]}</p>
<p className="mt-2 max-w-xl text-sm text-muted-foreground">
{PILLAR_TAGLINE[pillar]}
</p>
</div>
</div>
</div>

{list.length === 0 ? (
<p className="text-sm text-muted-foreground">Conteúdo deste pilar em preparação.</p>
<p className="text-sm text-muted-foreground">
Conteúdo deste pilar em preparação.
</p>
) : (
<div className="grid gap-0 border border-border sm:grid-cols-2">
{list.map((g) => (
Expand All @@ -117,11 +143,14 @@ export default async function EngineeringWorkHubPage() {
{g.meta.title}
</CardTitle>
<CardDescription className="mt-2 flex items-center gap-2 font-mono text-[10px] uppercase">
<Clock className="h-3 w-3 shrink-0" aria-hidden /> ~{g.meta.estimatedMinutes} min de leitura
<Clock className="h-3 w-3 shrink-0" aria-hidden /> ~
{g.meta.estimatedMinutes} min de leitura
</CardDescription>
</CardHeader>
<CardContent className="px-6 pb-6">
<p className="text-sm leading-relaxed text-muted-foreground">{g.meta.summary}</p>
<p className="text-sm leading-relaxed text-muted-foreground">
{g.meta.summary}
</p>
</CardContent>
</Card>
</Link>
Expand All @@ -133,8 +162,10 @@ export default async function EngineeringWorkHubPage() {
</div>

<p className="mt-20 border-l-[3px] border-primary/35 pl-6 text-sm text-muted-foreground leading-relaxed">
Sugestão de uso: escolhe um pilar por sprint, lê um guia na sexta ou segunda, e implementa uma única melhoria mensurável (métrica de produto ou
observabilidade) em vez de uma lista enorme de &quot;best practices&quot;.
Sugestão de uso: escolhe um pilar por sprint, lê um guia na sexta ou
segunda, e implementa uma única melhoria mensurável (métrica de
produto ou observabilidade) em vez de uma lista enorme de &quot;best
practices&quot;.
</p>
</div>
</div>
Expand Down
Loading
Loading