Landing page
This commit is contained in:
parent
5e4c33a168
commit
c014b95e62
3 changed files with 362 additions and 55 deletions
415
ui/src/App.tsx
415
ui/src/App.tsx
|
|
@ -1,64 +1,371 @@
|
|||
import { FieldError, Label } from "./ui-components/field";
|
||||
import { Heading, SubHeading } from "./ui-components/heading";
|
||||
import { Form } from "./ui-components/form";
|
||||
import { Text, Strong, TextLink } from "./ui-components/text";
|
||||
import { Button } from "./ui-components/button";
|
||||
import { Checkbox } from "./ui-components/checkbox";
|
||||
import { TextField, Input } from "./ui-components/field";
|
||||
import { ChevronRightIcon } from "./ui-components/icons";
|
||||
import { PasswordInput } from "./ui-components/password-input";
|
||||
import logo from "./assets/icon.jpg";
|
||||
import { useState, useEffect } from "react";
|
||||
import { Switch } from "./ui-components/switch";
|
||||
|
||||
type Theme = "dark" | "light" | "system";
|
||||
|
||||
export const App = () => {
|
||||
const [theme, setTheme] = useState<Theme>("system");
|
||||
|
||||
useEffect(() => {
|
||||
const root = window.document.documentElement;
|
||||
root.classList.remove("light", "dark");
|
||||
|
||||
if (theme === "system") {
|
||||
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
|
||||
.matches
|
||||
? "dark"
|
||||
: "light";
|
||||
root.classList.add(systemTheme);
|
||||
} else {
|
||||
root.classList.add(theme);
|
||||
}
|
||||
}, [theme]);
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="flex min-h-svh flex-col justify-center gap-6 px-2 py-4">
|
||||
<img className="mx-auto h-10 w-auto" src="./public/icon.jpg"></img>
|
||||
<div className="p-2 sm:p-4 sm:mx-auto sm:w-full sm:max-w-sm">
|
||||
<div>
|
||||
<Heading level={2} displayLevel={1} className="text-center">
|
||||
Sign in to your account
|
||||
</Heading>
|
||||
<SubHeading className="text-center">
|
||||
Welcome back! Please sign into continue
|
||||
</SubHeading>
|
||||
</div>
|
||||
<div className="min-h-screen bg-gradient-to-br from-emerald-100 via-green-100 to-white dark:bg-gradient-to-br dark:from-[#0a1f0a] dark:via-[#051505] dark:to-black">
|
||||
<div className="container mx-auto px-4 py-16">
|
||||
<nav className="flex items-center justify-between mb-16">
|
||||
<div className="flex items-center gap-2">
|
||||
<img src={logo} alt="Logo XTablo" className="w-8 h-8" />
|
||||
<h1 className="text-3xl font-bold text-slate-900 dark:text-white">
|
||||
XTablo
|
||||
</h1>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<Button
|
||||
variant="outline"
|
||||
className="text-slate-900 dark:text-white hover:text-slate-700 dark:hover:text-white/80 border-slate-300 dark:border-white/30 hover:border-slate-400 dark:hover:border-white/50 transition"
|
||||
>
|
||||
Connexion
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="text-slate-900 dark:text-white hover:text-slate-700 dark:hover:text-white/80 border-slate-300 dark:border-white/30 hover:border-slate-400 dark:hover:border-white/50 transition"
|
||||
>
|
||||
S'inscrire
|
||||
</Button>
|
||||
<Switch
|
||||
isSelected={theme === "dark"}
|
||||
onChange={() => setTheme(theme === "dark" ? "light" : "dark")}
|
||||
>
|
||||
Dark mode
|
||||
</Switch>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<Form className="mt-6 flex flex-col space-y-4">
|
||||
<TextField isRequired>
|
||||
<Label>Email address</Label>
|
||||
<Input type="email" />
|
||||
<FieldError></FieldError>
|
||||
</TextField>
|
||||
<main className="text-center">
|
||||
<h2 className="text-5xl font-bold text-slate-900 dark:text-white mb-6">
|
||||
Maîtrisez vos dépenses de chantier
|
||||
</h2>
|
||||
<p className="text-xl text-slate-700 dark:text-white mb-12 max-w-2xl mx-auto">
|
||||
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.
|
||||
</p>
|
||||
|
||||
<TextField isRequired>
|
||||
<div className="flex">
|
||||
<Label>Password</Label>
|
||||
<TextLink className="text-muted ms-auto mb-1 no-underline">
|
||||
Forgot password?
|
||||
</TextLink>
|
||||
</div>
|
||||
<PasswordInput />
|
||||
<FieldError></FieldError>
|
||||
</TextField>
|
||||
|
||||
<Checkbox>Remember me</Checkbox>
|
||||
|
||||
<Button type="submit">
|
||||
Continue <ChevronRightIcon />
|
||||
<Button
|
||||
className="inline-flex items-center gap-2 bg-blue-950 px-8 py-4 rounded-full
|
||||
text-white font-semibold hover:bg-blue-900 transition-colors
|
||||
shadow-lg hover:shadow-xl shadow-blue-950/20"
|
||||
>
|
||||
Démarrer gratuitement
|
||||
</Button>
|
||||
|
||||
<Button variant="outline">Sign in with Google</Button>
|
||||
</Form>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Text>
|
||||
Do you have account?{" "}
|
||||
<Strong>
|
||||
<TextLink>Register</TextLink>
|
||||
</Strong>
|
||||
</Text>
|
||||
<div className="mt-20">
|
||||
<div className="bg-white dark:bg-slate-800/50 backdrop-blur-lg rounded-2xl p-8 shadow-xl border border-emerald-200 dark:border-slate-700/50">
|
||||
<div className="aspect-video rounded-lg bg-emerald-100 dark:bg-slate-700/50 animate-pulse" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section className="mt-24">
|
||||
<h3 className="text-3xl font-bold text-slate-900 dark:text-white mb-12">
|
||||
Fait confiance par les entreprises du BTP
|
||||
</h3>
|
||||
<div className="flex overflow-x-hidden gap-12 pb-4 -mx-4 px-4 scrollbar-hide">
|
||||
<div className="flex-none w-[300px] bg-white dark:bg-slate-800/50 backdrop-blur-lg rounded-xl p-6 hover:bg-emerald-100/50 dark:hover:bg-slate-800/70 transition border border-emerald-200 dark:border-slate-700/50 flex flex-col animate-slide">
|
||||
<p className="text-slate-700 dark:text-white mb-4 flex-grow">
|
||||
"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."
|
||||
</p>
|
||||
<div className="flex items-center mt-auto">
|
||||
<div className="w-10 h-10 rounded-full bg-emerald-500/20 border border-emerald-500/30" />
|
||||
<div className="ml-3">
|
||||
<p className="text-slate-900 dark:text-white font-medium">
|
||||
Michel Dubois
|
||||
</p>
|
||||
<p className="text-slate-600 dark:text-white/80 text-sm">
|
||||
Chef de Projet
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex-none w-[300px] bg-white dark:bg-slate-800/50 backdrop-blur-lg rounded-xl p-6 hover:bg-emerald-100/50 dark:hover:bg-slate-800/70 transition border border-emerald-200 dark:border-slate-700/50 flex flex-col animate-slide">
|
||||
<p className="text-slate-700 dark:text-white mb-4 flex-grow">
|
||||
"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."
|
||||
</p>
|
||||
<div className="flex items-center mt-auto">
|
||||
<div className="w-10 h-10 rounded-full bg-emerald-500/20 border border-emerald-500/30" />
|
||||
<div className="ml-3">
|
||||
<p className="text-slate-900 dark:text-white font-medium">
|
||||
Sophie Martin
|
||||
</p>
|
||||
<p className="text-slate-600 dark:text-white/80 text-sm">
|
||||
Directrice Financière
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex-none w-[300px] bg-white dark:bg-slate-800/50 backdrop-blur-lg rounded-xl p-6 hover:bg-emerald-100/50 dark:hover:bg-slate-800/70 transition border border-emerald-200 dark:border-slate-700/50 flex flex-col animate-slide">
|
||||
<p className="text-slate-700 dark:text-white mb-4 flex-grow">
|
||||
"La gestion des dépenses sur plusieurs chantiers n'a jamais
|
||||
été aussi simple. XTablo nous donne une visibilité totale sur
|
||||
nos coûts."
|
||||
</p>
|
||||
<div className="flex items-center mt-auto">
|
||||
<div className="w-10 h-10 rounded-full bg-emerald-500/20 border border-emerald-500/30" />
|
||||
<div className="ml-3">
|
||||
<p className="text-slate-900 dark:text-white font-medium">
|
||||
David Laurent
|
||||
</p>
|
||||
<p className="text-slate-600 dark:text-white/80 text-sm">
|
||||
Chef de Chantier
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section className="mt-24">
|
||||
<h3 className="text-3xl font-bold text-slate-900 dark:text-white mb-12">
|
||||
Des tarifs adaptés à vos besoins
|
||||
</h3>
|
||||
<div className="grid md:grid-cols-2 gap-8 max-w-4xl mx-auto">
|
||||
<div className="bg-white dark:bg-slate-800/50 backdrop-blur-lg rounded-2xl p-8 border border-emerald-200 dark:border-white/30 hover:border-emerald-300 dark:hover:border-white/50 transition-all duration-300 hover:scale-[1.02] hover:shadow-2xl hover:shadow-emerald-200/20 dark:hover:shadow-emerald-900/20 flex flex-col">
|
||||
<h4 className="text-2xl font-bold text-slate-900 dark:text-white mb-4">
|
||||
Starter
|
||||
</h4>
|
||||
<div className="mb-6">
|
||||
<span className="text-4xl font-bold text-slate-900 dark:text-white">
|
||||
12€
|
||||
</span>
|
||||
<span className="text-slate-600 dark:text-white/80">
|
||||
/mois
|
||||
</span>
|
||||
</div>
|
||||
<ul className="space-y-4 mb-8 flex-grow">
|
||||
<li className="flex items-center text-slate-700 dark:text-white">
|
||||
<svg
|
||||
className="w-5 h-5 text-slate-700 dark:text-white mr-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
Jusqu'à 5 chantiers
|
||||
</li>
|
||||
<li className="flex items-center text-slate-700 dark:text-white">
|
||||
<svg
|
||||
className="w-5 h-5 text-slate-700 dark:text-white mr-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
Suivi des dépenses en temps réel
|
||||
</li>
|
||||
<li className="flex items-center text-slate-700 dark:text-white">
|
||||
<svg
|
||||
className="w-5 h-5 text-slate-700 dark:text-white mr-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
Rapports mensuels
|
||||
</li>
|
||||
<li className="flex items-center text-slate-700 dark:text-white">
|
||||
<svg
|
||||
className="w-5 h-5 text-slate-700 dark:text-white mr-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
Support par email
|
||||
</li>
|
||||
</ul>
|
||||
<button className="w-full px-6 py-3 bg-blue-950 rounded-full text-white font-semibold hover:bg-blue-900 transition-all duration-300 hover:scale-[1.02] hover:shadow-lg hover:shadow-xl shadow-blue-950/20 mt-auto">
|
||||
Commencer
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="bg-white dark:bg-slate-800/50 backdrop-blur-lg rounded-2xl p-8 border border-emerald-200 dark:border-white/50 relative flex flex-col transition-all duration-300 hover:scale-[1.02] hover:shadow-2xl hover:shadow-emerald-200/20 dark:hover:shadow-emerald-900/20">
|
||||
<div className="absolute -top-4 left-1/2 transform -translate-x-1/2 transition-all duration-300 group-hover:scale-110">
|
||||
<span className="bg-blue-950 text-white px-4 py-1 rounded-full text-sm font-semibold">
|
||||
Plus populaire
|
||||
</span>
|
||||
</div>
|
||||
<h4 className="text-2xl font-bold text-slate-900 dark:text-white mb-4">
|
||||
Pro
|
||||
</h4>
|
||||
<div className="mb-6">
|
||||
<span className="text-4xl font-bold text-slate-900 dark:text-white">
|
||||
25€
|
||||
</span>
|
||||
<span className="text-slate-600 dark:text-white/80">
|
||||
/mois
|
||||
</span>
|
||||
</div>
|
||||
<ul className="space-y-4 mb-8 flex-grow">
|
||||
<li className="flex items-center text-slate-700 dark:text-white">
|
||||
<svg
|
||||
className="w-5 h-5 text-slate-700 dark:text-white mr-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
Chantiers illimités
|
||||
</li>
|
||||
<li className="flex items-center text-slate-700 dark:text-white">
|
||||
<svg
|
||||
className="w-5 h-5 text-slate-700 dark:text-white mr-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
Suivi des dépenses en temps réel
|
||||
</li>
|
||||
<li className="flex items-center text-slate-700 dark:text-white">
|
||||
<svg
|
||||
className="w-5 h-5 text-slate-700 dark:text-white mr-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
Rapports personnalisés
|
||||
</li>
|
||||
<li className="flex items-center text-slate-700 dark:text-white">
|
||||
<svg
|
||||
className="w-5 h-5 text-slate-700 dark:text-white mr-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
Support prioritaire
|
||||
</li>
|
||||
<li className="flex items-center text-slate-700 dark:text-white">
|
||||
<svg
|
||||
className="w-5 h-5 text-slate-700 dark:text-white mr-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
API disponible
|
||||
</li>
|
||||
</ul>
|
||||
<button className="w-full px-6 py-3 bg-blue-950 rounded-full text-white font-semibold hover:bg-blue-900 transition-all duration-300 hover:scale-[1.02] hover:shadow-lg hover:shadow-xl shadow-blue-950/20 mt-auto">
|
||||
Commencer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section className="mt-24 text-center">
|
||||
<h3 className="text-3xl font-bold text-slate-900 dark:text-white mb-6">
|
||||
Prêt à optimiser vos dépenses de projet ?
|
||||
</h3>
|
||||
<p className="text-xl text-slate-700 dark:text-white mb-12 max-w-2xl mx-auto">
|
||||
Commencez votre essai gratuit de 14 jours aujourd'hui. Aucune
|
||||
carte bancaire requise.
|
||||
</p>
|
||||
<div className="flex justify-center gap-6">
|
||||
<button className="px-8 py-3 bg-blue-950 rounded-full text-white font-semibold hover:bg-blue-900 transition shadow-lg hover:shadow-xl shadow-blue-950/20">
|
||||
Essai gratuit
|
||||
</button>
|
||||
<button className="px-8 py-3 border border-blue-400/30 rounded-full text-slate-900 dark:text-white font-semibold hover:bg-blue-950/30 transition">
|
||||
Contacter les ventes
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
<style>
|
||||
{`
|
||||
@keyframes slide {
|
||||
0% { transform: translateX(-100vw); }
|
||||
100% { transform: translateX(100vw); }
|
||||
}
|
||||
.animate-slide {
|
||||
animation: slide 24s linear infinite;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
};
|
||||
|
|
|
|||
BIN
ui/src/assets/icon.jpg
Normal file
BIN
ui/src/assets/icon.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
|
|
@ -1,6 +1,6 @@
|
|||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import App from "./App.tsx";
|
||||
import { App } from "./App";
|
||||
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<StrictMode>
|
||||
|
|
|
|||
Loading…
Reference in a new issue