Merge branch 'legacy_dev' into legacy_staging

This commit is contained in:
Sosthene 2025-08-03 22:03:05 +02:00
commit 310634c930
12 changed files with 493 additions and 40 deletions

View File

@ -1,8 +1,8 @@
name: Prod - Build & Deploy to Scaleway
on:
push:
branches: [main]
schedule:
- cron: '00 20 * * *' # 20:00 UTC -> 22:00 CEST
env:

74
.github/workflows/test.yml vendored Normal file
View File

@ -0,0 +1,74 @@
name: Test - Build & Deploy to Scaleway
on:
push:
branches: [legacy_dev]
env:
PROJECT_ID_LECOFFRE: 72d08499-37c2-412b-877e-f8af0471654a
NAMESPACE_ID_LECOFFRE: 3829c5cd-9fb0-4871-97a1-eb33e4bc1114
CONTAINER_REGISTRY_ENDPOINT_LECOFFRE: rg.fr-par.scw.cloud/funcscwlecoffretestouylprmj
IMAGE_NAME: front
CONTAINER_NAME: front
jobs:
build-and-push-image-lecoffre:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Copy SSH
run: cp ~/.ssh/id_rsa id_rsa
- name: Login to Scaleway Container Registry
uses: docker/login-action@v3
with:
username: nologin
password: ${{ secrets.SCW_SECRET_KEY_LECOFFRE }}
registry: ${{ env.CONTAINER_REGISTRY_ENDPOINT_LECOFFRE }}
- name: Build the Docker Image
run: docker build . -t ${{ env.CONTAINER_REGISTRY_ENDPOINT_LECOFFRE }}/${{ env.IMAGE_NAME }}
- name: Push the Docker Image to Scaleway Container Registry
run: docker push ${{ env.CONTAINER_REGISTRY_ENDPOINT_LECOFFRE }}/${{ env.IMAGE_NAME }}
deploy-to-scaleway-lecoffre:
needs: build-and-push-image-lecoffre
runs-on: ubuntu-latest
environment: test
steps:
- name: Install CLI
uses: scaleway/action-scw@v0
- name: Get container ID
run: |
echo "CONTAINER_ID=$(scw container container list namespace-id=${{env.NAMESPACE_ID_LECOFFRE}} -o json | jq -r '.[] | select(.name == "${{ env.CONTAINER_NAME }}") | .id')" >> $GITHUB_ENV
env:
SCW_ACCESS_KEY: ${{ secrets.SCW_ACCESS_KEY_LECOFFRE }}
SCW_SECRET_KEY: ${{ secrets.SCW_SECRET_KEY_LECOFFRE }}
SCW_DEFAULT_PROJECT_ID: ${{ env.PROJECT_ID_LECOFFRE }}
SCW_DEFAULT_ORGANIZATION_ID: ${{ secrets.SCW_ORGANIZATION_ID_LECOFFRE }}
- name: Deploy the container based on the new image
run: |
env_string=""
while IFS= read -r line; do
if [[ "$line" == *"="* ]]; then
key=$(echo "$line" | cut -d '=' -f 1)
value=$(echo "$line" | cut -d '=' -f 2-)
if [[ -n "$key" ]]; then
env_string+="environment-variables.$key=$value "
fi
fi
done <<< "$ENV_VARS"
env_string=$(echo $env_string | sed 's/ $//')
scw container container update ${{ env.CONTAINER_ID }} $env_string
env:
ENV_VARS: ${{ secrets.ENV }}
SCW_ACCESS_KEY: ${{ secrets.SCW_ACCESS_KEY_LECOFFRE }}
SCW_SECRET_KEY: ${{ secrets.SCW_SECRET_KEY_LECOFFRE }}
SCW_DEFAULT_PROJECT_ID: ${{ env.PROJECT_ID_LECOFFRE }}
SCW_DEFAULT_ORGANIZATION_ID: ${{ secrets.SCW_ORGANIZATION_ID_LECOFFRE }}

224
package-lock.json generated
View File

