diff --git a/src/__tests__/pages/__snapshots__/AboutPage.test.tsx.snap b/src/__tests__/pages/__snapshots__/AboutPage.test.tsx.snap index 3575bb8..b722f79 100644 --- a/src/__tests__/pages/__snapshots__/AboutPage.test.tsx.snap +++ b/src/__tests__/pages/__snapshots__/AboutPage.test.tsx.snap @@ -6,7 +6,7 @@ exports[`AboutPage should match the snapshot 1`] = ` data-testid="about-page" >
{ + switch (i18n.resolvedLanguage) { + case SupportedLanguages.Portuguese: + return ptBR; + case SupportedLanguages.Spanish: + return es; + case SupportedLanguages.English: + default: + return enUS; + } + }, [i18n.resolvedLanguage]); + const formattedMediaDate = useMemo(() => { if (["code", "thesis"].includes(props.item.kind)) { return format(props.item.releaseDate, "yyyy"); } return format(props.item.releaseDate, "PPP", { - locale: i18n.resolvedLanguage === SupportedLanguages.PT ? ptBR : enUS, + locale: dateLocale, }); - }, [props.item.kind, props.item.releaseDate, i18n.resolvedLanguage]); + }, [dateLocale, props.item.kind, props.item.releaseDate]); const publicationIcon = useMemo<{ name: string; route: string }>(() => { switch (props.item.publication) { diff --git a/src/components/chip/KeywordChips.tsx b/src/components/chip/KeywordChips.tsx index c7ae35a..9e48a22 100644 --- a/src/components/chip/KeywordChips.tsx +++ b/src/components/chip/KeywordChips.tsx @@ -7,8 +7,10 @@ import { useTranslation } from "react-i18next"; import { KeywordSelection } from "../../hooks/useKeywordSelection"; import { StaticChip } from "./StaticChip"; +const DEFAULT_FADE_TIME = 500; + interface KeywordChipsProps { - fadeTime: number; + fadeTime?: number; keywordSelection: KeywordSelection; } @@ -20,7 +22,7 @@ export function KeywordChips(props: KeywordChipsProps) { const resolveLiteral = useCallback((key: string) => t(`literal:${key}` as any), [t]); return ( - + {[...props.keywordSelection.selectionMap.keys()] .sort((a, b) => resolveLiteral(a).localeCompare(resolveLiteral(b))) diff --git a/src/components/page/MediaSection.tsx b/src/components/page/MediaSection.tsx index b49116b..3eeffab 100644 --- a/src/components/page/MediaSection.tsx +++ b/src/components/page/MediaSection.tsx @@ -7,16 +7,26 @@ import { KeywordSelection } from "../../hooks/useKeywordSelection"; import { MediaItem } from "../../schema"; import { MediaCard } from "../card"; +const DEFAULT_FADE_TIME: MediaSectionFadeTime = { + title: 500, + item: 1000, +}; + +export interface MediaSectionFadeTime { + title: number; + item: number; +} + interface MediaSectionProps { title: string; mediaItems: MediaItem[]; - fadeTime: number; + fadeTime?: MediaSectionFadeTime; keywordSelection: KeywordSelection; } export function MediaSection(props: MediaSectionProps) { return ( - + {props.mediaItems.map((item: MediaItem, idx: number) => ( - - - + + + + + ))} diff --git a/src/components/page/PageHeader.tsx b/src/components/page/PageHeader.tsx index ced0556..e6379ef 100644 --- a/src/components/page/PageHeader.tsx +++ b/src/components/page/PageHeader.tsx @@ -2,14 +2,16 @@ import Box from "@mui/material/Box"; import Fade from "@mui/material/Fade"; import { ReactNode } from "react"; +const DEFAULT_FADE_TIME = 500; + interface PageHeaderProps { - fadeTime: number; + fadeTime?: number; children: ReactNode; } export function PageHeader(props: PageHeaderProps) { return ( - + {props.children} ); diff --git a/src/components/settings/SettingsPopover.tsx b/src/components/settings/SettingsPopover.tsx index 169cbe2..9437ee7 100644 --- a/src/components/settings/SettingsPopover.tsx +++ b/src/components/settings/SettingsPopover.tsx @@ -79,8 +79,13 @@ export function SettingsPopover(props: SettingsPopoverProps) { onChange={(event) => i18n.changeLanguage((event.target as HTMLInputElement).value)} name="language-group" > - - + + + diff --git a/src/i18n/index.tsx b/src/i18n/index.tsx index bc70661..1c34fb7 100644 --- a/src/i18n/index.tsx +++ b/src/i18n/index.tsx @@ -4,26 +4,28 @@ import Backend from "i18next-http-backend"; import { initReactI18next } from "react-i18next"; export enum SupportedLanguages { - EN = "en", - PT = "pt", + English = "en", + Portuguese = "pt", + Spanish = "es", } -const contextPath = process.env["WEBPACK_REPLACE__contextPath"]; +const CONTEXT_PATH = process.env["WEBPACK_REPLACE__contextPath"]; +const NAMESPACES = ["about", "code", "common", "drawer", "journey", "literal", "personal", "talk", "text"]; i18n .use(Backend) .use(LanguageDetector) .use(initReactI18next) .init({ - fallbackLng: SupportedLanguages.EN, + fallbackLng: SupportedLanguages.English, supportedLngs: Object.values(SupportedLanguages), - ns: ["about", "code", "common", "drawer", "journey", "literal", "personal", "talk", "text"], + ns: NAMESPACES, interpolation: { escapeValue: false, }, debug: false, backend: { - loadPath: `${contextPath}/static/locales/{{lng}}/{{ns}}.json`, + loadPath: `${CONTEXT_PATH}/static/locales/{{lng}}/{{ns}}.json`, }, }); diff --git a/src/pages/AboutPage.tsx b/src/pages/AboutPage.tsx index ac85a64..9fdb6be 100644 --- a/src/pages/AboutPage.tsx +++ b/src/pages/AboutPage.tsx @@ -12,8 +12,8 @@ import { Fonts } from "../fonts"; import { usePageActive } from "../hooks/usePageActive"; import { routes } from "../routes"; -const PAGE_FADE_TIME = { - content: 1000, +const FADE_TIME = { + card: 500, }; export default function AboutPage() { @@ -23,7 +23,7 @@ export default function AboutPage() { return ( {active && ( - +
diff --git a/src/pages/CodePage.tsx b/src/pages/CodePage.tsx index 0d6f349..4f99530 100644 --- a/src/pages/CodePage.tsx +++ b/src/pages/CodePage.tsx @@ -7,12 +7,6 @@ import { useFilteredMedias } from "../hooks/useFilteredMedias"; import { useKeywordSelection } from "../hooks/useKeywordSelection"; import { usePageActive } from "../hooks/usePageActive"; -const PAGE_FADE_TIME = { - header: 500, - keywordChips: 500, - repositoriesSection: 1000, -}; - export default function CodePage() { const app = useApp(); const active = usePageActive(0); @@ -22,7 +16,7 @@ export default function CodePage() { return ( - + Here you can find some of my code @@ -31,11 +25,10 @@ export default function CodePage() { {active && ( <> - + {filteredRepositories.length > 0 && ( diff --git a/src/pages/JourneyPage.tsx b/src/pages/JourneyPage.tsx index e2a6322..60562d7 100644 --- a/src/pages/JourneyPage.tsx +++ b/src/pages/JourneyPage.tsx @@ -25,8 +25,11 @@ import { usePageActive } from "../hooks/usePageActive"; import { routes } from "../routes"; import { JourneyItem, JourneyKind } from "../schema"; -const PAGE_FADE_TIME = { - header: 500, +const SECTION_FADE_TIME = { + education: 1000, + certifications: 1200, + toolbox: 1400, + experience: 1600, }; export default function JourneyPage() { @@ -36,7 +39,7 @@ export default function JourneyPage() { return ( - + Here you can see my journey summary @@ -47,7 +50,7 @@ export default function JourneyPage() { - + - + - + - + - + Here you can find some of my talks @@ -33,19 +26,13 @@ export default function TalkPage() { {active && ( <> - + {filteredLives.length > 0 && ( - + )} {filteredConferences.length > 0 && ( diff --git a/src/pages/TextPage.tsx b/src/pages/TextPage.tsx index 74e283f..2a45119 100644 --- a/src/pages/TextPage.tsx +++ b/src/pages/TextPage.tsx @@ -7,13 +7,6 @@ import { useFilteredMedias } from "../hooks/useFilteredMedias"; import { useKeywordSelection } from "../hooks/useKeywordSelection"; import { usePageActive } from "../hooks/usePageActive"; -const PAGE_FADE_TIME = { - header: 500, - keywordChips: 500, - masterThesisSection: 1000, - blogPostsSection: 1500, -}; - export default function TextPage() { const app = useApp(); const active = usePageActive(0); @@ -24,7 +17,7 @@ export default function TextPage() { return ( - + Here you can find some of my texts @@ -33,11 +26,10 @@ export default function TextPage() { {active && ( <> - + {filteredMasterThesis.length > 0 && ( @@ -45,7 +37,6 @@ export default function TextPage() { {filteredBlogPosts.length > 0 && ( diff --git a/static/favicon/about.txt b/static/favicon/about.txt index 59ad14e..28da86d 100644 --- a/static/favicon/about.txt +++ b/static/favicon/about.txt @@ -1,6 +1,6 @@ This favicon was generated using the following font: -- Font Title: Roboto -- Font Author: Copyright 2011 Google Inc. All Rights Reserved. -- Font Source: http://fonts.gstatic.com/s/roboto/v29/KFOlCnqEu92Fr1MmYUtvAx05IsDqlA.ttf +- Font Title: Roboto Slab +- Font Author: Copyright 2018 The Roboto Slab Project Authors (https://github.com/googlefonts/robotoslab) +- Font Source: http://fonts.gstatic.com/s/robotoslab/v23/BngbUXZYTXPIvIBgJJSb6s3BzlRRfKOFbvjojISWaG5iddG-1A.ttf - Font License: Apache License, version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html)) diff --git a/static/favicon/android-chrome-192x192.png b/static/favicon/android-chrome-192x192.png index be3e190..3f2543a 100644 Binary files a/static/favicon/android-chrome-192x192.png and b/static/favicon/android-chrome-192x192.png differ diff --git a/static/favicon/android-chrome-512x512.png b/static/favicon/android-chrome-512x512.png index a7983ec..1b47af7 100644 Binary files a/static/favicon/android-chrome-512x512.png and b/static/favicon/android-chrome-512x512.png differ diff --git a/static/favicon/apple-touch-icon.png b/static/favicon/apple-touch-icon.png index b86cb6e..d765dab 100644 Binary files a/static/favicon/apple-touch-icon.png and b/static/favicon/apple-touch-icon.png differ diff --git a/static/favicon/favicon-16x16.png b/static/favicon/favicon-16x16.png index 0e36f01..c4dbeed 100644 Binary files a/static/favicon/favicon-16x16.png and b/static/favicon/favicon-16x16.png differ diff --git a/static/favicon/favicon-32x32.png b/static/favicon/favicon-32x32.png index e105bbc..5ef8b53 100644 Binary files a/static/favicon/favicon-32x32.png and b/static/favicon/favicon-32x32.png differ diff --git a/static/favicon/favicon.ico b/static/favicon/favicon.ico index f7e69a2..5096801 100644 Binary files a/static/favicon/favicon.ico and b/static/favicon/favicon.ico differ diff --git a/static/locales/es/about.json b/static/locales/es/about.json new file mode 100644 index 0000000..09398ed --- /dev/null +++ b/static/locales/es/about.json @@ -0,0 +1,10 @@ +{ + "welcome": "Bienvenido a mi espacio personal 👋", + "paragraphs": [ + "¡Hola! Mi nombre es Guilherme Caponetto. Actualmente trabajo como ingeniero de software senior en Red Hat, donde construyo herramientas para desarrolladores. Soy un gran admirador de la comunidad de código abierto y siempre me emociona crear piezas de software que mejoren la vida de las personas.", + "Desde mi primer año de universidad (2007), he estado trabajando con el desarrollo tanto de back-end como de front-end. No estoy apegado a ningún lenguaje de programación o tecnología específica, así que estoy más que feliz mientras esté programando y aprendiendo.", + "Durante mi trayectoria, he tenido la oportunidad de contribuir en proyectos académicos y profesionales, la mayoría de ellos relacionados con Web, Windows y Android. Investigar, especialmente enfocándome en Aprendizaje Automático, también es algo que disfruto hacer.", + "Mis intereses radican en el desarrollo de software inteligente de alta calidad utilizando design patterns, código optimizado guiado por pruebas unitarias, aprendizaje automático y metodologías ágiles. Me hago cargo de los proyectos en los que participo, disfruto compartiendo mis conocimientos con los demás y me apasiona aprender cosas nuevas.", + "No dudes en contactarme en mis redes sociales. Siempre estoy abierto a discutir nuevas ideas y oportunidades." + ] +} diff --git a/static/locales/es/code.json b/static/locales/es/code.json new file mode 100644 index 0000000..289ca9d --- /dev/null +++ b/static/locales/es/code.json @@ -0,0 +1,15 @@ +{ + "header": "Aquí puedes encontrar algo de mi <1>código", + "repositories": { + "bhc": "Bayesian Hierarchical Clustering", + "vsCodeQuarkusDJL": "Servicios para editores en VS Code con Quarkus y DJL", + "lessIsMore": "Menos es más", + "jupyterNotebooks": "Jupyter Notebooks", + "vsCodeDiffViewer": "Visor de archivos git diff en VS Code", + "vsCodeToxicityClassifier": "Clasificación de toxicidad en VS Code", + "streamDecisionsWithDmnAndKafka": "Streaming decisiones con DMN y Kafka", + "vsCodeObjectDetection": "Detección de objetos en VS Code", + "personalWebApp": "Esta web app :)", + "teachableMachinePlayground": "Teachable Machine Playground" + } +} diff --git a/static/locales/es/common.json b/static/locales/es/common.json new file mode 100644 index 0000000..1d65f2a --- /dev/null +++ b/static/locales/es/common.json @@ -0,0 +1,12 @@ +{ + "social": { + "tooltip": "Perfil {{kind}}" + }, + "location": { + "tooltip": "Actualmente vive en {{location}}" + }, + "copyright": "© {{year}} {{name}}", + "messages": { + "storedCookies": "Sus preferencias se guardan en su navegador." + } +} diff --git a/static/locales/es/drawer.json b/static/locales/es/drawer.json new file mode 100644 index 0000000..3b5e0ae --- /dev/null +++ b/static/locales/es/drawer.json @@ -0,0 +1,17 @@ +{ + "about": { + "subtitle": "Palabras sobre mi" + }, + "journey": { + "subtitle": "Educación & experiencia" + }, + "text": { + "subtitle": "Contenido que escribí" + }, + "talk": { + "subtitle": "Temas que presenté" + }, + "code": { + "subtitle": "Proyectos que destaco" + } +} diff --git a/static/locales/es/journey.json b/static/locales/es/journey.json new file mode 100644 index 0000000..5885235 --- /dev/null +++ b/static/locales/es/journey.json @@ -0,0 +1,11 @@ +{ + "header": "Aquí puedes ver el resumen de mi <1>trayectoria", + "education": { + "master": { + "title": "Máster en Aprendizaje Automático" + }, + "bachelor": { + "title": "Bachillerato en Ciencia de la Computación" + } + } +} diff --git a/static/locales/es/literal.json b/static/locales/es/literal.json new file mode 100644 index 0000000..ede8a23 --- /dev/null +++ b/static/locales/es/literal.json @@ -0,0 +1,131 @@ +{ + "about": "Sobre", + "amazonWebServices": "Amazon Web Services", + "android": "Android", + "apacheKafka": "Apache Kafka", + "archetypes": "Archetypes", + "architecture": "Arquitectura", + "artifact": "Artefacto", + "b2mlSystems": "B2ML Sistemas", + "backend": "Backend", + "bayesianStatistics": "Estadística Bayesiana", + "blogPosts": "Publicaciones de blog", + "bpmn": "BPMN", + "brazil": "Brasil", + "businessCentral": "Business Central", + "certifications": "Certificaciones", + "changeRequests": "Change Requests", + "cicd": "CI/CD", + "classification": "Clasificación", + "clustering": "Agrupamiento", + "code": "Código", + "computerVision": "Visión Artificial", + "computerVisionNanoDegree": "Nanodegree en Visión Artificial", + "conferences": "Conferencias", + "cpp": "C++", + "csharp": "C#", + "css": "CSS", + "dark": "Oscuro", + "deepLearning": "Aprendizaje Profundo", + "designPatterns": "Design Patterns", + "dmn": "DMN", + "docker": "Docker", + "education": "Educación", + "english": "Inglés", + "experience": "Experiencia", + "frontend": "Frontend", + "git": "Git", + "gitDiff": "Git Diff", + "gitHubActions": "GitHub Actions", + "github": "GitHub", + "gitpod": "Gitpod", + "graduateResearcher": "Investigador Graduado", + "gwt": "GWT", + "html": "HTML", + "iFood": "iFood", + "java": "Java", + "javascript": "JavaScript", + "jboss": "JBoss", + "jni": "JNI", + "journey": "Trayectoria", + "jpa": "JPA", + "juniorSoftwareEngineer": "Ingeniero de Software Júnior", + "jupyterNotebooks": "Jupyter Notebooks", + "kanban": "Kanban", + "kieCommunity": "Comunidad KIE", + "kieTools": "KIE Tools", + "language": "Idioma", + "light": "Claro", + "linkedin": "LinkedIn", + "lives": "Lives", + "machineLearning": "Aprendizaje Automático", + "master": "Maestría", + "mastersThesis": "Tesis de maestria", + "matlab": "MATLAB", + "maven": "Maven", + "moreDetails": "Más detalles", + "motorola": "Motorola", + "multiTaskLearning": "Aprendizaje Multitarea", + "neuralNetworks": "Redes Neuronales", + "noSql": "NoSQL", + "nodeJs": "NodeJS", + "objectDetection": "Detección de Objetos", + "oop": "OOP", + "openShift": "OpenShift", + "optimization": "Optimización", + "oracle": "Oracle", + "oracleCertifiedProfessionalJavaSix": "Oracle Certified Professional, Java 6", + "portuguese": "Portugués", + "present": "Presente", + "python": "Python", + "quarkus": "Quarkus", + "randomSearch": "Búsqueda Aleatoria", + "reactJs": "ReactJS", + "read": "Leer", + "recommenderSystems": "Sistemas de Recomendación", + "redHat": "Red Hat", + "regression": "Regresión", + "repositories": "Repositorios", + "restfulWs": "RESTful WS", + "samsung": "Samsung", + "scrollToTop": "Ir al principio", + "scrum": "Scrum", + "seniorSoftwareEngineer": "Ingeniero de Software Senior", + "settings": "Ajustes", + "showAll": "Mostrar todo", + "slides": "Slides", + "softwareDevelopmentIntern": "Pasante de Desarrollo de Software", + "softwareEngineer": "Ingeniero de Software", + "speechEnhancement": "Mejora de la Voz", + "springFramework": "Spring Framework", + "sql": "SQL", + "syncRepositories": "Sincronización de Repositorios", + "systemDesign": "System Design", + "talk": "Presentación", + "talks": "Presentaciones", + "tdd": "TDD", + "teachableMachine": "Teachable Machine", + "tensorFlow": "TensorFlow", + "tensorFlowJs": "TensorFlow JS", + "text": "Texto", + "texts": "Textos", + "theDevelopersConference": "The Developer's Conference", + "theme": "Tema", + "tomcat": "Tomcat", + "toolbox": "Caja de herramientas", + "towardsDataScience": "Towards Data Science", + "twitter": "Twitter", + "typeScript": "TypeScript", + "udacity": "Udacity", + "undergraduateResearcher": "Investigador de Iniciación Científica", + "unicamp": "UNICAMP", + "unifei": "UNIFEI", + "universalWindowsPlatform": "Universal Windows Platform", + "version": "Versión", + "view": "Ver", + "vsCode": "VS Code", + "vsCodeExtension": "VS Code Extension", + "watch": "Ver", + "webApp": "Web App", + "xmpp": "XMPP" +} diff --git a/static/locales/es/personal.json b/static/locales/es/personal.json new file mode 100644 index 0000000..1689551 --- /dev/null +++ b/static/locales/es/personal.json @@ -0,0 +1,4 @@ +{ + "firstName": "Guilherme", + "lastName": "Caponetto" +} diff --git a/static/locales/es/talk.json b/static/locales/es/talk.json new file mode 100644 index 0000000..733bf23 --- /dev/null +++ b/static/locales/es/talk.json @@ -0,0 +1,11 @@ +{ + "header": "Aquí puedes encontrar algunas de mis <1>presentaciones", + "lives": { + "workspaceCollaborationInBC": "Workspace collaboration in Business Central", + "mavenArchetypesInBC": "Maven archetype support in Business Central", + "streamDecisionsWithDmnAndKafka": "Streaming decisions with DMN and Kafka" + }, + "conferences": { + "streamDecisionsWithDmnAndKafka": "Streaming suas decisões com DMN e Kafka (pt-BR)" + } +} diff --git a/static/locales/es/text.json b/static/locales/es/text.json new file mode 100644 index 0000000..2d26d51 --- /dev/null +++ b/static/locales/es/text.json @@ -0,0 +1,19 @@ +{ + "header": "Aquí puedes encontrar algunos de mis <1>textos", + "mastersThesis": "Data-driven hierarchical structures in multi-task learning", + "blogPosts": { + "workspaceCollaboration": "Workspace collaboration via change requests", + "playingWithObjectDetection": "Playing with object detection", + "randomVsGridSearch": "Random Search vs Grid Search for hyperparameter optimization", + "mavenArchetypesInBC": "Maven archetype support in Business Central", + "emptyReposInBC": "Import an empty repository into Business Central", + "squashCommitsInBC": "Squash commits when merging a change request", + "improvedWorkflowInBC": "An improved development workflow on Business Central using our new DevTools", + "exportAsGist": "Exporting diagrams as GitHub gists", + "backendKogitoTooling": "Backend support on Kogito Tooling", + "authoringOnGitpod": "Four steps to author BPMN and DMN assets on gitpod.io", + "dmnDevSandbox": "Deploy decisions to DMN Developer Sandbox", + "teachableMachineBitingNails": "From training to deployment: Stop biting your nails with machine learning", + "deployKieSandboxToOpenshift": "Deploy your KIE Sandbox to OpenShift" + } +} diff --git a/static/locales/pt/text.json b/static/locales/pt/text.json index 21e2754..0e5ddcc 100644 --- a/static/locales/pt/text.json +++ b/static/locales/pt/text.json @@ -1,6 +1,6 @@ { "header": "Aqui você encontra alguns de meus <1>textos", - "mastersThesis": "Estruturas hierárquicas orientadas por dados em aprendizado multi-tarefa", + "mastersThesis": "Data-driven hierarchical structures in multi-task learning", "blogPosts": { "workspaceCollaboration": "Workspace collaboration via change requests", "playingWithObjectDetection": "Playing with object detection",