From 372ab80724e4fcb41723ed3bf38c70ffaf99bae0 Mon Sep 17 00:00:00 2001
From: Nicolas Temciuc <nicotemciuc@gmail.com>
Date: Sat, 23 Nov 2024 21:17:10 -0300
Subject: [PATCH] chore: add no results found page

---
 .../src/app/components/news-cards.tsx         | 22 +++++++++++++--
 .../src/app/stats/components/stats-page.tsx   | 28 ++++++++++++++++---
 front-office/src/components/custom/card.tsx   | 26 ++++++++---------
 .../src/schemas/create-fact-schema.ts         | 12 ++++----
 4 files changed, 62 insertions(+), 26 deletions(-)

diff --git a/front-office/src/app/components/news-cards.tsx b/front-office/src/app/components/news-cards.tsx
index 9152401..d1b7d0f 100644
--- a/front-office/src/app/components/news-cards.tsx
+++ b/front-office/src/app/components/news-cards.tsx
@@ -206,9 +206,25 @@ const NewsCards = () => {
               <Skeleton className="h-96" />
             </>
           ) :
-            facts?.map((fact) => (
-              <CustomCard key={fact.id || fact.title} fact={fact} />
-            ))
+            ( (facts && facts.length > 0) ? (
+              facts?.map((fact) => (
+                <CustomCard key={fact.id || fact.title} fact={fact} />
+              )))
+              :
+              (
+                <Card className="col-span-3 w-full max-w-md mx-auto p-8 flex flex-col items-center justify-center text-center gap-6 self-center">
+                  <div className="bg-muted p-4 rounded-full">
+                    <SearchIcon className="w-8 h-8 text-muted-foreground" />
+                  </div>
+                  <div className="space-y-2">
+                    <h3 className="text-2xl font-semibold">No se encontraron resultados</h3>
+                    <p className="text-muted-foreground">
+                      No hay hechos que coincidan con los filtros seleccionados
+                    </p>
+                  </div>
+                </Card>
+              )
+            )
           }
         </div>
       </div>
diff --git a/front-office/src/app/stats/components/stats-page.tsx b/front-office/src/app/stats/components/stats-page.tsx
index 8e9fe4b..4602b41 100644
--- a/front-office/src/app/stats/components/stats-page.tsx
+++ b/front-office/src/app/stats/components/stats-page.tsx
@@ -2,6 +2,7 @@
 
 import { Calendar } from "@/components/ui/calendar"
 import { useState, useEffect } from "react"
+import { Card, CardContent } from "@/components/ui/card";
 import { Label } from "@/components/ui/label"
 import {
   Popover,
@@ -14,7 +15,7 @@ import DaysBarChart from "./days-bar-chart"
 import DonutChart from "./donut-chart"
 import RadarChartFact from "./radar-chart"
 import { Skeleton } from "@/components/ui/skeleton"
-import { CalendarIcon } from "lucide-react"
+import { CalendarIcon, ChartColumn } from "lucide-react"
 import { useForm } from "react-hook-form"
 import { z } from "zod"
 import { cn } from "@/lib/utils"
@@ -125,7 +126,10 @@ const StatsPage = ({className}) => {
               />
             </PopoverContent>
           </Popover>
-          <Select onValueChange={(value) => setCategory(value)} value={category} asChild>
+          <Select
+            onValueChange={(value) => setCategory(value)}
+            value={category || ""}
+          >
             <SelectTrigger className="w-auto bg-white">
               <SelectValue placeholder="Filtra por categoría" />
             </SelectTrigger>
@@ -143,7 +147,10 @@ const StatsPage = ({className}) => {
               </SelectGroup>
             </SelectContent>
           </Select>
-          <Select onValueChange={(value) => setResult(value)} value={result}>
+          <Select
+            onValueChange={(value) => setResult(value)}
+            value={result || ""}
+          >
             <SelectTrigger className="w-auto bg-white">
               <SelectValue placeholder="Filtra por resultado" />
             </SelectTrigger>
@@ -176,13 +183,26 @@ const StatsPage = ({className}) => {
             <Skeleton className="col-span-1 h-96" />
           </>
         ) : (
+        ( (facts && facts.length !== 0) ? (
           <>
             <MonthBarChart facts={facts} isLoading={isLoading} className="col-span-2" />
             <DaysBarChart facts={facts} isLoading={isLoading} className="col-span-2" date={date} />
             <DonutChart facts={facts} isLoading={isLoading} className="col-span-1" date={date} />
             <RadarChartFact facts={facts} isLoading={isLoading} className="col-span-1" date={date} />
           </>
-        )}
+        ) : (
+            <Card className="col-span-4 w-full max-w-md mx-auto p-8 flex flex-col items-center justify-center text-center gap-6 self-center">
+              <div className="bg-muted p-4 rounded-full">
+                <ChartColumn className="w-8 h-8 text-muted-foreground" />
+              </div>
+              <div className="space-y-2">
+                <h3 className="text-2xl font-semibold">No se encontraron estadisticas</h3>
+                <p className="text-muted-foreground">
+                  No hay hechos que coincidan con los filtros seleccionados
+                </p>
+              </div>
+            </Card>
+        )))}
       </div>
     </div>
   );
