diff --git a/astro-i18next.config.mjs b/astro-i18next.config.mjs new file mode 100644 index 0000000..e9044f5 --- /dev/null +++ b/astro-i18next.config.mjs @@ -0,0 +1,5 @@ +/** @type {import('astro-i18next').AstroI18nextConfig} */ +export default { + defaultLocale: 'en', + locales: ['en', 'es'], +}; diff --git a/astro.config.mjs b/astro.config.mjs index 70ca5e5..932112e 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,10 +1,11 @@ import { defineConfig } from 'astro/config'; import react from '@astrojs/react'; +import astroI18next from 'astro-i18next'; // https://astro.build/config export default defineConfig({ prefetch: true, - integrations: [react()], + integrations: [react(), astroI18next()], experimental: {}, }); diff --git a/package.json b/package.json index 392c10f..447236c 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,9 @@ "@types/react": "^18.0.21", "@types/react-dom": "^18.0.6", "astro": "^4.0.6", + "astro-i18next": "1.0.0-beta.21", + "i18next": "^22.5.1", + "i18next-fs-backend": "^2.3.1", "react": "^18.0.0", "react-dom": "^18.0.0", "sass": "^1.71.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5ca98ab..f87757e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,15 @@ dependencies: astro: specifier: ^4.0.6 version: 4.0.6(sass@1.71.1)(typescript@5.2.2) + astro-i18next: + specifier: 1.0.0-beta.21 + version: 1.0.0-beta.21(astro@4.0.6) + i18next: + specifier: ^22.5.1 + version: 22.5.1 + i18next-fs-backend: + specifier: ^2.3.1 + version: 2.3.1 react: specifier: ^18.0.0 version: 18.2.0 @@ -393,6 +402,13 @@ packages: '@babel/types': 7.23.4 dev: false + /@babel/runtime@7.24.0: + resolution: {integrity: sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + dev: false + /@babel/template@7.22.15: resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} engines: {node: '>=6.9.0'} @@ -478,6 +494,15 @@ packages: dev: false optional: true + /@esbuild/android-arm@0.15.18: + resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + /@esbuild/android-arm@0.19.8: resolution: {integrity: sha512-31E2lxlGM1KEfivQl8Yf5aYU/mflz9g06H6S15ITUFQueMFtFjESRMoDSkvMo8thYvLBax+VKTPlpnx+sPicOA==} engines: {node: '>=12'} @@ -559,6 +584,15 @@ packages: dev: false optional: true + /@esbuild/linux-loong64@0.15.18: + resolution: {integrity: sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@esbuild/linux-loong64@0.19.8: resolution: {integrity: sha512-fHZWS2JJxnXt1uYJsDv9+b60WCc2RlvVAy1F76qOLtXRO+H4mjt3Tr6MJ5l7Q78X8KgCFudnTuiQRBhULUyBKQ==} engines: {node: '>=12'} @@ -772,6 +806,22 @@ packages: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 + /@proload/core@0.3.3: + resolution: {integrity: sha512-7dAFWsIK84C90AMl24+N/ProHKm4iw0akcnoKjRvbfHifJZBLhaDsDus1QJmhG12lXj4e/uB/8mB/0aduCW+NQ==} + dependencies: + deepmerge: 4.3.1 + escalade: 3.1.1 + dev: false + + /@proload/plugin-tsm@0.2.1(@proload/core@0.3.3): + resolution: {integrity: sha512-Ex1sL2BxU+g8MHdAdq9SZKz+pU34o8Zcl9PHWo2WaG9hrnlZme607PU6gnpoAYsDBpHX327+eu60wWUk+d/b+A==} + peerDependencies: + '@proload/core': ^0.3.2 + dependencies: + '@proload/core': 0.3.3 + tsm: 2.3.0 + dev: false + /@rollup/rollup-android-arm-eabi@4.7.0: resolution: {integrity: sha512-rGku10pL1StFlFvXX5pEv88KdGW6DHUghsxyP/aRYb9eH+74jTGJ3U0S/rtlsQ4yYq1Hcc7AMkoJOb1xu29Fxw==} cpu: [arm] @@ -1375,6 +1425,26 @@ packages: engines: {node: '>=8'} dev: true + /astro-i18next@1.0.0-beta.21(astro@4.0.6): + resolution: {integrity: sha512-1YPqwexumHpK/d9afEoi52CBFTu6k4MYv/oHjsaAasZDvFClU6U5VPttC/OgZcXRYggCM6ee2LOnyHqlmXOeLA==} + hasBin: true + peerDependencies: + astro: '>=1.0.0' + dependencies: + '@proload/core': 0.3.3 + '@proload/plugin-tsm': 0.2.1(@proload/core@0.3.3) + astro: 4.0.6(sass@1.71.1)(typescript@5.2.2) + i18next: 22.5.1 + i18next-browser-languagedetector: 7.2.0 + i18next-fs-backend: 2.3.1 + i18next-http-backend: 2.5.0 + iso-639-1: 2.1.15 + locale-emoji: 0.3.0 + pathe: 1.1.2 + transitivePeerDependencies: + - encoding + dev: false + /astro@4.0.6(sass@1.71.1)(typescript@5.2.2): resolution: {integrity: sha512-P7CfFqWKzkJozzF6IoOC6qoI2ONndV8P3ULhGDgMiXPL7xVkWI5haTBSpyrcjBx643tVXspIRsSV/v+Cx+CjGw==} engines: {node: '>=18.14.1', npm: '>=6.14.0'} @@ -1843,6 +1913,14 @@ packages: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} dev: true + /cross-fetch@4.0.0: + resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + dev: false + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -1973,6 +2051,11 @@ packages: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true + /deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: false + /define-data-property@1.1.1: resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} engines: {node: '>= 0.4'} @@ -2198,6 +2281,216 @@ packages: is-symbol: 1.0.4 dev: true + /esbuild-android-64@0.15.18: + resolution: {integrity: sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /esbuild-android-arm64@0.15.18: + resolution: {integrity: sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /esbuild-darwin-64@0.15.18: + resolution: {integrity: sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /esbuild-darwin-arm64@0.15.18: + resolution: {integrity: sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /esbuild-freebsd-64@0.15.18: + resolution: {integrity: sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-freebsd-arm64@0.15.18: + resolution: {integrity: sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-32@0.15.18: + resolution: {integrity: sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-64@0.15.18: + resolution: {integrity: sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-arm64@0.15.18: + resolution: {integrity: sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-arm@0.15.18: + resolution: {integrity: sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-mips64le@0.15.18: + resolution: {integrity: sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-ppc64le@0.15.18: + resolution: {integrity: sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-riscv64@0.15.18: + resolution: {integrity: sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-s390x@0.15.18: + resolution: {integrity: sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-netbsd-64@0.15.18: + resolution: {integrity: sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-openbsd-64@0.15.18: + resolution: {integrity: sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-sunos-64@0.15.18: + resolution: {integrity: sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: false + optional: true + + /esbuild-windows-32@0.15.18: + resolution: {integrity: sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /esbuild-windows-64@0.15.18: + resolution: {integrity: sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /esbuild-windows-arm64@0.15.18: + resolution: {integrity: sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /esbuild@0.15.18: + resolution: {integrity: sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.15.18 + '@esbuild/linux-loong64': 0.15.18 + esbuild-android-64: 0.15.18 + esbuild-android-arm64: 0.15.18 + esbuild-darwin-64: 0.15.18 + esbuild-darwin-arm64: 0.15.18 + esbuild-freebsd-64: 0.15.18 + esbuild-freebsd-arm64: 0.15.18 + esbuild-linux-32: 0.15.18 + esbuild-linux-64: 0.15.18 + esbuild-linux-arm: 0.15.18 + esbuild-linux-arm64: 0.15.18 + esbuild-linux-mips64le: 0.15.18 + esbuild-linux-ppc64le: 0.15.18 + esbuild-linux-riscv64: 0.15.18 + esbuild-linux-s390x: 0.15.18 + esbuild-netbsd-64: 0.15.18 + esbuild-openbsd-64: 0.15.18 + esbuild-sunos-64: 0.15.18 + esbuild-windows-32: 0.15.18 + esbuild-windows-64: 0.15.18 + esbuild-windows-arm64: 0.15.18 + dev: false + /esbuild@0.19.8: resolution: {integrity: sha512-l7iffQpT2OrZfH2rXIp7/FkmaeZM0vxbxN9KfiCwGYuZqzMg/JdvX26R31Zxn/Pxvsrg3Y9N6XTcnknqDyyv4w==} engines: {node: '>=12'} @@ -3186,6 +3479,30 @@ packages: engines: {node: '>=16.17.0'} dev: false + /i18next-browser-languagedetector@7.2.0: + resolution: {integrity: sha512-U00DbDtFIYD3wkWsr2aVGfXGAj2TgnELzOX9qv8bT0aJtvPV9CRO77h+vgmHFBMe7LAxdwvT/7VkCWGya6L3tA==} + dependencies: + '@babel/runtime': 7.24.0 + dev: false + + /i18next-fs-backend@2.3.1: + resolution: {integrity: sha512-tvfXskmG/9o+TJ5Fxu54sSO5OkY6d+uMn+K6JiUGLJrwxAVfer+8V3nU8jq3ts9Pe5lXJv4b1N7foIjJ8Iy2Gg==} + dev: false + + /i18next-http-backend@2.5.0: + resolution: {integrity: sha512-Z/aQsGZk1gSxt2/DztXk92DuDD20J+rNudT7ZCdTrNOiK8uQppfvdjq9+DFQfpAnFPn3VZS+KQIr1S/W1KxhpQ==} + dependencies: + cross-fetch: 4.0.0 + transitivePeerDependencies: + - encoding + dev: false + + /i18next@22.5.1: + resolution: {integrity: sha512-8TGPgM3pAD+VRsMtUMNknRz3kzqwp/gPALrWMsDnmC1mKqJwpWyooQRLMcbTwq8z8YwSmuj+ZYvc+xCuEpkssA==} + dependencies: + '@babel/runtime': 7.24.0 + dev: false + /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -3507,6 +3824,11 @@ packages: /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + /iso-639-1@2.1.15: + resolution: {integrity: sha512-7c7mBznZu2ktfvyT582E2msM+Udc1EjOyhVRE/0ZsjD9LBtWSm23h3PtiRh2a35XoUsTQQjJXaJzuLjXsOdFDg==} + engines: {node: '>=6.0'} + dev: false + /isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} dev: true @@ -3679,6 +4001,10 @@ packages: strip-bom: 3.0.0 dev: false + /locale-emoji@0.3.0: + resolution: {integrity: sha512-JGm8+naU49CBDnH1jksS3LecPdfWQLxFgkLN6ZhYONKa850pJ0Xt8DPGJnYK0ZuJI8jTuiDDPCDtSL3nyacXwg==} + dev: false + /locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -4279,6 +4605,18 @@ packages: resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} dev: false + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + /node-releases@2.0.13: resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} dev: false @@ -4528,6 +4866,10 @@ packages: engines: {node: '>=8'} dev: true + /pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + dev: false + /pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} dev: true @@ -4776,6 +5118,10 @@ packages: which-builtin-type: 1.1.3 dev: true + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + dev: false + /regexp.prototype.flags@1.5.1: resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} engines: {node: '>= 0.4'} @@ -5485,6 +5831,10 @@ packages: url-parse: 1.5.10 dev: true + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + /trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} dev: false @@ -5530,6 +5880,14 @@ packages: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} dev: true + /tsm@2.3.0: + resolution: {integrity: sha512-++0HFnmmR+gMpDtKTnW3XJ4yv9kVGi20n+NfyQWB9qwJvTaIWY9kBmzek2YUQK5APTQ/1DTrXmm4QtFPmW9Rzw==} + engines: {node: '>=12'} + hasBin: true + dependencies: + esbuild: 0.15.18 + dev: false + /tsutils@3.21.0(typescript@5.2.2): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} @@ -5887,6 +6245,17 @@ packages: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} dev: false + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + /which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json new file mode 100644 index 0000000..ae10e63 --- /dev/null +++ b/public/locales/en/translation.json @@ -0,0 +1,5 @@ +{ + "titles": { + "featuredWork": "Featured Work" + } +} diff --git a/public/locales/es/translation.json b/public/locales/es/translation.json new file mode 100644 index 0000000..6f1e189 --- /dev/null +++ b/public/locales/es/translation.json @@ -0,0 +1,5 @@ +{ + "titles": { + "featuredWork": "Trabajo Destacado" + } +} diff --git a/src/components/LangSelector.astro b/src/components/LangSelector.astro new file mode 100644 index 0000000..9d2ac2d --- /dev/null +++ b/src/components/LangSelector.astro @@ -0,0 +1,16 @@ +--- +import { LanguageSelector } from 'astro-i18next/components'; +--- + + + + diff --git a/src/components/Navbar.astro b/src/components/Navbar.astro index 839b115..4894a75 100644 --- a/src/components/Navbar.astro +++ b/src/components/Navbar.astro @@ -1,13 +1,15 @@ --- +import { localizePath } from 'astro-i18next'; import OffCanvas from '@components/OffCanvas/OffCanvas.astro'; import OffCanvasBtn from '@components/OffCanvas/OffCanvasBtn.astro'; +import LangSelector from '@components/LangSelector.astro'; const links = [ - { href: '/', text: 'Home' }, - { href: '/blog', text: 'Blog' }, - { href: '/portafolio', text: 'Portafolio' }, - { href: '/curriculum', text: 'Curriculum' }, - { href: '/contact', text: 'Contact' }, + { href: localizePath('/'), text: 'Home' }, + { href: localizePath('/blog'), text: 'Blog' }, + { href: localizePath('/portafolio'), text: 'Portafolio' }, + { href: localizePath('/curriculum'), text: 'Curriculum' }, + { href: localizePath('/contact'), text: 'Contact' }, ]; --- @@ -23,6 +25,9 @@ const links = [ )) } + @@ -70,6 +75,10 @@ const links = [ .navbar-desktop ul { width: fit-content; margin-left: auto; + + .nav-item { + margin-bottom: 0; + } } ul { @@ -82,7 +91,7 @@ const links = [ a { --boder-color: transparent; - border: 1px solid var(--boder-color); + border: 1px solid transparent; border-radius: 4px; text-decoration: none; diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index b97bb31..eb66313 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -1,5 +1,7 @@ --- import { ViewTransitions } from 'astro:transitions'; +import i18next, { t } from 'i18next'; +import { HeadHrefLangs } from 'astro-i18next/components'; export interface Props { title: string; } @@ -12,13 +14,14 @@ const { title } = Astro.props; --- - + + {title} diff --git a/src/pages/404.astro b/src/pages/404.astro index 8b2f5a9..2c20794 100644 --- a/src/pages/404.astro +++ b/src/pages/404.astro @@ -1,5 +1,8 @@ --- -import Layout from '../layouts/Layout.astro'; +import { changeLanguage } from "i18next"; +import Layout from "../layouts/Layout.astro"; + +changeLanguage("en"); --- diff --git a/src/pages/blog.astro b/src/pages/blog.astro index c2a8e5c..9955b0e 100644 --- a/src/pages/blog.astro +++ b/src/pages/blog.astro @@ -1,5 +1,8 @@ --- -import Layout from '../layouts/Layout.astro'; +import { changeLanguage } from "i18next"; +import Layout from "../layouts/Layout.astro"; + +changeLanguage("en"); --- diff --git a/src/pages/blog/[...slug].astro b/src/pages/blog/[...slug].astro index 577ff08..e5470a5 100644 --- a/src/pages/blog/[...slug].astro +++ b/src/pages/blog/[...slug].astro @@ -1,20 +1,20 @@ --- -import type { InferGetStaticPropsType, GetStaticPaths } from 'astro'; -import { getCollection } from 'astro:content'; -import Layout from '@layouts/Layout.astro'; -import Toc from '@components/Toc/Toc'; +import { changeLanguage } from "i18next"; +import type { InferGetStaticPropsType, GetStaticPaths } from "astro"; +import { getCollection } from "astro:content"; +import Layout from "@layouts/Layout.astro"; +import Toc from "@components/Toc/Toc"; + +changeLanguage("en"); export const getStaticPaths = (async () => { - const entries = await getCollection('blog'); - - return entries.map((entry) => ({ - params: { slug: entry.slug }, - props: entry, - })); + const entries = await getCollection("blog"); + return entries.map((entry) => ({ + params: { slug: entry.slug }, + props: entry, + })); }) satisfies GetStaticPaths; - type Props = InferGetStaticPropsType; - const entry = Astro.props; const { Content, headings } = await entry.render(); --- diff --git a/src/pages/blog/index.astro b/src/pages/blog/index.astro index efb693d..c1edf1e 100644 --- a/src/pages/blog/index.astro +++ b/src/pages/blog/index.astro @@ -1,36 +1,37 @@ --- -import { getCollection } from 'astro:content'; -import Layout from '@layouts/Layout.astro'; -import Table from '@components/Table'; -import { HeaderType, type Header } from '@components/Table/types'; +import { changeLanguage } from "i18next"; +import { getCollection } from "astro:content"; +import Layout from "@layouts/Layout.astro"; +import Table from "@components/Table"; +import { HeaderType, type Header } from "@components/Table/types"; -const rawEntries = await getCollection('blog', ({ data }) => { - return import.meta.env.PROD ? data.draft !== true : true; +changeLanguage("en"); + +const rawEntries = await getCollection("blog", ({ data }) => { + return import.meta.env.PROD ? data.draft !== true : true; }); - const entries = rawEntries.map((item, idx) => ({ - ...item.data, - id: idx + 1, - slug: item.slug, + ...item.data, + id: idx + 1, + slug: item.slug, })); - const headers: Header[] = [ - { - key: 'id', - header: 'index', - type: HeaderType.Index, - }, - { - key: 'title', - header: 'Title', - formatter: (data) => `${data.title}`, - type: HeaderType.String, - }, - { - key: 'tags', - header: 'Tags', - type: HeaderType.Multiple, - }, + { + key: "id", + header: "index", + type: HeaderType.Index, + }, + { + key: "title", + header: "Title", + formatter: (data) => `${data.title}`, + type: HeaderType.String, + }, + { + key: "tags", + header: "Tags", + type: HeaderType.Multiple, + }, ]; --- diff --git a/src/pages/es/404.astro b/src/pages/es/404.astro new file mode 100644 index 0000000..c471e35 --- /dev/null +++ b/src/pages/es/404.astro @@ -0,0 +1,10 @@ +--- +import { changeLanguage } from "i18next"; +import Layout from "../../layouts/Layout.astro"; + +changeLanguage("es"); +--- + + +

