diff --git a/scripts/validate-content.mjs b/scripts/validate-content.mjs index eb35d2a..f8281a8 100644 --- a/scripts/validate-content.mjs +++ b/scripts/validate-content.mjs @@ -5,7 +5,7 @@ import { fileURLToPath } from 'url' const __dirname = path.dirname(fileURLToPath(import.meta.url)) const CONTENT_DIR = path.join(__dirname, '..', 'src', 'content') const REQUIRED_FIELDS = ['title', 'category', 'subcategory', 'tags', 'difficulty', 'lang'] -const VALID_DIFFICULTIES = ['beginner', 'intermediate', 'advanced'] +const VALID_DIFFICULTIES = ['junior', 'pleno', 'senior', 'especialista'] const VALID_LANGS = ['en', 'pt'] const REQUIRED_SECTIONS = ['## Full Answer', '## Quick Answer', '## Flashcard'] diff --git a/src/app/[locale]/questions/[category]/[slug]/page.tsx b/src/app/[locale]/questions/[category]/[slug]/page.tsx index d864c19..a292e2c 100644 --- a/src/app/[locale]/questions/[category]/[slug]/page.tsx +++ b/src/app/[locale]/questions/[category]/[slug]/page.tsx @@ -25,9 +25,10 @@ export async function generateStaticParams() { } const difficultyVariant: Record = { - beginner: 'green', - intermediate: 'blue', - advanced: 'orange', + junior: 'green', + pleno: 'blue', + senior: 'orange', + especialista: 'orange', } function extractFlashcardParts(flashcardHtml: string): { front: string; back: string } { diff --git a/src/app/[locale]/updates/page.tsx b/src/app/[locale]/updates/page.tsx new file mode 100644 index 0000000..bb3f4e7 --- /dev/null +++ b/src/app/[locale]/updates/page.tsx @@ -0,0 +1,153 @@ +import { getTranslations, getLocale } from 'next-intl/server' + +type ChangelogEntry = { + date: string + version: string + title: string + titlePt: string + points: string[] + pointsPt: string[] +} + +const CHANGELOG: ChangelogEntry[] = [ + { + date: '2026-06-03', + version: '1.4.0', + title: 'Filter redesign: seniority pills & tag search', + titlePt: 'Filtros redesenhados: pills de nível e busca de tags', + points: [ + 'Replaced flat tag button list with a search input — type to filter, click to add as chip', + 'Added seniority level filter pills (Junior / Mid-level / Senior / Specialist) with multi-select', + 'Filter logic: level AND tags — questions must match both active filters', + 'Keyboard shortcuts: Enter selects top suggestion, Escape clears input, Backspace removes last chip', + 'Clear all filters with one click', + ], + pointsPt: [ + 'Lista gigante de botões de tag substituída por input de busca — digite para filtrar, clique para adicionar como chip', + 'Filtro de nível de senioridade com pills multi-seleção (Júnior / Pleno / Sênior / Especialista)', + 'Lógica combinada: nível E tags — questões aparecem quando atendem ambos os filtros ativos', + 'Atalhos de teclado: Enter seleciona primeira sugestão, Escape limpa o input, Backspace remove último chip', + 'Limpar todos os filtros com um clique', + ], + }, + { + date: '2026-06-03', + version: '1.3.0', + title: 'Seniority levels & Updates page', + titlePt: 'Níveis de senioridade e página de Atualizações', + points: [ + 'Replaced generic difficulty labels (beginner/intermediate/advanced) with job seniority levels (Junior/Mid-level/Senior/Specialist)', + 'Added this Updates page to track project improvements over time', + ], + pointsPt: [ + 'Rótulos genéricos de dificuldade (beginner/intermediate/advanced) substituídos por níveis de cargo (Júnior/Pleno/Sênior/Especialista)', + 'Adicionada esta página de Atualizações para registrar melhorias ao longo do tempo', + ], + }, + { + date: '2026-05-26', + version: '1.2.0', + title: 'New questions & community contributions', + titlePt: 'Novas perguntas e contribuições da comunidade', + points: [ + 'Added Backend questions: Node.js middlewares', + 'Added Frontend questions: web accessibility', + 'Added DevOps questions: Docker, Kubernetes, containers vs VMs', + 'Added Architecture questions: scalable software architecture', + ], + pointsPt: [ + 'Novas perguntas de Backend: middlewares no Node.js', + 'Novas perguntas de Frontend: acessibilidade web', + 'Novas perguntas de DevOps: Docker, Kubernetes, containers vs VMs', + 'Novas perguntas de Arquitetura: arquitetura de software escalável', + ], + }, + { + date: '2026-05-10', + version: '1.1.0', + title: 'Syntax highlighting, analytics & polish', + titlePt: 'Syntax highlighting, analytics e melhorias visuais', + points: [ + 'Integrated Shiki for syntax highlighting in code blocks', + 'Added GitHub Flavored Markdown (GFM) support', + 'Integrated Vercel Analytics', + 'Updated favicon and app icons', + 'Fixed GitHub contributors API authentication', + ], + pointsPt: [ + 'Syntax highlighting em blocos de código com Shiki', + 'Suporte a GitHub Flavored Markdown (GFM)', + 'Analytics integrado via Vercel Analytics', + 'Atualização de favicon e ícones do app', + 'Correção na autenticação da API de contribuidores do GitHub', + ], + }, + { + date: '2026-05-01', + version: '1.0.0', + title: 'Initial launch', + titlePt: 'Lançamento inicial', + points: [ + 'Open-source interview preparation portal for developers', + 'Questions in English and Portuguese', + 'Full answer, quick answer, and interactive flashcard for each question', + 'Study progress saved locally in the browser — no login required', + 'Categories: Frontend, Backend, DevOps, Architecture, Security, Soft Skills', + ], + pointsPt: [ + 'Portal open source de preparação para entrevistas para desenvolvedores', + 'Perguntas em inglês e português', + 'Resposta completa, resposta rápida e flashcard interativo para cada pergunta', + 'Progresso de estudo salvo localmente no navegador — sem cadastro', + 'Categorias: Frontend, Backend, DevOps, Arquitetura, Segurança, Soft Skills', + ], + }, +] + +export default async function UpdatesPage() { + const t = await getTranslations('pages') + const locale = await getLocale() + const isPt = locale === 'pt' + + return ( +
+

+ {t('updates')} +

+

+ {isPt + ? 'O que foi melhorado, corrigido e adicionado ao longo do tempo.' + : 'What has been improved, fixed, and added over time.'} +

+ +
+ {CHANGELOG.map((entry) => ( +
+
+ + v{entry.version} + + + {entry.date} + +
+

+ {isPt ? entry.titlePt : entry.title} +

+
    + {(isPt ? entry.pointsPt : entry.points).map((point, i) => ( +
  • + + {point} +
  • + ))} +
+
+ ))} +
+
+ ) +} diff --git a/src/components/layout/Footer.tsx b/src/components/layout/Footer.tsx index 92697e4..e50f6b0 100644 --- a/src/components/layout/Footer.tsx +++ b/src/components/layout/Footer.tsx @@ -95,6 +95,14 @@ export function Footer() { {nav("contribute")} +
  • + + {nav("updates")} + +
  • diff --git a/src/components/questions/QuestionCard.tsx b/src/components/questions/QuestionCard.tsx index 9413820..cdaca1a 100644 --- a/src/components/questions/QuestionCard.tsx +++ b/src/components/questions/QuestionCard.tsx @@ -1,7 +1,7 @@ 'use client' import Link from 'next/link' -import { useLocale } from 'next-intl' +import { useLocale, useTranslations } from 'next-intl' import { useEffect, useState } from 'react' import { getQuestionStatus } from '@/lib/progress' import { Badge } from '@/components/ui/Badge' @@ -12,13 +12,15 @@ type Props = { } const difficultyVariant: Record = { - beginner: 'green', - intermediate: 'blue', - advanced: 'orange', + junior: 'green', + pleno: 'blue', + senior: 'orange', + especialista: 'orange', } export function QuestionCard({ question }: Props) { const locale = useLocale() + const t = useTranslations('question') const [status, setStatus] = useState<'known' | 'review' | null>(null) useEffect(() => { @@ -37,7 +39,7 @@ export function QuestionCard({ question }: Props) {
    - {question.difficulty} + {t(`difficulty.${question.difficulty}`)} {question.tags.slice(0, 3).map(tag => ( {tag} diff --git a/src/components/questions/QuestionListClient.tsx b/src/components/questions/QuestionListClient.tsx index 54d117e..a5859aa 100644 --- a/src/components/questions/QuestionListClient.tsx +++ b/src/components/questions/QuestionListClient.tsx @@ -1,6 +1,6 @@ 'use client' -import { useState, useMemo, useCallback } from 'react' +import { useState, useMemo, useCallback, useRef } from 'react' import Link from 'next/link' import { useLocale, useTranslations } from 'next-intl' import { useEffect } from 'react' @@ -9,10 +9,13 @@ import { Badge } from '@/components/ui/Badge' import { QuestionCard } from './QuestionCard' import type { QuestionMeta } from '@/lib/content' +const LEVELS = ['junior', 'pleno', 'senior', 'especialista'] as const + const difficultyVariant: Record = { - beginner: 'green', - intermediate: 'blue', - advanced: 'orange', + junior: 'green', + pleno: 'blue', + senior: 'orange', + especialista: 'orange', } function RandomCard({ question, onClose }: { @@ -21,6 +24,7 @@ function RandomCard({ question, onClose }: { }) { const locale = useLocale() const t = useTranslations('categories') + const tQuestion = useTranslations('question') const [status, setStatus] = useState<'known' | 'review' | null>(null) const [revealed, setRevealed] = useState(false) @@ -47,7 +51,7 @@ function RandomCard({ question, onClose }: {
    - {question.difficulty} + {tQuestion(`difficulty.${question.difficulty}`)} {question.tags.slice(0, 4).map(tag => ( {tag} @@ -96,21 +100,46 @@ type Props = { export function QuestionListClient({ questions }: Props) { const t = useTranslations('categories') + const tQuestion = useTranslations('question') const [selectedTags, setSelectedTags] = useState([]) + const [selectedLevels, setSelectedLevels] = useState([]) + const [tagInput, setTagInput] = useState('') + const [tagFocused, setTagFocused] = useState(false) const [randomQuestion, setRandomQuestion] = useState(null) const [seenSlugs, setSeenSlugs] = useState>(new Set()) + const inputRef = useRef(null) + const allTags = useMemo(() => { const set = new Set() questions.forEach(q => q.tags.forEach(tag => set.add(tag))) return Array.from(set).sort() }, [questions]) + const tagSuggestions = useMemo(() => { + if (!tagInput) return [] + const lower = tagInput.toLowerCase() + return allTags + .filter(t => !selectedTags.includes(t) && t.toLowerCase().includes(lower)) + .slice(0, 8) + }, [allTags, selectedTags, tagInput]) + const filtered = useMemo(() => { - if (selectedTags.length === 0) return questions - return questions.filter(q => selectedTags.some(tag => q.tags.includes(tag))) - }, [questions, selectedTags]) + return questions.filter(q => { + const levelMatch = selectedLevels.length === 0 || selectedLevels.includes(q.difficulty) + const tagMatch = selectedTags.length === 0 || selectedTags.some(tag => q.tags.includes(tag)) + return levelMatch && tagMatch + }) + }, [questions, selectedLevels, selectedTags]) + + const toggleLevel = (level: string) => { + setSelectedLevels(prev => + prev.includes(level) ? prev.filter(l => l !== level) : [...prev, level] + ) + setRandomQuestion(null) + setSeenSlugs(new Set()) + } const toggleTag = (tag: string) => { setSelectedTags(prev => @@ -120,12 +149,37 @@ export function QuestionListClient({ questions }: Props) { setSeenSlugs(new Set()) } + const addTag = (tag: string) => { + if (!selectedTags.includes(tag)) { + setSelectedTags(prev => [...prev, tag]) + setRandomQuestion(null) + setSeenSlugs(new Set()) + } + setTagInput('') + inputRef.current?.focus() + } + const clearFilters = () => { setSelectedTags([]) + setSelectedLevels([]) + setTagInput('') setRandomQuestion(null) setSeenSlugs(new Set()) } + const handleTagKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter' && tagSuggestions.length > 0) { + e.preventDefault() + addTag(tagSuggestions[0]) + } + if (e.key === 'Escape') { + setTagInput('') + } + if (e.key === 'Backspace' && tagInput === '' && selectedTags.length > 0) { + setSelectedTags(prev => prev.slice(0, -1)) + } + } + const pickRandom = useCallback(() => { if (filtered.length === 0) return let available = filtered.filter(q => !seenSlugs.has(q.slug)) @@ -144,33 +198,83 @@ export function QuestionListClient({ questions }: Props) { setSeenSlugs(new Set()) } - const isFiltering = selectedTags.length > 0 + const isFiltering = selectedTags.length > 0 || selectedLevels.length > 0 return (
    - {/* Tag filter bar */} - {allTags.length > 0 && ( -
    -
    - - {t('filterLabel')} - - {allTags.map(tag => ( + {/* Level filter */} +
    +
    + + {t('filterLabel')} + + {LEVELS.map(level => { + const active = selectedLevels.includes(level) + return ( + ) + })} +
    +
    + + {/* Tag search */} +
    +
    inputRef.current?.focus()} + > + {selectedTags.map(tag => ( + + {tag} + + + ))} + setTagInput(e.target.value)} + onKeyDown={handleTagKeyDown} + onFocus={() => setTagFocused(true)} + onBlur={() => setTagFocused(false)} + placeholder={selectedTags.length === 0 ? t('searchTags') : ''} + className="flex-1 bg-transparent text-sm text-dark-text placeholder-dark-muted outline-none min-w-[120px]" + /> +
    + + {/* Dropdown */} + {tagFocused && tagSuggestions.length > 0 && ( +
    + {tagSuggestions.map(tag => ( + ))}
    -
    - )} + )} +
    {/* Toolbar: count + random button */}
    diff --git a/src/content/en/architecture/solid/solid-principles.md b/src/content/en/architecture/solid/solid-principles.md index 343d763..392b1c7 100644 --- a/src/content/en/architecture/solid/solid-principles.md +++ b/src/content/en/architecture/solid/solid-principles.md @@ -3,7 +3,7 @@ title: "What are the SOLID principles?" category: architecture subcategory: solid tags: [solid, oop, design-principles, clean-code] -difficulty: intermediate +difficulty: pleno lang: en --- diff --git a/src/content/en/backend/general/sql-vs-nosql.md b/src/content/en/backend/general/sql-vs-nosql.md index ed1b162..7a33a69 100644 --- a/src/content/en/backend/general/sql-vs-nosql.md +++ b/src/content/en/backend/general/sql-vs-nosql.md @@ -3,7 +3,7 @@ title: "What is the difference between SQL and NoSQL databases?" category: backend subcategory: general tags: [database, sql, nosql, relational, mongodb, postgres] -difficulty: intermediate +difficulty: pleno lang: en --- diff --git a/src/content/en/backend/node/event-loop.md b/src/content/en/backend/node/event-loop.md index 9c00f57..d825852 100644 --- a/src/content/en/backend/node/event-loop.md +++ b/src/content/en/backend/node/event-loop.md @@ -3,7 +3,7 @@ title: "How does the Node.js event loop work?" category: backend subcategory: node tags: [event-loop, async, non-blocking, libuv] -difficulty: intermediate +difficulty: pleno lang: en --- diff --git a/src/content/en/devops/docker/docker-basics.md b/src/content/en/devops/docker/docker-basics.md index d37c30e..acce4b2 100644 --- a/src/content/en/devops/docker/docker-basics.md +++ b/src/content/en/devops/docker/docker-basics.md @@ -3,7 +3,7 @@ title: "What is Docker and why is it used?" category: devops subcategory: docker tags: [docker, containers, devops, deployment, images] -difficulty: beginner +difficulty: junior lang: en --- diff --git a/src/content/en/frontend/css/box-model.md b/src/content/en/frontend/css/box-model.md index 1e1d26d..0350325 100644 --- a/src/content/en/frontend/css/box-model.md +++ b/src/content/en/frontend/css/box-model.md @@ -3,7 +3,7 @@ title: "What is the CSS Box Model?" category: frontend subcategory: css tags: [css, box-model, layout, margin, padding] -difficulty: beginner +difficulty: junior lang: en --- diff --git a/src/content/en/frontend/javascript/event-delegation.md b/src/content/en/frontend/javascript/event-delegation.md index c1474b9..a96952b 100644 --- a/src/content/en/frontend/javascript/event-delegation.md +++ b/src/content/en/frontend/javascript/event-delegation.md @@ -3,7 +3,7 @@ title: "What is event delegation?" category: frontend subcategory: javascript tags: [dom, events, performance, bubbling] -difficulty: intermediate +difficulty: pleno lang: en --- diff --git a/src/content/en/frontend/javascript/let-const-var.md b/src/content/en/frontend/javascript/let-const-var.md index b0f504a..d94b84d 100644 --- a/src/content/en/frontend/javascript/let-const-var.md +++ b/src/content/en/frontend/javascript/let-const-var.md @@ -3,7 +3,7 @@ title: "What is the difference between let, const, and var?" category: frontend subcategory: javascript tags: [es6, scope, hoisting, variables] -difficulty: beginner +difficulty: junior lang: en --- diff --git a/src/content/en/frontend/react/controlled-vs-uncontrolled.md b/src/content/en/frontend/react/controlled-vs-uncontrolled.md index ecd0112..3ea1d12 100644 --- a/src/content/en/frontend/react/controlled-vs-uncontrolled.md +++ b/src/content/en/frontend/react/controlled-vs-uncontrolled.md @@ -3,7 +3,7 @@ title: "What is the difference between controlled and uncontrolled components in category: frontend subcategory: react tags: [react, forms, controlled, uncontrolled, state] -difficulty: intermediate +difficulty: pleno lang: en --- diff --git a/src/content/en/frontend/react/hooks.md b/src/content/en/frontend/react/hooks.md index 2f801d5..b38dbd9 100644 --- a/src/content/en/frontend/react/hooks.md +++ b/src/content/en/frontend/react/hooks.md @@ -3,7 +3,7 @@ title: "What are React Hooks and why were they introduced?" category: frontend subcategory: react tags: [hooks, useState, useEffect, functional-components] -difficulty: beginner +difficulty: junior lang: en --- diff --git a/src/content/en/frontend/react/what-is-a-component.md b/src/content/en/frontend/react/what-is-a-component.md index 1d9cce1..1171e63 100644 --- a/src/content/en/frontend/react/what-is-a-component.md +++ b/src/content/en/frontend/react/what-is-a-component.md @@ -3,7 +3,7 @@ title: "What is a component in React?" category: frontend subcategory: react tags: [component, props, JSX, functional-components] -difficulty: beginner +difficulty: junior lang: en --- diff --git a/src/content/en/security/web/xss.md b/src/content/en/security/web/xss.md index c4614b7..bdc530d 100644 --- a/src/content/en/security/web/xss.md +++ b/src/content/en/security/web/xss.md @@ -3,7 +3,7 @@ title: "What is Cross-Site Scripting (XSS) and how do you prevent it?" category: security subcategory: web tags: [xss, security, injection, csrf, sanitization] -difficulty: intermediate +difficulty: pleno lang: en --- diff --git a/src/content/en/soft-skills/hr/tell-me-about-yourself.md b/src/content/en/soft-skills/hr/tell-me-about-yourself.md index 901a4e1..2bb036b 100644 --- a/src/content/en/soft-skills/hr/tell-me-about-yourself.md +++ b/src/content/en/soft-skills/hr/tell-me-about-yourself.md @@ -3,7 +3,7 @@ title: "How do you answer \"Tell me about yourself\"?" category: soft-skills subcategory: hr tags: [hr, storytelling, intro, pitch, behavioral] -difficulty: beginner +difficulty: junior lang: en --- diff --git a/src/content/pt/architecture/software-engineering/arquitetura-escalavel.md b/src/content/pt/architecture/software-engineering/arquitetura-escalavel.md index 86d6b9d..8accec6 100644 --- a/src/content/pt/architecture/software-engineering/arquitetura-escalavel.md +++ b/src/content/pt/architecture/software-engineering/arquitetura-escalavel.md @@ -3,7 +3,7 @@ title: "O que é uma arquitetura escalável?" category: architecture subcategory: software-engineering tags: [escalabilidade, arquitetura, sistemas-distribuidos] -difficulty: intermediate +difficulty: pleno lang: pt --- @@ -36,4 +36,4 @@ Uma arquitetura escalável é capaz de crescer e suportar mais carga sem comprom **P:** O que é uma arquitetura escalável? -**R:** É uma arquitetura capaz de suportar aumento de carga e usuários mantendo bom desempenho e disponibilidade. \ No newline at end of file +**R:** É uma arquitetura capaz de suportar aumento de carga e usuários mantendo bom desempenho e disponibilidade. diff --git a/src/content/pt/architecture/solid/solid-principles.md b/src/content/pt/architecture/solid/solid-principles.md index e0b3462..6c24d42 100644 --- a/src/content/pt/architecture/solid/solid-principles.md +++ b/src/content/pt/architecture/solid/solid-principles.md @@ -3,7 +3,7 @@ title: "O que são os princípios SOLID?" category: architecture subcategory: solid tags: [solid, oop, design-principles, clean-code] -difficulty: intermediate +difficulty: pleno lang: pt --- diff --git a/src/content/pt/backend/general/graphql.md b/src/content/pt/backend/general/graphql.md index a456eaf..7bee5d7 100644 --- a/src/content/pt/backend/general/graphql.md +++ b/src/content/pt/backend/general/graphql.md @@ -3,7 +3,7 @@ title: "Explique o que é GraphQL" category: backend subcategory: general tags: [graphql, api, query, schema, rest, tipos] -difficulty: intermediate +difficulty: pleno lang: pt --- diff --git a/src/content/pt/backend/general/o-que-e-api.md b/src/content/pt/backend/general/o-que-e-api.md index ef3b84b..f624576 100644 --- a/src/content/pt/backend/general/o-que-e-api.md +++ b/src/content/pt/backend/general/o-que-e-api.md @@ -3,7 +3,7 @@ title: "O que é uma API?" category: backend subcategory: general tags: [api, http, rest, contrato, integração, web] -difficulty: beginner +difficulty: junior lang: pt --- diff --git a/src/content/pt/backend/general/rest.md b/src/content/pt/backend/general/rest.md index 3efb7b5..7d9900b 100644 --- a/src/content/pt/backend/general/rest.md +++ b/src/content/pt/backend/general/rest.md @@ -3,7 +3,7 @@ title: "Explique o que é REST" category: backend subcategory: general tags: [rest, api, http, stateless, web, arquitetura] -difficulty: beginner +difficulty: junior lang: pt --- diff --git a/src/content/pt/backend/node/middlewares.md b/src/content/pt/backend/node/middlewares.md index 233e3f7..90aab5c 100644 --- a/src/content/pt/backend/node/middlewares.md +++ b/src/content/pt/backend/node/middlewares.md @@ -3,7 +3,7 @@ title: "O que são e como funcionam middlewares no Node.js?" category: backend subcategory: node tags: [middleware, express, nodejs, request, response] -difficulty: intermediate +difficulty: pleno lang: pt --- diff --git a/src/content/pt/devops/containers/diferenca-docker-k8s.md b/src/content/pt/devops/containers/diferenca-docker-k8s.md index d3bc66f..ab18846 100644 --- a/src/content/pt/devops/containers/diferenca-docker-k8s.md +++ b/src/content/pt/devops/containers/diferenca-docker-k8s.md @@ -3,7 +3,7 @@ title: "Qual a diferença entre Docker e Kubernetes?" category: devops subcategory: containers tags: [docker, kubernetes, k8s, containers, orquestração] -difficulty: intermediate +difficulty: pleno lang: pt --- @@ -29,4 +29,4 @@ Docker é usado para criar e executar containers, enquanto Kubernetes é usado p **P:** Qual a diferença entre Docker e Kubernetes? -**R:** Docker cria e executa containers; Kubernetes gerencia e orquestra containers em ambientes distribuídos. \ No newline at end of file +**R:** Docker cria e executa containers; Kubernetes gerencia e orquestra containers em ambientes distribuídos. diff --git a/src/content/pt/devops/containers/o-que-e-docker.md b/src/content/pt/devops/containers/o-que-e-docker.md index b756177..874d016 100644 --- a/src/content/pt/devops/containers/o-que-e-docker.md +++ b/src/content/pt/devops/containers/o-que-e-docker.md @@ -3,7 +3,7 @@ title: "O que é Docker?" category: devops subcategory: containers tags: [docker, containers, virtualização] -difficulty: beginner +difficulty: junior lang: pt --- @@ -25,4 +25,4 @@ Docker é uma plataforma para criar e executar aplicações em containers, garan **P:** O que é Docker? -**R:** Docker é uma plataforma que empacota aplicações em containers para execução isolada e consistente. \ No newline at end of file +**R:** Docker é uma plataforma que empacota aplicações em containers para execução isolada e consistente. diff --git a/src/content/pt/devops/containers/o-que-e-k8s.md b/src/content/pt/devops/containers/o-que-e-k8s.md index 9606f9f..45f1ffe 100644 --- a/src/content/pt/devops/containers/o-que-e-k8s.md +++ b/src/content/pt/devops/containers/o-que-e-k8s.md @@ -3,7 +3,7 @@ title: "O que é Kubernetes?" category: devops subcategory: orchestration tags: [kubernetes, k8s, containers, orquestração] -difficulty: intermediate +difficulty: pleno lang: pt --- @@ -27,4 +27,4 @@ Kubernetes é uma plataforma que automatiza o gerenciamento e a orquestração d **P:** O que é Kubernetes? -**R:** Kubernetes é uma plataforma de orquestração de containers usada para automatizar deploy, escalabilidade e gerenciamento de aplicações. \ No newline at end of file +**R:** Kubernetes é uma plataforma de orquestração de containers usada para automatizar deploy, escalabilidade e gerenciamento de aplicações. diff --git a/src/content/pt/devops/containers/quando-usar-containers-em-vez-de-vm.md b/src/content/pt/devops/containers/quando-usar-containers-em-vez-de-vm.md index d283c24..43c357e 100644 --- a/src/content/pt/devops/containers/quando-usar-containers-em-vez-de-vm.md +++ b/src/content/pt/devops/containers/quando-usar-containers-em-vez-de-vm.md @@ -3,7 +3,7 @@ title: "Quando usar containers em vez de máquinas virtuais?" category: devops subcategory: containers tags: [docker, containers, virtual-machines, infraestrutura] -difficulty: intermediate +difficulty: pleno lang: pt --- @@ -32,4 +32,4 @@ Containers são preferíveis a máquinas virtuais quando precisamos de aplicaç **P:** Quando usar containers em vez de máquinas virtuais? -**R:** Containers são ideais para aplicações leves e escaláveis, enquanto máquinas virtuais oferecem isolamento mais forte e suporte a múltiplos sistemas operacionais. \ No newline at end of file +**R:** Containers são ideais para aplicações leves e escaláveis, enquanto máquinas virtuais oferecem isolamento mais forte e suporte a múltiplos sistemas operacionais. diff --git a/src/content/pt/frontend/accessibility/acessibilidade.md b/src/content/pt/frontend/accessibility/acessibilidade.md index 592a0b4..c32ac7c 100644 --- a/src/content/pt/frontend/accessibility/acessibilidade.md +++ b/src/content/pt/frontend/accessibility/acessibilidade.md @@ -3,7 +3,7 @@ title: "Como você abordaria a acessibilidade ao construir uma aplicação?" category: frontend subcategory: accessibility tags: [acessibilidade, a11y, aria, wcag, html-semantico] -difficulty: intermediate +difficulty: pleno lang: pt --- diff --git a/src/content/pt/frontend/css/box-model.md b/src/content/pt/frontend/css/box-model.md index bb5c2a1..3dd5c5f 100644 --- a/src/content/pt/frontend/css/box-model.md +++ b/src/content/pt/frontend/css/box-model.md @@ -3,7 +3,7 @@ title: "O que é o Box Model do CSS?" category: frontend subcategory: css tags: [css, box-model, layout, margin, padding] -difficulty: beginner +difficulty: junior lang: pt --- diff --git a/src/content/pt/frontend/javascript/let-const-var.md b/src/content/pt/frontend/javascript/let-const-var.md index f05fb7c..fa00d9c 100644 --- a/src/content/pt/frontend/javascript/let-const-var.md +++ b/src/content/pt/frontend/javascript/let-const-var.md @@ -3,7 +3,7 @@ title: "Qual é a diferença entre let, const e var?" category: frontend subcategory: javascript tags: [es6, escopo, hoisting, variaveis] -difficulty: beginner +difficulty: junior lang: pt --- diff --git a/src/content/pt/frontend/performance/otimizacao-carregamento.md b/src/content/pt/frontend/performance/otimizacao-carregamento.md index e6a3834..ef985a9 100644 --- a/src/content/pt/frontend/performance/otimizacao-carregamento.md +++ b/src/content/pt/frontend/performance/otimizacao-carregamento.md @@ -3,7 +3,7 @@ title: "Quais estratégias você usaria para otimizar o carregamento de uma pág category: frontend subcategory: performance tags: [performance, web, otimização, cache, lazy-loading, bundle, lcp, core-web-vitals] -difficulty: intermediate +difficulty: pleno lang: pt --- diff --git a/src/content/pt/frontend/react/ciclo-de-vida.md b/src/content/pt/frontend/react/ciclo-de-vida.md index 6cb3337..a8ac5e7 100644 --- a/src/content/pt/frontend/react/ciclo-de-vida.md +++ b/src/content/pt/frontend/react/ciclo-de-vida.md @@ -3,7 +3,7 @@ title: "Explique o ciclo de vida do React" category: frontend subcategory: react tags: [lifecycle, useEffect, hooks, montagem, desmontagem] -difficulty: intermediate +difficulty: pleno lang: pt --- diff --git a/src/content/pt/frontend/react/context-api-vs-redux.md b/src/content/pt/frontend/react/context-api-vs-redux.md index 1555262..aa2847f 100644 --- a/src/content/pt/frontend/react/context-api-vs-redux.md +++ b/src/content/pt/frontend/react/context-api-vs-redux.md @@ -3,7 +3,7 @@ title: "Qual a diferença entre Context API e Redux no gerenciamento de estado?" category: frontend subcategory: react tags: [react, context, redux, estado, gerenciamento, performance] -difficulty: intermediate +difficulty: pleno lang: pt --- diff --git a/src/content/pt/frontend/react/o-que-e-estado.md b/src/content/pt/frontend/react/o-que-e-estado.md index 561c6bb..8ab4972 100644 --- a/src/content/pt/frontend/react/o-que-e-estado.md +++ b/src/content/pt/frontend/react/o-que-e-estado.md @@ -3,7 +3,7 @@ title: "O que é estado no React?" category: frontend subcategory: react tags: [state, hooks, useState, re-render] -difficulty: beginner +difficulty: junior lang: pt --- diff --git a/src/content/pt/frontend/react/o-que-e-um-componente.md b/src/content/pt/frontend/react/o-que-e-um-componente.md index f2df51f..ce6ddf2 100644 --- a/src/content/pt/frontend/react/o-que-e-um-componente.md +++ b/src/content/pt/frontend/react/o-que-e-um-componente.md @@ -3,7 +3,7 @@ title: "O que é um componente no React?" category: frontend subcategory: react tags: [componente, props, JSX, functional-components] -difficulty: beginner +difficulty: junior lang: pt --- diff --git a/src/content/pt/frontend/react/o-que-sao-propriedades.md b/src/content/pt/frontend/react/o-que-sao-propriedades.md index b2556df..98d6643 100644 --- a/src/content/pt/frontend/react/o-que-sao-propriedades.md +++ b/src/content/pt/frontend/react/o-que-sao-propriedades.md @@ -3,7 +3,7 @@ title: "O que são propriedades no React?" category: frontend subcategory: react tags: [props, typescript, componentes, imutabilidade] -difficulty: beginner +difficulty: junior lang: pt --- diff --git a/src/content/pt/frontend/react/react-vs-next.md b/src/content/pt/frontend/react/react-vs-next.md index 884e9cf..f06018e 100644 --- a/src/content/pt/frontend/react/react-vs-next.md +++ b/src/content/pt/frontend/react/react-vs-next.md @@ -3,7 +3,7 @@ title: "Qual a diferença entre React e Next.js?" category: frontend subcategory: react tags: [react, nextjs, ssr, ssg, framework, spa] -difficulty: beginner +difficulty: junior lang: pt --- diff --git a/src/content/pt/frontend/react/ssr-ssg-isr-nextjs.md b/src/content/pt/frontend/react/ssr-ssg-isr-nextjs.md index 7ce8246..57d3efa 100644 --- a/src/content/pt/frontend/react/ssr-ssg-isr-nextjs.md +++ b/src/content/pt/frontend/react/ssr-ssg-isr-nextjs.md @@ -3,7 +3,7 @@ title: "Explique como funciona o conceito de SSR, SSG e ISR no Next.js" category: frontend subcategory: react tags: [nextjs, ssr, ssg, isr, renderização, performance, servidor] -difficulty: intermediate +difficulty: pleno lang: pt --- diff --git a/src/content/pt/frontend/react/usememo-usecallback.md b/src/content/pt/frontend/react/usememo-usecallback.md index f97efb4..ee64820 100644 --- a/src/content/pt/frontend/react/usememo-usecallback.md +++ b/src/content/pt/frontend/react/usememo-usecallback.md @@ -3,7 +3,7 @@ title: "O que são `useMemo` e `useCallback`, e quando usá-los?" category: frontend subcategory: react tags: [react, hooks, usememo, usecallback, performance, memoização] -difficulty: intermediate +difficulty: pleno lang: pt --- diff --git a/src/content/pt/soft-skills/hr/fale-sobre-voce.md b/src/content/pt/soft-skills/hr/fale-sobre-voce.md index f58bfca..6992ccc 100644 --- a/src/content/pt/soft-skills/hr/fale-sobre-voce.md +++ b/src/content/pt/soft-skills/hr/fale-sobre-voce.md @@ -3,7 +3,7 @@ title: "Como responder 'Fale sobre você'?" category: soft-skills subcategory: hr tags: [rh, storytelling, intro, pitch, comportamental] -difficulty: beginner +difficulty: junior lang: pt --- diff --git a/src/lib/__tests__/content.test.ts b/src/lib/__tests__/content.test.ts index d87d851..5ad8e24 100644 --- a/src/lib/__tests__/content.test.ts +++ b/src/lib/__tests__/content.test.ts @@ -21,7 +21,7 @@ describe('buildQuestionMeta', () => { category: 'frontend', subcategory: 'javascript', tags: ['es6'], - difficulty: 'beginner', + difficulty: 'junior', lang: 'en', } const meta = buildQuestionMeta('let-const-var', fm) diff --git a/src/lib/content.ts b/src/lib/content.ts index f5235ec..0a5afaf 100644 --- a/src/lib/content.ts +++ b/src/lib/content.ts @@ -7,7 +7,7 @@ import remarkRehype from 'remark-rehype' import rehypeShiki from '@shikijs/rehype' import rehypeStringify from 'rehype-stringify' -export type Difficulty = 'beginner' | 'intermediate' | 'advanced' +export type Difficulty = 'junior' | 'pleno' | 'senior' | 'especialista' export type QuestionMeta = { slug: string @@ -69,7 +69,7 @@ export function buildQuestionMeta( category: fm.category as string, subcategory: fm.subcategory as string, tags: (fm.tags as string[]) ?? [], - difficulty: (fm.difficulty as Difficulty) ?? 'intermediate', + difficulty: (fm.difficulty as Difficulty) ?? 'pleno', lang: fm.lang as string, path: `${fm.category}/${fm.subcategory}/${slug}`, quickAnswer: stripMarkdown(extractSection(rawContent, 'Quick Answer')), diff --git a/src/messages/en.json b/src/messages/en.json index 93f2332..b05ef80 100644 --- a/src/messages/en.json +++ b/src/messages/en.json @@ -5,7 +5,8 @@ "resume": "Resume", "contribute": "Contribute", "support": "Support Us", - "about": "About" + "about": "About", + "updates": "Updates" }, "home": { "title": "CodeQuestions", @@ -39,6 +40,7 @@ "noQuestions": "No questions yet for this category in this language.", "beFirst": "Be the first to contribute →", "filterLabel": "Tags", + "searchTags": "Search tags...", "clearFilters": "Clear filters", "questionsTotal": "questions", "questionsFiltered": "filtered", @@ -64,9 +66,10 @@ "gotIt": "Got it!", "needReview": "Need more study", "difficulty": { - "beginner": "Beginner", - "intermediate": "Intermediate", - "advanced": "Advanced" + "junior": "Junior", + "pleno": "Mid-level", + "senior": "Senior", + "especialista": "Specialist" } }, "progress": { @@ -80,7 +83,8 @@ "contribute": "How to Contribute", "contact": "Contact", "support": "Support the Project", - "storytelling": "StoryTelling Guide" + "storytelling": "StoryTelling Guide", + "updates": "Updates" }, "footer": { "openSource": "Open source on GitHub", diff --git a/src/messages/pt.json b/src/messages/pt.json index db56fe9..7cf4688 100644 --- a/src/messages/pt.json +++ b/src/messages/pt.json @@ -5,7 +5,8 @@ "resume": "Currículo", "contribute": "Contribuir", "support": "Apoie", - "about": "Sobre" + "about": "Sobre", + "updates": "Atualizações" }, "home": { "title": "CodeQuestions", @@ -39,6 +40,7 @@ "noQuestions": "Nenhuma pergunta ainda para esta categoria neste idioma.", "beFirst": "Seja o primeiro a contribuir →", "filterLabel": "Tags", + "searchTags": "Buscar tag...", "clearFilters": "Limpar filtros", "questionsTotal": "perguntas", "questionsFiltered": "filtradas", @@ -64,9 +66,10 @@ "gotIt": "Sei!", "needReview": "Preciso estudar", "difficulty": { - "beginner": "Iniciante", - "intermediate": "Intermediário", - "advanced": "Avançado" + "junior": "Júnior", + "pleno": "Pleno", + "senior": "Sênior", + "especialista": "Especialista" } }, "progress": { @@ -80,7 +83,8 @@ "contribute": "Como Contribuir", "contact": "Contato", "support": "Apoie o Projeto", - "storytelling": "Guia de StoryTelling" + "storytelling": "Guia de StoryTelling", + "updates": "Atualizações" }, "footer": { "openSource": "Open source no GitHub",