Landing page

This commit is contained in:
Arthur Belleville 2025-03-17 21:08:36 +01:00
parent 5e4c33a168
commit c014b95e62
No known key found for this signature in database
3 changed files with 362 additions and 55 deletions

View file

@ -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
é 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View file

@ -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>