Finish migrating components

This commit is contained in:
adilallo
2026-01-29 17:59:11 -07:00
parent b5735bb2ad
commit 539f6c62e3
79 changed files with 2449 additions and 1730 deletions
@@ -0,0 +1,73 @@
"use client";
import { memo, useState, useEffect, useMemo } from "react";
import LogoWallView from "./LogoWall.view";
import type { LogoWallProps } from "./LogoWall.types";
const defaultLogos = [
{
src: "/assets/logo-1.svg",
alt: "Partner Logo 1",
width: 120,
height: 40,
},
{
src: "/assets/logo-2.svg",
alt: "Partner Logo 2",
width: 120,
height: 40,
},
{
src: "/assets/logo-3.svg",
alt: "Partner Logo 3",
width: 120,
height: 40,
},
{
src: "/assets/logo-4.svg",
alt: "Partner Logo 4",
width: 120,
height: 40,
},
{
src: "/assets/logo-5.svg",
alt: "Partner Logo 5",
width: 120,
height: 40,
},
{
src: "/assets/logo-6.svg",
alt: "Partner Logo 6",
width: 120,
height: 40,
},
];
const LogoWallContainer = memo<LogoWallProps>(
({ logos, className = "" }) => {
const [isVisible, setIsVisible] = useState(false);
const displayLogos = useMemo(() => logos || defaultLogos, [logos]);
useEffect(() => {
// Trigger fade-in animation after component mounts
const timer = setTimeout(() => {
setIsVisible(true);
}, 100);
return () => clearTimeout(timer);
}, []);
return (
<LogoWallView
isVisible={isVisible}
displayLogos={displayLogos}
className={className}
/>
);
},
);
LogoWallContainer.displayName = "LogoWall";
export default LogoWallContainer;
+20
View File
@@ -0,0 +1,20 @@
export interface LogoWallProps {
logos?: Array<{
src: string;
alt: string;
width?: number;
height?: number;
}>;
className?: string;
}
export interface LogoWallViewProps {
isVisible: boolean;
displayLogos: Array<{
src: string;
alt: string;
width?: number;
height?: number;
}>;
className: string;
}
+33
View File
@@ -0,0 +1,33 @@
import { memo } from "react";
import Image from "next/image";
import type { LogoWallViewProps } from "./LogoWall.types";
function LogoWallView({ isVisible, displayLogos, className }: LogoWallViewProps) {
return (
<div
className={`flex flex-wrap items-center justify-center gap-[var(--spacing-scale-032)] md:gap-[var(--spacing-scale-048)] transition-opacity duration-1000 ${
isVisible ? "opacity-100" : "opacity-0"
} ${className}`}
>
{displayLogos.map((logo, index) => (
<div
key={`${logo.src}-${index}`}
className="flex items-center justify-center grayscale hover:grayscale-0 transition-all duration-300"
>
<Image
src={logo.src}
alt={logo.alt}
width={logo.width || 120}
height={logo.height || 40}
className="object-contain"
loading="lazy"
/>
</div>
))}
</div>
);
}
LogoWallView.displayName = "LogoWallView";
export default memo(LogoWallView);
+2
View File
@@ -0,0 +1,2 @@
export { default } from "./LogoWall.container";
export type { LogoWallProps } from "./LogoWall.types";