Merge branch 'inventory'
This commit is contained in:
55
apps/web/feactures/surveys/components/survey-card.tsx
Normal file
55
apps/web/feactures/surveys/components/survey-card.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import { Button } from '@repo/shadcn/button';
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from '@repo/shadcn/card';
|
||||
import { Badge } from '@repo/shadcn/badge';
|
||||
import { BadgeCheck } from 'lucide-react';
|
||||
import { SurveyAnswerForUser } from '../schemas/survey';
|
||||
|
||||
|
||||
interface cardProps {
|
||||
data: SurveyAnswerForUser;
|
||||
onClick: (id: number) => void;
|
||||
}
|
||||
|
||||
export function SurveyCard ({ data, onClick }: cardProps) {
|
||||
return (
|
||||
<Card key={data.surveys.id} className="flex flex-col">
|
||||
<CardHeader>
|
||||
<CardTitle>{data.surveys.title}</CardTitle>
|
||||
<CardDescription>{data.surveys.description}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-grow">
|
||||
<section className="space-y-2 text-sm">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-muted-foreground">Fecha de creación:</span>
|
||||
<span>{new Date(data.surveys.created_at).toLocaleDateString()}</span>
|
||||
</div>
|
||||
{data.surveys.closingDate && (
|
||||
<div className="flex justify-between">
|
||||
<span className="text-muted-foreground">Fecha de cierre:</span>
|
||||
<span>{new Date(data.surveys.closingDate).toLocaleDateString()}</span>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</CardContent>
|
||||
<CardFooter className="flex justify-center">
|
||||
{data.answers_surveys === null ? (
|
||||
<Button className="w-full" onClick={() => onClick(Number(data.surveys.id))}>
|
||||
Responder
|
||||
</Button>
|
||||
) : (
|
||||
<Badge className="px-4 py-2 w-full bg-green-600 text-black">
|
||||
<BadgeCheck size={28} />
|
||||
Realizada
|
||||
</Badge>
|
||||
)}
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -4,83 +4,99 @@
|
||||
// - Permite editar encuestas existentes
|
||||
// - Permite eliminar encuestas con confirmación
|
||||
// - Muestra el estado (publicada/borrador), fechas y conteo de respuestas
|
||||
|
||||
|
||||
'use client';
|
||||
|
||||
import { Button } from '@repo/shadcn/button';
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from '@repo/shadcn/card';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useSurveysForUserQuery } from '@/feactures/surveys/hooks/use-query-surveys';
|
||||
import { SurveyAnswerForUser } from '../schemas/survey';
|
||||
import { Badge } from '@repo/shadcn/badge';
|
||||
import { BadgeCheck } from 'lucide-react';
|
||||
import { useAllSurveysInfiniteQuery } from '@/feactures/surveys/hooks/use-query-surveys';
|
||||
import { SurveyCard } from '@/feactures/surveys/components/survey-card';
|
||||
|
||||
import { SurveyAnswerForUser } from '../schemas/survey';
|
||||
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { Input } from '@repo/shadcn/components/ui/input';
|
||||
|
||||
export function SurveyList() {
|
||||
|
||||
const router = useRouter();
|
||||
const {data: surveys} = useSurveysForUserQuery()
|
||||
const lastProductRef = useRef(null);
|
||||
const [search, setSearch] = useState("")
|
||||
|
||||
const {
|
||||
data,
|
||||
fetchNextPage,
|
||||
hasNextPage,
|
||||
isFetchingNextPage,
|
||||
isLoading
|
||||
} = useAllSurveysInfiniteQuery(search)
|
||||
|
||||
useEffect(() => {
|
||||
if (!lastProductRef.current || !hasNextPage || isFetchingNextPage) return;
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
if (entries[0]?.isIntersecting) {
|
||||
fetchNextPage();
|
||||
}
|
||||
},
|
||||
{
|
||||
root: null,
|
||||
rootMargin: '200px',
|
||||
threshold: 1.0,
|
||||
}
|
||||
);
|
||||
|
||||
observer.observe(lastProductRef.current);
|
||||
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
};
|
||||
}, [hasNextPage, isFetchingNextPage, fetchNextPage]);
|
||||
|
||||
const surveys = data?.pages.flatMap(page => page.data) || [];
|
||||
|
||||
// funcion para el buscador
|
||||
const formSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault()
|
||||
const formdata = new FormData(e.currentTarget)
|
||||
setSearch(formdata.get('search') as string)
|
||||
// console.log('submit')
|
||||
}
|
||||
|
||||
const handleRespond = (surveyId: number) => {
|
||||
router.push(`/dashboard/encuestas/${surveyId}/responder`);
|
||||
};
|
||||
|
||||
// console.log(surveys?.data)
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{surveys?.meta.totalPages === 0 ? (
|
||||
<div className="col-span-full text-center py-10">
|
||||
<form onSubmit={formSubmit} action={''} className='col-span-full text-center py-3 flex gap-3'>
|
||||
<Input name='search' type='text' placeholder='Buscar...' className='' defaultValue={search}/>
|
||||
<Button variant={'outline'} className=''>Buscar</Button>
|
||||
</form>
|
||||
{isLoading ? (
|
||||
<section className="col-span-full text-center py-10">
|
||||
<p className="text-muted-foreground">Cargando productos...</p>
|
||||
</section>
|
||||
) : surveys.length === 0 ? (
|
||||
<section className="col-span-full text-center py-10">
|
||||
<p className="text-muted-foreground">No hay encuestas disponibles en este momento.</p>
|
||||
</div>
|
||||
</section>
|
||||
) : (
|
||||
surveys?.data.map((data: SurveyAnswerForUser) => (
|
||||
|
||||
<Card key={data.surveys.id} className="flex flex-col">
|
||||
<CardHeader>
|
||||
<CardTitle>{data.surveys.title}</CardTitle>
|
||||
<CardDescription>{data.surveys.description}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-grow">
|
||||
<div className="space-y-2 text-sm">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-muted-foreground">Fecha de creación:</span>
|
||||
{/* <span>{data.surveys.created_at.toLocaleDateString()}</span> */}
|
||||
<span>{new Date(data.surveys.created_at).toLocaleDateString()}</span>
|
||||
</div>
|
||||
{data.surveys.closingDate && (
|
||||
<div className="flex justify-between">
|
||||
<span className="text-muted-foreground">Fecha de cierre:</span>
|
||||
{/* <span>{data.surveys.closingDate.toLocaleDateString()}</span> */}
|
||||
<span>{new Date(data.surveys.closingDate).toLocaleDateString()}</span>
|
||||
</div>
|
||||
)}
|
||||
<>
|
||||
{surveys.map((data: SurveyAnswerForUser, index) => {
|
||||
const isLastElement = index === surveys.length - 1;
|
||||
return (
|
||||
<div ref={isLastElement ? lastProductRef : null} key={data.surveys.id}>
|
||||
<SurveyCard data={data} onClick={handleRespond}/>
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter className="flex justify-center">
|
||||
{data.answers_surveys === null ? (
|
||||
<Button
|
||||
className="w-full"
|
||||
onClick={() => handleRespond(Number(data.surveys.id))}
|
||||
>
|
||||
Responder
|
||||
</Button>
|
||||
) : (
|
||||
<Badge className="px-4 py-2 w-full bg-green-600 text-black">
|
||||
<BadgeCheck size={28} />
|
||||
Realizada
|
||||
</Badge>
|
||||
)}
|
||||
</CardFooter>
|
||||
</Card>
|
||||
))
|
||||
)
|
||||
})}
|
||||
{isFetchingNextPage && (
|
||||
<section className="col-span-full text-center py-10">
|
||||
<p className="text-muted-foreground">Cargando más productos...</p>
|
||||
</section>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user