@ -394,6 +394,7 @@
}
},
"node_modules/@floating-ui/core": {
<<<<<<< HEAD
"version": "1.6.8",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz",
"integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==",
@ -414,6 +415,28 @@
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz",
"integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig=="
=======
"version": "1.6.7",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.7.tgz",
"integrity": "sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==",
"dependencies": {
"@floating-ui/utils": "^0.2.7"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.6.10",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.10.tgz",
"integrity": "sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==",
"dependencies": {
"@floating-ui/core": "^1.6.0",
"@floating-ui/utils": "^0.2.7"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.7.tgz",
"integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA=="
>>>>>>> main
},
"node_modules/@heroicons/react": {
"version": "2.1.5",
@ -648,9 +671,15 @@
}
},
"node_modules/@mui/types": {
<<<<<<< HEAD
"version": "7.2.17",
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.17.tgz",
"integrity": "sha512-oyumoJgB6jDV8JFzRqjBo2daUuHpzDjoO/e3IrRhhHo/FxJlaVhET6mcNrKHUq2E+R+q3ql0qAtvQ4rfWHhAeQ==",
=======
"version": "7.2.16",
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.16.tgz",
"integrity": "sha512-qI8TV3M7ShITEEc8Ih15A2vLzZGLhD+/UPNwck/hcls2gwg7dyRjNGXcQYHKLB5Q7PuTRfrTkAoPa2VV1s67Ag==",
>>>>>>> main
"peerDependencies": {
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0"
},
@ -690,9 +719,15 @@
}
},
"node_modules/@next/env": {
<<<<<<< HEAD
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.13.tgz",
"integrity": "sha512-s3lh6K8cbW1h5Nga7NNeXrbe0+2jIIYK9YaA9T7IufDWnZpozdFUp6Hf0d5rNWUKu4fEuSX2rCKlGjCrtylfDw=="
=======
"version": "14.2.8",
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.8.tgz",
"integrity": "sha512-L44a+ynqkolyNBnYfF8VoCiSrjSZWgEHYKkKLGcs/a80qh7AkfVUD/MduVPgdsWZ31tgROR+yJRA0PZjSVBXWQ=="
>>>>>>> main
},
"node_modules/@next/eslint-plugin-next": {
"version": "13.2.4",
@ -703,9 +738,15 @@
}
},
"node_modules/@next/swc-darwin-arm64": {
<<<<<<< HEAD
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.13.tgz",
"integrity": "sha512-IkAmQEa2Htq+wHACBxOsslt+jMoV3msvxCn0WFSfJSkv/scy+i/EukBKNad36grRxywaXUYJc9mxEGkeIs8Bzg==",
=======
"version": "14.2.8",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.8.tgz",
"integrity": "sha512-1VrQlG8OzdyvvGZhGJFnaNE2P10Jjy/2FopnqbY0nSa/gr8If3iINxvOEW3cmVeoAYkmW0RsBazQecA2dBFOSw==",
>>>>>>> main
"cpu": [
"arm64"
],
@ -718,9 +759,15 @@
}
},
"node_modules/@next/swc-darwin-x64": {
<<<<<<< HEAD
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.13.tgz",
"integrity": "sha512-Dv1RBGs2TTjkwEnFMVL5XIfJEavnLqqwYSD6LXgTPdEy/u6FlSrLBSSfe1pcfqhFEXRAgVL3Wpjibe5wXJzWog==",
=======
"version": "14.2.8",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.8.tgz",
"integrity": "sha512-87t3I86rNRSOJB1gXIUzaQWWSWrkWPDyZGsR0Z7JAPtLeX3uUOW2fHxl7dNWD2BZvbvftctTQjgtfpp7nMtmWg==",
>>>>>>> main
"cpu": [
"x64"
],
@ -733,9 +780,15 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
<<<<<<< HEAD
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.13.tgz",
"integrity": "sha512-yB1tYEFFqo4ZNWkwrJultbsw7NPAAxlPXURXioRl9SdW6aIefOLS+0TEsKrWBtbJ9moTDgU3HRILL6QBQnMevg==",
=======
"version": "14.2.8",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.8.tgz",
"integrity": "sha512-ta2sfVzbOpTbgBrF9HM5m+U58dv6QPuwU4n5EX4LLyCJGKc433Z0D9h9gay/HSOjLEXJ2fJYrMP5JYYbHdxhtw==",
>>>>>>> main
"cpu": [
"arm64"
],
@ -748,9 +801,15 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
<<<<<<< HEAD
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.13.tgz",
"integrity": "sha512-v5jZ/FV/eHGoWhMKYrsAweQ7CWb8xsWGM/8m1mwwZQ/sutJjoFaXchwK4pX8NqwImILEvQmZWyb8pPTcP7htWg==",
=======
"version": "14.2.8",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.8.tgz",
"integrity": "sha512-+IoLTPK6Z5uIgDhgeWnQF5/o5GBN7+zyUNrs4Bes1W3g9++YELb8y0unFybS8s87ntAKMDl6jeQ+mD7oNwp/Ng==",
>>>>>>> main
"cpu": [
"arm64"
],
@ -763,9 +822,15 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
<<<<<<< HEAD
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.13.tgz",
"integrity": "sha512-aVc7m4YL7ViiRv7SOXK3RplXzOEe/qQzRA5R2vpXboHABs3w8vtFslGTz+5tKiQzWUmTmBNVW0UQdhkKRORmGA==",
=======
"version": "14.2.8",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.8.tgz",
"integrity": "sha512-pO+hVXC+mvzUOQJJRG4RX4wJsRJ5BkURSf6dD6EjUXAX4Ml9es1WsEfkaZ4lcpmFzFvY47IkDaffks/GdCn9ag==",
>>>>>>> main
"cpu": [
"x64"
],
@ -778,9 +843,15 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
<<<<<<< HEAD
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.13.tgz",
"integrity": "sha512-4wWY7/OsSaJOOKvMsu1Teylku7vKyTuocvDLTZQq0TYv9OjiYYWt63PiE1nTuZnqQ4RPvME7Xai+9enoiN0Wrg==",
=======
"version": "14.2.8",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.8.tgz",
"integrity": "sha512-bCat9izctychCtf3uL1nqHq31N5e1VxvdyNcBQflkudPMLbxVnlrw45Vi87K+lt1CwrtVayHqzo4ie0Szcpwzg==",
>>>>>>> main
"cpu": [
"x64"
],
@ -793,9 +864,15 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
<<<<<<< HEAD
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.13.tgz",
"integrity": "sha512-uP1XkqCqV2NVH9+g2sC7qIw+w2tRbcMiXFEbMihkQ8B1+V6m28sshBwAB0SDmOe0u44ne1vFU66+gx/28RsBVQ==",
=======
"version": "14.2.8",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.8.tgz",
"integrity": "sha512-gbxfUaSPV7EyUobpavida2Hwi62GhSJaSg7iBjmBWoxkxlmETOD7U4tWt763cGIsyE6jM7IoNavq0BXqwdW2QA==",
>>>>>>> main
"cpu": [
"arm64"
],
@ -808,9 +885,15 @@
}
},
"node_modules/@next/swc-win32-ia32-msvc": {
<<<<<<< HEAD
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.13.tgz",
"integrity": "sha512-V26ezyjPqQpDBV4lcWIh8B/QICQ4v+M5Bo9ykLN+sqeKKBxJVDpEc6biDVyluTXTC40f5IqCU0ttth7Es2ZuMw==",
=======
"version": "14.2.8",
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.8.tgz",
"integrity": "sha512-PUXzEzjTTlUh3b5VAn1nlpwvujTnuCMMwbiCnaTazoVlN1nA3kWjlmp42IfURA2N/nyrlVEw7pURa/o4Qxj1cw==",
>>>>>>> main
"cpu": [
"ia32"
],
@ -823,9 +906,15 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
<<<<<<< HEAD
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.13.tgz",
"integrity": "sha512-WwzOEAFBGhlDHE5Z73mNU8CO8mqMNLqaG+AO9ETmzdCQlJhVtWZnOl2+rqgVQS+YHunjOWptdFmNfbpwcUuEsw==",
=======
"version": "14.2.8",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.8.tgz",
"integrity": "sha512-EnPKv0ttq02E9/1KZ/8Dn7kuutv6hy1CKc0HlNcvzOQcm4/SQtvfws5gY0zrG9tuupd3HfC2L/zcTrnBhpjTuQ==",
>>>>>>> main
"cpu": [
"x64"
],
@ -838,9 +927,15 @@
}
},
"node_modules/@next/third-parties": {
<<<<<<< HEAD
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/third-parties/-/third-parties-14.2.13.tgz",
"integrity": "sha512-OSqD2E9JO0/GE8HT5QAUsYVXwjWtPLScAX70kO2xopwDAdRzakrsQS55Cihd862X/4bUB37ApVZ9DlHcExzeOg==",
=======
"version": "14.2.8",
"resolved": "https://registry.npmjs.org/@next/third-parties/-/third-parties-14.2.8.tgz",
"integrity": "sha512-Vus4MYsb+7B2X4Mks9aCztZwgnzTxU9sHEm1Y35z7Vw1seh43ummniD9CBk7A8dVJZf8NGpx8re6YSZLkaSQiQ==",
>>>>>>> main
"dependencies": {
"third-party-capital": "1.0.20"
},
@ -991,9 +1086,15 @@
"integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw=="
},
"node_modules/@types/validator": {
<<<<<<< HEAD
"version": "13.12.2",
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.12.2.tgz",
"integrity": "sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA=="
=======
"version": "13.12.1",
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.12.1.tgz",
"integrity": "sha512-w0URwf7BQb0rD/EuiG12KP0bailHKHP5YVviJG9zw3ykAokL0TuxU2TUqMB7EwZ59bDHYdeTIvjI5m0S7qHfOA=="
>>>>>>> main
},
"node_modules/@typescript-eslint/parser": {
"version": "5.62.0",
@ -1390,9 +1491,15 @@
"optional": true
},
"node_modules/bare-fs": {
<<<<<<< HEAD
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz",
"integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==",
=======
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.3.tgz",
"integrity": "sha512-7RYKL+vZVCyAsMLi5SPu7QGauGGT8avnP/HO571ndEuV4MYdGXvLhtW67FuLPeEI8EiIY7zbbRR9x7x7HU0kgw==",
>>>>>>> main
"optional": true,
"dependencies": {
"bare-events": "^2.0.0",
@ -1401,9 +1508,15 @@
}
},
"node_modules/bare-os": {
<<<<<<< HEAD
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz",
"integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==",
=======
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.2.tgz",
"integrity": "sha512-HZoJwzC+rZ9lqEemTMiO0luOePoGYNBgsLLgegKR/cljiJvcDNhDZQkzC+NC5Oh0aHbdBNSOHpghwMuB5tqhjg==",
>>>>>>> main
"optional": true
},
"node_modules/bare-path": {
@ -1416,6 +1529,7 @@
}
},
"node_modules/bare-stream": {
<<<<<<< HEAD
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.0.tgz",
"integrity": "sha512-pVRWciewGUeCyKEuRxwv06M079r+fRjAQjBEK2P6OYGrO43O+Z0LrPZZEjlc4mB6C2RpZ9AxJ1s7NLEtOHO6eA==",
@ -1423,6 +1537,15 @@
"dependencies": {
"b4a": "^1.6.6",
"streamx": "^2.20.0"
=======
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.2.1.tgz",
"integrity": "sha512-YTB47kHwBW9zSG8LD77MIBAAQXjU2WjAkMHeeb7hUplVs6+IoM5I7uEVQNPMB7lj9r8I76UMdoMkGnCodHOLqg==",
"optional": true,
"dependencies": {
"b4a": "^1.6.6",
"streamx": "^2.18.0"
>>>>>>> main
}
},
"node_modules/base64-js": {
@ -1548,9 +1671,15 @@
}
},
"node_modules/caniuse-lite": {
<<<<<<< HEAD
"version": "1.0.30001662",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001662.tgz",
"integrity": "sha512-sgMUVwLmGseH8ZIrm1d51UbrhqMCH3jvS7gF/M6byuHOnKyLOBL7W8yz5V02OHwgLGA36o/AFhWzzh4uc5aqTA==",
=======
"version": "1.0.30001659",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001659.tgz",
"integrity": "sha512-Qxxyfv3RdHAfJcXelgf0hU4DFUVXBGTjqrBUZLUh8AtlGnsDo+CnncYtTd95+ZKfnANUOzxyIQCuU/UeBZBYoA==",
>>>>>>> main
"funding": [
{
"type": "opencollective",
@ -2437,9 +2566,15 @@
}
},
"node_modules/eslint-plugin-react": {
<<<<<<< HEAD
"version": "7.36.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.36.1.tgz",
"integrity": "sha512-/qwbqNXZoq+VP30s1d4Nc1C5GTxjJQjk4Jzs4Wq2qzxFM7dSmuG2UkIjg2USMLh3A/aVcUNrK7v0J5U1XEGGwA==",
=======
"version": "7.35.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.2.tgz",
"integrity": "sha512-Rbj2R9zwP2GYNcIak4xoAMV57hrBh3hTaR0k7hVjwCQgryE/pw5px4b13EYjduOI0hfXyZhwBxaGpOTbWSGzKQ==",
>>>>>>> main
"dependencies": {
"array-includes": "^3.1.8",
"array.prototype.findlast": "^1.2.5",
@ -2908,9 +3043,15 @@
}
},
"node_modules/get-tsconfig": {
<<<<<<< HEAD
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz",
"integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==",
=======
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.0.tgz",
"integrity": "sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==",
>>>>>>> main
"dependencies": {
"resolve-pkg-maps": "^1.0.0"
},
@ -3667,6 +3808,41 @@
"setimmediate": "^1.0.5"
}
},
<<<<<<< HEAD
=======
"node_modules/jszip/node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
},
"node_modules/jszip/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/jszip/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/jszip/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
>>>>>>> main
"node_modules/jwt-decode": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
@ -3697,7 +3873,11 @@
}
},
"node_modules/le-coffre-resources": {
<<<<<<< HEAD
"resolved": "git+ssh://git@github.com/smart-chain-fr/leCoffre-resources.git#2684918e1b3a18a3746218f452e75e0a6153544c",
=======
"resolved": "git+ssh://git@github.com/smart-chain-fr/leCoffre-resources.git#6c3cb06f1dc5307bf491e5f17289379c8e0b8ffc",
>>>>>>> main
"license": "MIT",
"dependencies": {
"class-transformer": "^0.5.1",
@ -3718,9 +3898,15 @@
}
},
"node_modules/libphonenumber-js": {
<<<<<<< HEAD
"version": "1.11.8",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.11.8.tgz",
"integrity": "sha512-0fv/YKpJBAgXKy0kaS3fnqoUVN8901vUYAKIGD/MWZaDfhJt1nZjPL3ZzdZBt/G8G8Hw2J1xOIrXWdNHFHPAvg=="
=======
"version": "1.11.7",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.11.7.tgz",
"integrity": "sha512-x2xON4/Qg2bRIS11KIN9yCNYUjhtiEjNyptjX0mX+pyKHecxuJVLIpfX1lq9ZD6CrC/rB+y4GBi18c6CEcUR+A=="
>>>>>>> main
},
"node_modules/lie": {
"version": "3.3.0",
@ -3877,11 +4063,19 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
},
"node_modules/next": {
<<<<<<< HEAD
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/next/-/next-14.2.13.tgz",
"integrity": "sha512-BseY9YNw8QJSwLYD7hlZzl6QVDoSFHL/URN5K64kVEVpCsSOWeyjbIGK+dZUaRViHTaMQX8aqmnn0PHBbGZezg==",
"dependencies": {
"@next/env": "14.2.13",
=======
"version": "14.2.8",
"resolved": "https://registry.npmjs.org/next/-/next-14.2.8.tgz",
"integrity": "sha512-EyEyJZ89r8C5FPlS/401AiF3O8jeMtHIE+bLom9MwcdWJJFBgRl+MR/2VgO0v5bI6tQORNY0a0DR5sjpFNrjbg==",
"dependencies": {
"@next/env": "14.2.8",
>>>>>>> main
"@swc/helpers": "0.5.5",
"busboy": "1.6.0",
"caniuse-lite": "^1.0.30001579",
@ -3896,6 +4090,7 @@
"node": ">=18.17.0"
},
"optionalDependencies": {
<<<<<<< HEAD
"@next/swc-darwin-arm64": "14.2.13",
"@next/swc-darwin-x64": "14.2.13",
"@next/swc-linux-arm64-gnu": "14.2.13",
@ -3905,6 +4100,17 @@
"@next/swc-win32-arm64-msvc": "14.2.13",
"@next/swc-win32-ia32-msvc": "14.2.13",
"@next/swc-win32-x64-msvc": "14.2.13"
=======
"@next/swc-darwin-arm64": "14.2.8",
"@next/swc-darwin-x64": "14.2.8",
"@next/swc-linux-arm64-gnu": "14.2.8",
"@next/swc-linux-arm64-musl": "14.2.8",
"@next/swc-linux-x64-gnu": "14.2.8",
"@next/swc-linux-x64-musl": "14.2.8",
"@next/swc-win32-arm64-msvc": "14.2.8",
"@next/swc-win32-ia32-msvc": "14.2.8",
"@next/swc-win32-x64-msvc": "14.2.8"
>>>>>>> main
},
"peerDependencies": {
"@opentelemetry/api": "^1.1.0",
@ -3926,9 +4132,15 @@
}
},
"node_modules/node-abi": {
<<<<<<< HEAD
"version": "3.68.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.68.0.tgz",
"integrity": "sha512-7vbj10trelExNjFSBm5kTvZXXa7pZyKWx9RCKIyqe6I9Ev3IzGpQoqBP3a+cOdxY+pWj6VkP28n/2wWysBHD/A==",
=======
"version": "3.67.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.67.0.tgz",
"integrity": "sha512-bLn/fU/ALVBE9wj+p4Y21ZJWYFjUXLXPi/IewyLZkx3ApxKDNBWCKdReeKOtD8dWpOdDCeMyLh6ZewzcLsG2Nw==",
>>>>>>> main
"dependencies": {
"semver": "^7.3.5"
},
@ -4689,9 +4901,15 @@
}
},
"node_modules/sass": {
<<<<<<< HEAD
"version": "1.79.2",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.79.2.tgz",
"integrity": "sha512-YmT1aoF1MwHsZEu/eXhbAJNsPGAhNP4UixW9ckEwWCvPcVdVF0/C104OGDVEqtoctKq0N+wM20O/rj+sSPsWeg==",
=======
"version": "1.78.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.78.0.tgz",
"integrity": "sha512-AaIqGSrjo5lA2Yg7RvFZrlXDBCp3nV4XP73GrLGvdRWWwk+8H3l0SDvq/5bA4eF+0RFPLuWUk3E+P1U/YqnpsQ==",
>>>>>>> main
"dependencies": {
"chokidar": "^4.0.0",
"immutable": "^4.0.0",
@ -4916,9 +5134,15 @@
}
},
"node_modules/streamx": {
<<<<<<< HEAD
"version": "2.20.1",
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz",
"integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==",
=======
"version": "2.20.0",
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.0.tgz",
"integrity": "sha512-ZGd1LhDeGFucr1CUCTBOS58ZhEendd0ttpGT3usTvosS4ntIwKN9LJFp+OeCSprsCPL14BXVRZlHGRY1V9PVzQ==",
>>>>>>> main
"dependencies": {
"fast-fifo": "^1.3.2",
"queue-tick": "^1.0.1",

View File

@ -30,7 +30,7 @@
"heroicons": "^2.1.5",
"jszip": "^3.10.1",
"jwt-decode": "^3.1.2",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.167",
"le-coffre-resources": "git+https://git.4nkweb.com/4nk/lecoffre-ressources.git#v2.167",
"next": "^14.2.3",
"prettier": "^2.8.7",
"react": "18.2.0",

View File

@ -30,6 +30,15 @@ export default abstract class BaseApiService {
}
protected buildHeaders(contentType: ContentType) {
// Don't try to access cookies during server-side rendering
if (typeof window === 'undefined') {
const headers = new Headers();
if (contentType === ContentType.JSON || contentType === ContentType.PDF) {
headers.set("Content-Type", contentType);
}
return headers;
}
const token = CookieService.getInstance().getCookie("leCoffreAccessToken");
const headers = new Headers();
@ -37,7 +46,14 @@ export default abstract class BaseApiService {
if (contentType === ContentType.JSON || contentType === ContentType.PDF) {
headers.set("Content-Type", contentType);
}
headers.set("Authorization", `Bearer ${token}`);
// Only set Authorization header if token exists
if (token) {
headers.set("Authorization", `Bearer ${token}`);
} else {
console.warn("No access token found in cookies when building headers");
}
return headers;
}
@ -134,38 +150,66 @@ export default abstract class BaseApiService {
}
private async checkJwtToken() {
// Don't check tokens during server-side rendering
if (typeof window === 'undefined') {
return;
}
const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken");
if (!accessToken) return;
const userDecodedToken = jwt_decode(accessToken) as IUserJwtPayload;
const customerDecodedToken = jwt_decode(accessToken) as ICustomerJwtPayload;
if (!userDecodedToken && !customerDecodedToken) return;
const now = Math.floor(Date.now() / 1000);
if (userDecodedToken.userId && userDecodedToken.exp < now) {
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
if (!refreshToken) {
return;
}
const decodedRefreshToken = jwt_decode(refreshToken) as IUserJwtPayload | ICustomerJwtPayload;
if (decodedRefreshToken.exp < now) {
return;
}
await JwtService.getInstance().refreshToken(refreshToken);
if (!accessToken) {
console.warn("No access token found during JWT check");
return;
}
if (customerDecodedToken.customerId && customerDecodedToken.exp < now) {
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
if (!refreshToken) {
try {
const userDecodedToken = jwt_decode(accessToken) as IUserJwtPayload;
const customerDecodedToken = jwt_decode(accessToken) as ICustomerJwtPayload;
if (!userDecodedToken && !customerDecodedToken) {
console.warn("Invalid token format during JWT check");
return;
}
const decodedRefreshToken = jwt_decode(refreshToken) as IUserJwtPayload | ICustomerJwtPayload;
if (decodedRefreshToken.exp < now) {
return;
const now = Math.floor(Date.now() / 1000);
if (userDecodedToken.userId && userDecodedToken.exp < now) {
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
if (!refreshToken) {
console.warn("Access token expired but no refresh token found");
return;
}
const decodedRefreshToken = jwt_decode(refreshToken) as IUserJwtPayload | ICustomerJwtPayload;
if (decodedRefreshToken.exp < now) {
console.warn("Both access and refresh tokens are expired");
return;
}
const refreshSuccess = await JwtService.getInstance().refreshToken(refreshToken);
if (!refreshSuccess) {
console.error("Failed to refresh token");
return;
}
}
await JwtService.getInstance().refreshToken(refreshToken);
if (customerDecodedToken.customerId && customerDecodedToken.exp < now) {
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
if (!refreshToken) {
console.warn("Access token expired but no refresh token found");
return;
}
const decodedRefreshToken = jwt_decode(refreshToken) as IUserJwtPayload | ICustomerJwtPayload;
if (decodedRefreshToken.exp < now) {
console.warn("Both access and refresh tokens are expired");
return;
}
const refreshSuccess = await JwtService.getInstance().refreshToken(refreshToken);
if (!refreshSuccess) {
console.error("Failed to refresh token");
return;
}
}
} catch (error) {
console.error("Error during JWT token check:", error);
}
return;
}
protected async processResponse<T>(response: Response, request: () => Promise<Response>, ref?: IRef, fileName?: string): Promise<T> {

View File

@ -313,10 +313,11 @@ export default function DocumentTables(props: IProps) {
);
const progress = useMemo(() => {
const total = askedDocuments.length + toValidateDocuments.length + validatedDocuments.length + refusedDocuments.length;
// Exclude refused documents from total - only count documents that are still in progress
const total = askedDocuments.length + toValidateDocuments.length + validatedDocuments.length;
if (total === 0) return 0;
return (validatedDocuments.length / total) * 100;
}, [askedDocuments.length, refusedDocuments.length, toValidateDocuments.length, validatedDocuments.length]);
}, [askedDocuments.length, toValidateDocuments.length, validatedDocuments.length]);
if (documents.length === 0 && documentsNotary.length === 0) return <NoDocument />;

View File

@ -6,6 +6,7 @@ import Module from "@Front/Config/Module";
import useOpenable from "@Front/Hooks/useOpenable";
import { ClockIcon, EnvelopeIcon } from "@heroicons/react/24/outline";
import Customer from "le-coffre-resources/dist/Customer";
import { EDocumentStatus } from "le-coffre-resources/dist/Customer/Document";
import { DocumentReminder } from "le-coffre-resources/dist/Notary";
import Link from "next/link";
import { useRouter } from "next/router";
@ -13,7 +14,6 @@ import { useCallback, useEffect, useMemo, useState } from "react";
import classes from "./classes.module.scss";
import ReminderModal from "./ReminderModal";
import { EDocumentStatus } from "le-coffre-resources/dist/Customer/Document";
type IProps = {
customer: Customer;
@ -95,7 +95,8 @@ export default function EmailReminder(props: IProps) {
</Link>
<div className={classes["info"]}>
<Typography typo={ETypo.TEXT_XS_REGULAR} color={ETypoColor.TEXT_SECONDARY}>
Dernière relance manuelle: {reminders && remindersLength > 0 ? formatDateWithHours(reminders[0]!.reminder_date) : "-"}
Dernière relance manuelle:{" "}
{reminders && remindersLength > 0 ? formatDateWithHours(reminders[0]!.reminder_date) : "-"}
</Typography>
<Typography typo={ETypo.TEXT_XS_REGULAR} color={ETypoColor.TEXT_SECONDARY}>
Nombre de relance: {remindersLength}

View File

@ -47,8 +47,10 @@ export default function FolderInformation(props: IProps) {
let validatedDocuments = 0;
folder?.customers?.forEach((customer) => {
const documents = customer.documents;
total += documents?.length ?? 0;
validatedDocuments += documents?.filter((document) => document.document_status === EDocumentStatus.VALIDATED).length ?? 0;
// Only count documents that are not refused (still in progress)
const activeDocuments = documents?.filter((document) => document.document_status !== EDocumentStatus.REFUSED) ?? [];
total += activeDocuments.length;
validatedDocuments += activeDocuments.filter((document) => document.document_status === EDocumentStatus.VALIDATED).length;
});
if (total === 0) return 0;
const percentage = (validatedDocuments / total) * 100;

View File

@ -83,7 +83,7 @@ export default function StepEmail(props: IProps) {
<div className={classes["content"]}>
<div className={classes["section"]}>
<Typography typo={ETypo.TITLE_H6} color={ETypoColor.TEXT_ACCENT} className={classes["section-title"]}>
Pour les notaires et les colaborateurs :
Pour les notaires et les collaborateurs :
</Typography>
<Button onClick={redirectUserOnConnection} rightIcon={<Image alt="id-not-logo" src={idNoteLogo} />}>
S'identifier avec ID.not

View File

@ -1,5 +1,6 @@
import Users from "@Front/Api/LeCoffreApi/Notary/Users/Users";
import JwtService from "@Front/Services/JwtService/JwtService";
import UserStore from "@Front/Stores/UserStore";
import User from "le-coffre-resources/dist/Notary";
import { useEffect, useState } from "react";
@ -7,8 +8,23 @@ export default function useUser() {
const [user, setUser] = useState<User | null>();
useEffect(() => {
// Don't run on server-side
if (typeof window === 'undefined') {
return;
}
// Check if user is connected before making API calls
if (!UserStore.instance.isConnected()) {
console.warn("User not connected, skipping API call");
return;
}
const decodedJwt = JwtService.getInstance().decodeJwt();
if (!decodedJwt) return;
if (!decodedJwt) {
console.warn("No valid JWT found, skipping API call");
return;
}
Users.getInstance()
.getByUid(decodedJwt.userId, {
q: {
@ -17,6 +33,9 @@ export default function useUser() {
})
.then((user) => {
setUser(user);
})
.catch((error) => {
console.error("Failed to fetch user:", error);
});
}, []);

View File

@ -9,10 +9,46 @@ export default class UserStore {
protected readonly event = new EventEmitter();
public accessToken: string | null = null;
public refreshToken: string | null = null;
private initialized = false;
private constructor() {}
private constructor() {
// Don't initialize tokens during server-side rendering
if (typeof window !== 'undefined') {
this.initializeFromCookies();
}
}
private initializeFromCookies() {
if (this.initialized) return;
try {
const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken");
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
if (accessToken) {
this.accessToken = accessToken;
}
if (refreshToken) {
this.refreshToken = refreshToken;
}
this.initialized = true;
} catch (error) {
console.warn("Failed to initialize tokens from cookies:", error);
}
}
public isConnected(): boolean {
// Ensure initialization on client side
if (typeof window !== 'undefined' && !this.initialized) {
this.initializeFromCookies();
}
// Check both instance variable and cookie to ensure consistency
if (typeof window !== 'undefined') {
const cookieToken = CookieService.getInstance().getCookie("leCoffreAccessToken");
return !!(this.accessToken || cookieToken);
}
return !!this.accessToken;
}
@ -27,6 +63,10 @@ export default class UserStore {
CookieService.getInstance().setCookie("leCoffreAccessToken", accessToken);
CookieService.getInstance().setCookie("leCoffreRefreshToken", refreshToken);
// Update instance variables
this.accessToken = accessToken;
this.refreshToken = refreshToken;
this.event.emit("connection", this.accessToken);
} catch (error) {
console.error(error);
@ -41,6 +81,10 @@ export default class UserStore {
CookieService.getInstance().deleteCookie("leCoffreAccessToken");
CookieService.getInstance().deleteCookie("leCoffreRefreshToken");
// Clear instance variables
this.accessToken = null;
this.refreshToken = null;
this.event.emit("disconnection", this.accessToken);
} catch (error) {
console.error(error);

View File

@ -9,10 +9,46 @@ export default class UserStore {
protected readonly event = new EventEmitter();
public accessToken: string | null = null;
public refreshToken: string | null = null;
private initialized = false;
private constructor() {}
private constructor() {
// Don't initialize tokens during server-side rendering
if (typeof window !== 'undefined') {
this.initializeFromCookies();
}
}
private initializeFromCookies() {
if (this.initialized) return;
try {
const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken");
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
if (accessToken) {
this.accessToken = accessToken;
}
if (refreshToken) {
this.refreshToken = refreshToken;
}
this.initialized = true;
} catch (error) {
console.warn("Failed to initialize tokens from cookies:", error);
}
}
public isConnected(): boolean {
// Ensure initialization on client side
if (typeof window !== 'undefined' && !this.initialized) {
this.initializeFromCookies();
}
// Check both instance variable and cookie to ensure consistency
if (typeof window !== 'undefined') {
const cookieToken = CookieService.getInstance().getCookie("leCoffreAccessToken");
return !!(this.accessToken || cookieToken);
}
return !!this.accessToken;
}
@ -27,6 +63,10 @@ export default class UserStore {
CookieService.getInstance().setCookie("leCoffreAccessToken", accessToken);
CookieService.getInstance().setCookie("leCoffreRefreshToken", refreshToken);
// Update instance variables
this.accessToken = accessToken;
this.refreshToken = refreshToken;
this.event.emit("connection", this.accessToken);
} catch (error) {
console.error(error);
@ -41,6 +81,10 @@ export default class UserStore {
CookieService.getInstance().deleteCookie("leCoffreAccessToken");
CookieService.getInstance().deleteCookie("leCoffreRefreshToken");
// Clear instance variables
this.accessToken = null;
this.refreshToken = null;
this.event.emit("disconnection", this.accessToken);
} catch (error) {
console.error(error);