base con autenticacion, registro, modulo encuestas

This commit is contained in:
2025-06-16 12:02:22 -04:00
commit 475e0754df
411 changed files with 26265 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
import { AlertModal } from '@/components/modal/alert-modal';
import { Button } from '@repo/shadcn/button';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@repo/shadcn/tooltip';
import { Edit, Trash } from 'lucide-react';
import { SurveyTable } from '@/feactures/surveys/schemas/survey';
import { useDeleteSurvey } from '@/feactures/surveys/hooks/use-mutation-surveys';
interface CellActionProps {
data: SurveyTable;
}
export const CellAction: React.FC<CellActionProps> = ({ data }) => {
const [loading, setLoading] = useState(false);
const [open, setOpen] = useState(false);
const { mutate: deleteSurvey } = useDeleteSurvey();
const router = useRouter();
const onConfirm = async () => {
try {
setLoading(true);
deleteSurvey(data.id!);
setOpen(false);
} catch (error) {
console.error('Error:', error);
} finally {
setLoading(false);
}
};
return (
<>
<AlertModal
isOpen={open}
onClose={() => setOpen(false)}
onConfirm={onConfirm}
loading={loading}
title="¿Estás seguro que desea eliminar la encuesta?"
description="Esta acción no se puede deshacer."
/>
<div className="flex gap-1">
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
size="icon"
onClick={() => router.push(`/dashboard/administracion/encuestas/editar/${data.id!}`)}
>
<Edit className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Editar</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
size="icon"
onClick={() => setOpen(true)}
>
<Trash className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Eliminar</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
</>
);
};

View File

@@ -0,0 +1,29 @@
import { Badge } from "@repo/shadcn/badge";
import { ColumnDef } from '@tanstack/react-table';
import { CellAction } from './cell-action';
import { SurveyTable } from '@/feactures/surveys/schemas/survey';
export const columns: ColumnDef<SurveyTable>[] = [
{
accessorKey: 'title',
header: 'Título',
},
{
accessorKey: "published",
header: "Estado",
cell: ({ row }) => {
const published = row.getValue("published");
return (
<Badge variant={published == 'Publicada' ? "default" : "secondary"}>
{published == 'Publicada' ? 'Publicada' : 'Borrador'}
</Badge>
)
},
},
{
id: 'actions',
header: 'Acciones',
cell: ({ row }) => <CellAction data={row.original} />,
},
];

View File

@@ -0,0 +1,36 @@
'use client';
import { DataTableFilterBox } from '@repo/shadcn/table/data-table-filter-box';
import { DataTableSearch } from '@repo/shadcn/table/data-table-search';
import {
TYPE_OPTIONS,
useSurveyTableFilters,
} from './use-survey-table-filters';
export default function SurveysTableAction() {
const {
typeFilter,
searchQuery,
setPage,
setTypeFilter,
setSearchQuery,
} = useSurveyTableFilters();
return (
<div className="flex flex-wrap items-center gap-4 pt-2">
<DataTableSearch
searchKey={searchQuery}
searchQuery={searchQuery || ''}
setSearchQuery={setSearchQuery}
setPage={setPage}
/>
<DataTableFilterBox
filterKey="type"
title="Estado"
options={TYPE_OPTIONS}
setFilterValue={setTypeFilter}
filterValue={typeFilter}
/>
</div>
);
}

View File

@@ -0,0 +1,59 @@
'use client';
import { PUBLISHED_TYPES } from '@/feactures/surveys/schemas/surveys-options';
import { searchParams } from '@repo/shadcn/lib/searchparams';
import { useQueryState } from 'nuqs';
import { useCallback, useMemo } from 'react';
export const TYPE_OPTIONS = Object.entries(PUBLISHED_TYPES).map(
([value, label]) => ({
value,
label,
}),
);
export function useSurveyTableFilters() {
const [searchQuery, setSearchQuery] = useQueryState(
'q',
searchParams.q
.withOptions({
shallow: false,
throttleMs: 500, // Add 500ms delay
// Removed dedupingInterval as it's not a valid option
})
.withDefault(''),
);
const [typeFilter, setTypeFilter] = useQueryState(
'published',
searchParams.q.withOptions({ shallow: false }).withDefault(''),
);
const [page, setPage] = useQueryState(
'page',
searchParams.page.withDefault(1),
);
const resetFilters = useCallback(() => {
setSearchQuery(null);
setTypeFilter(null);
setPage(1);
}, [setSearchQuery, setPage]);
const isAnyFilterActive = useMemo(() => {
return !!searchQuery || !!typeFilter;
}, [searchQuery]);
return {
searchQuery,
setSearchQuery,
page,
setPage,
resetFilters,
isAnyFilterActive,
typeFilter,
setTypeFilter
};
}