@@ -2,12 +2,14 @@ import { useEffect, useState } from "react";
22import { useParams } from "react-router" ;
33import { JsonData , Entry } from "./types" ;
44import ResourceCard from "./ResourceCard" ;
5- import { sortEntries } from "./utils" ;
5+ import { extractTags , sortEntries } from "./utils" ;
66
77const ResourcePage = ( ) => {
88 const { category } = useParams ( ) ;
99 const [ data , setData ] = useState < JsonData | null > ( null ) ;
1010 const [ entries , setEntries ] = useState < Entry [ ] > ( [ ] ) ;
11+ const [ tags , setTags ] = useState < string [ ] > ( [ ] ) ;
12+ const [ filters , setFilters ] = useState < string [ ] > ( [ ] ) ;
1113
1214 useEffect ( ( ) => {
1315 const fetchData = async ( ) => {
@@ -26,19 +28,54 @@ const ResourcePage = () => {
2628 if ( json . entries . length > 0 ) {
2729 setData ( json ) ;
2830 setEntries ( sortEntries ( json . entries ) ) ;
31+ setTags ( extractTags ( json . entries ) ) ;
2932 }
3033 } )
3134 . catch ( console . error ) ;
3235 } , [ category ] ) ;
3336
37+ const filterColor = ( tag : string ) =>
38+ filters . includes ( tag ) ? "bg-slate-400" : "bg-slate-300" ;
39+
3440 if ( data ) {
3541 return (
3642 < >
37- < section className = "h-2/3 w-full bg-background" >
43+ < section className = "w-full bg-background" >
3844 < h3 className = "my-12 text-center text-4xl text-primary" >
3945 { data . pageName }
4046 </ h3 >
41- < div className = "flex w-full justify-center" >
47+ < div className = "mb-6 flex w-full flex-col items-center justify-center text-center" >
48+ < h4 className = "text-xl font-bold text-primary" > Categories</ h4 >
49+ < div className = "mt-4 flex w-96 flex-wrap justify-center gap-2 xl:w-[600px]" >
50+ { tags . map ( ( t ) => (
51+ < div
52+ key = { t }
53+ onClick = { ( ) => {
54+ setFilters ( [ ...filters , t ] ) ;
55+ setEntries ( entries . filter ( ( e ) => e . tags . includes ( t ) ) ) ;
56+ } }
57+ >
58+ < button
59+ className = { `rounded-xl border-transparent bg-slate-300 px-2 pb-1 ${ filterColor ( t ) } ` }
60+ >
61+ { t }
62+ </ button >
63+ </ div >
64+ ) ) }
65+ { filters . length > 0 && (
66+ < button
67+ className = "rounded-xl bg-accent px-2 pb-1 text-primary"
68+ onClick = { ( ) => {
69+ setFilters ( [ ] ) ;
70+ setEntries ( sortEntries ( data . entries ) ) ;
71+ } }
72+ >
73+ Clear filters ×
74+ </ button >
75+ ) }
76+ </ div >
77+ </ div >
78+ < div className = "flex w-full justify-center pb-12" >
4279 < div className = "mx-4 flex flex-wrap justify-center gap-6 sm:w-5/6 xl:w-3/4" >
4380 { entries . map ( ( e ) => (
4481 < ResourceCard entry = { e } key = { e . title } />
0 commit comments