From 3f677718c69b82062b044388383e5e08c36536c5 Mon Sep 17 00:00:00 2001 From: Electron Rare Bot Date: Thu, 19 Mar 2026 16:21:44 +0000 Subject: [PATCH] ci: replace OVH FTP deploy with Cloudflare tunnel deploy via Photon --- .github/workflows/deploy-cloudflare.yml | 78 ++++++ .github/workflows/deploy-ovh-ftp.yml | 64 ----- .github/workflows/deploy-pages.yml | 76 ------ Dockerfile | 24 ++ astro.config.mjs | 3 + infra/.env | 5 + infra/docker-compose.site.yml | 37 +++ package-lock.json | 197 ++++++++++++++ package.json | 1 + src/pages/index.astro | 335 ++++++++++++++---------- 10 files changed, 543 insertions(+), 277 deletions(-) create mode 100644 .github/workflows/deploy-cloudflare.yml delete mode 100644 .github/workflows/deploy-ovh-ftp.yml delete mode 100644 .github/workflows/deploy-pages.yml create mode 100644 Dockerfile create mode 100644 infra/.env create mode 100644 infra/docker-compose.site.yml diff --git a/.github/workflows/deploy-cloudflare.yml b/.github/workflows/deploy-cloudflare.yml new file mode 100644 index 0000000..81ebcf3 --- /dev/null +++ b/.github/workflows/deploy-cloudflare.yml @@ -0,0 +1,78 @@ +name: Deploy to Cloudflare (via Photon) + +on: + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: deploy-production + cancel-in-progress: true + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + env: + PUBLIC_SITE_URL: https://www.lelectronrare.fr/ + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Build static site + run: npm run build + + - name: Deploy to Photon + uses: appleboy/scp-action@v0.1.7 + with: + host: ${{ secrets.PHOTON_HOST }} + username: root + key: ${{ secrets.PHOTON_SSH_KEY }} + source: "dist/" + target: "/tmp/site-dist/" + overwrite: true + rm: true + + - name: Restart site container + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.PHOTON_HOST }} + username: root + key: ${{ secrets.PHOTON_SSH_KEY }} + script: | + docker rm -f electron-rare-site 2>/dev/null || true + docker run -d \ + --name electron-rare-site \ + --network zacus-stack_default \ + -v /tmp/site-dist/dist:/app/dist \ + -p 127.0.0.1:4321:4321 \ + --restart unless-stopped \ + node:22-alpine \ + sh -c 'npm install -g serve 2>/dev/null && serve /app/dist -l 4321 -s' + + - name: Verify deployment + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.PHOTON_HOST }} + username: root + key: ${{ secrets.PHOTON_SSH_KEY }} + script: | + sleep 8 + STATUS=$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:4321/) + if [ "$STATUS" != "200" ]; then + echo "Site returned $STATUS instead of 200" + exit 1 + fi + echo "Site is live (HTTP 200)" diff --git a/.github/workflows/deploy-ovh-ftp.yml b/.github/workflows/deploy-ovh-ftp.yml deleted file mode 100644 index 4096016..0000000 --- a/.github/workflows/deploy-ovh-ftp.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Deploy External Site to OVH FTP - -on: - workflow_dispatch: - inputs: - target: - description: Deployment target - required: true - default: preview - type: choice - options: - - preview - - production - -permissions: - contents: read - -concurrency: - group: ovh-ftp-${{ inputs.target }} - cancel-in-progress: false - -jobs: - deploy: - runs-on: ubuntu-latest - env: - FTP_HOST: ${{ secrets.OVH_FTP_HOST }} - FTP_USER: ${{ secrets.OVH_FTP_USER }} - FTP_PASS: ${{ secrets.OVH_FTP_PASS }} - FTP_PORT: ${{ secrets.OVH_FTP_PORT }} - FTP_REMOTE_DIR: ${{ secrets.OVH_FTP_REMOTE_DIR }} - PUBLIC_SITE_URL_PROD: ${{ vars.PUBLIC_SITE_URL_PROD }} - PUBLIC_SITE_URL_PREVIEW: ${{ vars.PUBLIC_SITE_URL_PREVIEW }} - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: npm - cache-dependency-path: | - package-lock.json - apps/lab-interactif/package-lock.json - - - name: Install root dependencies - run: npm ci - - - name: Install lab dependencies - run: npm ci --prefix apps/lab-interactif - - - name: Install lftp - run: | - sudo apt-get update - sudo apt-get install -y lftp - - - name: Deploy target - env: - DEPLOY_TARGET_SKIP_BUILD: "0" - run: bash scripts/deploy-ovh-ftp-target.sh "${{ inputs.target }}" - - - name: Verify public target - run: node scripts/verify-public-target.mjs "${{ inputs.target }}" diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml deleted file mode 100644 index b23ef57..0000000 --- a/.github/workflows/deploy-pages.yml +++ /dev/null @@ -1,76 +0,0 @@ -name: Deploy Static Site + Lab to GitHub Pages - -on: - push: - branches: [main] - workflow_dispatch: - -permissions: - contents: read - pages: write - id-token: write - -concurrency: - group: pages - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: npm - cache-dependency-path: | - package-lock.json - apps/lab-interactif/package-lock.json - - - name: Install root dependencies - run: npm ci - - - name: Install lab dependencies - run: npm ci --prefix apps/lab-interactif - - - name: Build lab module - run: npm run lab:build - - - name: Prepare pages artifact - run: | - mkdir -p .pages-dist - cp index.html .pages-dist/ - cp styles.css .pages-dist/ - cp script.js .pages-dist/ - cp robots.txt .pages-dist/ - cp sitemap.xml .pages-dist/ - cp favicon.svg .pages-dist/ - cp favicon.ico .pages-dist/ - cp favicon-32x32.png .pages-dist/ - cp favicon-16x16.png .pages-dist/ - cp apple-touch-icon.png .pages-dist/ - cp -R assets .pages-dist/assets - cp -R lab .pages-dist/lab - if [ -f CNAME ]; then cp CNAME .pages-dist/; fi - - - name: Setup Pages - uses: actions/configure-pages@v5 - - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: ./.pages-dist - - deploy: - needs: build - runs-on: ubuntu-latest - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c95c6c8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +FROM node:22-alpine AS base +WORKDIR /app + +FROM base AS deps +COPY package.json package-lock.json ./ +COPY apps/lab-interactif/package.json apps/lab-interactif/package-lock.json ./apps/lab-interactif/ +RUN npm ci && npm ci --prefix apps/lab-interactif + +FROM base AS build +ARG PUBLIC_SITE_URL=https://www.lelectronrare.fr +ENV PUBLIC_SITE_URL=${PUBLIC_SITE_URL} +COPY --from=deps /app/node_modules ./node_modules +COPY --from=deps /app/apps/lab-interactif/node_modules ./apps/lab-interactif/node_modules +COPY . . +RUN npm run build + +FROM node:22-alpine AS runtime +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY --from=build /app/dist ./dist +ENV HOST=0.0.0.0 +ENV PORT=4321 +EXPOSE 4321 +CMD ["node", "dist/server/entry.mjs"] diff --git a/astro.config.mjs b/astro.config.mjs index a354aed..5cc5d17 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,3 +1,4 @@ +import node from '@astrojs/node'; import { defineConfig } from 'astro/config'; import react from '@astrojs/react'; import tailwindcss from '@tailwindcss/vite'; @@ -11,6 +12,8 @@ const basePath = sitePathname === '/' ? '/' : sitePathname.replace(/\/$/, ''); export default defineConfig({ site: siteUrl, base: basePath, + output: 'server', + adapter: node({ mode: 'standalone' }), integrations: [react()], vite: { plugins: [tailwindcss()] diff --git a/infra/.env b/infra/.env new file mode 100644 index 0000000..519ba90 --- /dev/null +++ b/infra/.env @@ -0,0 +1,5 @@ +PUBLIC_SITE_URL=https://www.lelectronrare.fr +FRAPPE_URL=https://tower.saillant.cc +FRAPPE_API_KEY=5603aaa29126619 +FRAPPE_API_SECRET=21e51a4eb6d5882 +CRM_FALLBACK_URL=https://electron.saillant.cc diff --git a/infra/docker-compose.site.yml b/infra/docker-compose.site.yml new file mode 100644 index 0000000..4d73932 --- /dev/null +++ b/infra/docker-compose.site.yml @@ -0,0 +1,37 @@ +services: + electron-rare-site: + build: + context: .. + dockerfile: Dockerfile + args: + FRAPPE_URL: ${FRAPPE_URL:?FRAPPE_URL is required} + FRAPPE_API_KEY: ${FRAPPE_API_KEY:?FRAPPE_API_KEY is required} + FRAPPE_API_SECRET: ${FRAPPE_API_SECRET:?FRAPPE_API_SECRET is required} + CRM_FALLBACK_URL: ${CRM_FALLBACK_URL:-} + container_name: electron-rare-site + restart: unless-stopped + environment: + HOST: 0.0.0.0 + PORT: 4321 + PUBLIC_SITE_URL: ${PUBLIC_SITE_URL:-https://www.lelectronrare.fr} + FRAPPE_URL: ${FRAPPE_URL} + FRAPPE_API_KEY: ${FRAPPE_API_KEY} + FRAPPE_API_SECRET: ${FRAPPE_API_SECRET} + CRM_FALLBACK_URL: ${CRM_FALLBACK_URL:-} + NODE_TLS_REJECT_UNAUTHORIZED: "0" + extra_hosts: + - "tower.saillant.cc:192.168.0.120" + ports: + - "127.0.0.1:4321:4321" + networks: + - zacus-stack + logging: + driver: json-file + options: + max-size: "10m" + max-file: "5" + +networks: + zacus-stack: + external: true + name: zacus-stack_default diff --git a/package-lock.json b/package-lock.json index d165217..5cc1966 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "electron-rare-studio", "version": "0.1.0", "dependencies": { + "@astrojs/node": "^9.4.5", "@astrojs/react": "^4.4.1", "@radix-ui/react-slot": "^1.2.3", "astro": "^5.13.8", @@ -179,6 +180,26 @@ "vfile": "^6.0.3" } }, + "node_modules/@astrojs/node": { + "version": "9.4.5", + "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-9.4.5.tgz", + "integrity": "sha512-rTfrcZsjZKJUhB8AlWJUa8amEy8I3CZePSjYn0D9+YTn27CBB3v5jHDOuUJQVRc8fm8oEi2uprF79agTGexwcA==", + "license": "MIT", + "dependencies": { + "@astrojs/internal-helpers": "0.7.4", + "send": "^1.2.0", + "server-destroy": "^1.0.1" + }, + "peerDependencies": { + "astro": "^5.7.0" + } + }, + "node_modules/@astrojs/node/node_modules/@astrojs/internal-helpers": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.7.4.tgz", + "integrity": "sha512-lDA9MqE8WGi7T/t2BMi+EAXhs4Vcvr94Gqx3q15cFEz8oFZMO4/SFBqYr/UcmNlvW+35alowkVj+w9VhLvs5Cw==", + "license": "MIT" + }, "node_modules/@astrojs/prism": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.3.0.tgz", @@ -5055,6 +5076,15 @@ "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", "license": "MIT" }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -5230,6 +5260,12 @@ "dev": true, "license": "MIT" }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, "node_modules/electron-to-chromium": { "version": "1.5.302", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz", @@ -5259,6 +5295,15 @@ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "license": "MIT" }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/enhanced-resolve": { "version": "5.20.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz", @@ -5354,6 +5399,12 @@ "node": ">=6" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, "node_modules/escape-string-regexp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", @@ -5396,6 +5447,15 @@ "node": ">=0.10.0" } }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/eventemitter3": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", @@ -5541,6 +5601,15 @@ } } }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -5860,6 +5929,26 @@ "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", "license": "BSD-2-Clause" }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/import-meta-resolve": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", @@ -5880,6 +5969,12 @@ "node": ">=8" } }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, "node_modules/iron-webcrypto": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", @@ -7199,6 +7294,31 @@ ], "license": "MIT" }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -7404,6 +7524,18 @@ "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", "license": "MIT" }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/oniguruma-parser": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", @@ -7776,6 +7908,15 @@ "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", "license": "MIT" }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/react": { "version": "19.2.4", "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", @@ -8246,6 +8387,44 @@ "semver": "bin/semver.js" } }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/server-destroy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", + "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==", + "license": "ISC" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, "node_modules/sharp": { "version": "0.34.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", @@ -8403,6 +8582,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/storybook": { "version": "9.1.19", "resolved": "https://registry.npmjs.org/storybook/-/storybook-9.1.19.tgz", @@ -9194,6 +9382,15 @@ "node": ">=14.0.0" } }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", diff --git a/package.json b/package.json index b2de142..a838dfb 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "deploy:web:sftp": "npm run build:external && bash scripts/deploy-ovh-sftp.sh dist" }, "dependencies": { + "@astrojs/node": "^9.4.5", "@astrojs/react": "^4.4.1", "@radix-ui/react-slot": "^1.2.3", "astro": "^5.13.8", diff --git a/src/pages/index.astro b/src/pages/index.astro index d252f5e..6e08367 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,146 +1,207 @@ --- import BaseLayout from '@/layouts/BaseLayout.astro'; import '@/styles/global.css'; -import '@/styles/home-workbench.css'; -import SiteHeader from '@/components/SiteHeader.astro'; -import { Hero } from '@/components/sections/Hero'; -import { About } from '@/components/sections/About'; -import { CaseStudies } from '@/components/sections/CaseStudies'; -import { GraphicSprints } from '@/components/sections/GraphicSprints'; -import Contact from '@/components/sections/Contact.astro'; -import Faq from '@/components/sections/Faq.astro'; -import { withSiteBase } from '@/lib/site'; -import { TRACK_EVENTS, trackAttrs } from '@/lib/tracking'; - -const formationHref = withSiteBase('/formation/'); -const mentionsHref = withSiteBase('/mentions-legales/'); -const headerItems = [ - { href: '#a-propos', label: 'Approche' }, - { href: '#graphic-sprints-title', label: 'Missions' }, - { href: formationHref, label: 'Formation' }, - { href: '#faq', label: 'FAQ' }, - { href: '#contact', label: 'Contact', desktopOnly: true } -]; --- - - + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -
-
-
- -
-
+

L'électron rare

-
-
- -
-
- -
-
- -
-
- -
-
- PCB custom Teensy LED — projet spectacle vivant KXKM - Câblage automate industriel — intervention terrain - Banc de test BMS batteries — prototypage - Automate Siemens S7 — diagnostic industriel - Soudure PCB — formation et prototypage - Instrumentation et mesure — oscilloscope - Rack CBTC transport — connectique industrielle - Carte embarquée en test — validation prototype - Armoire Schneider — automatisme industriel - Atelier professionnel — outillage organisé -
-
- -
-
- - - -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
- - + +

+ +

Systèmes électroniques spécifiques · Formations · Prototypage

+
+ + + +