not found

+
diff --git a/src/pages/es/blog.astro b/src/pages/es/blog.astro new file mode 100644 index 0000000..3c5832f --- /dev/null +++ b/src/pages/es/blog.astro @@ -0,0 +1,10 @@ +--- +import { changeLanguage } from "i18next"; +import Layout from "../../layouts/Layout.astro"; + +changeLanguage("es"); +--- + + +

Blog

+
diff --git a/src/pages/es/blog/[...slug].astro b/src/pages/es/blog/[...slug].astro new file mode 100644 index 0000000..14f73f6 --- /dev/null +++ b/src/pages/es/blog/[...slug].astro @@ -0,0 +1,26 @@ +--- +import { changeLanguage } from "i18next"; +import type { InferGetStaticPropsType, GetStaticPaths } from "astro"; +import { getCollection } from "astro:content"; +import Layout from "@layouts/Layout.astro"; +import Toc from "@components/Toc/Toc"; + +changeLanguage("es"); + +export const getStaticPaths = (async () => { + const entries = await getCollection("blog"); + return entries.map((entry) => ({ + params: { slug: entry.slug }, + props: entry, + })); +}) satisfies GetStaticPaths; +type Props = InferGetStaticPropsType; +const entry = Astro.props; +const { Content, headings } = await entry.render(); +--- + + + + + + diff --git a/src/pages/es/blog/index.astro b/src/pages/es/blog/index.astro new file mode 100644 index 0000000..22b02b6 --- /dev/null +++ b/src/pages/es/blog/index.astro @@ -0,0 +1,44 @@ +--- +import { changeLanguage } from "i18next"; +import { getCollection } from "astro:content"; +import Layout from "@layouts/Layout.astro"; +import Table from "@components/Table"; +import { HeaderType, type Header } from "@components/Table/types"; + +changeLanguage("es"); + +const rawEntries = await getCollection("blog", ({ data }) => { + return import.meta.env.PROD ? data.draft !== true : true; +}); +const entries = rawEntries.map((item, idx) => ({ + ...item.data, + id: idx + 1, + slug: item.slug, +})); +const headers: Header[] = [ + { + key: "id", + header: "index", + type: HeaderType.Index, + }, + { + key: "title", + header: "Title", + formatter: (data) => `${data.title}`, + type: HeaderType.String, + }, + { + key: "tags", + header: "Tags", + type: HeaderType.Multiple, + }, +]; +--- + + +

Blog's entries

+ +
+ + + diff --git a/src/pages/es/games/[...slug].astro b/src/pages/es/games/[...slug].astro new file mode 100644 index 0000000..64c061d --- /dev/null +++ b/src/pages/es/games/[...slug].astro @@ -0,0 +1,26 @@ +--- +import { changeLanguage } from "i18next"; +import { InferGetStaticParamsType, InferGetStaticPropsType, GetStaticPaths, } from "astro"; +import { getCollection } from "astro:content"; +import Layout from "@layouts/Layout.astro"; +import Toc from "@components/Toc/Toc"; + +changeLanguage("es"); + +export const getStaticPaths = (async () => { + const games = await getCollection("games"); + return games.map((entry) => ({ + params: { slug: entry.slug }, + props: entry, + })); +}) satisfies GetStaticPaths; +type Props = InferGetStaticPropsType; +const entry = Astro.props; +const { Content, headings } = await entry.render(); +--- + + + + + + diff --git a/src/pages/es/games/index.astro b/src/pages/es/games/index.astro new file mode 100644 index 0000000..70a76bd --- /dev/null +++ b/src/pages/es/games/index.astro @@ -0,0 +1,61 @@ +--- +import { changeLanguage } from "i18next"; +import { getCollection } from "astro:content"; +import Layout from "@layouts/Layout.astro"; +import Table from "@components/Table"; +import { HeaderType, type Header } from "@components/Table/types"; + +changeLanguage("es"); + +const rawGames = await getCollection("games"); +let games = rawGames.map((item, idx) => ({ + ...item.data, + id: idx + 1, + slug: item.slug, + customCell: item.data.has_content + ? `${item.data.title}` + : `
${item.data.title}
`, +})); +games = games.sort((a, b) => b.date_added.getTime() - a.date_added.getTime()); +const headers: Header[] = [ + { + key: "id", + header: "index", + type: HeaderType.Index, + }, + { + key: "title", + header: "Title", + type: HeaderType.String, + hasCustomCell: true, + }, + { + key: "status", + header: "Status", + type: HeaderType.Select, + }, + { + key: "genres", + header: "Genres", + type: HeaderType.Multiple, + }, + { + key: "times_played", + header: "Times Played", + type: HeaderType.Number, + }, + { + key: "registered_hours", + header: "Registered Hours", + type: HeaderType.Number, + }, +]; +--- + + +

