Skip to content

Commit

Permalink
Merge branch 'main' into feature/add-api-for-request-and-ofers
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickwebsdev authored Nov 8, 2024
2 parents 811bde1 + 4e172df commit 4c275ff
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 194 deletions.
4 changes: 2 additions & 2 deletions src/app/api/user/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createServerRoleClient } from '@/lib/supabase/server_role';
import { createClient } from '@/lib/supabase/server';

export async function GET() {
const supabase = await createServerRoleClient();
const supabase = await createClient();
const { data, error } = await supabase.auth.getUser();
if (error || !data?.user) {
return Response.json({ message: 'Not logged.', error });
Expand Down
190 changes: 38 additions & 152 deletions src/app/casos-activos/solicitudes/page.tsx
Original file line number Diff line number Diff line change
@@ -1,181 +1,67 @@
'use client';

import { Suspense, useEffect, useState } from 'react';
import { supabase } from '@/lib/supabase/client';
import { Search } from 'lucide-react';
import SolicitudCard from '@/components/SolicitudCard';
import Pagination from '@/components/Pagination';
import { useRouter, useSearchParams } from 'next/navigation';
import { tiposAyudaOptions } from '@/helpers/constants';
import { useTowns } from '@/context/TownProvider';
import { useSession } from '@/context/SessionProvider';
import Link from 'next/link';
import { useQuery } from '@tanstack/react-query';
import { HelpRequestData } from '@/types/Requests';
import { helpRequestService } from '@/lib/service';

export const dynamic = 'force-dynamic';

export default function SolicitudesPage() {
return (
<Suspense>
<Solicitudes />
</Suspense>
);
}

function Solicitudes() {
const { towns } = useTowns();
const searchParams = useSearchParams();
const router = useRouter();

const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);

const [data, setData] = useState<HelpRequestData[]>([]);
const [currentPage, setCurrentPage] = useState<number>(Number(searchParams.get('page')) || 1);
const [currentCount, setCurrentCount] = useState<number>(0);

const itemsPerPage = 10;
const numPages = (count: number) => {
return Math.ceil(count / itemsPerPage) || 0;
};

const updateFilter = (filter: 'urgencia' | 'tipoAyuda' | 'pueblo' | 'page', value: string | number) => {
const params = new URLSearchParams(searchParams.toString());
params.set(filter, value.toString());
router.push(`?${params.toString()}`);
};

const [filtroData, setFiltroData] = useState({
urgencia: searchParams.get('urgencia') || 'todas',
tipoAyuda: searchParams.get('tipoAyuda') || 'todas',
pueblo: searchParams.get('pueblo') || 'todos',
export default function ListaSolicitudes() {
const session = useSession();
const userId = session.user?.id;

const {
data: requests,
isLoading,
error,
} = useQuery<HelpRequestData[]>({
queryKey: ['help_requests', { user_id: userId, type: 'necesita' }],
queryFn: () => helpRequestService.getRequestsByUser(userId),
});

const changeDataFilter = (type: 'urgencia' | 'tipoAyuda' | 'pueblo', newFilter: string) => {
setFiltroData((prev) => ({
...prev,
[type]: newFilter,
}));
updateFilter(type, newFilter);
};

function changePage(newPage: number) {
setCurrentPage(newPage);
updateFilter('page', newPage);
}

useEffect(() => {
async function fetchData() {
const url = process.env.NEXT_PUBLIC_BASE_URL + '/api/solicitudes/?';
try {
setLoading(true);
setError(null);
const filter = [];

if (filtroData.tipoAyuda !== 'todas') {
filter.push('type=' + filtroData.tipoAyuda);
}

// Solo agregar filtro si no es "todos"
if (filtroData.pueblo !== 'todos') {
filter.push('town=' + filtroData.pueblo);
}

// Solo agregar filtro si no es "todas"
if (filtroData.urgencia !== 'todas') {
filter.push('urgency=' + filtroData.urgencia);
}
filter.push('page=' + currentPage);
const filterUrl = url + filter.join('&');
const response = await fetch(filterUrl);
if (!response.ok) {
console.log(`Error fetching solicitudes: ${response.status}`);
setData([]);
} else {
const { data, count } = await response.json();
setData(data || []);
setCurrentCount(count ?? 0);
}
} catch (err) {
console.log('Error general:', err);
setError('Error de conexión.');
} finally {
setLoading(false);
}
}

fetchData();
}, [filtroData, currentPage]);

if (loading) {
if (isLoading) {
return (
<div className="flex justify-center items-center min-h-screen">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500"></div>
</div>
);
}

if (error) {
if (error || requests === undefined) {
return (
<div className="bg-red-100 border-l-4 border-red-500 p-4 rounded">
<p className="text-red-700">{error}</p>
<p className="text-red-700">{error?.message}</p>
</div>
);
}

return (
<>
{/* FILTROS */}
<div className="flex flex-col sm:flex-row gap-2 items-center justify-between">
<p className="font-bold text-md">Filtros</p>
<div className="flex flex-col sm:flex-row gap-2 w-full justify-end">
<select
value={filtroData.tipoAyuda}
onChange={(e) => changeDataFilter('tipoAyuda', e.target.value)}
className="px-4 py-2 rounded-lg w-full border border-gray-300 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 bg-white text-gray-900 shadow-sm"
>
<option value="todas">Todas las necesidades</option>
{Object.entries(tiposAyudaOptions).map(([key, label]) => (
<option key={key} value={key}>
{label}
</option>
))}
</select>
<select
value={filtroData.urgencia}
onChange={(e) => changeDataFilter('urgencia', e.target.value)}
className="px-4 py-2 rounded-lg w-full border border-gray-300 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 bg-white text-gray-900 shadow-sm"
>
<option value="todas">Todas las prioridades</option>
<option value="alta">Alta prioridad</option>
<option value="media">Media prioridad</option>
<option value="baja">Baja prioridad</option>
</select>
<select
value={filtroData.pueblo}
onChange={(e) => changeDataFilter('pueblo', e.target.value)}
className="px-4 py-2 rounded-lg w-full border border-gray-300 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 bg-white text-gray-900 shadow-sm"
>
<option value="todos">Todos los pueblos</option>
{towns.map((item) => (
<option key={item.id} value={item.id}>
{item.name}
</option>
))}
</select>
<div className="space-y-6 mx-auto max-w-7xl px-4 sm:px-6 mt-10">
<div className="grid gap-4">
{requests.length === 0 ? (
<div className="bg-white rounded-lg shadow-lg border border-gray-300 text-center flex justify-center items-center p-10 flex-col gap-5">
<p className="text-gray-700 text-lg font-medium">
No se encontraron solicitudes de ayuda correspondientes a tu cuenta.
</p>

<Link
href="/solicitar-ayuda"
className="bg-red-500 text-white px-4 py-2 rounded hover:bg-red-600 flex items-center gap-2 whitespace-nowrap"
>
<Search className="w-5 h-5" />
Solicitar ayuda
</Link>
</div>
) : (
requests.map((caso) => <SolicitudCard showLink={true} showEdit={true} key={caso.id} caso={caso as any} />)
)}
</div>
</div>
<div className="grid gap-4">
{data.length === 0 ? (
<div className="bg-white rounded-lg shadow-lg border border-gray-300 text-center flex justify-center items-center p-10 flex-col gap-5">
<p className="text-gray-700 text-lg font-medium">
No se encontraron solicitudes que coincidan con los filtros.
</p>
</div>
) : (
data.map((caso) => <SolicitudCard showLink={true} showEdit={true} key={caso.id} caso={caso as any} />)
)}
</div>
<div className="flex items-center justify-center">
<Pagination currentPage={currentPage} totalPages={numPages(currentCount)} onPageChange={changePage} />
</div>
</>
);
}
2 changes: 1 addition & 1 deletion src/app/solicitudes/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default function CasoDetalle() {
Volver
</button>
</div>
<SolicitudCard caso={request as any} showLink={false} showEdit={true} />
<SolicitudCard caso={request} showLink={false} showEdit={true} />
</div>
);
}
2 changes: 1 addition & 1 deletion src/app/solicitudes/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default function ListaSolicitudes() {
</Link>
</div>
) : (
requests.map((caso) => <SolicitudCard showLink={true} showEdit={true} key={caso.id} caso={caso as any} />)
requests.map((caso) => <SolicitudCard showLink={true} showEdit={true} key={caso.id} caso={caso} />)
)}
</div>
</div>
Expand Down
8 changes: 5 additions & 3 deletions src/components/SolicitudCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { useState } from 'react';
import ChangeUrgencyHelpRequest from './ChangeUrgencyHelpRequest';

type SolicitudCardProps = {
caso: HelpRequestData & { special_situations: string; user_id: string };
caso: HelpRequestData;
showLink?: boolean;
showEdit?: boolean;
};
Expand All @@ -22,6 +22,8 @@ export default function SolicitudCard({ caso, showLink = true, showEdit = false
const session = useSession();
const role = useRole();
const { getTownById } = useTowns();
const additionalInfo = caso.additional_info as HelpRequestAdditionalInfo;
const special_situations = 'special_situations' in additionalInfo ? additionalInfo.special_situations : undefined;
const isAdmin = role === 'admin';
const [deleted, setDeleted] = useState(false);
const isMyRequest = session.user?.id && session.user.id === caso.user_id;
Expand Down Expand Up @@ -124,12 +126,12 @@ export default function SolicitudCard({ caso, showLink = true, showEdit = false
</span>
</div>
)}
{caso.special_situations && (
{special_situations && (
<>
<hr />
<div className="pt-2">
<span className="font-semibold block mb-1">Situaciones especiales:</span>
<p className="text-gray-700 break-words">{caso.special_situations}</p>
<p className="text-gray-700 break-words">{special_situations}</p>
</div>
</>
)}
Expand Down
2 changes: 1 addition & 1 deletion src/helpers/format.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ export const getMarkerColorBySolicitud = (solicitud: HelpRequestData) => {
};
export const getMarkerDescriptionBySolicitudAndTowns = (solicitud: HelpRequestData) => {
return ReactDOMServer.renderToString(
<SolicitudCard key={solicitud.id} caso={solicitud as any} showEdit={false} showLink={true} />,
<SolicitudCard key={solicitud.id} caso={solicitud} showEdit={false} showLink={true} />,
);
};
30 changes: 0 additions & 30 deletions src/lib/supabase/server_role.ts

This file was deleted.

4 changes: 0 additions & 4 deletions src/types/Requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,3 @@ export type HelpRequestAdditionalInfo = {
special_situations?: string;
email?: string;
};

export type CollectionPointType = 'permanente' | 'temporal';
export type CollectionPointStatus = 'active' | 'inactive';
export type CollectionPointData = Database['public']['Tables']['collection_points']['Row'];

0 comments on commit 4c275ff

Please sign in to comment.