First commit
This commit is contained in:
13
src/app/globals.css
Normal file
13
src/app/globals.css
Normal file
@@ -0,0 +1,13 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
|
||||
|
||||
@layer base {
|
||||
html,
|
||||
body {
|
||||
@apply dark:bg-trueGray-900;
|
||||
}
|
||||
}
|
||||
|
||||
88
src/app/layout.tsx
Normal file
88
src/app/layout.tsx
Normal file
@@ -0,0 +1,88 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Inter } from "next/font/google";
|
||||
import { ThemeProvider } from "next-themes";
|
||||
import "./globals.css";
|
||||
|
||||
import { Navbar } from "@/components/Navbar";
|
||||
import { Footer } from "@/components/Footer";
|
||||
import { PopupWidget } from "@/components/PopupWidget";
|
||||
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Retake | Achat et revente de matériel informatique pour les professionnels",
|
||||
description: "Découvrez Retake: rachat et revalorisation de matériel informatique pour les professionnels. Recyclez et valorisez vos équipements !",
|
||||
publisher: "Retake",
|
||||
keywords: [
|
||||
"seconde vie",
|
||||
"revente matériel informatique",
|
||||
"recyclage informatique",
|
||||
"revalorisation informatique",
|
||||
"Retake",
|
||||
"équipement informatique écoresponsable",
|
||||
],
|
||||
alternates: {
|
||||
canonical: "https://retake.fr",
|
||||
},
|
||||
robots: {
|
||||
index: true,
|
||||
follow: true,
|
||||
googleBot: {
|
||||
notranslate: true,
|
||||
"max-snippet": -1,
|
||||
"max-image-preview": "large",
|
||||
"max-video-preview": -1,
|
||||
},
|
||||
},
|
||||
openGraph: {
|
||||
title: "Retake | Achat et Revente de Matériel Informatique",
|
||||
description: "Achetez, revendez et valorisez du matériel informatique chez Retake. Un service destiné aux pros, particuliers et associations pour des solutions écoresponsables.",
|
||||
url: "https://retake.fr",
|
||||
siteName: "Retake",
|
||||
images: [
|
||||
{
|
||||
url: "https://retake.fr/img/logo.png",
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: "Retake - Achat et revente de matériel informatique",
|
||||
},
|
||||
],
|
||||
locale: "fr_FR",
|
||||
type: "website",
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image", // Optimisé pour les aperçus Twitter
|
||||
title: "Retake | Achat et Revente de Matériel Informatique",
|
||||
description: "Revalorisez et recyclez votre matériel informatique chez Retake, le service pour les pros.",
|
||||
images: ["https://retake.fr/img/logo.png"],
|
||||
},
|
||||
icons: {
|
||||
icon: "/favicon.ico",
|
||||
apple: "/apple-touch-icon.png",
|
||||
},
|
||||
manifest: "/site.webmanifest",
|
||||
};
|
||||
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="fr" suppressHydrationWarning>
|
||||
<head>
|
||||
<script defer src="https://analytics.retake.fr/script.js" data-website-id="2cabddab-19cf-4987-8d2a-b573ec9fc714"></script>
|
||||
</head>
|
||||
<body className={inter.className}>
|
||||
<ThemeProvider attribute="class">
|
||||
<Navbar />
|
||||
<div>{children}</div>
|
||||
<Footer />
|
||||
<PopupWidget />
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
30
src/app/page.tsx
Normal file
30
src/app/page.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import { Container } from "@/components/Container";
|
||||
import { Hero } from "@/components/Hero";
|
||||
import { SectionTitle } from "@/components/SectionTitle";
|
||||
import { Benefits } from "@/components/Benefits";
|
||||
|
||||
import { Faq } from "@/components/Faq";
|
||||
|
||||
import { benefitOne, benefitTwo } from "@/components/data";
|
||||
export default function Home() {
|
||||
return (
|
||||
<Container>
|
||||
<Hero />
|
||||
<SectionTitle
|
||||
title="Pourquoi choisir Retake ?"
|
||||
>
|
||||
Chez Retake, nous cherchons à donner une seconde vie à votre matériel informatique en suivant une démarche transparente, sans prise de tête et tournée vers un impact durable,
|
||||
bénéfique pour tous : vous, les particuliers, les associations et la planète.
|
||||
</SectionTitle>
|
||||
|
||||
<Benefits data={benefitOne} />
|
||||
<Benefits imgPos="right" data={benefitTwo} />
|
||||
|
||||
<SectionTitle preTitle="FAQ" title="Foire aux questions">
|
||||
Parce qu'on se pose tous des questions !
|
||||
</SectionTitle>
|
||||
|
||||
<Faq />
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
52
src/app/produits/page.tsx
Normal file
52
src/app/produits/page.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import { Container } from "@/components/Container";
|
||||
|
||||
const articles = [
|
||||
{
|
||||
imageUrl: "https://img.leboncoin.fr/api/v1/lbcpb1/images/02/60/84/026084690ccdb649efa30f07c2228736a8e6f5a7.jpg?rule=classified-1200x800-webp",
|
||||
title: "Serveur Workstation HP Z440",
|
||||
description: "Serveur / Workstation / Ordinateur de CAO",
|
||||
url: "https://www.leboncoin.fr/ad/ordinateurs/2851218069",
|
||||
},
|
||||
{
|
||||
imageUrl: "https://img.leboncoin.fr/api/v1/lbcpb1/images/de/4e/73/de4e73c704bb22a74493b93bd6d07e4a522ab3ae.jpg?rule=classified-1200x800-webp",
|
||||
title: "Mini ordinateur Lenovo tiny m72e",
|
||||
description: "Mini PC Lenovo tiny ThinkCenter m72e",
|
||||
url: "https://www.leboncoin.fr/ad/ordinateurs/2859959432",
|
||||
},
|
||||
{
|
||||
imageUrl: "https://img.leboncoin.fr/api/v1/lbcpb1/images/78/dc/ce/78dcce7f5f4c98298a4446af25bc2b4358ecac5f.jpg?rule=classified-1200x800-webp",
|
||||
title: "Imprimante HP LaserJet Pro 400 m401dn",
|
||||
description: "Imprimante Laser HP m401dn",
|
||||
url: "https://www.leboncoin.fr/ad/accessoires_informatique/2889667257",
|
||||
},
|
||||
];
|
||||
|
||||
export default function ArticlesPage() {
|
||||
return (
|
||||
<Container>
|
||||
<div className="py-12">
|
||||
<h1 className="text-3xl font-bold text-center mb-8">Nos Articles</h1>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{articles.map((article, index) => (
|
||||
<div key={index} className="bg-white p-6 rounded-lg shadow-lg dark:bg-trueGray-800">
|
||||
<img
|
||||
src={article.imageUrl}
|
||||
alt={article.title}
|
||||
className="w-full h-48 object-cover rounded-t-lg mb-4"
|
||||
/>
|
||||
<h2 className="text-xl font-semibold text-gray-800 mb-2 dark:text-white">{article.title}</h2>
|
||||
<p className="text-gray-600 mb-4 dark:text-grey-200">{article.description}</p>
|
||||
<a
|
||||
href={article.url}
|
||||
className="text-[#7ed957] hover:text-indigo-500"
|
||||
>
|
||||
Voir l'article
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
4
src/app/robots.txt
Normal file
4
src/app/robots.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
User-Agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://retake.fr/sitemap.xml
|
||||
12
src/app/sitemap.ts
Normal file
12
src/app/sitemap.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { MetadataRoute } from 'next'
|
||||
|
||||
export default function sitemap(): MetadataRoute.Sitemap {
|
||||
return [
|
||||
{
|
||||
url: 'https://acme.com',
|
||||
lastModified: new Date(),
|
||||
changeFrequency: 'monthly',
|
||||
priority: 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
86
src/components/Benefits.tsx
Normal file
86
src/components/Benefits.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
import Image from "next/image";
|
||||
import React from "react";
|
||||
import { Container } from "@/components/Container";
|
||||
|
||||
interface BenefitsProps {
|
||||
imgPos?: "left" | "right";
|
||||
data: {
|
||||
imgPos?: "left" | "right";
|
||||
title: string;
|
||||
desc: string;
|
||||
image: any;
|
||||
bullets: {
|
||||
title: string;
|
||||
desc: string;
|
||||
icon: React.ReactNode;
|
||||
}[];
|
||||
};
|
||||
}
|
||||
export const Benefits = (props: Readonly<BenefitsProps>) => {
|
||||
const { data } = props;
|
||||
return (
|
||||
<Container className="flex flex-wrap mb-20 lg:gap-10 lg:flex-nowrap ">
|
||||
<div
|
||||
className={`flex items-center justify-center w-full lg:w-1/2 ${
|
||||
props.imgPos === "right" ? "lg:order-1" : ""
|
||||
}`}>
|
||||
<div>
|
||||
<Image
|
||||
src={data.image}
|
||||
width={521}
|
||||
height={521}
|
||||
alt="Benefits"
|
||||
className={"object-cover"}
|
||||
placeholder="blur"
|
||||
blurDataURL={data.image.src}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`flex flex-wrap items-center w-full lg:w-1/2 ${
|
||||
data.imgPos === "right" ? "lg:justify-end" : ""
|
||||
}`}>
|
||||
<div>
|
||||
<div className="flex flex-col w-full mt-4">
|
||||
<h3 className="max-w-2xl mt-3 text-3xl font-bold leading-snug tracking-tight text-gray-800 lg:leading-tight lg:text-4xl dark:text-white">
|
||||
{data.title}
|
||||
</h3>
|
||||
|
||||
<p className="max-w-2xl py-4 text-lg leading-normal text-gray-500 lg:text-xl xl:text-xl dark:text-gray-300">
|
||||
{data.desc}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="w-full mt-5">
|
||||
{data.bullets.map((item, index) => (
|
||||
<Benefit key={index} title={item.title} icon={item.icon}>
|
||||
{item.desc}
|
||||
</Benefit>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
function Benefit(props: any) {
|
||||
return (
|
||||
<div className="flex items-start mt-8 space-x-3">
|
||||
<div className="flex items-center justify-center flex-shrink-0 mt-1 bg-[#7ed957] rounded-md w-11 h-11 ">
|
||||
{React.cloneElement(props.icon, {
|
||||
className: "w-7 h-7 text-indigo-50",
|
||||
})}
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-xl font-medium text-gray-800 dark:text-gray-200">
|
||||
{props.title}
|
||||
</h4>
|
||||
<p className="mt-1 text-gray-500 dark:text-gray-400">
|
||||
{props.children}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
18
src/components/Container.tsx
Normal file
18
src/components/Container.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
|
||||
interface ContainerProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function Container(props: Readonly<ContainerProps>) {
|
||||
return (
|
||||
<div
|
||||
className={`container p-8 mx-auto xl:px-0 ${
|
||||
props.className ? props.className : ""
|
||||
}`}>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
54
src/components/DarkSwitch.tsx
Normal file
54
src/components/DarkSwitch.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
"use client";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
const ThemeChanger = () => {
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const { theme, setTheme } = useTheme();
|
||||
|
||||
// When mounted on client, now we can show the UI
|
||||
useEffect(() => setMounted(true), []);
|
||||
|
||||
if (!mounted) return null;
|
||||
|
||||
return (
|
||||
<div className="flex items-center order-last ">
|
||||
{theme === "dark" ? (
|
||||
<button
|
||||
onClick={() => setTheme("light")}
|
||||
className="text-gray-300 rounded-full outline-none focus:outline-none ">
|
||||
<span className="sr-only">Light Mode</span>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="w-5 h-5"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor">
|
||||
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" />
|
||||
</svg>
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
onClick={() => setTheme("dark")}
|
||||
className="text-gray-500 rounded-full outline-none focus:outline-none focus-visible:ring focus-visible:ring-gray-100 focus:ring-opacity-20">
|
||||
<span className="sr-only">Dark Mode</span>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round">
|
||||
<circle cx="12" cy="12" r="5" />
|
||||
<path d="M12 1v2M12 21v2M4.2 4.2l1.4 1.4M18.4 18.4l1.4 1.4M1 12h2M21 12h2M4.2 19.8l1.4-1.4M18.4 5.6l1.4-1.4" />
|
||||
</svg>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemeChanger;
|
||||
107
src/components/DisclosureClient.tsx
Normal file
107
src/components/DisclosureClient.tsx
Normal file
@@ -0,0 +1,107 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Disclosure,
|
||||
DisclosurePanel,
|
||||
DisclosureButton,
|
||||
} from "@headlessui/react";
|
||||
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
|
||||
interface LinkProps {
|
||||
text: string;
|
||||
href: string;
|
||||
external: boolean;
|
||||
}
|
||||
|
||||
interface DisclosureClientProps {
|
||||
topnav: {
|
||||
logoLink: {
|
||||
text: string;
|
||||
href: string;
|
||||
image: {
|
||||
url: string;
|
||||
alternativeText: string | null;
|
||||
name: string;
|
||||
};
|
||||
};
|
||||
link: LinkProps[];
|
||||
cta: LinkProps;
|
||||
};
|
||||
}
|
||||
|
||||
export function DisclosureClient(props: Readonly<DisclosureClientProps>) {
|
||||
const navigation = props.topnav.link;
|
||||
const logo = props.topnav.logoLink;
|
||||
const cta = props.topnav.cta;
|
||||
|
||||
return (
|
||||
<Disclosure>
|
||||
{({ open }) => (
|
||||
<div className="flex flex-wrap items-center justify-between w-full lg:w-auto">
|
||||
<Link href={logo.href || "/"}>
|
||||
<span className="flex items-center space-x-2 text-2xl font-medium text-indigo-500 dark:text-gray-100">
|
||||
<span>
|
||||
<Image
|
||||
src={logo.image.url}
|
||||
alt={logo.image.alternativeText || logo.image.name}
|
||||
width={32}
|
||||
height={32}
|
||||
className="w-8"
|
||||
/>
|
||||
</span>
|
||||
<span>{logo.text}</span>
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
<DisclosureButton
|
||||
aria-label="Toggle Menu"
|
||||
className="px-2 py-1 ml-auto text-gray-500 rounded-md lg:hidden hover:text-indigo-500 focus:text-indigo-500 focus:bg-indigo-100 focus:outline-none dark:text-gray-300 dark:focus:bg-trueGray-700"
|
||||
>
|
||||
<svg
|
||||
className="w-6 h-6 fill-current"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
{open && (
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M18.278 16.864a1 1 0 0 1-1.414 1.414l-4.829-4.828-4.828 4.828a1 1 0 0 1-1.414-1.414l4.828-4.829-4.828-4.828a1 1 0 0 1 1.414-1.414l4.829 4.828 4.828-4.828a1 1 0 1 1 1.414 1.414l-4.828 4.829 4.828 4.828z"
|
||||
/>
|
||||
)}
|
||||
{!open && (
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M4 5h16a1 1 0 0 1 0 2H4a1 1 0 1 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2z"
|
||||
/>
|
||||
)}
|
||||
</svg>
|
||||
</DisclosureButton>
|
||||
|
||||
<DisclosurePanel className="flex flex-wrap w-full my-5 lg:hidden">
|
||||
<>
|
||||
{navigation.map((item, index) => (
|
||||
<Link
|
||||
key={index}
|
||||
href={item.href}
|
||||
className="w-full px-4 py-2 -ml-4 text-gray-500 rounded-md dark:text-gray-300 hover:text-indigo-500 focus:text-indigo-500 focus:bg-indigo-100 dark:focus:bg-gray-800 focus:outline-none"
|
||||
>
|
||||
{item.text}
|
||||
</Link>
|
||||
))}
|
||||
<Link
|
||||
href={cta.href}
|
||||
target={cta.external ? "_blank" : "_self"}
|
||||
className="w-full px-6 py-2 mt-3 text-center text-white bg-[#7ed957] rounded-md lg:ml-5"
|
||||
>
|
||||
{cta.text}
|
||||
</Link>
|
||||
</>
|
||||
</DisclosurePanel>
|
||||
</div>
|
||||
)}
|
||||
</Disclosure>
|
||||
);
|
||||
}
|
||||
56
src/components/Faq.tsx
Normal file
56
src/components/Faq.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import { Container } from "@/components/Container";
|
||||
import { Disclosure, DisclosureButton, DisclosurePanel } from "@headlessui/react";
|
||||
import { ChevronUpIcon } from "@heroicons/react/24/solid";
|
||||
|
||||
export const Faq = () => {
|
||||
return (
|
||||
<Container className="!p-0">
|
||||
<div className="w-full max-w-2xl p-2 mx-auto rounded-2xl">
|
||||
{faqdata.map((item, index) => (
|
||||
<div key={item.question} className="mb-5">
|
||||
<Disclosure>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<DisclosureButton className="flex items-center justify-between w-full px-4 py-4 text-lg text-left text-gray-800 rounded-lg bg-gray-50 hover:bg-gray-100 focus:outline-none focus-visible:ring focus-visible:ring-indigo-100 focus-visible:ring-opacity-75 dark:bg-trueGray-800 dark:text-gray-200">
|
||||
<span>{item.question}</span>
|
||||
<ChevronUpIcon
|
||||
className={`${
|
||||
open ? "transform rotate-180" : ""
|
||||
} w-5 h-5 text-[#7ed957]`}
|
||||
/>
|
||||
</DisclosureButton>
|
||||
<DisclosurePanel className="px-4 pt-4 pb-2 text-gray-500 dark:text-gray-300">
|
||||
{item.answer}
|
||||
</DisclosurePanel>
|
||||
</>
|
||||
)}
|
||||
</Disclosure>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
const faqdata = [
|
||||
{
|
||||
question: "Depuis combien de temps Retake existe ?",
|
||||
answer: "Retake existe depuis le début de l'année 2024 !",
|
||||
},
|
||||
{
|
||||
question: "Quels types de matériel informatique acceptez-vous ?",
|
||||
answer: "Nous rachetons une large gamme d’équipements, incluant ordinateurs, serveurs, périphériques et autres matériels IT décommissionnés.",
|
||||
},
|
||||
{
|
||||
question: "Nos données sont-elles protégées ?",
|
||||
answer:
|
||||
"Oui ! Retake s'engage à effacer vos données en suivant les recommandations de l'ANSII et vous envoie les rapports d'effacement sur demande.",
|
||||
},
|
||||
{
|
||||
question: "Que se passe-t-il si mon matériel est trop vieux ou irréparable ?",
|
||||
answer:
|
||||
"Si un équipement ne peut pas être revalorisé, nous nous assurons qu’il soit recyclé dans des centres agréés, conformément aux réglementations en vigueur.",
|
||||
},
|
||||
];
|
||||
240
src/components/Footer.tsx
Normal file
240
src/components/Footer.tsx
Normal file
@@ -0,0 +1,240 @@
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import React from "react";
|
||||
import { Container } from "@/components/Container";
|
||||
import retakeLogo from "../../public/img/logo.png";
|
||||
|
||||
export function Footer() {
|
||||
const navigation = [
|
||||
{ name: "Produits", href: "/produits" },
|
||||
// { name: "Features", href: "/features" },
|
||||
// { name: "Pricing", href: "/pricing" },
|
||||
// { name: "Company", href: "/company" },
|
||||
// { name: "Blog", href: "/blog" },
|
||||
];
|
||||
|
||||
const legal = [
|
||||
{ name: "Mentions Légales", href: "https://s3.retake.fr/public/mentions_legales.pdf"},
|
||||
{ name: "CGV", href: "https://s3.retake.fr/public/cgv.pdf"}
|
||||
// { name: "Terms", href: "/terms" },
|
||||
// { name: "Privacy", href: "/privacy" },
|
||||
// { name: "Legal", href: "/legal" },
|
||||
];
|
||||
return (
|
||||
<div id="footer" className="relative">
|
||||
<Container>
|
||||
<div className="grid max-w-screen-xl grid-cols-1 gap-10 pt-10 mx-auto mt-5 border-t border-gray-100 dark:border-trueGray-700 lg:grid-cols-5">
|
||||
<div className="lg:col-span-2">
|
||||
<div>
|
||||
{" "}
|
||||
<Link
|
||||
href="/"
|
||||
className="flex items-center space-x-2 text-2xl font-medium text-indigo-500 dark:text-gray-100"
|
||||
>
|
||||
<Image
|
||||
src={retakeLogo}
|
||||
alt="N"
|
||||
width="128"
|
||||
height="128"
|
||||
className="w-24"
|
||||
/>
|
||||
{/* <span>Retake</span> */}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* <div className="max-w-md mt-4 text-gray-500 dark:text-gray-400">
|
||||
Nextly is a free landing page & marketing website template for
|
||||
startups and indie projects. Its built with Next.js & TailwindCSS.
|
||||
And its completely open-source.
|
||||
</div> */}
|
||||
|
||||
{/* <div className="mt-5">
|
||||
<a
|
||||
href="https://vercel.com/?utm_source=web3templates&utm_campaign=oss"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
className="relative block w-44"
|
||||
>
|
||||
<Image
|
||||
src="/img/vercel.svg"
|
||||
alt="Powered by Vercel"
|
||||
width="212"
|
||||
height="44"
|
||||
/>
|
||||
</a>
|
||||
</div> */}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="flex flex-wrap w-full -mt-2 -ml-3 lg:ml-0">
|
||||
{navigation.map((item, index) => (
|
||||
<Link
|
||||
key={index}
|
||||
href={item.href}
|
||||
className="w-full px-4 py-2 text-gray-500 rounded-md dark:text-gray-300 hover:text-indigo-500 focus:text-indigo-500 focus:bg-indigo-100 focus:outline-none dark:focus:bg-trueGray-700"
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="flex flex-wrap w-full -mt-2 -ml-3 lg:ml-0">
|
||||
{legal.map((item, index) => (
|
||||
<Link
|
||||
key={index}
|
||||
href={item.href}
|
||||
className="w-full px-4 py-2 text-gray-500 rounded-md dark:text-gray-300 hover:text-indigo-500 focus:text-indigo-500 focus:bg-indigo-100 focus:outline-none dark:focus:bg-trueGray-700"
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="">
|
||||
<div>Suivez-Nous</div>
|
||||
<div className="flex mt-5 space-x-5 text-gray-400 dark:text-gray-500">
|
||||
{/* <a
|
||||
href="https://twitter.com/web3templates"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<span className="sr-only">Twitter</span>
|
||||
<Twitter />
|
||||
</a>
|
||||
<a
|
||||
href="https://facebook.com/web3templates"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<span className="sr-only">Facebook</span>
|
||||
<Facebook />
|
||||
</a>
|
||||
<a
|
||||
href="https://instagram.com/web3templates"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<span className="sr-only">Instagram</span>
|
||||
<Instagram />
|
||||
</a> */}
|
||||
<a href="https://www.linkedin.com/company/retake-léo-nonnenmacher" target="_blank" rel="noopener">
|
||||
<span className="sr-only">Linkedin</span>
|
||||
<Linkedin />
|
||||
</a>
|
||||
<a href="https://github.com/Retake-IT" target="_blank" rel="noopener">
|
||||
<span className="sr-only">Github</span>
|
||||
<Github />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="my-10 text-sm text-center text-gray-600 dark:text-gray-400">
|
||||
Copyright © {new Date().getFullYear()}. Fait avec ♥ par{" "}
|
||||
<a href="https://retake.fr" target="_blank" rel="noopener">
|
||||
Retake.
|
||||
</a>{" "}
|
||||
Illustrations par{" "}
|
||||
<a href="https://www.vecteezy.com/" target="_blank" rel="noopener ">
|
||||
Vecteezy
|
||||
</a>
|
||||
<span> & </span>
|
||||
<a href="https://www.anyrgb.com/" target="_blank" rel="noopener ">
|
||||
Angrybg
|
||||
</a>
|
||||
</div>
|
||||
</Container>
|
||||
{/* Do not remove this */}
|
||||
<Backlink />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// const Twitter = ({ size = 24 }) => (
|
||||
// <svg
|
||||
// xmlns="http://www.w3.org/2000/svg"
|
||||
// width={size}
|
||||
// height={size}
|
||||
// viewBox="0 0 24 24"
|
||||
// fill="currentColor"
|
||||
// >
|
||||
// <path d="M24 4.37a9.6 9.6 0 0 1-2.83.8 5.04 5.04 0 0 0 2.17-2.8c-.95.58-2 1-3.13 1.22A4.86 4.86 0 0 0 16.61 2a4.99 4.99 0 0 0-4.79 6.2A13.87 13.87 0 0 1 1.67 2.92 5.12 5.12 0 0 0 3.2 9.67a4.82 4.82 0 0 1-2.23-.64v.07c0 2.44 1.7 4.48 3.95 4.95a4.84 4.84 0 0 1-2.22.08c.63 2.01 2.45 3.47 4.6 3.51A9.72 9.72 0 0 1 0 19.74 13.68 13.68 0 0 0 7.55 22c9.06 0 14-7.7 14-14.37v-.65c.96-.71 1.79-1.6 2.45-2.61z" />
|
||||
// </svg>
|
||||
// );
|
||||
|
||||
// const Facebook = ({ size = 24 }) => (
|
||||
// <svg
|
||||
// xmlns="http://www.w3.org/2000/svg"
|
||||
// width={size}
|
||||
// height={size}
|
||||
// viewBox="0 0 24 24"
|
||||
// fill="currentColor"
|
||||
// >
|
||||
// <path d="M24 12.07C24 5.41 18.63 0 12 0S0 5.4 0 12.07C0 18.1 4.39 23.1 10.13 24v-8.44H7.08v-3.49h3.04V9.41c0-3.02 1.8-4.7 4.54-4.7 1.31 0 2.68.24 2.68.24v2.97h-1.5c-1.5 0-1.96.93-1.96 1.89v2.26h3.32l-.53 3.5h-2.8V24C19.62 23.1 24 18.1 24 12.07" />
|
||||
// </svg>
|
||||
// );
|
||||
// const Instagram = ({ size = 24 }) => (
|
||||
// <svg
|
||||
// xmlns="http://www.w3.org/2000/svg"
|
||||
// width={size}
|
||||
// height={size}
|
||||
// viewBox="0 0 24 24"
|
||||
// fill="currentColor"
|
||||
// >
|
||||
// <path d="M16.98 0a6.9 6.9 0 0 1 5.08 1.98A6.94 6.94 0 0 1 24 7.02v9.96c0 2.08-.68 3.87-1.98 5.13A7.14 7.14 0 0 1 16.94 24H7.06a7.06 7.06 0 0 1-5.03-1.89A6.96 6.96 0 0 1 0 16.94V7.02C0 2.8 2.8 0 7.02 0h9.96zm.05 2.23H7.06c-1.45 0-2.7.43-3.53 1.25a4.82 4.82 0 0 0-1.3 3.54v9.92c0 1.5.43 2.7 1.3 3.58a5 5 0 0 0 3.53 1.25h9.88a5 5 0 0 0 3.53-1.25 4.73 4.73 0 0 0 1.4-3.54V7.02a5 5 0 0 0-1.3-3.49 4.82 4.82 0 0 0-3.54-1.3zM12 5.76c3.39 0 6.2 2.8 6.2 6.2a6.2 6.2 0 0 1-12.4 0 6.2 6.2 0 0 1 6.2-6.2zm0 2.22a3.99 3.99 0 0 0-3.97 3.97A3.99 3.99 0 0 0 12 15.92a3.99 3.99 0 0 0 3.97-3.97A3.99 3.99 0 0 0 12 7.98zm6.44-3.77a1.4 1.4 0 1 1 0 2.8 1.4 1.4 0 0 1 0-2.8z" />
|
||||
// </svg>
|
||||
// );
|
||||
|
||||
const Linkedin = ({ size = 24 }) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path d="M22.23 0H1.77C.8 0 0 .77 0 1.72v20.56C0 23.23.8 24 1.77 24h20.46c.98 0 1.77-.77 1.77-1.72V1.72C24 .77 23.2 0 22.23 0zM7.27 20.1H3.65V9.24h3.62V20.1zM5.47 7.76h-.03c-1.22 0-2-.83-2-1.87 0-1.06.8-1.87 2.05-1.87 1.24 0 2 .8 2.02 1.87 0 1.04-.78 1.87-2.05 1.87zM20.34 20.1h-3.63v-5.8c0-1.45-.52-2.45-1.83-2.45-1 0-1.6.67-1.87 1.32-.1.23-.11.55-.11.88v6.05H9.28s.05-9.82 0-10.84h3.63v1.54a3.6 3.6 0 0 1 3.26-1.8c2.39 0 4.18 1.56 4.18 4.89v6.21z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
const Github = ({ size = 24 }) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
const Backlink = () => {
|
||||
return (
|
||||
<a
|
||||
href="https://web3templates.com"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
className="absolute flex px-3 py-1 space-x-2 text-sm font-semibold text-gray-900 bg-white border border-gray-300 rounded shadow-sm place-items-center left-5 bottom-5 dark:bg-trueGray-900 dark:border-trueGray-700 dark:text-trueGray-300"
|
||||
>
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 30 30"
|
||||
fill="none"
|
||||
className="w-4 h-4"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect width="30" height="29.5385" rx="2.76923" fill="#362F78" />
|
||||
<path
|
||||
d="M10.14 21.94H12.24L15.44 12.18L18.64 21.94H20.74L24.88 8H22.64L19.58 18.68L16.36 8.78H14.52L11.32 18.68L8.24 8H6L10.14 21.94Z"
|
||||
fill="#F7FAFC"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<span>Web3Templates</span>
|
||||
</a>
|
||||
);
|
||||
};
|
||||
61
src/components/Hero.tsx
Normal file
61
src/components/Hero.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { Container } from "@/components/Container";
|
||||
import heroImg from "../../public/img/nature.png";
|
||||
import usocomeLogo from "../../public/img/usocome-logo.png";
|
||||
|
||||
export const Hero = () => {
|
||||
return (
|
||||
<>
|
||||
<Container className="flex flex-wrap ">
|
||||
<div className="flex items-center w-full lg:w-1/2">
|
||||
<div className="max-w-2xl mb-8">
|
||||
<h1 className="text-4xl font-bold leading-snug tracking-tight text-gray-800 lg:text-4xl lg:leading-tight xl:text-6xl xl:leading-tight dark:text-white">
|
||||
Bienvenue chez Retake
|
||||
</h1>
|
||||
<p className="py-5 text-xl leading-normal text-gray-500 lg:text-xl xl:text-2xl dark:text-gray-300">
|
||||
Nous simplifions la gestion de votre matériel informatique décommissionné, tout en offrant des solutions abordables pour les particuliers et les associations.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col items-start space-y-3 sm:space-x-4 sm:space-y-0 sm:items-center sm:flex-row">
|
||||
<a
|
||||
href="#benefits"
|
||||
rel="noopener"
|
||||
className="px-8 py-4 text-lg font-medium text-center text-white bg-[#7ed957] rounded-md ">
|
||||
En savoir plus
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-center w-full lg:w-1/2">
|
||||
<div className="">
|
||||
<Image
|
||||
src={heroImg}
|
||||
width="616"
|
||||
height="617"
|
||||
className={"object-cover"}
|
||||
alt="Hero Illustration"
|
||||
loading="eager"
|
||||
placeholder="blur"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
<Container>
|
||||
<div className="flex flex-col justify-center">
|
||||
<div className="text-xl text-center text-gray-700 dark:text-white">
|
||||
<h2 className=" font-bold leading-snug tracking-tight text-gray-800 lg:leading-tight lg:text-4xl dark:text-white">Ils nous font confiance</h2>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap justify-center gap-5 mt-10 md:justify-around">
|
||||
<div className="pt-2 text-gray-400 dark:text-gray-400">
|
||||
<Link href={"https://www.usocome.com/"}>
|
||||
<Image className="object-contain h-48 w-96" src={usocomeLogo} alt="Usocome Logo"></Image>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
}
|
||||
94
src/components/Navbar.tsx
Normal file
94
src/components/Navbar.tsx
Normal file
@@ -0,0 +1,94 @@
|
||||
"use client";
|
||||
import Link from "next/link";
|
||||
import ThemeChanger from "./DarkSwitch";
|
||||
import Image from "next/image";
|
||||
import retakeLogo from "../../public/img/logo.png";
|
||||
// import { Disclosure } from "@headlessui/react";
|
||||
|
||||
export const Navbar = () => {
|
||||
const navigation = [
|
||||
"Articles",
|
||||
"Features",
|
||||
"Pricing",
|
||||
"Company",
|
||||
"Blog",
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="w-full">
|
||||
<nav className="container relative flex flex-wrap items-center justify-between p-8 mx-auto lg:justify-between xl:px-1">
|
||||
{/* Logo */}
|
||||
<Link href="/">
|
||||
<Image className="h-20 w-40" src={retakeLogo} alt="" />
|
||||
</Link>
|
||||
|
||||
{/* get started */}
|
||||
<div className="gap-3 nav__item mr-2 lg:flex ml-auto lg:ml-0 lg:order-2">
|
||||
<ThemeChanger />
|
||||
<div className="hidden mr-3 lg:flex nav__item">
|
||||
<Link href="#footer" className="px-6 py-2 text-white bg-[#7ed957] rounded-md md:ml-5">
|
||||
Nous contacter
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* <Disclosure>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Disclosure.Button
|
||||
aria-label="Toggle Menu"
|
||||
className="px-2 py-1 text-gray-500 rounded-md lg:hidden hover:text-indigo-500 focus:text-indigo-500 focus:bg-indigo-100 focus:outline-none dark:text-gray-300 dark:focus:bg-trueGray-700">
|
||||
<svg
|
||||
className="w-6 h-6 fill-current"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24">
|
||||
{open && (
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M18.278 16.864a1 1 0 0 1-1.414 1.414l-4.829-4.828-4.828 4.828a1 1 0 0 1-1.414-1.414l4.828-4.829-4.828-4.828a1 1 0 0 1 1.414-1.414l4.829 4.828 4.828-4.828a1 1 0 1 1 1.414 1.414l-4.828 4.829 4.828 4.828z"
|
||||
/>
|
||||
)}
|
||||
{!open && (
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M4 5h16a1 1 0 0 1 0 2H4a1 1 0 1 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2z"
|
||||
/>
|
||||
)}
|
||||
</svg>
|
||||
</Disclosure.Button>
|
||||
|
||||
<Disclosure.Panel className="flex flex-wrap w-full my-5 lg:hidden">
|
||||
<>
|
||||
{navigation.map((item, index) => (
|
||||
<Link key={index} href="/" className="w-full px-4 py-2 -ml-4 text-gray-500 rounded-md dark:text-gray-300 hover:text-indigo-500 focus:text-indigo-500 focus:bg-indigo-100 dark:focus:bg-gray-800 focus:outline-none">
|
||||
{item}
|
||||
</Link>
|
||||
))}
|
||||
<Link href="/" className="w-full px-6 py-2 mt-3 text-center text-white bg-[#7ed957] rounded-md lg:ml-5">
|
||||
Nous contacter
|
||||
</Link>
|
||||
</>
|
||||
</Disclosure.Panel>
|
||||
</>
|
||||
)}
|
||||
</Disclosure> */}
|
||||
|
||||
{/* menu */}
|
||||
{/* <div className="hidden text-center lg:flex lg:items-center">
|
||||
<ul className="items-center justify-end flex-1 pt-6 list-none lg:pt-0 lg:flex">
|
||||
{navigation.map((menu, index) => (
|
||||
<li className="mr-3 nav__item" key={index}>
|
||||
<Link href="/" className="inline-block px-4 py-2 text-lg font-normal text-gray-800 no-underline rounded-md dark:text-gray-200 hover:text-indigo-500 focus:text-indigo-500 focus:bg-indigo-100 focus:outline-none dark:focus:bg-gray-800">
|
||||
{menu}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div> */}
|
||||
|
||||
</nav>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
356
src/components/PopupWidget.tsx
Normal file
356
src/components/PopupWidget.tsx
Normal file
@@ -0,0 +1,356 @@
|
||||
"use client";
|
||||
import React, { useState } from "react";
|
||||
import { useForm, useWatch } from "react-hook-form";
|
||||
import {
|
||||
Disclosure,
|
||||
Transition,
|
||||
DisclosurePanel,
|
||||
DisclosureButton,
|
||||
} from "@headlessui/react";
|
||||
|
||||
export function PopupWidget() {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
reset,
|
||||
control,
|
||||
formState: { errors, isSubmitSuccessful, isSubmitting },
|
||||
} = useForm({
|
||||
mode: "onTouched",
|
||||
});
|
||||
|
||||
const [isSuccess, setIsSuccess] = useState(false);
|
||||
const [Message, setMessage] = useState("");
|
||||
|
||||
const userName = useWatch({ control, name: "name", defaultValue: "Someone" });
|
||||
|
||||
const onSubmit = async (data: any, e: any) => {
|
||||
console.log(data);
|
||||
await fetch("https://api.web3forms.com/submit", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
},
|
||||
body: JSON.stringify(data, null, 2),
|
||||
})
|
||||
.then(async (response) => {
|
||||
let json = await response.json();
|
||||
if (json.success) {
|
||||
setIsSuccess(true);
|
||||
setMessage(json.message);
|
||||
e.target.reset();
|
||||
reset();
|
||||
} else {
|
||||
setIsSuccess(false);
|
||||
setMessage(json.message);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
setIsSuccess(false);
|
||||
setMessage("Client Error. Please check the console.log for more info");
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Disclosure>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<DisclosureButton className="fixed z-40 flex items-center justify-center transition duration-300 bg-[#7ed957] rounded-full shadow-lg right-5 bottom-5 w-14 h-14 focus:outline-none hover:bg-[#7ed957] focus:bg-[#7ed957] ease">
|
||||
<span className="sr-only">Open Contact form Widget</span>
|
||||
<Transition
|
||||
show={!open}
|
||||
enter="transition duration-200 transform ease"
|
||||
enterFrom="opacity-0 -rotate-45 scale-75"
|
||||
leave="transition duration-100 transform ease"
|
||||
leaveTo="opacity-0 -rotate-45"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="absolute w-6 h-6 text-white"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
|
||||
</svg>
|
||||
</Transition>
|
||||
|
||||
<Transition
|
||||
show={open}
|
||||
enter="transition duration-200 transform ease"
|
||||
enterFrom="opacity-0 rotate-45 scale-75"
|
||||
leave="transition duration-100 transform ease"
|
||||
leaveTo="opacity-0 rotate-45"
|
||||
className="absolute w-6 h-6 text-white"
|
||||
as={"div"}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="w-6 h-6"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</Transition>
|
||||
</DisclosureButton>
|
||||
<Transition
|
||||
className="fixed z-50 bottom-[100px] top-0 right-0 left-0 sm:top-auto sm:right-5 sm:left-auto"
|
||||
enter="transition duration-200 transform ease"
|
||||
enterFrom="opacity-0 translate-y-5"
|
||||
leave="transition duration-200 transform ease"
|
||||
leaveTo="opacity-0 translate-y-5"
|
||||
as="div"
|
||||
>
|
||||
<DisclosurePanel className=" flex flex-col overflow-hidden left-0 h-full w-full sm:w-[350px] min-h-[250px] sm:h-[600px] border border-gray-300 dark:border-gray-800 bg-white shadow-2xl rounded-md sm:max-h-[calc(100vh-120px)]">
|
||||
<div className="flex flex-col items-center justify-center h-32 p-5 bg-[#7ed957]">
|
||||
<h3 className="text-lg text-white">Une question ?</h3>
|
||||
<p className="text-white opacity-50">
|
||||
On vous répond en quelque heures !
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex-grow h-full p-6 overflow-auto bg-gray-50 ">
|
||||
{!isSubmitSuccessful && (
|
||||
<form onSubmit={handleSubmit(onSubmit)} noValidate>
|
||||
<input
|
||||
type="hidden"
|
||||
value="b76d18cf-9601-4bc7-9e5e-8395a6b4a6d6"
|
||||
{...register("apikey")}
|
||||
/>
|
||||
<input
|
||||
type="hidden"
|
||||
value={`${userName} sent a message from retake.fr`}
|
||||
{...register("subject")}
|
||||
/>
|
||||
<input
|
||||
type="hidden"
|
||||
value="retake.fr"
|
||||
{...register("from_name")}
|
||||
/>
|
||||
<input
|
||||
type="checkbox"
|
||||
className="hidden"
|
||||
style={{ display: "none" }}
|
||||
{...register("botcheck")}
|
||||
></input>
|
||||
|
||||
<div className="mb-4">
|
||||
<label
|
||||
htmlFor="full_name"
|
||||
className="block mb-2 text-sm text-gray-600 dark:text-gray-400"
|
||||
>
|
||||
Nom & Pénom / Entreprise
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="full_name"
|
||||
placeholder="John Doe / ACME Inc"
|
||||
{...register("name", {
|
||||
required: "Nom complet requis",
|
||||
maxLength: 80,
|
||||
})}
|
||||
className={`w-full px-3 py-2 text-gray-600 placeholder-gray-300 bg-white border border-gray-300 rounded-md focus:outline-none focus:ring ${
|
||||
errors.name
|
||||
? "border-red-600 focus:border-red-600 ring-red-100"
|
||||
: "border-gray-300 focus:border-indigo-600 ring-indigo-100"
|
||||
}`}
|
||||
/>
|
||||
{errors.name && (
|
||||
<div className="mt-1 text-sm text-red-400 invalid-feedback">
|
||||
{errors.name.message as string}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mb-4">
|
||||
<label
|
||||
htmlFor="email"
|
||||
className="block mb-2 text-sm text-gray-600 dark:text-gray-400"
|
||||
>
|
||||
Adresse Email
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
{...register("email", {
|
||||
required: "Entrer votre email",
|
||||
pattern: {
|
||||
value: /^\S+@\S+$/i,
|
||||
message: "Email invalide",
|
||||
},
|
||||
})}
|
||||
placeholder="john.doe@acme.inc"
|
||||
className={`w-full px-3 py-2 text-gray-600 placeholder-gray-300 bg-white border border-gray-300 rounded-md focus:outline-none focus:ring ${
|
||||
errors.email
|
||||
? "border-red-600 focus:border-red-600 ring-red-100"
|
||||
: "border-gray-300 focus:border-indigo-600 ring-indigo-100"
|
||||
}`}
|
||||
/>
|
||||
|
||||
{errors.email && (
|
||||
<div className="mt-1 text-sm text-red-400 invalid-feedback">
|
||||
{errors.email.message as string}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mb-4">
|
||||
<label
|
||||
htmlFor="message"
|
||||
className="block mb-2 text-sm text-gray-600 dark:text-gray-400"
|
||||
>
|
||||
Votre Message
|
||||
</label>
|
||||
|
||||
<textarea
|
||||
rows={4}
|
||||
id="message"
|
||||
{...register("message", {
|
||||
required: "Entrer votre message",
|
||||
})}
|
||||
placeholder="Votre message"
|
||||
className={`w-full px-3 py-2 text-gray-600 placeholder-gray-300 bg-white border border-gray-300 rounded-md h-28 focus:outline-none focus:ring ${
|
||||
errors.message
|
||||
? "border-red-600 focus:border-red-600 ring-red-100"
|
||||
: "border-gray-300 focus:border-indigo-600 ring-indigo-100"
|
||||
}`}
|
||||
required
|
||||
></textarea>
|
||||
{errors.message && (
|
||||
<div className="mt-1 text-sm text-red-400 invalid-feedback">
|
||||
{errors.message.message as string}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<button
|
||||
type="submit"
|
||||
className="w-full px-3 py-4 text-white bg-[#7ed957] rounded-md focus:bg-[#7ed957] focus:outline-none"
|
||||
>
|
||||
{isSubmitting ? (
|
||||
<svg
|
||||
className="w-5 h-5 mx-auto text-white animate-spin"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<circle
|
||||
className="opacity-25"
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="10"
|
||||
stroke="currentColor"
|
||||
strokeWidth="4"
|
||||
></circle>
|
||||
<path
|
||||
className="opacity-75"
|
||||
fill="currentColor"
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||
></path>
|
||||
</svg>
|
||||
) : (
|
||||
"Envoyer"
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
<p
|
||||
className="text-xs text-center text-gray-400"
|
||||
id="result"
|
||||
>
|
||||
<span>
|
||||
Propulsé par{" "}
|
||||
<a
|
||||
href="https://Web3Forms.com"
|
||||
className="text-gray-600"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Web3Forms
|
||||
</a>
|
||||
</span>
|
||||
</p>
|
||||
</form>
|
||||
)}
|
||||
|
||||
{isSubmitSuccessful && isSuccess && (
|
||||
<div className="flex flex-col items-center justify-center h-full text-center text-white rounded-md">
|
||||
<svg
|
||||
width="60"
|
||||
height="60"
|
||||
className="text-green-300"
|
||||
viewBox="0 0 100 100"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M26.6666 50L46.6666 66.6667L73.3333 33.3333M50 96.6667C43.8716 96.6667 37.8033 95.4596 32.1414 93.1144C26.4796 90.7692 21.3351 87.3317 17.0017 82.9983C12.6683 78.6649 9.23082 73.5204 6.8856 67.8586C4.54038 62.1967 3.33331 56.1283 3.33331 50C3.33331 43.8716 4.54038 37.8033 6.8856 32.1414C9.23082 26.4796 12.6683 21.3351 17.0017 17.0017C21.3351 12.6683 26.4796 9.23084 32.1414 6.88562C37.8033 4.5404 43.8716 3.33333 50 3.33333C62.3767 3.33333 74.2466 8.24998 82.9983 17.0017C91.75 25.7534 96.6666 37.6232 96.6666 50C96.6666 62.3768 91.75 74.2466 82.9983 82.9983C74.2466 91.75 62.3767 96.6667 50 96.6667Z"
|
||||
stroke="currentColor"
|
||||
strokeWidth="3"
|
||||
/>
|
||||
</svg>
|
||||
<h3 className="py-5 text-xl text-green-500">
|
||||
Message sent successfully
|
||||
</h3>
|
||||
<p className="text-gray-700 md:px-3">{Message}</p>
|
||||
<button
|
||||
className="mt-6 text-indigo-600 focus:outline-none"
|
||||
onClick={() => reset()}
|
||||
>
|
||||
Go back
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isSubmitSuccessful && !isSuccess && (
|
||||
<div className="flex flex-col items-center justify-center h-full text-center text-white rounded-md">
|
||||
<svg
|
||||
width="60"
|
||||
height="60"
|
||||
viewBox="0 0 97 97"
|
||||
className="text-red-400"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M27.9995 69C43.6205 53.379 52.3786 44.621 67.9995 29M26.8077 29L67.9995 69M48.2189 95C42.0906 95 36.0222 93.7929 30.3604 91.4477C24.6985 89.1025 19.554 85.6651 15.2206 81.3316C10.8872 76.9982 7.44975 71.8538 5.10454 66.1919C2.75932 60.53 1.55225 54.4617 1.55225 48.3333C1.55225 42.205 2.75932 36.1366 5.10454 30.4748C7.44975 24.8129 10.8872 19.6684 15.2206 15.335C19.554 11.0016 24.6985 7.56418 30.3604 5.21896C36.0222 2.87374 42.0906 1.66667 48.2189 1.66667C60.5957 1.66667 72.4655 6.58333 81.2172 15.335C89.9689 24.0867 94.8856 35.9566 94.8856 48.3333C94.8856 60.7101 89.9689 72.58 81.2172 81.3316C72.4655 90.0833 60.5957 95 48.2189 95Z"
|
||||
stroke="CurrentColor"
|
||||
strokeWidth="3"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<h3 className="text-xl text-red-400 py-7">
|
||||
Oops, Something went wrong!
|
||||
</h3>
|
||||
<p className="text-gray-700 md:px-3">{Message}</p>
|
||||
<button
|
||||
className="mt-6 text-indigo-600 focus:outline-none"
|
||||
onClick={() => reset()}
|
||||
>
|
||||
Go back
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</DisclosurePanel>
|
||||
</Transition>
|
||||
</>
|
||||
)}
|
||||
</Disclosure>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
37
src/components/SectionTitle.tsx
Normal file
37
src/components/SectionTitle.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import React from "react";
|
||||
import { Container } from "@/components/Container";
|
||||
|
||||
interface SectionTitleProps {
|
||||
preTitle?: string;
|
||||
title?: string;
|
||||
align?: "left" | "center";
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const SectionTitle = (props: Readonly<SectionTitleProps>) => {
|
||||
return (
|
||||
<Container
|
||||
className={`flex w-full flex-col mt-4 ${
|
||||
props.align === "left" ? "" : "items-center justify-center text-center"
|
||||
}`}>
|
||||
{props.preTitle && (
|
||||
<div className="text-sm font-bold tracking-wider text-[#7ed957] uppercase">
|
||||
{props.preTitle}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{props.title && (
|
||||
<h2 id="benefits" className="max-w-2xl mt-3 text-3xl font-bold leading-snug tracking-tight text-gray-800 lg:leading-tight lg:text-4xl dark:text-white">
|
||||
{props.title}
|
||||
</h2>
|
||||
)}
|
||||
|
||||
{props.children && (
|
||||
<p className="max-w-2xl py-4 text-lg leading-normal text-gray-500 lg:text-xl xl:text-xl dark:text-gray-300">
|
||||
{props.children}
|
||||
</p>
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
60
src/components/data.js
Normal file
60
src/components/data.js
Normal file
@@ -0,0 +1,60 @@
|
||||
import {
|
||||
InboxArrowDownIcon,
|
||||
ArrowPathIcon,
|
||||
BanknotesIcon,
|
||||
ArrowPathRoundedSquareIcon,
|
||||
GlobeAltIcon,
|
||||
CogIcon,
|
||||
} from "@heroicons/react/24/solid";
|
||||
|
||||
import benefitOneImg from "../../public/img/building.png";
|
||||
import benefitTwoImg from "../../public/img/house.png";
|
||||
|
||||
const benefitOne = {
|
||||
title: "Notre mission",
|
||||
desc: "Un processus rapide pour vous simplifier la vie, valoriser votre matériel et agir pour la planète",
|
||||
image: benefitOneImg,
|
||||
bullets: [
|
||||
{
|
||||
title: "Faciliter",
|
||||
desc: "On s'occupe de tout : estimation, reprise et logistique simplifiées.",
|
||||
icon: <InboxArrowDownIcon />,
|
||||
},
|
||||
{
|
||||
title: "Revaloriser",
|
||||
desc: "Votre matériel trouve une seconde vie utile et durable.",
|
||||
icon: <ArrowPathRoundedSquareIcon />,
|
||||
},
|
||||
{
|
||||
title: "Rentabiliser",
|
||||
desc: "Réduisez vos coûts en réinvestissant dans votre futur parc informatique.",
|
||||
icon: <BanknotesIcon />,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const benefitTwo = {
|
||||
title: "Notre vision",
|
||||
desc: "Un monde où chaque équipement trouve une seconde vie.",
|
||||
image: benefitTwoImg,
|
||||
bullets: [
|
||||
{
|
||||
title: "Un cercle vertueux",
|
||||
desc: "Nous croyons en une économie où rien ne se perd et tout se transforme.",
|
||||
icon: <ArrowPathIcon />,
|
||||
},
|
||||
{
|
||||
title: "L'inclusion technologique",
|
||||
desc: "Permettre à chacun, associations comme particuliers, d’accéder à des outils essentiels.",
|
||||
icon: <GlobeAltIcon />,
|
||||
},
|
||||
{
|
||||
title: "L'innovation durable",
|
||||
desc: "Imaginer des moyens toujours plus simples et efficaces de prolonger la vie des équipements.",
|
||||
icon: <CogIcon />,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
export {benefitOne, benefitTwo};
|
||||
6
src/types.ts
Normal file
6
src/types.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export interface PageProps {
|
||||
params: {
|
||||
slug: string;
|
||||
};
|
||||
searchParams: {};
|
||||
}
|
||||
Reference in New Issue
Block a user