Games

+ +
+
+ + diff --git a/src/pages/es/index.astro b/src/pages/es/index.astro new file mode 100644 index 0000000..a19fd04 --- /dev/null +++ b/src/pages/es/index.astro @@ -0,0 +1,276 @@ +--- +import { getCollection } from "astro:content"; +import Layout from "../../layouts/Layout.astro"; +import Card from "../../components/Card.astro"; +import Button from "../../components/Button/Button.astro"; +import { Image } from "astro:assets"; +import { t, changeLanguage } from "i18next"; +import portrait from "../../assets/images/portrait.jpg"; + +changeLanguage("es"); + +const blog = await getCollection("blog", ({ data }) => import.meta.env.PROD ? data.draft !== true : true); +// TODO: show the pinned ones, not the recents +const portafolio = await getCollection("portafolio", ({ data }) => import.meta.env.PROD ? data.draft !== true : true); +--- + + +
+
+ + + + + + + +
+

Alexander Navarro

+

+ Lorem ipsum dolor sit amet consectetur, adipisicing elit. Amet, + repudiandae veritatis totam animi ut facere omnis. Quasi, tempore + porro, neque officia nisi error quia deleniti nesciunt provident vitae + consequuntur quod? +

+
+
+
+ +
+

{t('titles.featuredWork')}

