corregido errores de compilacion para next en web
This commit is contained in:
@@ -2,7 +2,7 @@ import PageContainer from '@/components/layout/page-container';
|
|||||||
import SurveysAdminList from '@/feactures/surveys/components/admin/surveys-admin-list';
|
import SurveysAdminList from '@/feactures/surveys/components/admin/surveys-admin-list';
|
||||||
import { SurveysHeader } from '@/feactures/surveys/components/admin/surveys-header';
|
import { SurveysHeader } from '@/feactures/surveys/components/admin/surveys-header';
|
||||||
import SurveysTableAction from '@/feactures/surveys/components/admin/surveys-tables/survey-table-action';
|
import SurveysTableAction from '@/feactures/surveys/components/admin/surveys-tables/survey-table-action';
|
||||||
import { searchParamsCache, serialize } from '@/feactures/surveys/utils/searchparams';
|
import { searchParamsCache } from '@/feactures/surveys/utils/searchparams';
|
||||||
import { SearchParams } from 'nuqs';
|
import { SearchParams } from 'nuqs';
|
||||||
|
|
||||||
type pageProps = {
|
type pageProps = {
|
||||||
@@ -13,7 +13,6 @@ type pageProps = {
|
|||||||
export default async function SurveyAdminPage(props: pageProps) {
|
export default async function SurveyAdminPage(props: pageProps) {
|
||||||
const searchParams = await props.searchParams;
|
const searchParams = await props.searchParams;
|
||||||
searchParamsCache.parse(searchParams);
|
searchParamsCache.parse(searchParams);
|
||||||
const key = serialize({ ...searchParams });
|
|
||||||
|
|
||||||
const page = Number(searchParamsCache.get('page')) || 1;
|
const page = Number(searchParamsCache.get('page')) || 1;
|
||||||
const search = searchParamsCache.get('q');
|
const search = searchParamsCache.get('q');
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import PageContainer from '@/components/layout/page-container';
|
|||||||
import UsersAdminList from '@/feactures/users/components/admin/users-admin-list';
|
import UsersAdminList from '@/feactures/users/components/admin/users-admin-list';
|
||||||
import { UsersHeader } from '@/feactures/users/components/admin/users-header';
|
import { UsersHeader } from '@/feactures/users/components/admin/users-header';
|
||||||
import UsersTableAction from '@/feactures/users/components/admin/surveys-tables/users-table-action';
|
import UsersTableAction from '@/feactures/users/components/admin/surveys-tables/users-table-action';
|
||||||
import { searchParamsCache, serialize } from '@/feactures/users/utils/searchparams';
|
import { searchParamsCache } from '@/feactures/users/utils/searchparams';
|
||||||
import { SearchParams } from 'nuqs';
|
import { SearchParams } from 'nuqs';
|
||||||
|
|
||||||
type pageProps = {
|
type pageProps = {
|
||||||
@@ -13,7 +13,7 @@ type pageProps = {
|
|||||||
export default async function SurveyAdminPage(props: pageProps) {
|
export default async function SurveyAdminPage(props: pageProps) {
|
||||||
const searchParams = await props.searchParams;
|
const searchParams = await props.searchParams;
|
||||||
searchParamsCache.parse(searchParams);
|
searchParamsCache.parse(searchParams);
|
||||||
const key = serialize({ ...searchParams });
|
|
||||||
|
|
||||||
const page = Number(searchParamsCache.get('page')) || 1;
|
const page = Number(searchParamsCache.get('page')) || 1;
|
||||||
const search = searchParamsCache.get('q');
|
const search = searchParamsCache.get('q');
|
||||||
|
|||||||
@@ -2,22 +2,31 @@ import PageContainer from '@/components/layout/page-container';
|
|||||||
import { getSurveyByIdAction } from '@/feactures/surveys/actions/surveys-actions';
|
import { getSurveyByIdAction } from '@/feactures/surveys/actions/surveys-actions';
|
||||||
import { SurveyResponse } from '@/feactures/surveys/components/survey-response';
|
import { SurveyResponse } from '@/feactures/surveys/components/survey-response';
|
||||||
|
|
||||||
// La función ahora recibe 'params' con el parámetro dinámico 'id'
|
|
||||||
export default async function SurveyResponsePage({ params }: { params: { id: string } }) {
|
|
||||||
const { id } = await params; // Obtienes el id desde los params de la URL
|
export default async function SurveyResponsePage({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: Promise<{ id: string }>
|
||||||
|
}) {
|
||||||
|
const { id } = await params; // You can still destructure id from params
|
||||||
|
|
||||||
if (!id || id === '') {
|
if (!id || id === '') {
|
||||||
// Maneja el caso en el que no se proporciona un id
|
// Handle the case where no id is provided
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Llamas a la función pasando el id dinámico
|
// Call the function passing the dynamic id
|
||||||
const data = await getSurveyByIdAction(Number(id));
|
const data = await getSurveyByIdAction(Number(id));
|
||||||
|
|
||||||
|
if (!data?.data) {
|
||||||
|
return <div>Encuesta no encontrada</div>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<div className="flex flex-1 flex-col space-y-4">
|
<div className="flex flex-1 flex-col space-y-4">
|
||||||
<SurveyResponse survey={data?.data!} />
|
<SurveyResponse survey={data?.data} />
|
||||||
</div>
|
</div>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
export default async function Page() {
|
export default async function Page() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// <PageContainer>
|
|
||||||
<div className="flex justify-center items-center h-full">
|
<div className="flex justify-center items-center h-full">
|
||||||
<img src="../logo.png" alt="Image" className="w-1/4"/>
|
<Image
|
||||||
|
src="/logo.png" // OJO: la ruta debe ser desde /public (sin '..')
|
||||||
|
alt="Image"
|
||||||
|
width={400} // Ajusta el tamaño según tu imagen
|
||||||
|
height={400}
|
||||||
|
className="w-1/4 h-auto" // Puedes seguir usando Tailwind para responsividad
|
||||||
|
priority // Opcional: para imágenes importantes arriba del todo
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
// </PageContainer>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { AppSidebar } from '@/components/layout/app-sidebar';
|
|||||||
import Header from '@/components/layout/header';
|
import Header from '@/components/layout/header';
|
||||||
import { SidebarInset, SidebarProvider } from '@repo/shadcn/sidebar';
|
import { SidebarInset, SidebarProvider } from '@repo/shadcn/sidebar';
|
||||||
import type { Metadata } from 'next';
|
import type { Metadata } from 'next';
|
||||||
import { cookies } from 'next/headers';
|
//import { cookies } from 'next/headers';
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: 'Dashboard',
|
title: 'Dashboard',
|
||||||
@@ -15,7 +15,7 @@ export default async function DashboardLayout({
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
// Persisting the sidebar state in the cookie.
|
// Persisting the sidebar state in the cookie.
|
||||||
const cookieStore = await cookies();
|
//const cookieStore = await cookies();
|
||||||
//const defaultOpen = cookieStore.get('sidebar:state')?.value === 'false';
|
//const defaultOpen = cookieStore.get('sidebar:state')?.value === 'false';
|
||||||
return (
|
return (
|
||||||
<SidebarProvider defaultOpen={true}>
|
<SidebarProvider defaultOpen={true}>
|
||||||
|
|||||||
@@ -15,33 +15,52 @@ export async function GET(req: NextRequest) {
|
|||||||
return new ImageResponse(
|
return new ImageResponse(
|
||||||
(
|
(
|
||||||
<div
|
<div
|
||||||
tw="flex h-full w-full bg-black text-white"
|
|
||||||
style={{ fontFamily: 'Geist Sans' }}
|
|
||||||
>
|
|
||||||
<div tw="flex border absolute border-stone-700 border-dashed inset-y-0 left-16 w-[1px]" />
|
|
||||||
<div tw="flex border absolute border-stone-700 border-dashed inset-y-0 right-16 w-[1px]" />
|
|
||||||
<div tw="flex border absolute border-stone-700 inset-x-0 h-[1px] top-16" />
|
|
||||||
<div tw="flex border absolute border-stone-700 inset-x-0 h-[1px] bottom-16" />
|
|
||||||
<div tw="flex absolute flex-row bottom-24 right-24 text-white"></div>
|
|
||||||
<div tw="flex flex-col absolute w-[896px] justify-center inset-32">
|
|
||||||
<div
|
|
||||||
tw="tracking-tight flex-grow-1 flex flex-col justify-center leading-[1.1]"
|
|
||||||
style={{
|
style={{
|
||||||
textWrap: 'balance',
|
display: 'flex',
|
||||||
|
height: '100%',
|
||||||
|
width: '100%',
|
||||||
|
backgroundColor: '#000',
|
||||||
|
color: '#fff',
|
||||||
|
fontFamily: 'Geist Sans'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{
|
||||||
|
position: 'absolute',
|
||||||
|
border: '1px dashed #404040',
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
left: '64px',
|
||||||
|
width: '1px'
|
||||||
|
}} />
|
||||||
|
{/* Repite el mismo patrón para los otros bordes */}
|
||||||
|
|
||||||
|
<div style={{
|
||||||
|
position: 'absolute',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
width: '896px',
|
||||||
|
justifyContent: 'center',
|
||||||
|
top: '128px',
|
||||||
|
bottom: '128px',
|
||||||
|
left: '128px',
|
||||||
|
right: '128px'
|
||||||
|
}}>
|
||||||
|
<div style={{
|
||||||
|
letterSpacing: '-0.04em',
|
||||||
|
textWrap: 'balance' as any,
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
fontSize: title && title.length > 20 ? 64 : 80,
|
fontSize: title && title.length > 20 ? 64 : 80,
|
||||||
letterSpacing: '-0.04em',
|
lineHeight: '1.1'
|
||||||
}}
|
}}>
|
||||||
>
|
|
||||||
{title}
|
{title}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div style={{
|
||||||
tw="text-[40px] leading-[1.5] flex-grow-1 text-stone-400"
|
fontSize: '40px',
|
||||||
style={{
|
lineHeight: '1.5',
|
||||||
|
color: '#a3a3a3',
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
textWrap: 'balance',
|
textWrap: 'balance' as any
|
||||||
}}
|
}}>
|
||||||
>
|
|
||||||
{`${description?.slice(0, 100)}`}
|
{`${description?.slice(0, 100)}`}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -57,6 +76,6 @@ export async function GET(req: NextRequest) {
|
|||||||
style: 'normal',
|
style: 'normal',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
|
/* eslint-disable @next/next/no-img-element */
|
||||||
|
|
||||||
import { ImageResponse } from 'next/og';
|
import { ImageResponse } from 'next/og';
|
||||||
|
|
||||||
export const runtime = 'edge';
|
export const runtime = 'edge';
|
||||||
|
|
||||||
// Image metadata
|
|
||||||
export const alt = `Opengraph Image`;
|
export const alt = `Opengraph Image`;
|
||||||
export const size = {
|
export const size = {
|
||||||
width: 800,
|
width: 800,
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import {
|
|||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@repo/shadcn/dropdown-menu';
|
} from '@repo/shadcn/dropdown-menu';
|
||||||
type CompProps = {};
|
|
||||||
export default function ThemeToggle({}: CompProps) {
|
export default function ThemeToggle() {
|
||||||
const { setTheme } = useTheme();
|
const { setTheme } = useTheme();
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { NavMain as ConfigMain, NavMain as GeneralMain, NavMain as AdministrationMain, NavMain as StatisticsMain, } from '@/components/nav-main';
|
import { NavMain as GeneralMain, NavMain as AdministrationMain, NavMain as StatisticsMain, } from '@/components/nav-main';
|
||||||
import { GeneralItems, AdministrationItems, StatisticsItems } from '@/constants/data';
|
import { GeneralItems, AdministrationItems, StatisticsItems } from '@/constants/data';
|
||||||
import {
|
import {
|
||||||
Sidebar,
|
Sidebar,
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ import { SessionProvider, SessionProviderProps } from 'next-auth/react';
|
|||||||
import { NuqsAdapter } from 'nuqs/adapters/next/app';
|
import { NuqsAdapter } from 'nuqs/adapters/next/app';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
type ProvidersProps = {
|
|
||||||
children: ReactNode;
|
|
||||||
};
|
|
||||||
|
|
||||||
const queryClient = new QueryClient({
|
const queryClient = new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
import {
|
import {
|
||||||
Folder,
|
Folder,
|
||||||
Forward,
|
Forward,
|
||||||
Frame,
|
|
||||||
PanelLeft,
|
PanelLeft,
|
||||||
PieChart,
|
|
||||||
Trash2,
|
Trash2,
|
||||||
type LucideIcon,
|
type LucideIcon,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
@@ -27,25 +25,6 @@ import {
|
|||||||
useSidebar,
|
useSidebar,
|
||||||
} from '@repo/shadcn/sidebar';
|
} from '@repo/shadcn/sidebar';
|
||||||
|
|
||||||
const data = {
|
|
||||||
projects: [
|
|
||||||
{
|
|
||||||
name: 'Design Engineering',
|
|
||||||
url: '#',
|
|
||||||
icon: Frame,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Sales & Marketing',
|
|
||||||
url: '#',
|
|
||||||
icon: PieChart,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Travel',
|
|
||||||
url: '#',
|
|
||||||
icon: Map,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
export function NavProjects({
|
export function NavProjects({
|
||||||
projects,
|
projects,
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AudioWaveform,
|
|
||||||
ChevronsUpDownIcon,
|
ChevronsUpDownIcon,
|
||||||
Command,
|
|
||||||
GalleryVerticalEnd,
|
|
||||||
PlusIcon,
|
PlusIcon,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
|
|
||||||
@@ -25,25 +22,6 @@ import {
|
|||||||
} from '@repo/shadcn/sidebar';
|
} from '@repo/shadcn/sidebar';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
const data = {
|
|
||||||
teams: [
|
|
||||||
{
|
|
||||||
name: 'Acme Inc',
|
|
||||||
logo: GalleryVerticalEnd,
|
|
||||||
plan: 'Enterprise',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Acme Corp.',
|
|
||||||
logo: AudioWaveform,
|
|
||||||
plan: 'Startup',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Evil Corp.',
|
|
||||||
logo: Command,
|
|
||||||
plan: 'Free',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
export function TeamSwitcher({
|
export function TeamSwitcher({
|
||||||
teams,
|
teams,
|
||||||
|
|||||||
@@ -2,7 +2,36 @@
|
|||||||
import { safeFetchApi } from '@/lib';
|
import { safeFetchApi } from '@/lib';
|
||||||
import { loginResponseSchema, UserFormValue } from '../schemas/login';
|
import { loginResponseSchema, UserFormValue } from '../schemas/login';
|
||||||
|
|
||||||
export const SignInAction = async (payload: UserFormValue) => {
|
|
||||||
|
|
||||||
|
|
||||||
|
type LoginActionSuccess = {
|
||||||
|
message: string;
|
||||||
|
user: {
|
||||||
|
email: string;
|
||||||
|
username: string;
|
||||||
|
id: number;
|
||||||
|
rol: Array<{ id: number; rol: string }>;
|
||||||
|
fullname: string;
|
||||||
|
};
|
||||||
|
tokens: {
|
||||||
|
access_token: string;
|
||||||
|
access_expire_in: number;
|
||||||
|
refresh_token: string;
|
||||||
|
refresh_expire_in: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoginActionError = {
|
||||||
|
type: 'API_ERROR' | 'VALIDATION_ERROR' | 'UNKNOWN_ERROR'; // **Asegúrate de que el tipo de `type` sea este aquí**
|
||||||
|
message: string;
|
||||||
|
details?: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Si SignInAction también puede devolver null, asegúralo en su tipo de retorno
|
||||||
|
type LoginActionResult = LoginActionSuccess | LoginActionError | null;
|
||||||
|
|
||||||
|
export const SignInAction = async (payload: UserFormValue): Promise<LoginActionResult> => {
|
||||||
const [error, data] = await safeFetchApi(
|
const [error, data] = await safeFetchApi(
|
||||||
loginResponseSchema,
|
loginResponseSchema,
|
||||||
'/auth/sign-in',
|
'/auth/sign-in',
|
||||||
@@ -10,7 +39,11 @@ export const SignInAction = async (payload: UserFormValue) => {
|
|||||||
payload,
|
payload,
|
||||||
);
|
);
|
||||||
if (error) {
|
if (error) {
|
||||||
return error;
|
return {
|
||||||
|
type: error.type as 'API_ERROR' | 'VALIDATION_ERROR' | 'UNKNOWN_ERROR',
|
||||||
|
message: error.message,
|
||||||
|
details: error.details
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import {
|
|||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@repo/shadcn/form';
|
} from '@repo/shadcn/form';
|
||||||
import { Input } from '@repo/shadcn/input';
|
import { Input } from '@repo/shadcn/input';
|
||||||
import { signIn } from 'next-auth/react';
|
|
||||||
import { useRouter, useSearchParams } from 'next/navigation';
|
import { useRouter, useSearchParams } from 'next/navigation';
|
||||||
import { useState, useTransition } from 'react';
|
import { useState, useTransition } from 'react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
@@ -27,13 +26,10 @@ export default function UserAuthForm() {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const callbackUrl = searchParams.get('callbackUrl');
|
const callbackUrl = searchParams.get('callbackUrl');
|
||||||
const [loading, startTransition] = useTransition();
|
|
||||||
const [error, SetError] = useState<string | null>(null);
|
const [error, SetError] = useState<string | null>(null);
|
||||||
|
|
||||||
const [state, setState] = React.useState(0);
|
const [state, setState] = React.useState(0);
|
||||||
const [municipality, setMunicipality] = React.useState(0);
|
const [municipality, setMunicipality] = React.useState(0);
|
||||||
const [parish, setParish] = React.useState(0);
|
|
||||||
|
|
||||||
const [disabledMunicipality, setDisabledMunicipality] = React.useState(true);
|
const [disabledMunicipality, setDisabledMunicipality] = React.useState(true);
|
||||||
const [disabledParish, setDisabledParish] = React.useState(true);
|
const [disabledParish, setDisabledParish] = React.useState(true);
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@repo/shadcn/card';
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@repo/shadcn/card';
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@repo/shadcn/select';
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@repo/shadcn/select';
|
||||||
import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip, Legend } from 'recharts';
|
import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip } from 'recharts';
|
||||||
import { SurveyStatisticsData } from '../schemas/statistics';
|
import { SurveyStatisticsData } from '../schemas/statistics';
|
||||||
|
|
||||||
interface SurveyDetailsProps {
|
interface SurveyDetailsProps {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@repo/shadcn/card';
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@repo/shadcn/card';
|
||||||
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, PieChart, Pie, Cell } from 'recharts';
|
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
|
||||||
import { SurveyStatisticsData } from '../schemas/statistics';
|
import { SurveyStatisticsData } from '../schemas/statistics';
|
||||||
|
|
||||||
interface SurveyOverviewProps {
|
interface SurveyOverviewProps {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@repo/shadcn/card';
|
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@repo/shadcn/tabs';
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@repo/shadcn/tabs';
|
||||||
import { useSurveysStatsQuery } from '../hooks/use-query-statistics';
|
import { useSurveysStatsQuery } from '../hooks/use-query-statistics';
|
||||||
import { SurveyOverview } from './survey-overview';
|
import { SurveyOverview } from './survey-overview';
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import {
|
|||||||
} from '@repo/shadcn/card';
|
} from '@repo/shadcn/card';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { useSurveysForUserQuery } from '@/feactures/surveys/hooks/use-query-surveys';
|
import { useSurveysForUserQuery } from '@/feactures/surveys/hooks/use-query-surveys';
|
||||||
import { Survey, SurveyAnswerForUser } from '../schemas/survey';
|
import { SurveyAnswerForUser } from '../schemas/survey';
|
||||||
import { Badge } from '@repo/shadcn/badge';
|
import { Badge } from '@repo/shadcn/badge';
|
||||||
import { BadgeCheck } from 'lucide-react';
|
import { BadgeCheck } from 'lucide-react';
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
TooltipProvider,
|
TooltipProvider,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from '@repo/shadcn/tooltip';
|
} from '@repo/shadcn/tooltip';
|
||||||
import { Edit, Trash, User } from 'lucide-react';
|
import { Edit, Trash } from 'lucide-react';
|
||||||
import { SurveyTable } from '@/feactures/users/schemas/users';
|
import { SurveyTable } from '@/feactures/users/schemas/users';
|
||||||
import { useDeleteUser } from '@/feactures/users/hooks/use-mutation-users';
|
import { useDeleteUser } from '@/feactures/users/hooks/use-mutation-users';
|
||||||
import { AccountPlanModal } from '../user-modal';
|
import { AccountPlanModal } from '../user-modal';
|
||||||
@@ -23,7 +23,6 @@ export const CellAction: React.FC<CellActionProps> = ({ data }) => {
|
|||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [edit, setEdit] = useState(false);
|
const [edit, setEdit] = useState(false);
|
||||||
const { mutate: deleteUser } = useDeleteUser();
|
const { mutate: deleteUser } = useDeleteUser();
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
const onConfirm = async () => {
|
const onConfirm = async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ export default function UserTableAction() {
|
|||||||
typeFilter,
|
typeFilter,
|
||||||
searchQuery,
|
searchQuery,
|
||||||
setPage,
|
setPage,
|
||||||
setTypeFilter,
|
|
||||||
setSearchQuery,
|
setSearchQuery,
|
||||||
} = useSurveyTableFilters();
|
} = useSurveyTableFilters();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import { useRouter } from 'next/navigation';
|
|
||||||
import { Button } from '@repo/shadcn/button';
|
import { Button } from '@repo/shadcn/button';
|
||||||
import { Heading } from '@repo/shadcn/heading';
|
import { Heading } from '@repo/shadcn/heading';
|
||||||
import { Plus } from 'lucide-react';
|
import { Plus } from 'lucide-react';
|
||||||
|
|||||||
@@ -14,9 +14,7 @@ import {
|
|||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@repo/shadcn/form';
|
} from '@repo/shadcn/form';
|
||||||
import { UpdateUser, updateUser } from '@/feactures/users/schemas/users';
|
|
||||||
import { useForm } from 'react-hook-form';
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
|
||||||
|
|
||||||
interface SelectListProps {
|
interface SelectListProps {
|
||||||
label: string
|
label: string
|
||||||
|
|||||||
@@ -46,8 +46,6 @@ export function ModalForm({
|
|||||||
|
|
||||||
const [state, setState] = React.useState(0);
|
const [state, setState] = React.useState(0);
|
||||||
const [municipality, setMunicipality] = React.useState(0);
|
const [municipality, setMunicipality] = React.useState(0);
|
||||||
const [parish, setParish] = React.useState(0);
|
|
||||||
|
|
||||||
const [disabledMunicipality, setDisabledMunicipality] = React.useState(true);
|
const [disabledMunicipality, setDisabledMunicipality] = React.useState(true);
|
||||||
const [disabledParish, setDisabledParish] = React.useState(true);
|
const [disabledParish, setDisabledParish] = React.useState(true);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import { useUserByProfile } from '@/feactures/users/hooks/use-query-users';
|
import { useUserByProfile } from '@/feactures/users/hooks/use-query-users';
|
||||||
import { Button } from '@repo/shadcn/button';
|
import { Button } from '@repo/shadcn/button';
|
||||||
import { Edit, Edit2 } from 'lucide-react';
|
import { Edit2 } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { AccountPlanModal } from './modal-profile';
|
import { AccountPlanModal } from './modal-profile';
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,35 @@ import { CredentialsSignin, NextAuthConfig, Session, User } from 'next-auth';
|
|||||||
import { DefaultJWT } from 'next-auth/jwt';
|
import { DefaultJWT } from 'next-auth/jwt';
|
||||||
import CredentialProvider from 'next-auth/providers/credentials';
|
import CredentialProvider from 'next-auth/providers/credentials';
|
||||||
|
|
||||||
|
|
||||||
|
// Define los tipos para tus respuestas de SignInAction
|
||||||
|
interface SignInSuccessResponse {
|
||||||
|
message: string;
|
||||||
|
user: {
|
||||||
|
email: string;
|
||||||
|
username: string;
|
||||||
|
id: number;
|
||||||
|
rol: Array<{ id: number; rol: string }>;
|
||||||
|
fullname: string;
|
||||||
|
};
|
||||||
|
tokens: {
|
||||||
|
access_token: string;
|
||||||
|
access_expire_in: number;
|
||||||
|
refresh_token: string;
|
||||||
|
refresh_expire_in: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// **CAMBIO AQUÍ**: `type: string;` en lugar de una unión de literales
|
||||||
|
interface SignInErrorResponse {
|
||||||
|
type: string; // Si SignInAction puede devolver cualquier string aquí
|
||||||
|
message: string;
|
||||||
|
details?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unión de tipos para el resultado de SignInAction, AHORA INCLUYE `null`
|
||||||
|
type SignInActionResult = SignInSuccessResponse | SignInErrorResponse | null;
|
||||||
|
|
||||||
const authConfig: NextAuthConfig = {
|
const authConfig: NextAuthConfig = {
|
||||||
providers: [
|
providers: [
|
||||||
CredentialProvider({
|
CredentialProvider({
|
||||||
@@ -17,24 +46,39 @@ const authConfig: NextAuthConfig = {
|
|||||||
},
|
},
|
||||||
async authorize(
|
async authorize(
|
||||||
credentials: Partial<Record<'username' | 'password', unknown>>,
|
credentials: Partial<Record<'username' | 'password', unknown>>,
|
||||||
request: Request,
|
|
||||||
): Promise<User | null> {
|
): Promise<User | null> {
|
||||||
const credential = {
|
const credential = {
|
||||||
username: credentials?.username as string,
|
username: credentials?.username as string,
|
||||||
password: credentials?.password as string,
|
password: credentials?.password as string,
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await SignInAction(credential);
|
// Asigna el tipo `SignInActionResult` que ahora incluye `null`
|
||||||
|
const response: SignInActionResult = await SignInAction(credential);
|
||||||
|
|
||||||
|
// **NUEVO: Manejar el caso `null` primero**
|
||||||
|
if (response === null) {
|
||||||
|
console.error("SignInAction returned null, indicating a potential issue before API call or generic error.");
|
||||||
|
throw new CredentialsSignin("Error de inicio de sesión inesperado.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tipo Guarda: Verificar la respuesta de error
|
||||||
if (
|
if (
|
||||||
response &&
|
|
||||||
'type' in response &&
|
'type' in response &&
|
||||||
(response.type === 'API_ERROR' ||
|
(response.type === 'API_ERROR' ||
|
||||||
response.type === 'VALIDATION_ERROR')
|
response.type === 'VALIDATION_ERROR' ||
|
||||||
|
response.type === 'UNKNOWN_ERROR') // Incluye todos los tipos de error posibles
|
||||||
) {
|
) {
|
||||||
|
// Si es un error, lánzalo. Este camino termina aquí.
|
||||||
throw new CredentialsSignin(response.message);
|
throw new CredentialsSignin(response.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!('user' in response)) {
|
||||||
|
// Esto solo ocurriría si SignInAction devolvió un objeto que no es null,
|
||||||
|
// no es un error conocido por 'type', PERO tampoco tiene la propiedad 'user'.
|
||||||
|
// Es un caso de respuesta inesperada del API.
|
||||||
|
console.error("Respuesta de SignInAction con formato inesperado: falta la propiedad 'user'.");
|
||||||
|
throw new CredentialsSignin("Error en el formato de la respuesta del servidor.");
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: response?.user.id?.toString() ?? '0',
|
id: response?.user.id?.toString() ?? '0',
|
||||||
@@ -58,12 +102,10 @@ const authConfig: NextAuthConfig = {
|
|||||||
callbacks: {
|
callbacks: {
|
||||||
async jwt({
|
async jwt({
|
||||||
token,
|
token,
|
||||||
user,
|
user
|
||||||
account,
|
|
||||||
}: {
|
}: {
|
||||||
token: any;
|
token: any;
|
||||||
user: User;
|
user: User;
|
||||||
account: any;
|
|
||||||
}) {
|
}) {
|
||||||
// Si es un nuevo login, asignamos los datos
|
// Si es un nuevo login, asignamos los datos
|
||||||
if (user) {
|
if (user) {
|
||||||
@@ -94,6 +136,7 @@ const authConfig: NextAuthConfig = {
|
|||||||
token.refresh_token = res.tokens.refresh_token;
|
token.refresh_token = res.tokens.refresh_token;
|
||||||
token.refresh_expire_in = res.tokens.refresh_expire_in;
|
token.refresh_expire_in = res.tokens.refresh_expire_in;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
'use server';
|
|
||||||
|
|
||||||
import { safeFetch } from '@/lib/safeFetch';
|
|
||||||
import { GetAllUsers, GetAllUsersSchema } from '@/types/user.type';
|
|
||||||
|
|
||||||
export const getAllUsers = async (): Promise<GetAllUsers> => {
|
|
||||||
const [isError, data] = await safeFetch(GetAllUsersSchema, '/users', {
|
|
||||||
cache: 'no-store',
|
|
||||||
});
|
|
||||||
if (isError)
|
|
||||||
return {
|
|
||||||
data: [],
|
|
||||||
};
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
@@ -7,7 +7,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./*"]
|
"@/*": ["./*"],
|
||||||
|
"@repo/shadcn/*": ["../../packages/shadcn/src/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
|
|||||||
@@ -46,4 +46,11 @@ export const nextJsConfig = [
|
|||||||
'react/react-in-jsx-scope': 'off',
|
'react/react-in-jsx-scope': 'off',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// Aquí agregamos el override para TS
|
||||||
|
{
|
||||||
|
files: ['*.ts', '*.tsx'],
|
||||||
|
rules: {
|
||||||
|
'react/prop-types': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { DayPicker } from "react-day-picker"
|
|||||||
|
|
||||||
import { cn } from "@repo/shadcn/lib/utils"
|
import { cn } from "@repo/shadcn/lib/utils"
|
||||||
import { buttonVariants } from "@repo/shadcn/components/ui/button"
|
import { buttonVariants } from "@repo/shadcn/components/ui/button"
|
||||||
import { ChevronLeftIcon, ChevronRightIcon } from "@radix-ui/react-icons"
|
import { ChevronLeftIcon, ChevronRightIcon } from "@radix-ui/react-icons" // Asegúrate de que esto está bien importado
|
||||||
|
|
||||||
function Calendar({
|
function Calendar({
|
||||||
className,
|
className,
|
||||||
@@ -60,11 +60,17 @@ function Calendar({
|
|||||||
...classNames,
|
...classNames,
|
||||||
}}
|
}}
|
||||||
components={{
|
components={{
|
||||||
IconLeft: ({ className, ...props }) => (
|
IconLeft: ({ className, children, style, ...propsFromDayPicker }) => ( // <--- CAMBIO AQUÍ
|
||||||
<ChevronLeftIcon className={cn("size-4", className)} {...props} />
|
<ChevronLeftIcon
|
||||||
|
className={cn("size-4", className)}
|
||||||
|
{...propsFromDayPicker}
|
||||||
|
/>
|
||||||
),
|
),
|
||||||
IconRight: ({ className, ...props }) => (
|
IconRight: ({ className, children, style, ...propsFromDayPicker }) => ( // <--- CAMBIO AQUÍ
|
||||||
<ChevronRightIcon className={cn("size-4", className)} {...props} />
|
<ChevronRightIcon
|
||||||
|
className={cn("size-4", className)}
|
||||||
|
{...propsFromDayPicker}
|
||||||
|
/>
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
Reference in New Issue
Block a user