feat(langs): Add internacionalization functionality
This commit is contained in:
parent
eef9ec9457
commit
45fcc13497
27 changed files with 1330 additions and 390 deletions
5
astro-i18next.config.mjs
Normal file
5
astro-i18next.config.mjs
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
/** @type {import('astro-i18next').AstroI18nextConfig} */
|
||||||
|
export default {
|
||||||
|
defaultLocale: 'en',
|
||||||
|
locales: ['en', 'es'],
|
||||||
|
};
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import { defineConfig } from 'astro/config';
|
import { defineConfig } from 'astro/config';
|
||||||
|
|
||||||
import react from '@astrojs/react';
|
import react from '@astrojs/react';
|
||||||
|
import astroI18next from 'astro-i18next';
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
prefetch: true,
|
prefetch: true,
|
||||||
integrations: [react()],
|
integrations: [react(), astroI18next()],
|
||||||
experimental: {},
|
experimental: {},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@
|
||||||
"@types/react": "^18.0.21",
|
"@types/react": "^18.0.21",
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/react-dom": "^18.0.6",
|
||||||
"astro": "^4.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": "^18.0.0",
|
||||||
"react-dom": "^18.0.0",
|
"react-dom": "^18.0.0",
|
||||||
"sass": "^1.71.1",
|
"sass": "^1.71.1",
|
||||||
|
|
|
||||||
369
pnpm-lock.yaml
generated
369
pnpm-lock.yaml
generated
|
|
@ -20,6 +20,15 @@ dependencies:
|
||||||
astro:
|
astro:
|
||||||
specifier: ^4.0.6
|
specifier: ^4.0.6
|
||||||
version: 4.0.6(sass@1.71.1)(typescript@5.2.2)
|
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:
|
react:
|
||||||
specifier: ^18.0.0
|
specifier: ^18.0.0
|
||||||
version: 18.2.0
|
version: 18.2.0
|
||||||
|
|
@ -393,6 +402,13 @@ packages:
|
||||||
'@babel/types': 7.23.4
|
'@babel/types': 7.23.4
|
||||||
dev: false
|
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:
|
/@babel/template@7.22.15:
|
||||||
resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==}
|
resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
@ -478,6 +494,15 @@ packages:
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
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:
|
/@esbuild/android-arm@0.19.8:
|
||||||
resolution: {integrity: sha512-31E2lxlGM1KEfivQl8Yf5aYU/mflz9g06H6S15ITUFQueMFtFjESRMoDSkvMo8thYvLBax+VKTPlpnx+sPicOA==}
|
resolution: {integrity: sha512-31E2lxlGM1KEfivQl8Yf5aYU/mflz9g06H6S15ITUFQueMFtFjESRMoDSkvMo8thYvLBax+VKTPlpnx+sPicOA==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
@ -559,6 +584,15 @@ packages:
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
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:
|
/@esbuild/linux-loong64@0.19.8:
|
||||||
resolution: {integrity: sha512-fHZWS2JJxnXt1uYJsDv9+b60WCc2RlvVAy1F76qOLtXRO+H4mjt3Tr6MJ5l7Q78X8KgCFudnTuiQRBhULUyBKQ==}
|
resolution: {integrity: sha512-fHZWS2JJxnXt1uYJsDv9+b60WCc2RlvVAy1F76qOLtXRO+H4mjt3Tr6MJ5l7Q78X8KgCFudnTuiQRBhULUyBKQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
@ -772,6 +806,22 @@ packages:
|
||||||
'@nodelib/fs.scandir': 2.1.5
|
'@nodelib/fs.scandir': 2.1.5
|
||||||
fastq: 1.15.0
|
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:
|
/@rollup/rollup-android-arm-eabi@4.7.0:
|
||||||
resolution: {integrity: sha512-rGku10pL1StFlFvXX5pEv88KdGW6DHUghsxyP/aRYb9eH+74jTGJ3U0S/rtlsQ4yYq1Hcc7AMkoJOb1xu29Fxw==}
|
resolution: {integrity: sha512-rGku10pL1StFlFvXX5pEv88KdGW6DHUghsxyP/aRYb9eH+74jTGJ3U0S/rtlsQ4yYq1Hcc7AMkoJOb1xu29Fxw==}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
|
|
@ -1375,6 +1425,26 @@ packages:
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
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):
|
/astro@4.0.6(sass@1.71.1)(typescript@5.2.2):
|
||||||
resolution: {integrity: sha512-P7CfFqWKzkJozzF6IoOC6qoI2ONndV8P3ULhGDgMiXPL7xVkWI5haTBSpyrcjBx643tVXspIRsSV/v+Cx+CjGw==}
|
resolution: {integrity: sha512-P7CfFqWKzkJozzF6IoOC6qoI2ONndV8P3ULhGDgMiXPL7xVkWI5haTBSpyrcjBx643tVXspIRsSV/v+Cx+CjGw==}
|
||||||
engines: {node: '>=18.14.1', npm: '>=6.14.0'}
|
engines: {node: '>=18.14.1', npm: '>=6.14.0'}
|
||||||
|
|
@ -1843,6 +1913,14 @@ packages:
|
||||||
resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==}
|
resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==}
|
||||||
dev: true
|
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:
|
/cross-spawn@7.0.3:
|
||||||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
|
|
@ -1973,6 +2051,11 @@ packages:
|
||||||
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
|
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
|
||||||
dev: true
|
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:
|
/define-data-property@1.1.1:
|
||||||
resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==}
|
resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
@ -2198,6 +2281,216 @@ packages:
|
||||||
is-symbol: 1.0.4
|
is-symbol: 1.0.4
|
||||||
dev: true
|
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:
|
/esbuild@0.19.8:
|
||||||
resolution: {integrity: sha512-l7iffQpT2OrZfH2rXIp7/FkmaeZM0vxbxN9KfiCwGYuZqzMg/JdvX26R31Zxn/Pxvsrg3Y9N6XTcnknqDyyv4w==}
|
resolution: {integrity: sha512-l7iffQpT2OrZfH2rXIp7/FkmaeZM0vxbxN9KfiCwGYuZqzMg/JdvX26R31Zxn/Pxvsrg3Y9N6XTcnknqDyyv4w==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
@ -3186,6 +3479,30 @@ packages:
|
||||||
engines: {node: '>=16.17.0'}
|
engines: {node: '>=16.17.0'}
|
||||||
dev: false
|
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:
|
/iconv-lite@0.4.24:
|
||||||
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
|
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
@ -3507,6 +3824,11 @@ packages:
|
||||||
/isexe@2.0.0:
|
/isexe@2.0.0:
|
||||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
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:
|
/isstream@0.1.2:
|
||||||
resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==}
|
resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
@ -3679,6 +4001,10 @@ packages:
|
||||||
strip-bom: 3.0.0
|
strip-bom: 3.0.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/locale-emoji@0.3.0:
|
||||||
|
resolution: {integrity: sha512-JGm8+naU49CBDnH1jksS3LecPdfWQLxFgkLN6ZhYONKa850pJ0Xt8DPGJnYK0ZuJI8jTuiDDPCDtSL3nyacXwg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/locate-path@5.0.0:
|
/locate-path@5.0.0:
|
||||||
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
|
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
@ -4279,6 +4605,18 @@ packages:
|
||||||
resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==}
|
resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==}
|
||||||
dev: false
|
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:
|
/node-releases@2.0.13:
|
||||||
resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==}
|
resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
@ -4528,6 +4866,10 @@ packages:
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/pathe@1.1.2:
|
||||||
|
resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/pend@1.2.0:
|
/pend@1.2.0:
|
||||||
resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
|
resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
@ -4776,6 +5118,10 @@ packages:
|
||||||
which-builtin-type: 1.1.3
|
which-builtin-type: 1.1.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/regenerator-runtime@0.14.1:
|
||||||
|
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/regexp.prototype.flags@1.5.1:
|
/regexp.prototype.flags@1.5.1:
|
||||||
resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==}
|
resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
@ -5485,6 +5831,10 @@ packages:
|
||||||
url-parse: 1.5.10
|
url-parse: 1.5.10
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/tr46@0.0.3:
|
||||||
|
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/trim-lines@3.0.1:
|
/trim-lines@3.0.1:
|
||||||
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
|
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
@ -5530,6 +5880,14 @@ packages:
|
||||||
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
|
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
|
||||||
dev: true
|
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):
|
/tsutils@3.21.0(typescript@5.2.2):
|
||||||
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
|
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
|
@ -5887,6 +6245,17 @@ packages:
|
||||||
resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
|
resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
|
||||||
dev: false
|
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:
|
/which-boxed-primitive@1.0.2:
|
||||||
resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
|
resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
|
||||||
5
public/locales/en/translation.json
Normal file
5
public/locales/en/translation.json
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"titles": {
|
||||||
|
"featuredWork": "Featured Work"
|
||||||
|
}
|
||||||
|
}
|
||||||
5
public/locales/es/translation.json
Normal file
5
public/locales/es/translation.json
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"titles": {
|
||||||
|
"featuredWork": "Trabajo Destacado"
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/components/LangSelector.astro
Normal file
16
src/components/LangSelector.astro
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
import { LanguageSelector } from 'astro-i18next/components';
|
||||||
|
---
|
||||||
|
|
||||||
|
<LanguageSelector showFlag={false} class="selector" />
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.selector {
|
||||||
|
padding: var(--prj-spacing-1);
|
||||||
|
border: 1px solid var(--prj-input);
|
||||||
|
color: var(--prj-input-text);
|
||||||
|
background-color: var(--prj-input);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
---
|
---
|
||||||
|
import { localizePath } from 'astro-i18next';
|
||||||
import OffCanvas from '@components/OffCanvas/OffCanvas.astro';
|
import OffCanvas from '@components/OffCanvas/OffCanvas.astro';
|
||||||
import OffCanvasBtn from '@components/OffCanvas/OffCanvasBtn.astro';
|
import OffCanvasBtn from '@components/OffCanvas/OffCanvasBtn.astro';
|
||||||
|
import LangSelector from '@components/LangSelector.astro';
|
||||||
|
|
||||||
const links = [
|
const links = [
|
||||||
{ href: '/', text: 'Home' },
|
{ href: localizePath('/'), text: 'Home' },
|
||||||
{ href: '/blog', text: 'Blog' },
|
{ href: localizePath('/blog'), text: 'Blog' },
|
||||||
{ href: '/portafolio', text: 'Portafolio' },
|
{ href: localizePath('/portafolio'), text: 'Portafolio' },
|
||||||
{ href: '/curriculum', text: 'Curriculum' },
|
{ href: localizePath('/curriculum'), text: 'Curriculum' },
|
||||||
{ href: '/contact', text: 'Contact' },
|
{ href: localizePath('/contact'), text: 'Contact' },
|
||||||
];
|
];
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -23,6 +25,9 @@ const links = [
|
||||||
</li>
|
</li>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
<li class="nav-item">
|
||||||
|
<LangSelector />
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|
@ -70,6 +75,10 @@ const links = [
|
||||||
.navbar-desktop ul {
|
.navbar-desktop ul {
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
|
|
||||||
|
.nav-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
|
|
@ -82,7 +91,7 @@ const links = [
|
||||||
|
|
||||||
a {
|
a {
|
||||||
--boder-color: transparent;
|
--boder-color: transparent;
|
||||||
border: 1px solid var(--boder-color);
|
border: 1px solid transparent;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
---
|
---
|
||||||
import { ViewTransitions } from 'astro:transitions';
|
import { ViewTransitions } from 'astro:transitions';
|
||||||
|
import i18next, { t } from 'i18next';
|
||||||
|
import { HeadHrefLangs } from 'astro-i18next/components';
|
||||||
export interface Props {
|
export interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
@ -12,13 +14,14 @@ const { title } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang={i18next.language}>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="description" content="Astro description" />
|
<meta name="description" content="Astro description" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
<meta name="generator" content={Astro.generator} />
|
<meta name="generator" content={Astro.generator} />
|
||||||
|
<HeadHrefLangs />
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
<ViewTransitions />
|
<ViewTransitions />
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
---
|
---
|
||||||
import Layout from '../layouts/Layout.astro';
|
import { changeLanguage } from "i18next";
|
||||||
|
import Layout from "../layouts/Layout.astro";
|
||||||
|
|
||||||
|
changeLanguage("en");
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Welcome to Astro.">
|
<Layout title="Welcome to Astro.">
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
---
|
---
|
||||||
import Layout from '../layouts/Layout.astro';
|
import { changeLanguage } from "i18next";
|
||||||
|
import Layout from "../layouts/Layout.astro";
|
||||||
|
|
||||||
|
changeLanguage("en");
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Blog">
|
<Layout title="Blog">
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
---
|
---
|
||||||
import type { InferGetStaticPropsType, GetStaticPaths } from 'astro';
|
import { changeLanguage } from "i18next";
|
||||||
import { getCollection } from 'astro:content';
|
import type { InferGetStaticPropsType, GetStaticPaths } from "astro";
|
||||||
import Layout from '@layouts/Layout.astro';
|
import { getCollection } from "astro:content";
|
||||||
import Toc from '@components/Toc/Toc';
|
import Layout from "@layouts/Layout.astro";
|
||||||
|
import Toc from "@components/Toc/Toc";
|
||||||
|
|
||||||
|
changeLanguage("en");
|
||||||
|
|
||||||
export const getStaticPaths = (async () => {
|
export const getStaticPaths = (async () => {
|
||||||
const entries = await getCollection('blog');
|
const entries = await getCollection("blog");
|
||||||
|
|
||||||
return entries.map((entry) => ({
|
return entries.map((entry) => ({
|
||||||
params: { slug: entry.slug },
|
params: { slug: entry.slug },
|
||||||
props: entry,
|
props: entry,
|
||||||
}));
|
}));
|
||||||
}) satisfies GetStaticPaths;
|
}) satisfies GetStaticPaths;
|
||||||
|
|
||||||
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
||||||
|
|
||||||
const entry = Astro.props;
|
const entry = Astro.props;
|
||||||
const { Content, headings } = await entry.render();
|
const { Content, headings } = await entry.render();
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,35 @@
|
||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { changeLanguage } from "i18next";
|
||||||
import Layout from '@layouts/Layout.astro';
|
import { getCollection } from "astro:content";
|
||||||
import Table from '@components/Table';
|
import Layout from "@layouts/Layout.astro";
|
||||||
import { HeaderType, type Header } from '@components/Table/types';
|
import Table from "@components/Table";
|
||||||
|
import { HeaderType, type Header } from "@components/Table/types";
|
||||||
|
|
||||||
const rawEntries = await getCollection('blog', ({ data }) => {
|
changeLanguage("en");
|
||||||
|
|
||||||
|
const rawEntries = await getCollection("blog", ({ data }) => {
|
||||||
return import.meta.env.PROD ? data.draft !== true : true;
|
return import.meta.env.PROD ? data.draft !== true : true;
|
||||||
});
|
});
|
||||||
|
|
||||||
const entries = rawEntries.map((item, idx) => ({
|
const entries = rawEntries.map((item, idx) => ({
|
||||||
...item.data,
|
...item.data,
|
||||||
id: idx + 1,
|
id: idx + 1,
|
||||||
slug: item.slug,
|
slug: item.slug,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const headers: Header[] = [
|
const headers: Header[] = [
|
||||||
{
|
{
|
||||||
key: 'id',
|
key: "id",
|
||||||
header: 'index',
|
header: "index",
|
||||||
type: HeaderType.Index,
|
type: HeaderType.Index,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'title',
|
key: "title",
|
||||||
header: 'Title',
|
header: "Title",
|
||||||
formatter: (data) => `<a href="blog/${data.slug}">${data.title}</a>`,
|
formatter: (data) => `<a href="blog/${data.slug}">${data.title}</a>`,
|
||||||
type: HeaderType.String,
|
type: HeaderType.String,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'tags',
|
key: "tags",
|
||||||
header: 'Tags',
|
header: "Tags",
|
||||||
type: HeaderType.Multiple,
|
type: HeaderType.Multiple,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
||||||
10
src/pages/es/404.astro
Normal file
10
src/pages/es/404.astro
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
import { changeLanguage } from "i18next";
|
||||||
|
import Layout from "../../layouts/Layout.astro";
|
||||||
|
|
||||||
|
changeLanguage("es");
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="Welcome to Astro.">
|
||||||
|
<h1>not found</h1>
|
||||||
|
</Layout>
|
||||||
10
src/pages/es/blog.astro
Normal file
10
src/pages/es/blog.astro
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
import { changeLanguage } from "i18next";
|
||||||
|
import Layout from "../../layouts/Layout.astro";
|
||||||
|
|
||||||
|
changeLanguage("es");
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="Blog">
|
||||||
|
<h1>Blog</h1>
|
||||||
|
</Layout>
|
||||||
26
src/pages/es/blog/[...slug].astro
Normal file
26
src/pages/es/blog/[...slug].astro
Normal file
|
|
@ -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<typeof getStaticPaths>;
|
||||||
|
const entry = Astro.props;
|
||||||
|
const { Content, headings } = await entry.render();
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title={entry.data.title}>
|
||||||
|
<Toc headings={headings} />
|
||||||
|
|
||||||
|
<Content />
|
||||||
|
</Layout>
|
||||||
44
src/pages/es/blog/index.astro
Normal file
44
src/pages/es/blog/index.astro
Normal file
|
|
@ -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) => `<a href="blog/${data.slug}">${data.title}</a>`,
|
||||||
|
type: HeaderType.String,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "tags",
|
||||||
|
header: "Tags",
|
||||||
|
type: HeaderType.Multiple,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="List of blog entries">
|
||||||
|
<h1>Blog's entries</h1>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<Table client:load data={entries} headers={headers} />
|
||||||
|
</section>
|
||||||
|
</Layout>
|
||||||
26
src/pages/es/games/[...slug].astro
Normal file
26
src/pages/es/games/[...slug].astro
Normal file
|
|
@ -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<typeof getStaticPaths>;
|
||||||
|
const entry = Astro.props;
|
||||||
|
const { Content, headings } = await entry.render();
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title={entry.data.title}>
|
||||||
|
<Toc headings={headings} />
|
||||||
|
|
||||||
|
<Content />
|
||||||
|
</Layout>
|
||||||
61
src/pages/es/games/index.astro
Normal file
61
src/pages/es/games/index.astro
Normal file
|
|
@ -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
|
||||||
|
? `<a href="games/${item.slug}">${item.data.title}</a>`
|
||||||
|
: `<div>${item.data.title}</div>`,
|
||||||
|
}));
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="List of games">
|
||||||
|
<h1>Games</h1>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<Table client:load data={games} headers={headers} />
|
||||||
|
</section>
|
||||||
|
</Layout>
|
||||||
276
src/pages/es/index.astro
Normal file
276
src/pages/es/index.astro
Normal file
|
|
@ -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);
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="aleidk">
|
||||||
|
<section
|
||||||
|
id="hero"
|
||||||
|
class="bg-image flex-center"
|
||||||
|
style="--bg-image: url(https://placehold.co/600x400)"
|
||||||
|
>
|
||||||
|
<div class="hstack gap-5">
|
||||||
|
<!-- <Image -->
|
||||||
|
<!-- id="portrait" -->
|
||||||
|
<!-- src={portrait} -->
|
||||||
|
<!-- alt="portrait of Alexander Navarro" -->
|
||||||
|
<!-- loading="eager" -->
|
||||||
|
<!-- width={200} -->
|
||||||
|
<!-- /> -->
|
||||||
|
<div>
|
||||||
|
<h1 class="my-0">Alexander Navarro</h1>
|
||||||
|
<p>
|
||||||
|
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?
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2 class="text-center">{t('titles.featuredWork')}</h2>Featured Work
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 grid-lg-cols-3 gap-4">
|
||||||
|
<Card className="anim-hover-zoom">
|
||||||
|
<img
|
||||||
|
src="https://placehold.co/600x400"
|
||||||
|
alt="project img"
|
||||||
|
class="border-radius"
|
||||||
|
/>
|
||||||
|
<h3 class="fs-4 text-center my-1">Project N°1</h3>
|
||||||
|
<p class="text-justify">
|
||||||
|
Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint
|
||||||
|
cillum sint consectetur cupidatat.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="text-end">
|
||||||
|
<a href="">See more...</a>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className="anim-hover-zoom">
|
||||||
|
<img
|
||||||
|
src="https://placehold.co/600x400"
|
||||||
|
alt="project img"
|
||||||
|
class="border-radius"
|
||||||
|
/>
|
||||||
|
<h3 class="fs-4 text-center my-1">Project N°1</h3>
|
||||||
|
<p class="text-justify">
|
||||||
|
Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint
|
||||||
|
cillum sint consectetur cupidatat.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="text-end">
|
||||||
|
<a href="">See more...</a>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className="anim-hover-zoom">
|
||||||
|
<img
|
||||||
|
src="https://placehold.co/600x400"
|
||||||
|
alt="project img"
|
||||||
|
class="border-radius"
|
||||||
|
/>
|
||||||
|
<h3 class="fs-4 text-center my-1">Project N°1</h3>
|
||||||
|
<p class="text-justify">
|
||||||
|
Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint
|
||||||
|
cillum sint consectetur cupidatat.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="text-end">
|
||||||
|
<a href="">See more...</a>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-4 text-center">
|
||||||
|
<Button className="px-4 py-2 fs-5 ">View Work</Button>
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
|
|
||||||
|
<section class:list={[{ 'd-none': import.meta.env.PROD }]}>
|
||||||
|
<h2 class="mb-4">What I've been up to...</h2>
|
||||||
|
|
||||||
|
<div class="hstack flex-eq flex-wrap flex-md-nowrap">
|
||||||
|
<div class="vstack justify-content-center">
|
||||||
|
<h4 class="text-center">Blog</h4>
|
||||||
|
<ol class="list-unstyle mt-0 fs-5">
|
||||||
|
<li class="mb-3">
|
||||||
|
<a href="#"
|
||||||
|
>Qui minim labore adipisicing minim sint cillum sint consectetur
|
||||||
|
cupidatat.</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li class="mb-3">
|
||||||
|
<a href="#"
|
||||||
|
>Qui minim labore adipisicing minim sint cillum sint consectetur
|
||||||
|
cupidatat.</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li class="mb-3">
|
||||||
|
<a href="#"
|
||||||
|
>Qui minim labore adipisicing minim sint cillum sint consectetur
|
||||||
|
cupidatat.</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="text-center mb-2">
|
||||||
|
<img class="" src="https://placehold.co/400x200" alt="project img" />
|
||||||
|
</div>
|
||||||
|
<p class="text-justify">
|
||||||
|
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.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hstack-reverse flex-eq flex-wrap flex-md-nowrap">
|
||||||
|
<div class="vstack justify-content-center">
|
||||||
|
<h4 class="text-center">Games</h4>
|
||||||
|
<ol class="list-unstyle mt-0 fs-5">
|
||||||
|
<li class="mb-3">
|
||||||
|
<a href="#"
|
||||||
|
>Qui minim labore adipisicing minim sint cillum sint consectetur
|
||||||
|
cupidatat.</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li class="mb-3">
|
||||||
|
<a href="#"
|
||||||
|
>Qui minim labore adipisicing minim sint cillum sint consectetur
|
||||||
|
cupidatat.</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li class="mb-3">
|
||||||
|
<a href="#"
|
||||||
|
>Qui minim labore adipisicing minim sint cillum sint consectetur
|
||||||
|
cupidatat.</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="text-center mb-2">
|
||||||
|
<img class="" src="https://placehold.co/400x200" alt="project img" />
|
||||||
|
</div>
|
||||||
|
<p class="text-justify">
|
||||||
|
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.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="bg-image" style="--bg-image: url(https://placehold.co/600x400)">
|
||||||
|
<h2 class="text-center">Who am I?</h2>
|
||||||
|
|
||||||
|
<p class="w-95 w-lg-70 mx-auto text-justify">
|
||||||
|
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.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="text-center fs-4 mb-0">
|
||||||
|
<a href="">
|
||||||
|
<Button>View full curriculum</Button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Contact</h2>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 grid-lg-cols-2">
|
||||||
|
<div>
|
||||||
|
<div class="text-center">
|
||||||
|
<img
|
||||||
|
class="respect-width border-radius"
|
||||||
|
src="https://placehold.co/500x300"
|
||||||
|
alt="project img"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p class="text-justify">
|
||||||
|
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!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="vstack justify-content-center">
|
||||||
|
<ul
|
||||||
|
class="list-unstyle fs-5 ml-lg-5 mt-3 d-flex d-lg-block justify-content-around anim-idle-hover-group anim-group-lg-none"
|
||||||
|
>
|
||||||
|
{
|
||||||
|
[
|
||||||
|
{
|
||||||
|
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) => (
|
||||||
|
<li class="mb-3">
|
||||||
|
<a href={item.link} class="hstack flex-column flex-lg-row gap-2">
|
||||||
|
<>
|
||||||
|
<img src={item.img} alt={item.alt} />
|
||||||
|
<span>{item.text}</span>
|
||||||
|
</>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#portrait {
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 5px solid var(--prj-text);
|
||||||
|
}
|
||||||
|
#hero {
|
||||||
|
min-height: 50vh;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
31
src/pages/es/portafolio/[...slug].astro
Normal file
31
src/pages/es/portafolio/[...slug].astro
Normal file
|
|
@ -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<typeof getStaticPaths>;
|
||||||
|
const entry = Astro.props;
|
||||||
|
const { Content, headings } = await entry.render();
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title={entry.data.title}>
|
||||||
|
<h1>{entry.data.title}</h1>
|
||||||
|
|
||||||
|
<Gallery client:load items={entry.data.media} />
|
||||||
|
|
||||||
|
<Toc headings={headings} />
|
||||||
|
|
||||||
|
<Content />
|
||||||
|
</Layout>
|
||||||
44
src/pages/es/portafolio/index.astro
Normal file
44
src/pages/es/portafolio/index.astro
Normal file
|
|
@ -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) => `<a href="portafolio/${data.slug}">${data.title}</a>`,
|
||||||
|
type: HeaderType.String,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "technologies",
|
||||||
|
header: "Technologies",
|
||||||
|
type: HeaderType.Multiple,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="List of blog entries">
|
||||||
|
<h1>Blog's entries</h1>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<Table client:load data={entries} headers={headers} />
|
||||||
|
</section>
|
||||||
|
</Layout>
|
||||||
|
|
@ -1,24 +1,20 @@
|
||||||
---
|
---
|
||||||
import {
|
import { changeLanguage } from "i18next";
|
||||||
InferGetStaticParamsType,
|
import { InferGetStaticParamsType, InferGetStaticPropsType, GetStaticPaths, } from "astro";
|
||||||
InferGetStaticPropsType,
|
import { getCollection } from "astro:content";
|
||||||
GetStaticPaths,
|
import Layout from "@layouts/Layout.astro";
|
||||||
} from 'astro';
|
import Toc from "@components/Toc/Toc";
|
||||||
import { getCollection } from 'astro:content';
|
|
||||||
import Layout from '@layouts/Layout.astro';
|
changeLanguage("en");
|
||||||
import Toc from '@components/Toc/Toc';
|
|
||||||
|
|
||||||
export const getStaticPaths = (async () => {
|
export const getStaticPaths = (async () => {
|
||||||
const games = await getCollection('games');
|
const games = await getCollection("games");
|
||||||
|
|
||||||
return games.map((entry) => ({
|
return games.map((entry) => ({
|
||||||
params: { slug: entry.slug },
|
params: { slug: entry.slug },
|
||||||
props: entry,
|
props: entry,
|
||||||
}));
|
}));
|
||||||
}) satisfies GetStaticPaths;
|
}) satisfies GetStaticPaths;
|
||||||
|
|
||||||
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
||||||
|
|
||||||
const entry = Astro.props;
|
const entry = Astro.props;
|
||||||
const { Content, headings } = await entry.render();
|
const { Content, headings } = await entry.render();
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { changeLanguage } from "i18next";
|
||||||
import Layout from '@layouts/Layout.astro';
|
import { getCollection } from "astro:content";
|
||||||
import Table from '@components/Table';
|
import Layout from "@layouts/Layout.astro";
|
||||||
import { HeaderType, type Header } from '@components/Table/types';
|
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) => ({
|
let games = rawGames.map((item, idx) => ({
|
||||||
...item.data,
|
...item.data,
|
||||||
id: idx + 1,
|
id: idx + 1,
|
||||||
|
|
@ -14,39 +16,37 @@ let games = rawGames.map((item, idx) => ({
|
||||||
? `<a href="games/${item.slug}">${item.data.title}</a>`
|
? `<a href="games/${item.slug}">${item.data.title}</a>`
|
||||||
: `<div>${item.data.title}</div>`,
|
: `<div>${item.data.title}</div>`,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
games = games.sort((a, b) => b.date_added.getTime() - a.date_added.getTime());
|
games = games.sort((a, b) => b.date_added.getTime() - a.date_added.getTime());
|
||||||
|
|
||||||
const headers: Header[] = [
|
const headers: Header[] = [
|
||||||
{
|
{
|
||||||
key: 'id',
|
key: "id",
|
||||||
header: 'index',
|
header: "index",
|
||||||
type: HeaderType.Index,
|
type: HeaderType.Index,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'title',
|
key: "title",
|
||||||
header: 'Title',
|
header: "Title",
|
||||||
type: HeaderType.String,
|
type: HeaderType.String,
|
||||||
hasCustomCell: true,
|
hasCustomCell: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'status',
|
key: "status",
|
||||||
header: 'Status',
|
header: "Status",
|
||||||
type: HeaderType.Select,
|
type: HeaderType.Select,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'genres',
|
key: "genres",
|
||||||
header: 'Genres',
|
header: "Genres",
|
||||||
type: HeaderType.Multiple,
|
type: HeaderType.Multiple,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'times_played',
|
key: "times_played",
|
||||||
header: 'Times Played',
|
header: "Times Played",
|
||||||
type: HeaderType.Number,
|
type: HeaderType.Number,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'registered_hours',
|
key: "registered_hours",
|
||||||
header: 'Registered Hours',
|
header: "Registered Hours",
|
||||||
type: HeaderType.Number,
|
type: HeaderType.Number,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,17 @@
|
||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from "astro:content";
|
||||||
import Layout from '../layouts/Layout.astro';
|
import Layout from "../layouts/Layout.astro";
|
||||||
import Card from '../components/Card.astro';
|
import Card from "../components/Card.astro";
|
||||||
import Button from '../components/Button/Button.astro';
|
import Button from "../components/Button/Button.astro";
|
||||||
import { Image } from 'astro:assets';
|
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 }) =>
|
const blog = await getCollection("blog", ({ data }) => import.meta.env.PROD ? data.draft !== true : true);
|
||||||
import.meta.env.PROD ? data.draft !== true : true,
|
|
||||||
);
|
|
||||||
// TODO: show the pinned ones, not the recents
|
// TODO: show the pinned ones, not the recents
|
||||||
const portafolio = await getCollection('portafolio', ({ data }) =>
|
const portafolio = await getCollection("portafolio", ({ data }) => import.meta.env.PROD ? data.draft !== true : true);
|
||||||
import.meta.env.PROD ? data.draft !== true : true,
|
|
||||||
);
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="aleidk">
|
<Layout title="aleidk">
|
||||||
|
|
@ -43,7 +41,8 @@ const portafolio = await getCollection('portafolio', ({ data }) =>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h2 class="text-center">Featured Work</h2>
|
<h2 class="text-center">{t('titles.featuredWork')}</h2>Featured Work
|
||||||
|
</section>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 grid-lg-cols-3 gap-4">
|
<div class="grid grid-cols-1 grid-lg-cols-3 gap-4">
|
||||||
<Card className="anim-hover-zoom">
|
<Card className="anim-hover-zoom">
|
||||||
|
|
@ -101,7 +100,7 @@ const portafolio = await getCollection('portafolio', ({ data }) =>
|
||||||
<div class="mt-4 text-center">
|
<div class="mt-4 text-center">
|
||||||
<Button className="px-4 py-2 fs-5 ">View Work</Button>
|
<Button className="px-4 py-2 fs-5 ">View Work</Button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</Layout>
|
||||||
|
|
||||||
<section class:list={[{ 'd-none': import.meta.env.PROD }]}>
|
<section class:list={[{ 'd-none': import.meta.env.PROD }]}>
|
||||||
<h2 class="mb-4">What I've been up to...</h2>
|
<h2 class="mb-4">What I've been up to...</h2>
|
||||||
|
|
@ -183,10 +182,7 @@ const portafolio = await getCollection('portafolio', ({ data }) =>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section
|
<section class="bg-image" style="--bg-image: url(https://placehold.co/600x400)">
|
||||||
class="bg-image"
|
|
||||||
style="--bg-image: url(https://placehold.co/600x400)"
|
|
||||||
>
|
|
||||||
<h2 class="text-center">Who am I?</h2>
|
<h2 class="text-center">Who am I?</h2>
|
||||||
|
|
||||||
<p class="w-95 w-lg-70 mx-auto text-justify">
|
<p class="w-95 w-lg-70 mx-auto text-justify">
|
||||||
|
|
@ -198,8 +194,8 @@ const portafolio = await getCollection('portafolio', ({ data }) =>
|
||||||
occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat
|
occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat
|
||||||
officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in
|
officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in
|
||||||
Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non
|
Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non
|
||||||
excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco
|
excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut
|
||||||
ut ea consectetur et est culpa et culpa duis.
|
ea consectetur et est culpa et culpa duis.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="text-center fs-4 mb-0">
|
<div class="text-center fs-4 mb-0">
|
||||||
|
|
@ -255,10 +251,7 @@ const portafolio = await getCollection('portafolio', ({ data }) =>
|
||||||
},
|
},
|
||||||
].map((item) => (
|
].map((item) => (
|
||||||
<li class="mb-3">
|
<li class="mb-3">
|
||||||
<a
|
<a href={item.link} class="hstack flex-column flex-lg-row gap-2">
|
||||||
href={item.link}
|
|
||||||
class="hstack flex-column flex-lg-row gap-2"
|
|
||||||
>
|
|
||||||
<>
|
<>
|
||||||
<img src={item.img} alt={item.alt} />
|
<img src={item.img} alt={item.alt} />
|
||||||
<span>{item.text}</span>
|
<span>{item.text}</span>
|
||||||
|
|
@ -281,4 +274,3 @@ const portafolio = await getCollection('portafolio', ({ data }) =>
|
||||||
min-height: 50vh;
|
min-height: 50vh;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</Layout>
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
---
|
---
|
||||||
import type { InferGetStaticPropsType, GetStaticPaths } from 'astro';
|
import { changeLanguage } from "i18next";
|
||||||
import { getCollection } from 'astro:content';
|
import type { InferGetStaticPropsType, GetStaticPaths } from "astro";
|
||||||
import Layout from '@layouts/Layout.astro';
|
import { getCollection } from "astro:content";
|
||||||
import Toc from '@components/Toc/Toc';
|
import Layout from "@layouts/Layout.astro";
|
||||||
import Gallery from '@components/MediaGallery/Gallery';
|
import Toc from "@components/Toc/Toc";
|
||||||
|
import Gallery from "@components/MediaGallery/Gallery";
|
||||||
|
|
||||||
|
changeLanguage("en");
|
||||||
|
|
||||||
export const getStaticPaths = (async () => {
|
export const getStaticPaths = (async () => {
|
||||||
const entries = await getCollection('portafolio');
|
const entries = await getCollection("portafolio");
|
||||||
|
|
||||||
return entries.map((entry) => ({
|
return entries.map((entry) => ({
|
||||||
params: { slug: entry.slug },
|
params: { slug: entry.slug },
|
||||||
props: entry,
|
props: entry,
|
||||||
}));
|
}));
|
||||||
}) satisfies GetStaticPaths;
|
}) satisfies GetStaticPaths;
|
||||||
|
|
||||||
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
||||||
|
|
||||||
const entry = Astro.props;
|
const entry = Astro.props;
|
||||||
const { Content, headings } = await entry.render();
|
const { Content, headings } = await entry.render();
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,35 @@
|
||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { changeLanguage } from "i18next";
|
||||||
import Layout from '@layouts/Layout.astro';
|
import { getCollection } from "astro:content";
|
||||||
import Table from '@components/Table';
|
import Layout from "@layouts/Layout.astro";
|
||||||
import { HeaderType, type Header } from '@components/Table/types';
|
import Table from "@components/Table";
|
||||||
|
import { HeaderType, type Header } from "@components/Table/types";
|
||||||
|
|
||||||
const rawEntries = await getCollection('portafolio', ({ data }) => {
|
changeLanguage("en");
|
||||||
|
|
||||||
|
const rawEntries = await getCollection("portafolio", ({ data }) => {
|
||||||
return import.meta.env.PROD ? data.draft !== true : true;
|
return import.meta.env.PROD ? data.draft !== true : true;
|
||||||
});
|
});
|
||||||
|
|
||||||
const entries = rawEntries.map((item, idx) => ({
|
const entries = rawEntries.map((item, idx) => ({
|
||||||
...item.data,
|
...item.data,
|
||||||
id: idx + 1,
|
id: idx + 1,
|
||||||
slug: item.slug,
|
slug: item.slug,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const headers: Header[] = [
|
const headers: Header[] = [
|
||||||
{
|
{
|
||||||
key: 'id',
|
key: "id",
|
||||||
header: 'index',
|
header: "index",
|
||||||
type: HeaderType.Index,
|
type: HeaderType.Index,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'title',
|
key: "title",
|
||||||
header: 'Title',
|
header: "Title",
|
||||||
formatter: (data) => `<a href="portafolio/${data.slug}">${data.title}</a>`,
|
formatter: (data) => `<a href="portafolio/${data.slug}">${data.title}</a>`,
|
||||||
type: HeaderType.String,
|
type: HeaderType.String,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'technologies',
|
key: "technologies",
|
||||||
header: 'Technologies',
|
header: "Technologies",
|
||||||
type: HeaderType.Multiple,
|
type: HeaderType.Multiple,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue