@@ -3,7 +3,7 @@ import { GetStaticProps } from "next";
33import { useRouter } from "next/router" ;
44import Head from "next/head" ;
55import TagIcon from "@heroicons/react/24/solid/TagIcon" ;
6- import { motion , AnimatePresence } from "framer-motion" ;
6+ import { motion , AnimatePresence , Variants } from "framer-motion" ;
77import { useForm , useWatch } from "react-hook-form" ;
88import { zodResolver } from "@hookform/resolvers/zod" ;
99import { z } from "zod" ;
@@ -29,16 +29,16 @@ interface BlogPageProps {
2929
3030const SORT_OPTIONS = [
3131 {
32- " direction" : "new" ,
33- " name" : "Newest" ,
34- " func" : ( a : IArticleBrief , b : IArticleBrief ) => {
32+ direction : 1 ,
33+ name : "Newest" ,
34+ func : ( a : IArticleBrief , b : IArticleBrief ) => {
3535 return new Date ( b . date ) . getTime ( ) - new Date ( a . date ) . getTime ( ) ;
3636 }
3737 } ,
3838 {
39- " direction" : "old" ,
40- " name" : "Oldest" ,
41- " func" : ( a : IArticleBrief , b : IArticleBrief ) => {
39+ direction : 2 ,
40+ name : "Oldest" ,
41+ func : ( a : IArticleBrief , b : IArticleBrief ) => {
4242 return new Date ( a . date ) . getTime ( ) - new Date ( b . date ) . getTime ( ) ;
4343 }
4444 }
@@ -47,12 +47,30 @@ const SORT_OPTIONS = [
4747const filterSchema = z . object ( {
4848 search : z . string ( ) ,
4949 sort : z . object ( {
50- direction : z . union ( [ z . literal ( "new" ) , z . literal ( "old" ) ] ) ,
50+ direction : z . union ( [ z . literal ( 1 ) , z . literal ( 2 ) ] ) ,
5151 name : z . string ( ) ,
5252 func : z . function ( z . tuple ( [ z . object ( { } ) , z . object ( { } ) ] ) , z . number ( ) )
5353 } )
5454} ) ;
5555
56+ const NO_RESULTS_ANIM = {
57+ in : {
58+ opacity : 0
59+ } ,
60+ anim : {
61+ opacity : 1 ,
62+ transition : {
63+ duration : 0.25
64+ }
65+ } ,
66+ exit : {
67+ opacity : 0 ,
68+ transition : {
69+ duration : 0.25
70+ }
71+ }
72+ } as Variants ;
73+
5674const filterSchemaResolver = zodResolver ( filterSchema ) ;
5775
5876type FilterSchema = z . infer < typeof filterSchema > ;
@@ -99,7 +117,7 @@ const BlogPage: Page<BlogPageProps> = ({ articles, pathname }) => {
99117 < Heading . H1 id = "blog" className = "text-center text-secondary" >
100118 Blog
101119 </ Heading . H1 >
102- { computedArticles . length > 0 && < >
120+ { articles . length > 0 && < >
103121 < div className = "mx-0 sm:mx-16 md:mx-0 motion-safe:transition-[margin-inline] motion-safe:duration-500 flex gap-2 items-end" >
104122 < div >
105123 < Label htmlFor = "search-input" className = "text-secondary" >
@@ -149,13 +167,25 @@ const BlogPage: Page<BlogPageProps> = ({ articles, pathname }) => {
149167 </ motion . div > }
150168 </ AnimatePresence >
151169 </ div >
152- < ul className = "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3" aria-label = "blog articles" >
170+ < AnimatePresence >
171+ { computedArticles . length <= 0 && < motion . p
172+ role = "note"
173+ className = "w-full text-2xl font-semibold text-center"
174+ variants = { NO_RESULTS_ANIM }
175+ initial = "in"
176+ animate = "anim"
177+ exit = "exit"
178+ >
179+ There are no blog posts that fit this criteria
180+ </ motion . p > }
181+ </ AnimatePresence >
182+ < ul className = "grid w-full grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3" aria-label = "blog articles" >
153183 < AnimatePresence >
154184 { computedArticles . map ( ( brief , i ) => < ArticleBrief key = { brief . url } { ...brief } imgLoading = { i > 3 ? "lazy" : "eager" } /> ) }
155185 </ AnimatePresence >
156186 </ ul >
157187 </ > }
158- { computedArticles . length < 1 && < p role = "note" className = "text-3xl font-semibold text-center" >
188+ { articles . length <= 0 && < p role = "note" className = "text-2xl font-semibold text-center" >
159189 There are no blog posts yet! Stay tuned!
160190 </ p > }
161191 </ main >
0 commit comments