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 react from '@astrojs/react';
|
||||
import astroI18next from 'astro-i18next';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
prefetch: true,
|
||||
integrations: [react()],
|
||||
integrations: [react(), astroI18next()],
|
||||
experimental: {},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
369
pnpm-lock.yaml
generated
369
pnpm-lock.yaml
generated
|
|
@ -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:
|
||||
|
|
|
|||
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 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 = [
|
|||
</li>
|
||||
))
|
||||
}
|
||||
<li class="nav-item">
|
||||
<LangSelector />
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
|||
---
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang={i18next.language}>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="description" content="Astro description" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<HeadHrefLangs />
|
||||
<title>{title}</title>
|
||||
<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.">
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
||||
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();
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,34 +1,35 @@
|
|||
---
|
||||
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 }) => {
|
||||
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,
|
||||
}));
|
||||
|
||||
const headers: Header[] = [
|
||||
{
|
||||
key: 'id',
|
||||
header: 'index',
|
||||
key: "id",
|
||||
header: "index",
|
||||
type: HeaderType.Index,
|
||||
},
|
||||
{
|
||||
key: 'title',
|
||||
header: 'Title',
|
||||
key: "title",
|
||||
header: "Title",
|
||||
formatter: (data) => `<a href="blog/${data.slug}">${data.title}</a>`,
|
||||
type: HeaderType.String,
|
||||
},
|
||||
{
|
||||
key: 'tags',
|
||||
header: 'Tags',
|
||||
key: "tags",
|
||||
header: "Tags",
|
||||
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 {
|
||||
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');
|
||||
|
||||
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();
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
---
|
||||
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,
|
||||
|
|
@ -14,39 +16,37 @@ let games = rawGames.map((item, idx) => ({
|
|||
? `<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',
|
||||
key: "id",
|
||||
header: "index",
|
||||
type: HeaderType.Index,
|
||||
},
|
||||
{
|
||||
key: 'title',
|
||||
header: 'Title',
|
||||
key: "title",
|
||||
header: "Title",
|
||||
type: HeaderType.String,
|
||||
hasCustomCell: true,
|
||||
},
|
||||
{
|
||||
key: 'status',
|
||||
header: 'Status',
|
||||
key: "status",
|
||||
header: "Status",
|
||||
type: HeaderType.Select,
|
||||
},
|
||||
{
|
||||
key: 'genres',
|
||||
header: 'Genres',
|
||||
key: "genres",
|
||||
header: "Genres",
|
||||
type: HeaderType.Multiple,
|
||||
},
|
||||
{
|
||||
key: 'times_played',
|
||||
header: 'Times Played',
|
||||
key: "times_played",
|
||||
header: "Times Played",
|
||||
type: HeaderType.Number,
|
||||
},
|
||||
{
|
||||
key: 'registered_hours',
|
||||
header: 'Registered Hours',
|
||||
key: "registered_hours",
|
||||
header: "Registered Hours",
|
||||
type: HeaderType.Number,
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
---
|
||||
|
||||
<Layout title="aleidk">
|
||||
|
|
@ -43,7 +41,8 @@ const portafolio = await getCollection('portafolio', ({ data }) =>
|
|||
</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">
|
||||
<Card className="anim-hover-zoom">
|
||||
|
|
@ -101,9 +100,9 @@ const portafolio = await getCollection('portafolio', ({ data }) =>
|
|||
<div class="mt-4 text-center">
|
||||
<Button className="px-4 py-2 fs-5 ">View Work</Button>
|
||||
</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>
|
||||
|
||||
<div class="hstack flex-eq flex-wrap flex-md-nowrap">
|
||||
|
|
@ -181,12 +180,9 @@ const portafolio = await getCollection('portafolio', ({ data }) =>
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="bg-image"
|
||||
style="--bg-image: url(https://placehold.co/600x400)"
|
||||
>
|
||||
<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">
|
||||
|
|
@ -198,8 +194,8 @@ const portafolio = await getCollection('portafolio', ({ data }) =>
|
|||
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.
|
||||
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">
|
||||
|
|
@ -207,9 +203,9 @@ const portafolio = await getCollection('portafolio', ({ data }) =>
|
|||
<Button>View full curriculum</Button>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section>
|
||||
<h2>Contact</h2>
|
||||
|
||||
<div class="grid grid-cols-1 grid-lg-cols-2">
|
||||
|
|
@ -255,10 +251,7 @@ const portafolio = await getCollection('portafolio', ({ data }) =>
|
|||
},
|
||||
].map((item) => (
|
||||
<li class="mb-3">
|
||||
<a
|
||||
href={item.link}
|
||||
class="hstack flex-column flex-lg-row gap-2"
|
||||
>
|
||||
<a href={item.link} class="hstack flex-column flex-lg-row gap-2">
|
||||
<>
|
||||
<img src={item.img} alt={item.alt} />
|
||||
<span>{item.text}</span>
|
||||
|
|
@ -270,9 +263,9 @@ const portafolio = await getCollection('portafolio', ({ data }) =>
|
|||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
<style>
|
||||
#portrait {
|
||||
border-radius: 50%;
|
||||
border: 5px solid var(--prj-text);
|
||||
|
|
@ -280,5 +273,4 @@ const portafolio = await getCollection('portafolio', ({ data }) =>
|
|||
#hero {
|
||||
min-height: 50vh;
|
||||
}
|
||||
</style>
|
||||
</Layout>
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
||||
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();
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,34 +1,35 @@
|
|||
---
|
||||
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 }) => {
|
||||
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,
|
||||
}));
|
||||
|
||||
const headers: Header[] = [
|
||||
{
|
||||
key: 'id',
|
||||
header: 'index',
|
||||
key: "id",
|
||||
header: "index",
|
||||
type: HeaderType.Index,
|
||||
},
|
||||
{
|
||||
key: 'title',
|
||||
header: 'Title',
|
||||
key: "title",
|
||||
header: "Title",
|
||||
formatter: (data) => `<a href="portafolio/${data.slug}">${data.title}</a>`,
|
||||
type: HeaderType.String,
|
||||
},
|
||||
{
|
||||
key: 'technologies',
|
||||
header: 'Technologies',
|
||||
key: "technologies",
|
||||
header: "Technologies",
|
||||
type: HeaderType.Multiple,
|
||||
},
|
||||
];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue