11import React , { useState , useEffect } from 'react' ;
22import { Link } from 'react-router-dom' ;
33import { ArrowLeftIcon , CaretDown , CaretRight } from '@phosphor-icons/react' ;
4+ import { motion , AnimatePresence } from 'framer-motion' ; // Import motion and AnimatePresence
45import AppCard from '../components/AppCard' ;
56import useSeo from "../hooks/useSeo" ;
67import { appIcons } from '../utils/appIcons' ; // Import appIcons
@@ -43,6 +44,11 @@ function AppPage() {
4344 } ) ) ;
4445 } ;
4546
47+ const variants = {
48+ open : { opacity : 1 , height : "auto" } ,
49+ collapsed : { opacity : 0 , height : 0 }
50+ } ;
51+
4652 return (
4753 < div className = "py-16 sm:py-24" >
4854 < div className = "mx-auto max-w-7xl px-6 lg:px-8 text-gray-300" >
@@ -63,27 +69,39 @@ function AppPage() {
6369 . map ( categoryKey => {
6470 const category = groupedApps [ categoryKey ] ;
6571 const CategoryIcon = appIcons [ category . icon ] ;
66- return (
67- < div key = { categoryKey } className = "mt-8" >
68- < h2
69- className = "text-3xl font-arvo font-normal tracking-tight text-gray-200 mb-2 flex items-center cursor-pointer"
70- onClick = { ( ) => toggleCategoryCollapse ( categoryKey ) }
71- >
72- { collapsedCategories [ categoryKey ] ? < CaretRight size = { 24 } className = "mr-2" /> : < CaretDown size = { 24 } className = "mr-2" /> }
73- { CategoryIcon && < CategoryIcon size = { 28 } className = "mr-2" /> }
74- { category . name } ({ category . apps . length } )
75- </ h2 >
76- < p className = "text-gray-400 mb-4 ml-10" > { category . description } </ p >
77- { ! collapsedCategories [ categoryKey ] && (
78- < div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8" >
79- { category . apps . map ( ( app , index ) => (
80- < AppCard key = { index } app = { app } />
81- ) ) }
82- </ div >
83- ) }
84- </ div >
85- ) ;
86- } ) }
72+ return (
73+ < div key = { categoryKey } className = "mt-8" >
74+ < h2
75+ className = "text-3xl font-arvo font-normal tracking-tight text-gray-200 mb-2 flex items-center cursor-pointer"
76+ onClick = { ( ) => toggleCategoryCollapse ( categoryKey ) }
77+ >
78+ { collapsedCategories [ categoryKey ] ? < CaretRight size = { 24 } className = "mr-2" /> : < CaretDown size = { 24 } className = "mr-2" /> }
79+ { CategoryIcon && < CategoryIcon size = { 28 } className = "mr-2" /> }
80+ { category . name } ({ category . apps . length } )
81+ </ h2 >
82+ < p className = "text-gray-400 mb-4 ml-10" > { category . description } </ p >
83+ < AnimatePresence initial = { false } >
84+ { ! collapsedCategories [ categoryKey ] && (
85+ < motion . div
86+ key = "content"
87+ initial = "collapsed"
88+ animate = "open"
89+ exit = "collapsed"
90+ variants = { variants }
91+ transition = { { duration : 0.3 , ease : "easeInOut" } }
92+ style = { { overflow : "hidden" } }
93+ >
94+ < div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8" >
95+ { category . apps . map ( ( app , index ) => (
96+ < AppCard key = { index } app = { app } />
97+ ) ) }
98+ </ div >
99+ </ motion . div >
100+ ) }
101+ </ AnimatePresence >
102+ </ div >
103+ ) ;
104+ } ) }
87105 </ div >
88106 </ div >
89107 ) ;
0 commit comments