diff --git a/front-office/src/components/custom/card.tsx b/front-office/src/components/custom/card.tsx
index 0a67611..f93706e 100644
--- a/front-office/src/components/custom/card.tsx
+++ b/front-office/src/components/custom/card.tsx
@@ -17,23 +17,23 @@ const CustomCard = ({ fact }) => {
   return (
     <Sheet>
       <SheetTrigger>
-        <div className="max-w w-full items-start" key={fact.id || fact.title}>
+        <div className="max-w w-full items-start" key={fact?.id || fact?.title}>
           <div
             className="cursor-pointer overflow-hidden relative card h-96 rounded-md shadow-xl max mx-auto flex flex-col justify-between p-4 bg-cover"
-            style={{ backgroundImage: `url(${fact.pictureUrl})` }}
+            style={{ backgroundImage: `url(${fact?.pictureUrl})` }}
           >
             <div className="absolute w-full h-full top-0 left-0 transition duration-300 group-hover/card:bg-black opacity-60"></div>
             <div className="flex flex-row space-x-4 z-10">
               <div className="flex flex-col">
-                <FactResultBadge result={fact.check.result} />
+                <FactResultBadge result={fact?.check?.result} />
               </div>
             </div>
             <div className="text content justify-end bg-gray-100 bg-opacity-60 p-4 rounded-md">
               <h1 className="font-bold text-xl md:text-2xl text-black relative z-10">
-                {fact.category}
+                {fact?.category}
               </h1>
               <span className="text-lg font-bold text-sm text-black relative z-10 my-4">
-                {fact.title}
+                {fact?.title}
               </span>
             </div>
           </div>
@@ -44,21 +44,21 @@ const CustomCard = ({ fact }) => {
           <SheetTitle className="text-lg font-bold relative z-10 my-4 text-center">Datos de la noticia</SheetTitle>
           <SheetDescription className="flex flex-col">
             <span className="text-lg font-bold text-sm text-black relative z-10 my-4">Descripción:</span>
-            <span> {fact.description}</span>
+            <span> {fact?.description}</span>
             <span className="text-lg font-bold text-sm text-black relative z-10 my-4">Fuente:</span>
-            <span> {fact.source}</span>
+            <span> {fact?.source}</span>
             <span className="text-lg font-bold text-sm text-black relative z-10 my-4">Comentarios del verificador:</span>
-            <span> {fact.check.comments}</span>
+            <span> {fact?.check?.comments}</span>
             <span className="text-lg font-bold text-sm text-black relative z-10 my-4">Fecha:</span>
-            <span> {fact.date ? format(new Date(fact.date), "dd/MM/yyyy") : "No disponible"}</span>
+            <span> {fact?.date ? format(new Date(fact.date), "dd/MM/yyyy") : "No disponible"}</span>
             <span className="text-lg font-bold text-sm text-black relative z-10 my-4">Resultado:</span>
-            <span> {fact.check.result} </span>
+            <span> {fact?.check?.result} </span>
             <span className="text-lg font-bold text-sm text-black relative z-10 my-4">Categoría:</span>
-            <span> {fact.category}</span>
+            <span> {fact?.category}</span>
             <span className="text-lg font-bold text-sm text-black relative z-10 my-4">Verificador:</span>
-            <span> {fact.check.checker}</span>
+            <span> {fact?.check?.checker}</span>
             <span className="text-lg font-bold text-sm text-black relative z-10 my-4">Subido por:</span>
-            <span> {fact.submittedBy}</span>
+            <span> {fact?.submittedBy}</span>
           </SheetDescription>
         </SheetHeader>
       </SheetContent>
diff --git a/front-office/src/schemas/create-fact-schema.ts b/front-office/src/schemas/create-fact-schema.ts
index cf7e5d6..aec15da 100644
--- a/front-office/src/schemas/create-fact-schema.ts
+++ b/front-office/src/schemas/create-fact-schema.ts
@@ -1,10 +1,10 @@
 import { z } from "zod";
 
 export const createFactSchema = z.object({
-  category: z.string().min(1, "La categoría del hecho debe tener al menos 1 caracter"),
-  description: z.string().min(1, "La descripción del hecho debe tener al menos 1 caracter"),
-  pictureUrl: z.string().url().min(1, "La url de la imagen debe tener al menos 1 caracter"),
-  title: z.string().min(1, "El titulo del hecho debe tener al menos 1 caracter"),
-  source: z.string().min(1, "La fuente del hecho debe tener al menos 1 caracter"),
-  date: z.date().min(new Date(0), "La fecha del hecho debe ser mayor a 01/01/1970"),
+  category: z.string().min(1, "Debe seleccionar una categoría"),
+  description: z.string().min(1, "Debe ingresar una descripción del hecho"),
+  pictureUrl: z.string().url().min(1, "Debe ingresar una URL de una imagen"),
+  title: z.string().min(1, "Debe ingresar un título del hecho"),
+  source: z.string().min(1, "Debe ingresar la fuente del hecho"),
+  date: z.date().min(new Date(0), "Debe ingresar una fecha válida"),
 });
-- 
GitLab