diff --git a/app/components/LogoWall.js b/app/components/LogoWall.js index 3625854..3eea9f3 100644 --- a/app/components/LogoWall.js +++ b/app/components/LogoWall.js @@ -1,40 +1,45 @@ "use client"; +import { useState, useEffect } from "react"; +import Image from "next/image"; + const LogoWall = ({ logos = [] }) => { + const [isVisible, setIsVisible] = useState(false); + // Default logos if none provided - ordered for mobile (3 rows × 2 columns) const defaultLogos = [ { - src: "assets/Section/Logo_FoodNotBombs.png", + src: "/assets/Section/Logo_FoodNotBombs.png", alt: "Food Not Bombs", size: "h-11 lg:h-14 xl:h-[70px]", order: "order-1 sm:order-4", // Mobile: row 1 col 1, SM: row 2 col 1 (bottom left) }, { - src: "assets/Section/Logo_StartCOOP.png", + src: "/assets/Section/Logo_StartCOOP.png", alt: "Start COOP", size: "h-[42px] lg:h-[53px] xl:h-[66px]", order: "order-2 sm:order-2", // Mobile: row 1 col 2, SM: row 1 col 2 (top middle) }, { - src: "assets/Section/Logo_Metagov.png", + src: "/assets/Section/Logo_Metagov.png", alt: "Metagov", size: "h-6 lg:h-8 xl:h-[41px]", order: "order-3 sm:order-1", // Mobile: row 2 col 1, SM: row 1 col 1 (top left) }, { - src: "assets/Section/Logo_OpenCivics.png", + src: "/assets/Section/Logo_OpenCivics.png", alt: "Open Civics", size: "h-8 lg:h-10 xl:h-[50px]", order: "order-4 sm:order-5 md:order-6", // Mobile: row 2 col 2, SM: row 2 col 2, MD: swapped with Mutual Aid CO }, { - src: "assets/Section/Logo_MutualAidCO.png", + src: "/assets/Section/Logo_MutualAidCO.png", alt: "Mutual Aid CO", size: "h-11 lg:h-14 xl:h-[70px]", order: "order-5 sm:order-6 md:order-5", // Mobile: row 3 col 1, SM: row 2 col 3, MD: swapped with OpenCivics }, { - src: "assets/Section/Logo_CUBoulder.png", + src: "/assets/Section/Logo_CUBoulder.png", alt: "CU Boulder", size: "h-10 lg:h-12 xl:h-[60px]", order: "order-6 sm:order-3", // Mobile: row 3 col 2, SM: row 1 col 3 (top right) @@ -43,6 +48,15 @@ const LogoWall = ({ logos = [] }) => { const displayLogos = logos.length > 0 ? logos : defaultLogos; + // Simple fade-in effect after component mounts + useEffect(() => { + const timer = setTimeout(() => { + setIsVisible(true); + }, 100); + + return () => clearTimeout(timer); + }, []); + return (
@@ -52,19 +66,29 @@ const LogoWall = ({ logos = [] }) => {

{/* Logo Grid Container */} -
+
{displayLogos.map((logo, index) => (
- {logo.alt}
))} diff --git a/stories/LogoWall.stories.js b/stories/LogoWall.stories.js index 90644e3..4e58e6f 100644 --- a/stories/LogoWall.stories.js +++ b/stories/LogoWall.stories.js @@ -17,6 +17,15 @@ export default { - **LG**: Larger logo sizes and 64px horizontal padding - **XL**: Largest logo sizes, 160px horizontal padding, and 14px label text +## Animations & Transitions + +- **Fade-in Effect**: Logos fade in from opacity 0 to 60% after component mounts (500ms transition) +- **Hover Interactions**: Individual logos respond to hover with: + - Opacity change from 60% to 100% + - Scale transform (105% zoom) + - 500ms smooth transitions for all effects +- **Loading States**: Progressive loading with fallback timer for reliable display + ## Props - **logos** (optional): Array of logo objects with src, alt, size, and order properties. If not provided, uses default partner logos. @@ -67,7 +76,7 @@ export const Default = { docs: { description: { story: - "Default LogoWall with all partner logos. Displays in a 3×2 grid on mobile, 2×3 grid on small screens, single row on medium screens, and larger sizes on large screens.", + "Default LogoWall with all partner logos. Displays in a 3×2 grid on mobile, 2×3 grid on small screens, single row on medium screens, and larger sizes on large screens. Features smooth fade-in animations and hover interactions.", }, }, },