Featured Work +
+ +
+ + project img +

Project N°1

+

+ Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint + cillum sint consectetur cupidatat. +

+ + +
+ + + project img +

Project N°1

+

+ Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint + cillum sint consectetur cupidatat. +

+ + +
+ + + project img +

Project N°1

+

+ Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint + cillum sint consectetur cupidatat. +

+ + +
+
+ +
+ +
+
+ +
+

What I've been up to...

+ +
+ + +
+
+ project img +
+

+ Lorem ipsum dolor sit, amet consectetur adipisicing elit. Esse + consequatur iste molestiae blanditiis eligendi consectetur ullam. + Excepturi quasi sed est animi laudantium necessitatibus, tempore + delectus nulla aspernatur quod nesciunt fugiat. +

+
+
+ +
+ + +
+
+ project img +
+

+ Lorem ipsum dolor sit, amet consectetur adipisicing elit. Esse + consequatur iste molestiae blanditiis eligendi consectetur ullam. + Excepturi quasi sed est animi laudantium necessitatibus, tempore + delectus nulla aspernatur quod nesciunt fugiat. +

+
+
+
+ +
+

Who am I?

+ +

+ Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim + labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. + Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum + Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. + Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex + occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat + officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in + Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non + excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut + ea consectetur et est culpa et culpa duis. +

