generated from avior/template-web-astro
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
3fc900a1e6 | |||
dc58e29760 | |||
40d0d84619 | |||
962ba24f7b | |||
e16134f15b | |||
83d66eb440 | |||
5c49bd2190 | |||
c4e702af67 | |||
30c0ac14a3 | |||
a8ce0b4494 | |||
45e79cf212 | |||
fa8f946ff5 | |||
9ffffcd927 | |||
9a96cb063a | |||
4651debb38 | |||
a641749d45 | |||
898d5a241a | |||
ca799e17b0 | |||
0ff26c24b8 | |||
4a944f9e61 | |||
9a70042506 | |||
0f1a3b7cc8 | |||
fb97ea4a9d |
53
.github/workflows/build_and_check.yml
vendored
53
.github/workflows/build_and_check.yml
vendored
@ -2,9 +2,13 @@ name: Build, check & Test
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ "master" ]
|
branches:
|
||||||
|
- '*'
|
||||||
|
tags:
|
||||||
|
- v*
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "master" ]
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
run:
|
run:
|
||||||
@ -13,23 +17,36 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Use Node.js 20
|
- name: Docker meta
|
||||||
uses: actions/setup-node@v3
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
images: git.dzeio.com/avior/avior.me
|
||||||
|
tags: |
|
||||||
|
type=edge
|
||||||
|
type=ref,event=pr
|
||||||
|
type=ref,event=branch,prefix=branch-
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
|
type=semver,pattern={{major}}
|
||||||
|
type=semver,pattern=latest
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Login to Docker Hub
|
||||||
run: npm ci
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: git.dzeio.com
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_TOKEN }}
|
||||||
|
|
||||||
- name: Build
|
- name: Set up Docker Buildx
|
||||||
run: npm run build
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Check
|
- name: Build and push
|
||||||
run: npm run check
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
- name: Prepare Tests
|
context: .
|
||||||
run: npm run install:test
|
push: true
|
||||||
|
file: ./Dockerfile.static
|
||||||
- name: Test
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
run : npm run test
|
labels: ${{ steps.meta.outputs.labels }}
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -4,5 +4,8 @@
|
|||||||
},
|
},
|
||||||
"tailwindCSS.includeLanguages": {
|
"tailwindCSS.includeLanguages": {
|
||||||
"astro": "html"
|
"astro": "html"
|
||||||
|
},
|
||||||
|
"files.associations": {
|
||||||
|
"*.mdx": "markdown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,3 +36,5 @@ ADD ./nginx.conf /etc/nginx/nginx.conf
|
|||||||
|
|
||||||
# Copy dist fro mthe build image
|
# Copy dist fro mthe build image
|
||||||
COPY --from=BUILD_IMAGE /home/node/dist ./
|
COPY --from=BUILD_IMAGE /home/node/dist ./
|
||||||
|
|
||||||
|
EXPOSE 3000
|
@ -1,44 +1,43 @@
|
|||||||
import { defineConfig } from 'astro/config'
|
import { defineConfig } from 'astro/config'
|
||||||
import tailwind from "@astrojs/tailwind"
|
import tailwind from "@astrojs/tailwind"
|
||||||
import node from "@astrojs/node"
|
import mdx from "@astrojs/mdx"
|
||||||
|
|
||||||
// const faviconHook = {
|
// const faviconHook = {
|
||||||
// name: 'Favicon',
|
// name: 'Favicon',
|
||||||
// hooks: {
|
// hooks: {
|
||||||
// "astro:build:setup": async () => {
|
// "astro:build:setup": async () => {
|
||||||
// await Manifest.create('./src/assets/favicon.png', {
|
// await Manifest.create('./src/assets/favicon.png', {
|
||||||
// name: 'Template'
|
// name: 'Template'
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [tailwind()],
|
integrations: [tailwind(), mdx()],
|
||||||
compressHTML: true,
|
compressHTML: true,
|
||||||
build: {
|
build: {
|
||||||
assets: 'assets',
|
assets: 'assets',
|
||||||
inlineStylesheets: 'auto'
|
inlineStylesheets: 'auto'
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
host: true,
|
host: true,
|
||||||
port: 3000
|
port: 3000
|
||||||
},
|
},
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
vite: {
|
vite: {
|
||||||
server: {
|
server: {
|
||||||
watch: {
|
watch: {
|
||||||
// support WSL strange things
|
// support WSL strange things
|
||||||
usePolling: !!process.env.WSL_DISTRO_NAME
|
usePolling: !!process.env.WSL_DISTRO_NAME
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// Customizable depending on goal
|
||||||
// Customizable depending on goal
|
output: 'static',
|
||||||
output: 'static',
|
// adapter: node({
|
||||||
// adapter: node({
|
// mode: "standalone"
|
||||||
// mode: "standalone"
|
// }),
|
||||||
// }),
|
site: 'https://avior.me'
|
||||||
site: 'https://avior.me',
|
})
|
||||||
})
|
|
||||||
|
791
package-lock.json
generated
791
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,7 @@
|
|||||||
"install:test": "playwright install --with-deps"
|
"install:test": "playwright install --with-deps"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/node": "^6",
|
"@astrojs/mdx": "^1.1.0",
|
||||||
"@astrojs/tailwind": "^5",
|
"@astrojs/tailwind": "^5",
|
||||||
"@dzeio/logger": "^3",
|
"@dzeio/logger": "^3",
|
||||||
"@dzeio/object-util": "^1",
|
"@dzeio/object-util": "^1",
|
||||||
|
1
src/assets/pages/404/404.light.svg
Normal file
1
src/assets/pages/404/404.light.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 23 KiB |
1
src/assets/pages/404/404.svg
Normal file
1
src/assets/pages/404/404.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 23 KiB |
88
src/components/Picture.astro
Normal file
88
src/components/Picture.astro
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
---
|
||||||
|
import { getImage } from 'astro:assets'
|
||||||
|
import AstroUtils from '../libs/AstroUtils'
|
||||||
|
import { objectOmit } from '@dzeio/object-util'
|
||||||
|
|
||||||
|
const formats = [
|
||||||
|
'avif',
|
||||||
|
'webp'
|
||||||
|
]
|
||||||
|
|
||||||
|
export interface Props extends Omit<astroHTML.JSX.ImgHTMLAttributes, 'src'> {
|
||||||
|
src: ImageMetadata | string
|
||||||
|
srcDark?: ImageMetadata | string
|
||||||
|
width?: number
|
||||||
|
height?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
type PictureResult = {
|
||||||
|
format: 'new'
|
||||||
|
formats: Array<{format: string, img: Awaited<ReturnType<typeof getImage>>}>
|
||||||
|
src: Awaited<ReturnType<typeof getImage>>
|
||||||
|
} | {
|
||||||
|
format: 'raw'
|
||||||
|
src: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Result {
|
||||||
|
light: PictureResult
|
||||||
|
dark?: PictureResult | undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
async function resolvePicture(image: ImageMetadata | string): Promise<PictureResult> {
|
||||||
|
const ext = typeof image === 'string' ? image.substring(image.lastIndexOf('.')) : image.format
|
||||||
|
if (ext === 'svg') {
|
||||||
|
return {
|
||||||
|
format: 'raw',
|
||||||
|
src: typeof image === 'string' ? image : image.src
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageFormats: Array<{format: string, img: Awaited<ReturnType<typeof getImage>>}> = await Promise.all(
|
||||||
|
formats.map(async (it) => ({
|
||||||
|
img: await getImage({src: Astro.props.src, format: it, width: Astro.props.width, height: Astro.props.height}),
|
||||||
|
format: it
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
|
||||||
|
const orig = await getImage({src: Astro.props.src, format: ext, width: Astro.props.width, height: Astro.props.height})
|
||||||
|
|
||||||
|
return {
|
||||||
|
format: 'new',
|
||||||
|
formats: imageFormats,
|
||||||
|
src: orig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await AstroUtils.wrap<Result>(async () => {
|
||||||
|
return {
|
||||||
|
light: await resolvePicture(Astro.props.src),
|
||||||
|
dark: Astro.props.srcDark ? await resolvePicture(Astro.props.srcDark) : undefined
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const props = objectOmit(Astro.props, 'src', 'srcDark', 'class')
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
{res.light.format === 'new' && (
|
||||||
|
<picture {...props} {...res.light.src.attributes} class:list={[res.light.src.attributes.class, Astro.props.class, {'dark:hidden': res.dark}]}>
|
||||||
|
{res.light.formats.map((it) => (
|
||||||
|
<source srcset={it.img.src} type={`image/${it.format}`} />
|
||||||
|
))}
|
||||||
|
<img src={res.light.src.src} />
|
||||||
|
</picture>
|
||||||
|
) || (
|
||||||
|
<img {...props} class:list={[Astro.props.class, {'dark:hidden': res.dark}]} src={res.light.src as string} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
{res.dark && res.dark.format === 'new' && (
|
||||||
|
<picture {...props} {...res.dark.src.attributes} class:list={[res.dark.src.attributes.class, Astro.props.class, 'hidden', 'dark:block']}>
|
||||||
|
{res.dark.formats.map((it) => (
|
||||||
|
<source srcset={it.img.src} type={`image/${it.format}`} />
|
||||||
|
))}
|
||||||
|
<img src={res.dark.src.src} />
|
||||||
|
</picture>
|
||||||
|
) || (res.dark && (
|
||||||
|
<img {...props} class:list={[Astro.props.class, 'hidden', 'dark:block']} src={res.dark.src as string} />
|
||||||
|
))}
|
@ -1,42 +0,0 @@
|
|||||||
---
|
|
||||||
import { LocalImageProps, RemoteImageProps, getImage } from 'astro:assets'
|
|
||||||
import AstroUtils from '../libs/AstroUtils'
|
|
||||||
type ImageProps = LocalImageProps | RemoteImageProps
|
|
||||||
export type Props = ImageProps
|
|
||||||
|
|
||||||
const res = await AstroUtils.wrap(async () => {
|
|
||||||
const image = Astro.props.src
|
|
||||||
const ext = typeof image === 'string' ? image.substring(image.lastIndexOf('.')) : image.format
|
|
||||||
if (ext === 'svg') {
|
|
||||||
return {
|
|
||||||
format: 'raw',
|
|
||||||
props: {
|
|
||||||
...Astro.props,
|
|
||||||
src: typeof image === 'string' ? image : image.src
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const avif = await getImage({src: Astro.props.src, format: 'avif'})
|
|
||||||
const webp = await getImage({src: Astro.props.src, format: 'webp'})
|
|
||||||
const orig = await getImage({src: Astro.props.src, format: ext})
|
|
||||||
|
|
||||||
return {
|
|
||||||
format: 'new',
|
|
||||||
avif,
|
|
||||||
webp,
|
|
||||||
orig
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
{res.format === 'new' && (
|
|
||||||
<picture class:list={[res.orig!.attributes.class, Astro.props.class]}>
|
|
||||||
<source srcset={res.avif!.src} type="image/avif" />
|
|
||||||
<source srcset={res.webp!.src} type="image/webp" />
|
|
||||||
<img src={res.orig!.src} class="" {...res.orig!.attributes} />
|
|
||||||
</picture>
|
|
||||||
) || (
|
|
||||||
<img {...res.props} />
|
|
||||||
)}
|
|
@ -2,20 +2,20 @@
|
|||||||
interface Props {
|
interface Props {
|
||||||
items: Array<{
|
items: Array<{
|
||||||
text: string
|
text: string
|
||||||
href?: string
|
href?: string | undefined
|
||||||
}>
|
}>
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
<ol vocab="https://schema.org/" typeof="BreadcrumbList">
|
<ol vocab="https://schema.org/" typeof="BreadcrumbList" class="inline-flex items-center flex-wrap px-0 mb-4">
|
||||||
{Astro.props.items.map((el, index) => (
|
{Astro.props.items.map((el, index) => (
|
||||||
<li property="itemListElement" typeof="ListItem">
|
<li property="itemListElement" typeof="ListItem" class="inline-block px-0">
|
||||||
{index > 0 && (
|
{index > 0 && (
|
||||||
<span class="text-slate-900 dark:text-slate-100 mx-4">/</span>
|
<span class="text-gray-900 dark:text-gray-100 mx-4">/</span>
|
||||||
)}
|
)}
|
||||||
{el.href ? (
|
{el.href ? (
|
||||||
<a class="text-slate-900 dark:text-slate-100" href={el.href} property="item" typeof="WebPage">
|
<a class="text-gray-900 dark:text-gray-100 font-normal" href={el.href} property="item" typeof="WebPage">
|
||||||
<span property="name">{el.text}</span>
|
<span property="name">{el.text}</span>
|
||||||
</a>
|
</a>
|
||||||
) : (
|
) : (
|
||||||
@ -26,15 +26,3 @@ interface Props {
|
|||||||
))}
|
))}
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<style>
|
|
||||||
ol {
|
|
||||||
@apply inline-flex items-center flex-wrap px-0 mb-4
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
@apply inline-block px-0
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
@apply font-normal
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
@ -1,18 +1,12 @@
|
|||||||
---
|
---
|
||||||
import Logo from 'assets/logo.svg'
|
import Logo from 'assets/logo.svg'
|
||||||
import LogoDark from 'assets/logo.dark.svg'
|
import LogoDark from 'assets/logo.dark.svg'
|
||||||
import { Image } from 'astro:assets'
|
import Picture from 'components/Picture.astro'
|
||||||
---
|
---
|
||||||
|
|
||||||
<header class="bg-white/1 flex justify-center sm:justify-normal">
|
<header class="bg-white/1 z-10 justify-center sm:justify-normal transition-opacity
|
||||||
|
fixed w-full h-20 flex items-center border-b border-slate-900/10 backdrop-blur-md">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<Image src={Logo} alt="Avior.me Logo" class="h-9 dark:hidden" />
|
<Picture src={Logo} srcDark={LogoDark} alt="Avior.me Logo" class="h-9" />
|
||||||
<Image src={LogoDark} alt="Avior.me Logo" class="h-9 hidden dark:block" />
|
|
||||||
</a>
|
</a>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<style>
|
|
||||||
header {
|
|
||||||
@apply transition-opacity fixed w-full h-20 flex items-center border-b border-slate-900/10 backdrop-blur-md
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
@ -11,11 +11,13 @@ const projectsCollection = defineCollection({
|
|||||||
link: z.object({
|
link: z.object({
|
||||||
href: z.string(),
|
href: z.string(),
|
||||||
rel: z.string().optional(),
|
rel: z.string().optional(),
|
||||||
text: z.string().optional()
|
text: z.string().optional(),
|
||||||
|
target: z.string().optional()
|
||||||
}).optional(),
|
}).optional(),
|
||||||
disabled: z.string().optional(),
|
disabled: z.string().optional(),
|
||||||
created: z.date().optional(),
|
created: z.date().optional(),
|
||||||
updated: z.date().optional()
|
updated: z.date().optional(),
|
||||||
|
techs: z.string().array().optional()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
const blogCollection = defineCollection({
|
const blogCollection = defineCollection({
|
||||||
|
@ -7,6 +7,13 @@ link:
|
|||||||
image: ./og.png
|
image: ./og.png
|
||||||
created: 2022-09-03
|
created: 2022-09-03
|
||||||
updated: 2023-07-02
|
updated: 2023-07-02
|
||||||
|
techs:
|
||||||
|
- NextJS
|
||||||
|
- Typescript
|
||||||
|
- Appwrite
|
||||||
|
- Scrapping
|
||||||
|
- Docker
|
||||||
|
- Stylus
|
||||||
---
|
---
|
||||||
|
|
||||||

|

|
||||||
@ -49,21 +56,21 @@ FI3D propose également des fonctionnalités pratiques telles que le thème somb
|
|||||||
|
|
||||||
Que l'on travaille sur des prototypes, des maquettes, des objets décoratifs ou des pièces fonctionnelles, FI3D offre un monde de possibilités. Découvrez la polyvalence de l'impression 3D en explorant les différents types de filaments disponibles, des PLA aux ABS en passant par le PETG et bien d'autres.
|
Que l'on travaille sur des prototypes, des maquettes, des objets décoratifs ou des pièces fonctionnelles, FI3D offre un monde de possibilités. Découvrez la polyvalence de l'impression 3D en explorant les différents types de filaments disponibles, des PLA aux ABS en passant par le PETG et bien d'autres.
|
||||||
|
|
||||||
<!-- 
|
{/* 
|
||||||
*Image 7 : Objets imprimés en 3D avec différents filaments* -->
|
*Image 7 : Objets imprimés en 3D avec différents filaments* */}
|
||||||
|
|
||||||
**Notez et Partagez Vos Expériences**
|
**Notez et Partagez Vos Expériences**
|
||||||
|
|
||||||
Il est encouragé de partager ses expériences et ses avis sur les filaments. Si l'on a utilisé un filament particulier et que l'on souhaite aider d'autres membres de la communauté FI3D, il suffit de laisser une note et un commentaire.
|
Il est encouragé de partager ses expériences et ses avis sur les filaments. Si l'on a utilisé un filament particulier et que l'on souhaite aider d'autres membres de la communauté FI3D, il suffit de laisser une note et un commentaire.
|
||||||
|
|
||||||
<!-- 
|
{/* 
|
||||||
*Image 8 : Utilisateur laissant une critique sur un filament* -->
|
*Image 8 : Utilisateur laissant une critique sur un filament* */}
|
||||||
|
|
||||||
**Inscrivez-vous dès aujourd'hui sur FI3D**
|
**Inscrivez-vous dès aujourd'hui sur FI3D**
|
||||||
|
|
||||||
Pour profiter pleinement de toutes les fonctionnalités de FI3D, il est possible de s'inscrire gratuitement sur la plateforme. On pourra ainsi ajouter des filaments à sa liste de favoris, suivre les dernières tendances en matière d'impression 3D et participer à une communauté dynamique de passionnés d'impression 3D.
|
Pour profiter pleinement de toutes les fonctionnalités de FI3D, il est possible de s'inscrire gratuitement sur la plateforme. On pourra ainsi ajouter des filaments à sa liste de favoris, suivre les dernières tendances en matière d'impression 3D et participer à une communauté dynamique de passionnés d'impression 3D.
|
||||||
|
|
||||||
<!-- 
|
{/* 
|
||||||
*Image 9: Processus d'inscription sur FI3D* -->
|
*Image 9: Processus d'inscription sur FI3D* */}
|
||||||
|
|
||||||
Que l'on soit un professionnel de l'industrie, un bricoleur ou simplement curieux de découvrir le monde de l'impression 3D, FI3D est l'outil idéal pour trouver le filament qui répond à ses besoins.
|
Que l'on soit un professionnel de l'industrie, un bricoleur ou simplement curieux de découvrir le monde de l'impression 3D, FI3D est l'outil idéal pour trouver le filament qui répond à ses besoins.
|
@ -6,6 +6,14 @@ link:
|
|||||||
image: ./og.png
|
image: ./og.png
|
||||||
created: 2018-09-10
|
created: 2018-09-10
|
||||||
updated: 2021-04-29
|
updated: 2021-04-29
|
||||||
|
techs:
|
||||||
|
- NextJS
|
||||||
|
- Typescript
|
||||||
|
- MongoDB
|
||||||
|
- Firebase
|
||||||
|
- Symphony
|
||||||
|
- Docker
|
||||||
|
- Stylus
|
||||||
---
|
---
|
||||||
|
|
||||||

|

|
@ -7,14 +7,14 @@ import Breadcrumb from 'components/global/Breadcrumb.astro'
|
|||||||
export interface Props extends BaseProps {
|
export interface Props extends BaseProps {
|
||||||
link?: {
|
link?: {
|
||||||
href: string
|
href: string
|
||||||
rel?: string
|
rel?: string | undefined
|
||||||
text?: string
|
text?: string | undefined
|
||||||
target?: string
|
target?: string | undefined
|
||||||
}
|
} | undefined
|
||||||
disabled?: string
|
disabled?: string | undefined
|
||||||
breadcrumb: Array<{
|
breadcrumb: Array<{
|
||||||
text: string
|
text: string
|
||||||
href?: string
|
href?: string | undefined
|
||||||
}>
|
}>
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
@ -5,23 +5,23 @@ import IconPNG from '../assets/layouts/Base/favicon.png'
|
|||||||
import '@fontsource-variable/lexend'
|
import '@fontsource-variable/lexend'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
siteName?: string
|
siteName?: string | undefined
|
||||||
title?: string
|
title?: string | undefined
|
||||||
description?: string
|
description?: string | undefined
|
||||||
canonical?: string
|
canonical?: string | undefined
|
||||||
image?: Array<typeof IconPNG>
|
image?: Array<typeof IconPNG> | undefined
|
||||||
twitter?: {
|
twitter?: {
|
||||||
title?: string
|
title?: string | undefined
|
||||||
card?: "summary" | "summary_large_image" | "app" | "player"
|
card?: "summary" | "summary_large_image" | "app" | "player" | undefined
|
||||||
site?: string
|
site?: string | undefined
|
||||||
creator?: string
|
creator?: string | undefined
|
||||||
}
|
} | undefined
|
||||||
og?: {
|
og?: {
|
||||||
title?: string
|
title?: string | undefined
|
||||||
type?: string
|
type?: string | undefined
|
||||||
description?: string
|
description?: string | undefined
|
||||||
url?: string
|
url?: string | undefined
|
||||||
}
|
} | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = Astro.props
|
const props = Astro.props
|
||||||
|
25
src/pages/404.astro
Normal file
25
src/pages/404.astro
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
import Layout from 'layouts/Layout.astro'
|
||||||
|
import I404 from 'assets/pages/404/404.svg'
|
||||||
|
import I404Light from 'assets/pages/404/404.light.svg'
|
||||||
|
import Button from 'components/global/Button.astro'
|
||||||
|
import ButtonLink from 'components/global/ButtonLink.astro'
|
||||||
|
import Picture from 'components/Picture.astro'
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<main class="container flex flex-col gap-24 justify-center items-center md:mt-6">
|
||||||
|
<h1 class="text-6xl text-center font-bold">404 La page recherché n'existe pas :(</h1>
|
||||||
|
<Picture src={I404Light} srcDark={I404} alt="404 error image" />
|
||||||
|
<div class="flex gap-6">
|
||||||
|
<ButtonLink href="/">Retour à la page d'accueil</ButtonLink>
|
||||||
|
<Button id="back_button">Retour à la page précédente</Button>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</Layout>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(document.querySelector('button.back_button') as HTMLButtonElement).addEventListener('click', () => {
|
||||||
|
history.back()
|
||||||
|
})
|
||||||
|
</script>
|
@ -1,60 +1,60 @@
|
|||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content'
|
import { getCollection } from 'astro:content'
|
||||||
import { Image } from 'astro:assets'
|
import Layout from 'layouts/Layout.astro'
|
||||||
import Layout from 'layouts/Layout.astro'
|
import Picture from 'components/Picture.astro'
|
||||||
|
|
||||||
const projects = await getCollection('projects')
|
const projects = await getCollection('projects')
|
||||||
const clients = await Promise.all((await getCollection('clients')).map(async (it) => ({...it, obj: await it.render()})))
|
const clients = await Promise.all((await getCollection('clients')).map(async (it) => ({...it, obj: await it.render()})))
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Avior.me - Developpement de solutions selon vos besoins">
|
<Layout title="Avior.me - Developpement de solutions selon vos besoins">
|
||||||
<main class="container">
|
<main class="container">
|
||||||
|
|
||||||
<div class="flex justify-center items-center h-64">
|
<div class="flex justify-center items-center h-64">
|
||||||
<h1 class="text-4xl font-bold">Développement de solutions selon vos besoins</h1>
|
<h1 class="text-4xl font-bold">Développement de solutions selon vos besoins</h1>
|
||||||
</div>
|
</div>
|
||||||
<h2 class="text-center md:text-left text-2xl font-semibold mb-4">Projets</h2>
|
<h2 class="text-center md:text-left text-2xl font-semibold mb-4">Projets</h2>
|
||||||
<div class="md:grid grid-cols-3 gap-4">
|
<div class="md:grid grid-cols-3 gap-4">
|
||||||
{projects.map((it) => (
|
{projects.map((it) => (
|
||||||
<a href={`/projets/${it.slug}`} class="flex flex-col gap-4 mb-6 md:mb-0">
|
<a href={`/projets/${it.slug}`} class="flex flex-col gap-4 mb-6 md:mb-0">
|
||||||
{it.data.image && (
|
{it.data.image && (
|
||||||
<Image src={it.data.image} alt="" />
|
<Picture src={it.data.image} alt="" />
|
||||||
)}
|
)}
|
||||||
<p>{it.data.title}</p>
|
<p>{it.data.title}</p>
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<h2 class="text-center md:text-left text-2xl font-semibold my-8">Clients</h2>
|
<h2 class="text-center md:text-left text-2xl font-semibold my-8">Clients</h2>
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div class="prose dark:prose-invert max-w-none">
|
<div class="prose dark:prose-invert max-w-none">
|
||||||
<p class="font-semibold">Tâches :</p>
|
<p class="font-semibold">Tâches :O :</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{clients.map((client, index) => {
|
{clients.map((client, index) => {
|
||||||
const { Content } = client.obj
|
const { Content } = client.obj
|
||||||
client.data.logo
|
client.data.logo
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{index > 0 && (
|
{index > 0 && (
|
||||||
<div class="hidden md:block w-10/12 mx-auto h-0.5 bg-gray-300 dark:bg-gray-700"></div>
|
<div class="hidden md:block w-10/12 mx-auto h-0.5 bg-gray-300 dark:bg-gray-700"></div>
|
||||||
)}
|
)}
|
||||||
<div class="mt-6 md:mt-0 md:grid grid-cols-2 items-center">
|
<div class="mt-6 md:mt-0 md:grid grid-cols-2 items-center">
|
||||||
<a href={client.data.site} target="_blank" rel="noreferrer nofollow" class="flex flex-col gap-4">
|
<a href={client.data.site} target="_blank" rel="noreferrer nofollow" class="flex flex-col gap-4">
|
||||||
{client.data.logo && (
|
{client.data.logo && (
|
||||||
<Image class:list={{'mx-auto': true, 'md:mx-0': true, 'dark:invert': client.data.logo.invert}} src={client.data.logo.src} height={48} alt="" />
|
<Picture class:list={{'mx-auto': true, 'md:mx-0': true, 'dark:invert': client.data.logo.invert}} src={client.data.logo.src} height={48} alt="" />
|
||||||
) || (
|
) || (
|
||||||
<div>{client.data.title}</div>
|
<div>{client.data.title}</div>
|
||||||
)}
|
)}
|
||||||
</a>
|
</a>
|
||||||
<div class="prose dark:prose-invert max-w-none">
|
<div class="prose dark:prose-invert max-w-none">
|
||||||
<Content />
|
<Content />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
|
import Picture from 'components/Picture.astro'
|
||||||
import Article from 'layouts/Article.astro'
|
import Article from 'layouts/Article.astro'
|
||||||
|
|
||||||
export const prerender = true
|
export const prerender = true
|
||||||
@ -11,16 +12,28 @@ export async function getStaticPaths() {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
// 2. For your template, you can get the entry directly from the prop
|
// 2. For your template, you can get the entry directly from the prop
|
||||||
const { entry } = Astro.props;
|
const { entry } = Astro.props as Awaited<ReturnType<typeof getStaticPaths>>[0]['props'];
|
||||||
const { Content } = await entry.render();
|
const { Content } = await entry.render();
|
||||||
---
|
---
|
||||||
<Article title={entry.data.title} image={[entry.data.image]} description={entry.data.description} link={entry.data.link} breadcrumb={[{text: 'Accueil', href: '/'}, {text: 'Projets', href: '/projets'}, {text: entry.data.title}]}>
|
<Article
|
||||||
|
title={entry.data.title}
|
||||||
|
image={entry.data.image ? [entry.data.image] : undefined}
|
||||||
|
description={entry.data.description}
|
||||||
|
link={entry.data.link}
|
||||||
|
breadcrumb={[
|
||||||
|
{text: 'Accueil', href: '/'},
|
||||||
|
{text: 'Projets', href: '/projets'},
|
||||||
|
{text: entry.data.title}
|
||||||
|
]}
|
||||||
|
>
|
||||||
<h1>{entry.data.title}</h1>
|
<h1>{entry.data.title}</h1>
|
||||||
<p class="flex justify-end font-lights my-0">
|
<p class="flex justify-end font-lights my-0">
|
||||||
<span>Sortie initial le {entry.data.created.toLocaleDateString('fr')}</span>
|
{entry.data.created && (
|
||||||
|
<span>Sortie initial le {entry.data.created.toLocaleDateString('fr')}</span>
|
||||||
|
)}
|
||||||
<!-- <p>Software updated: {entry.data.updated.toLocaleDateString()}</p> -->
|
<!-- <p>Software updated: {entry.data.updated.toLocaleDateString()}</p> -->
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<Content />
|
<Content components={{img: Picture }}/>
|
||||||
|
|
||||||
</Article>
|
</Article>
|
||||||
|
@ -13,11 +13,11 @@ export const ALL: APIRoute = async () => {
|
|||||||
sitemap.addEntry('/', {
|
sitemap.addEntry('/', {
|
||||||
priority: 1
|
priority: 1
|
||||||
})
|
})
|
||||||
sitemap.addEntry('/projets/', {
|
sitemap.addEntry('/projects/', {
|
||||||
priority: 0.5
|
priority: 0.5
|
||||||
})
|
})
|
||||||
for (const project of projects) {
|
for (const project of projects) {
|
||||||
sitemap.addEntry('/projets/' + project.slug, {
|
sitemap.addEntry('/projects/' + project.slug, {
|
||||||
priority: 0.7
|
priority: 0.7
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user