feat(wip homepage with new design)
This commit is contained in:
8
resources/js/components/common/Container.tsx
Normal file
8
resources/js/components/common/Container.tsx
Normal file
@@ -0,0 +1,8 @@
|
||||
import { cn } from '@/lib/utils';
|
||||
import React from "react";
|
||||
|
||||
export function Container({ className, ...props }: React.ComponentProps<'div'>) {
|
||||
return (
|
||||
<div className={cn('w-full max-w-7xl mx-auto px-4', className)} {...props} />
|
||||
);
|
||||
}
|
||||
33
resources/js/components/common/ScrollToTop.tsx
Normal file
33
resources/js/components/common/ScrollToTop.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { ChevronUp } from 'lucide-react';
|
||||
|
||||
export function ScrollToTop() {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const hero = document.getElementById('hero');
|
||||
if (!hero) return;
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => setIsVisible(!entry.isIntersecting),
|
||||
{ threshold: 0 },
|
||||
);
|
||||
|
||||
observer.observe(hero);
|
||||
return () => observer.disconnect();
|
||||
}, []);
|
||||
|
||||
const scrollToTop = () => window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
|
||||
if (!isVisible) return null;
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={scrollToTop}
|
||||
aria-label="Retour en haut"
|
||||
className="fixed bottom-6 right-6 z-50 p-3 rounded-full border-3 border-black bg-primary shadow-[4px_4px_0px_rgba(0,0,0,1)] hover:shadow-none hover:translate-x-1 hover:translate-y-1 transition duration-200"
|
||||
>
|
||||
<ChevronUp className="size-5" />
|
||||
</button>
|
||||
);
|
||||
}
|
||||
27
resources/js/components/common/SectionHeading.tsx
Normal file
27
resources/js/components/common/SectionHeading.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import {cn} from '@/lib/utils';
|
||||
|
||||
interface SectionHeadingProps {
|
||||
title: string;
|
||||
color?: string;
|
||||
subtitle?: string;
|
||||
align?: 'left' | 'center';
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function SectionHeading({title, color, subtitle, align = 'center', className}: SectionHeadingProps) {
|
||||
return (
|
||||
<div className={cn(
|
||||
'flex gap-10 items-center ',
|
||||
align === 'center' && 'text-center',
|
||||
align === 'left' && 'text-left',
|
||||
className,
|
||||
)}>
|
||||
<h2 className={`text-3xl text-black font-medium bg-${color} rounded p-1`}>
|
||||
{title}
|
||||
</h2>
|
||||
{subtitle && (
|
||||
<p className="text-md text-muted-foreground max-w-2xl">{subtitle}</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
0
resources/js/components/common/ServiceCard.tsx
Normal file
0
resources/js/components/common/ServiceCard.tsx
Normal file
Reference in New Issue
Block a user