diff --git a/ui/package.json b/ui/package.json index 1fce942..b635a46 100644 --- a/ui/package.json +++ b/ui/package.json @@ -43,6 +43,8 @@ "dependencies": { "@react-stately/calendar": "^3.7.1", "@tailwindcss/vite": "^4.0.14", + "@types/react-router-dom": "^5.3.3", + "react-router-dom": "^7.3.0", "react-stately": "^3.36.1" } } diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml index aab1cad..bb7cc4f 100644 --- a/ui/pnpm-lock.yaml +++ b/ui/pnpm-lock.yaml @@ -14,6 +14,12 @@ importers: '@tailwindcss/vite': specifier: ^4.0.14 version: 4.0.14(vite@6.2.2(jiti@2.4.2)(lightningcss@1.29.2)) + '@types/react-router-dom': + specifier: ^5.3.3 + version: 5.3.3 + react-router-dom: + specifier: ^7.3.0 + version: 7.3.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) react-stately: specifier: ^3.36.1 version: 3.36.1(react@19.0.0) @@ -1259,12 +1265,18 @@ packages: '@types/babel__traverse@7.20.6': resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} '@types/gensync@1.0.4': resolution: {integrity: sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA==} + '@types/history@4.7.11': + resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -1273,6 +1285,12 @@ packages: peerDependencies: '@types/react': ^19.0.0 + '@types/react-router-dom@5.3.3': + resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} + + '@types/react-router@5.1.20': + resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} + '@types/react@19.0.10': resolution: {integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==} @@ -1458,6 +1476,10 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie@1.0.2: + resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + engines: {node: '>=18'} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -1980,6 +2002,23 @@ packages: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} + react-router-dom@7.3.0: + resolution: {integrity: sha512-z7Q5FTiHGgQfEurX/FBinkOXhWREJIAB2RiU24lvcBa82PxUpwqvs/PAXb9lJyPjTs2jrl6UkLvCZVGJPeNuuQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + + react-router@7.3.0: + resolution: {integrity: sha512-466f2W7HIWaNXTKM5nHTqNxLrHTyXybm7R0eBlVSt0k/u55tTCDO194OIx/NrYD4TS5SXKTNekXfT37kMKUjgw==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true + react-stately@3.36.1: resolution: {integrity: sha512-H9kiGAylNec/iE5qk7qQLV1cvtSAIVq3mgt87zx2EA+f+/sYy2oBtchFPaDiBf/m7xMEKf0Fr9zSLU6G99xQ8g==} peerDependencies: @@ -2034,6 +2073,9 @@ packages: engines: {node: '>=10'} hasBin: true + set-cookie-parser@2.7.1: + resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2111,6 +2153,9 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + turbo-stream@2.4.0: + resolution: {integrity: sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -3750,16 +3795,31 @@ snapshots: dependencies: '@babel/types': 7.26.8 + '@types/cookie@0.6.0': {} + '@types/estree@1.0.6': {} '@types/gensync@1.0.4': {} + '@types/history@4.7.11': {} + '@types/json-schema@7.0.15': {} '@types/react-dom@19.0.4(@types/react@19.0.10)': dependencies: '@types/react': 19.0.10 + '@types/react-router-dom@5.3.3': + dependencies: + '@types/history': 4.7.11 + '@types/react': 19.0.10 + '@types/react-router': 5.1.20 + + '@types/react-router@5.1.20': + dependencies: + '@types/history': 4.7.11 + '@types/react': 19.0.10 + '@types/react@19.0.10': dependencies: csstype: 3.1.3 @@ -3969,6 +4029,8 @@ snapshots: convert-source-map@2.0.0: {} + cookie@1.0.2: {} + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -4478,6 +4540,22 @@ snapshots: react-refresh@0.14.2: {} + react-router-dom@7.3.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + dependencies: + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + react-router: 7.3.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + + react-router@7.3.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + dependencies: + '@types/cookie': 0.6.0 + cookie: 1.0.2 + react: 19.0.0 + set-cookie-parser: 2.7.1 + turbo-stream: 2.4.0 + optionalDependencies: + react-dom: 19.0.0(react@19.0.0) + react-stately@3.36.1(react@19.0.0): dependencies: '@react-stately/calendar': 3.7.1(react@19.0.0) @@ -4560,6 +4638,8 @@ snapshots: semver@7.7.1: {} + set-cookie-parser@2.7.1: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -4616,6 +4696,8 @@ snapshots: tslib@2.8.1: {} + turbo-stream@2.4.0: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 diff --git a/ui/src/App.tsx b/ui/src/App.tsx index bee3eef..4751792 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -2,6 +2,9 @@ import { Button } from "./ui-components/button"; import { useState, useEffect } from "react"; import { twMerge } from "tailwind-merge"; import { Header } from "./ui-components/header"; +import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; +import { LoginPage } from "./pages/login"; +import { SignUpPage } from "./pages/signup"; type Theme = "dark" | "light" | "system"; @@ -24,403 +27,419 @@ export const App = () => { }, [theme]); return ( -
-
-
-
-

- Maîtrisez vos dépenses de chantier -

-

- XTablo aide les entreprises du BTP à suivre, analyser et optimiser - leurs dépenses de projet. Obtenez des insights en temps réel sur vos - coûts et prenez de meilleures décisions financières. Mise en place - en moins de 48h. -

- - - -
-
-
-
-
- -
-

- Fait confiance par les entreprises du BTP -

-
-
-

- "XTablo a révolutionné notre gestion des dépenses. Nous - pouvons maintenant suivre chaque euro en temps réel et prendre - de meilleures décisions pour nos projets de construction." -

-
-
-
-

- Michel Dubois -

-

- Chef de Projet -

-
-
-
- -
-

- "Les fonctionnalités de suivi des dépenses sont exactement ce - dont nous avions besoin. Cela nous a permis de réduire nos - coûts de 15% et d'améliorer significativement nos marges." -

-
-
-
-

- Sophie Martin -

-

- Directrice Financière -

-
-
-
- -
-

- "La gestion des dépenses sur plusieurs chantiers n'a jamais - été aussi simple. XTablo nous donne une visibilité totale sur - nos coûts." -

-
-
-
-

- David Laurent -

-

- Chef de Chantier -

-
-
-
-
-
- -
-

- Des tarifs adaptés à vos besoins -

-
-
-

- Starter -

-
- - 12€ - - - /mois - -
-
    -
  • - - - - Jusqu'à 5 chantiers -
  • -
  • - - - - Suivi des dépenses en temps réel -
  • -
  • - - - - Rapports mensuels -
  • -
  • - - - - Support par email -
  • -
- -
- -
-
- - Plus populaire - -
-

- Pro -

-
- - 25€ - - - /mois - -
-
    -
  • - - - - Chantiers illimités -
  • -
  • - - - - Suivi des dépenses en temps réel -
  • -
  • - - - - Rapports personnalisés -
  • -
  • - - - - Support prioritaire -
  • -
  • - - - - API disponible -
  • -
- -
-
-
- -
-

- Prêt à optimiser vos dépenses de projet ? -

-

- Commencez votre essai gratuit de 14 jours aujourd'hui. Aucune - carte bancaire requise. -

-
- - -
-
-
-
-
+
-
-

- © {new Date().getFullYear()} XTablo. Tous droits réservés. -

-

- XTablo est une marque déposée. Les logos et noms de marques sont des - marques déposées de leurs propriétaires respectifs. -

-
-
- -
+ + +
+
+
+

+ Maîtrisez vos dépenses de chantier +

+

+ XTablo aide les entreprises du BTP à suivre, analyser et + optimiser leurs dépenses de projet. Obtenez des insights + en temps réel sur vos coûts et prenez de meilleures + décisions financières. Mise en place en moins de 48h. +

+ + + +
+
+
+
+
+ +
+

+ Fait confiance par les entreprises du BTP +

+
+
+

+ "XTablo a révolutionné notre gestion des dépenses. + Nous pouvons maintenant suivre chaque euro en temps + réel et prendre de meilleures décisions pour nos + projets de construction." +

+
+
+
+

+ Michel Dubois +

+

+ Chef de Projet +

+
+
+
+ +
+

+ "Les fonctionnalités de suivi des dépenses sont + exactement ce dont nous avions besoin. Cela nous a + permis de réduire nos coûts de 15% et d'améliorer + significativement nos marges." +

+
+
+
+

+ Sophie Martin +

+

+ Directrice Financière +

+
+
+
+ +
+

+ "La gestion des dépenses sur plusieurs chantiers n'a + jamais été aussi simple. XTablo nous donne une + visibilité totale sur nos coûts." +

+
+
+
+

+ David Laurent +

+

+ Chef de Chantier +

+
+
+
+
+
+ +
+

+ Des tarifs adaptés à vos besoins +

+
+
+

+ Starter +

+
+ + 12€ + + + /mois + +
+
    +
  • + + + + Jusqu'à 5 chantiers +
  • +
  • + + + + Suivi des dépenses en temps réel +
  • +
  • + + + + Rapports mensuels +
  • +
  • + + + + Support par email +
  • +
+ +
+ +
+
+ + Plus populaire + +
+

+ Pro +

+
+ + 25€ + + + /mois + +
+
    +
  • + + + + Chantiers illimités +
  • +
  • + + + + Suivi des dépenses en temps réel +
  • +
  • + + + + Rapports personnalisés +
  • +
  • + + + + Support prioritaire +
  • +
  • + + + + API disponible +
  • +
+ +
+
+
+ +
+

+ Prêt à optimiser vos dépenses de projet ? +

+

+ Commencez votre essai gratuit de 14 jours aujourd'hui. + Aucune carte bancaire requise. +

+
+ + +
+
+
+
+
+
+

+ © {new Date().getFullYear()} XTablo. Tous droits réservés. +

+

+ XTablo est une marque déposée. Les logos et noms de + marques sont des marques déposées de leurs propriétaires + respectifs. +

+
+
+ + } + /> + } /> + } /> + + + + ); }; diff --git a/ui/src/pages/login.tsx b/ui/src/pages/login.tsx new file mode 100644 index 0000000..96db704 --- /dev/null +++ b/ui/src/pages/login.tsx @@ -0,0 +1,157 @@ +import { Button } from "../ui-components/button"; +import { twMerge } from "tailwind-merge"; + +export function LoginPage() { + return ( +
+
+

+ Connexion +

+ +
+ + + + +
+
+
+
+
+ + Ou continuer avec + +
+
+ +
+
+ + +
+ +
+ + +
+ +
+
+ + +
+ + Mot de passe oublié ? + +
+ + +
+ +

+ Pas encore de compte ?{" "} + + S'inscrire + +

+
+
+
+ ); +} diff --git a/ui/src/pages/signup.tsx b/ui/src/pages/signup.tsx new file mode 100644 index 0000000..5d66699 --- /dev/null +++ b/ui/src/pages/signup.tsx @@ -0,0 +1,229 @@ +import { Button } from "../ui-components/button"; +import { twMerge } from "tailwind-merge"; + +export function SignUpPage() { + return ( +
+
+

+ Créer un compte +

+ +
+ + + + +
+
+
+
+
+ + Ou continuer avec + +
+
+ +
+
+
+ + +
+
+ + +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+ +

+ Déjà un compte ?{" "} + + Se connecter + +

+
+
+
+ ); +} diff --git a/ui/src/ui-components/header.tsx b/ui/src/ui-components/header.tsx index c83f0b5..c8ffb6c 100644 --- a/ui/src/ui-components/header.tsx +++ b/ui/src/ui-components/header.tsx @@ -5,6 +5,7 @@ import logo from "../assets/icon.jpg"; import { useState } from "react"; import { ConnectionForm } from "./connection-form"; import { SignUpForm } from "./signup-form"; +import { Link, useNavigate } from "react-router-dom"; interface HeaderProps { theme: "dark" | "light" | "system"; @@ -14,24 +15,25 @@ interface HeaderProps { export function Header({ theme, onThemeChange }: HeaderProps) { const [showConnectionForm, setShowConnectionForm] = useState(false); const [showSignUpForm, setShowSignUpForm] = useState(false); + const navigate = useNavigate(); return ( <> -
+