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