+ + +
+ +
+

Contact

+ +
+
+
+ project img +
+

+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis + reprehenderit, porro dolorem cumque suscipit accusantium officiis eius + exercitationem harum itaque perferendis praesentium asperiores vitae + pariatur ad culpa mollitia necessitatibus hic! +

+
+ +
+
    + { + [ + { + link: '#', + img: 'https://placehold.co/60', + alt: '', + text: 'Github', + }, + { + link: '#', + img: 'https://placehold.co/60', + alt: '', + text: 'Linkedin', + }, + { + link: '#', + img: 'https://placehold.co/60', + alt: '', + text: 'Email', + }, + ].map((item) => ( +
  • + + <> + {item.alt} + {item.text} + + +
  • + )) + } +
+
+
+
+ + diff --git a/src/pages/es/portafolio/[...slug].astro b/src/pages/es/portafolio/[...slug].astro new file mode 100644 index 0000000..129dbfe --- /dev/null +++ b/src/pages/es/portafolio/[...slug].astro @@ -0,0 +1,31 @@ +--- +import { changeLanguage } from "i18next"; +import type { InferGetStaticPropsType, GetStaticPaths } from "astro"; +import { getCollection } from "astro:content"; +import Layout from "@layouts/Layout.astro"; +import Toc from "@components/Toc/Toc"; +import Gallery from "@components/MediaGallery/Gallery"; + +changeLanguage("es"); + +export const getStaticPaths = (async () => { + const entries = await getCollection("portafolio"); + return entries.map((entry) => ({ + params: { slug: entry.slug }, + props: entry, + })); +}) satisfies GetStaticPaths; +type Props = InferGetStaticPropsType; +const entry = Astro.props; +const { Content, headings } = await entry.render(); +--- + + +

{entry.data.title}

+ + + + + + +
diff --git a/src/pages/es/portafolio/index.astro b/src/pages/es/portafolio/index.astro new file mode 100644 index 0000000..96dfc3c --- /dev/null +++ b/src/pages/es/portafolio/index.astro @@ -0,0 +1,44 @@ +--- +import { changeLanguage } from "i18next"; +import { getCollection } from "astro:content"; +import Layout from "@layouts/Layout.astro"; +import Table from "@components/Table"; +import { HeaderType, type Header } from "@components/Table/types"; + +changeLanguage("es"); + +const rawEntries = await getCollection("portafolio", ({ data }) => { + return import.meta.env.PROD ? data.draft !== true : true; +}); +const entries = rawEntries.map((item, idx) => ({ + ...item.data, + id: idx + 1, + slug: item.slug, +})); +const headers: Header[] = [ + { + key: "id", + header: "index", + type: HeaderType.Index, + }, + { + key: "title", + header: "Title", + formatter: (data) => `${data.title}`, + type: HeaderType.String, + }, + { + key: "technologies", + header: "Technologies", + type: HeaderType.Multiple, + }, +]; +--- + + +

Blog's entries

+ +
+
+ + diff --git a/src/pages/games/[...slug].astro b/src/pages/games/[...slug].astro index f6116a6..6f8fd1a 100644 --- a/src/pages/games/[...slug].astro +++ b/src/pages/games/[...slug].astro @@ -1,24 +1,20 @@ --- -import { - InferGetStaticParamsType, - InferGetStaticPropsType, - GetStaticPaths, -} from 'astro'; -import { getCollection } from 'astro:content'; -import Layout from '@layouts/Layout.astro'; -import Toc from '@components/Toc/Toc'; +import { changeLanguage } from "i18next"; +import { InferGetStaticParamsType, InferGetStaticPropsType, GetStaticPaths, } from "astro"; +import { getCollection } from "astro:content"; +import Layout from "@layouts/Layout.astro"; +import Toc from "@components/Toc/Toc"; + +changeLanguage("en"); export const getStaticPaths = (async () => { - const games = await getCollection('games'); - - return games.map((entry) => ({ - params: { slug: entry.slug }, - props: entry, - })); + const games = await getCollection("games"); + return games.map((entry) => ({ + params: { slug: entry.slug }, + props: entry, + })); }) satisfies GetStaticPaths; - type Props = InferGetStaticPropsType; - const entry = Astro.props; const { Content, headings } = await entry.render(); --- diff --git a/src/pages/games/index.astro b/src/pages/games/index.astro index a9e3b80..5dd810b 100644 --- a/src/pages/games/index.astro +++ b/src/pages/games/index.astro @@ -1,54 +1,54 @@ --- -import { getCollection } from 'astro:content'; -import Layout from '@layouts/Layout.astro'; -import Table from '@components/Table'; -import { HeaderType, type Header } from '@components/Table/types'; +import { changeLanguage } from "i18next"; +import { getCollection } from "astro:content"; +import Layout from "@layouts/Layout.astro"; +import Table from "@components/Table"; +import { HeaderType, type Header } from "@components/Table/types"; -const rawGames = await getCollection('games'); +changeLanguage("en"); +const rawGames = await getCollection("games"); let games = rawGames.map((item, idx) => ({ - ...item.data, - id: idx + 1, - slug: item.slug, - customCell: item.data.has_content - ? `${item.data.title}` - : `
${item.data.title}
`, + ...item.data, + id: idx + 1, + slug: item.slug, + customCell: item.data.has_content + ? `${item.data.title}` + : `
${item.data.title}
`, })); - games = games.sort((a, b) => b.date_added.getTime() - a.date_added.getTime()); - const headers: Header[] = [ - { - key: 'id', - header: 'index', - type: HeaderType.Index, - }, - { - key: 'title', - header: 'Title', - type: HeaderType.String, - hasCustomCell: true, - }, - { - key: 'status', - header: 'Status', - type: HeaderType.Select, - }, - { - key: 'genres', - header: 'Genres', - type: HeaderType.Multiple, - }, - { - key: 'times_played', - header: 'Times Played', - type: HeaderType.Number, - }, - { - key: 'registered_hours', - header: 'Registered Hours', - type: HeaderType.Number, - }, + { + key: "id", + header: "index", + type: HeaderType.Index, + }, + { + key: "title", + header: "Title", + type: HeaderType.String, + hasCustomCell: true, + }, + { + key: "status", + header: "Status", + type: HeaderType.Select, + }, + { + key: "genres", + header: "Genres", + type: HeaderType.Multiple, + }, + { + key: "times_played", + header: "Times Played", + type: HeaderType.Number, + }, + { + key: "registered_hours", + header: "Registered Hours", + type: HeaderType.Number, + }, ]; --- diff --git a/src/pages/index.astro b/src/pages/index.astro index ff3674f..5520175 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,19 +1,17 @@ --- -import { getCollection } from 'astro:content'; -import Layout from '../layouts/Layout.astro'; -import Card from '../components/Card.astro'; -import Button from '../components/Button/Button.astro'; -import { Image } from 'astro:assets'; +import { getCollection } from "astro:content"; +import Layout from "../layouts/Layout.astro"; +import Card from "../components/Card.astro"; +import Button from "../components/Button/Button.astro"; +import { Image } from "astro:assets"; +import { t, changeLanguage } from "i18next"; +import portrait from "../assets/images/portrait.jpg"; -import portrait from '../assets/images/portrait.jpg'; +changeLanguage("en"); -const blog = await getCollection('blog', ({ data }) => - import.meta.env.PROD ? data.draft !== true : true, -); +const blog = await getCollection("blog", ({ data }) => import.meta.env.PROD ? data.draft !== true : true); // TODO: show the pinned ones, not the recents -const portafolio = await getCollection('portafolio', ({ data }) => - import.meta.env.PROD ? data.draft !== true : true, -); +const portafolio = await getCollection("portafolio", ({ data }) => import.meta.env.PROD ? data.draft !== true : true); --- @@ -43,242 +41,236 @@ const portafolio = await getCollection('portafolio', ({ data }) =>
-

Featured Work

- -
- - project img -

Project N°1

-

- Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint - cillum sint consectetur cupidatat. -

- - -
- - - project img -

Project N°1

-

- Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint - cillum sint consectetur cupidatat. -

- - -
- - - project img -

Project N°1

-

- Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint - cillum sint consectetur cupidatat. -

- - -
-
- -
- -
+

{t('titles.featuredWork')}

Featured Work
-
-

What I've been up to...

+
+ + project img +

Project N°1

+

+ Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint + cillum sint consectetur cupidatat. +

-
-
-

Blog

-
    -
  1. - Qui minim labore adipisicing minim sint cillum sint consectetur - cupidatat. -
  2. -
  3. - Qui minim labore adipisicing minim sint cillum sint consectetur - cupidatat. -
  4. -
  5. - Qui minim labore adipisicing minim sint cillum sint consectetur - cupidatat. -
  6. -
+ + -
-
- project img -
-

- Lorem ipsum dolor sit, amet consectetur adipisicing elit. Esse - consequatur iste molestiae blanditiis eligendi consectetur ullam. - Excepturi quasi sed est animi laudantium necessitatibus, tempore - delectus nulla aspernatur quod nesciunt fugiat. -

+ + project img +

Project N°1

+

+ Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint + cillum sint consectetur cupidatat. +

+ + -
+ -
-
-

Games

-
    -
  1. - Qui minim labore adipisicing minim sint cillum sint consectetur - cupidatat. -
  2. -
  3. - Qui minim labore adipisicing minim sint cillum sint consectetur - cupidatat. -
  4. -
  5. - Qui minim labore adipisicing minim sint cillum sint consectetur - cupidatat. -
  6. -
+ + project img +

Project N°1

+

+ Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint + cillum sint consectetur cupidatat. +

+ + +
+
-
-
- project img -
-

- Lorem ipsum dolor sit, amet consectetur adipisicing elit. Esse - consequatur iste molestiae blanditiis eligendi consectetur ullam. - Excepturi quasi sed est animi laudantium necessitatibus, tempore - delectus nulla aspernatur quod nesciunt fugiat. -

-
-
-
- -
-

Who am I?

- -

- Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim - labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. - Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum - Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. - Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex - occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat - officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in - Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non - excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco - ut ea consectetur et est culpa et culpa duis. -

- - -
- -
-

Contact

- -
-
-
- project img -
-

- Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis - reprehenderit, porro dolorem cumque suscipit accusantium officiis eius - exercitationem harum itaque perferendis praesentium asperiores vitae - pariatur ad culpa mollitia necessitatibus hic! -

-
- -
-
    - { - [ - { - link: '#', - img: 'https://placehold.co/60', - alt: '', - text: 'Github', - }, - { - link: '#', - img: 'https://placehold.co/60', - alt: '', - text: 'Linkedin', - }, - { - link: '#', - img: 'https://placehold.co/60', - alt: '', - text: 'Email', - }, - ].map((item) => ( -
  • - - <> - {item.alt} - {item.text} - - -
  • - )) - } -
-
-
-
- - +
+ +
+ +
+

What I've been up to...

+ +
+ + +
+
+ project img +
+

+ Lorem ipsum dolor sit, amet consectetur adipisicing elit. Esse + consequatur iste molestiae blanditiis eligendi consectetur ullam. + Excepturi quasi sed est animi laudantium necessitatibus, tempore + delectus nulla aspernatur quod nesciunt fugiat. +

+
+
+ +
+ + +
+
+ project img +
+

+ Lorem ipsum dolor sit, amet consectetur adipisicing elit. Esse + consequatur iste molestiae blanditiis eligendi consectetur ullam. + Excepturi quasi sed est animi laudantium necessitatibus, tempore + delectus nulla aspernatur quod nesciunt fugiat. +

+
+
+
+ +
+

Who am I?

+ +

+ Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim + labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. + Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum + Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. + Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex + occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat + officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in + Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non + excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut + ea consectetur et est culpa et culpa duis. +

+ + +
+ +
+

Contact

+ +
+
+
+ project img +
+

+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis + reprehenderit, porro dolorem cumque suscipit accusantium officiis eius + exercitationem harum itaque perferendis praesentium asperiores vitae + pariatur ad culpa mollitia necessitatibus hic! +

+
+ +
+
    + { + [ + { + link: '#', + img: 'https://placehold.co/60', + alt: '', + text: 'Github', + }, + { + link: '#', + img: 'https://placehold.co/60', + alt: '', + text: 'Linkedin', + }, + { + link: '#', + img: 'https://placehold.co/60', + alt: '', + text: 'Email', + }, + ].map((item) => ( +
  • + + <> + {item.alt} + {item.text} + + +
  • + )) + } +
+
+
+
+ + diff --git a/src/pages/portafolio/[...slug].astro b/src/pages/portafolio/[...slug].astro index 1954e40..2a78c61 100644 --- a/src/pages/portafolio/[...slug].astro +++ b/src/pages/portafolio/[...slug].astro @@ -1,21 +1,21 @@ --- -import type { InferGetStaticPropsType, GetStaticPaths } from 'astro'; -import { getCollection } from 'astro:content'; -import Layout from '@layouts/Layout.astro'; -import Toc from '@components/Toc/Toc'; -import Gallery from '@components/MediaGallery/Gallery'; +import { changeLanguage } from "i18next"; +import type { InferGetStaticPropsType, GetStaticPaths } from "astro"; +import { getCollection } from "astro:content"; +import Layout from "@layouts/Layout.astro"; +import Toc from "@components/Toc/Toc"; +import Gallery from "@components/MediaGallery/Gallery"; + +changeLanguage("en"); export const getStaticPaths = (async () => { - const entries = await getCollection('portafolio'); - - return entries.map((entry) => ({ - params: { slug: entry.slug }, - props: entry, - })); + const entries = await getCollection("portafolio"); + return entries.map((entry) => ({ + params: { slug: entry.slug }, + props: entry, + })); }) satisfies GetStaticPaths; - type Props = InferGetStaticPropsType; - const entry = Astro.props; const { Content, headings } = await entry.render(); --- diff --git a/src/pages/portafolio/index.astro b/src/pages/portafolio/index.astro index bbf2fa7..7a408e8 100644 --- a/src/pages/portafolio/index.astro +++ b/src/pages/portafolio/index.astro @@ -1,36 +1,37 @@ --- -import { getCollection } from 'astro:content'; -import Layout from '@layouts/Layout.astro'; -import Table from '@components/Table'; -import { HeaderType, type Header } from '@components/Table/types'; +import { changeLanguage } from "i18next"; +import { getCollection } from "astro:content"; +import Layout from "@layouts/Layout.astro"; +import Table from "@components/Table"; +import { HeaderType, type Header } from "@components/Table/types"; -const rawEntries = await getCollection('portafolio', ({ data }) => { - return import.meta.env.PROD ? data.draft !== true : true; +changeLanguage("en"); + +const rawEntries = await getCollection("portafolio", ({ data }) => { + return import.meta.env.PROD ? data.draft !== true : true; }); - const entries = rawEntries.map((item, idx) => ({ - ...item.data, - id: idx + 1, - slug: item.slug, + ...item.data, + id: idx + 1, + slug: item.slug, })); - const headers: Header[] = [ - { - key: 'id', - header: 'index', - type: HeaderType.Index, - }, - { - key: 'title', - header: 'Title', - formatter: (data) => `${data.title}`, - type: HeaderType.String, - }, - { - key: 'technologies', - header: 'Technologies', - type: HeaderType.Multiple, - }, + { + key: "id", + header: "index", + type: HeaderType.Index, + }, + { + key: "title", + header: "Title", + formatter: (data) => `${data.title}`, + type: HeaderType.String, + }, + { + key: "technologies", + header: "Technologies", + type: HeaderType.Multiple, + }, ]; ---