102 lines
3.4 KiB
TypeScript
102 lines
3.4 KiB
TypeScript
import { Button } from '@/components/ui/button';
|
|
import { apiClient } from '@/lib/api-client';
|
|
import type { ComplexWithRole } from '@repo/api-contract';
|
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
import { useNavigate } from '@tanstack/react-router';
|
|
import { Building2, Loader2 } from 'lucide-react';
|
|
|
|
export function SelectComplexPage() {
|
|
const navigate = useNavigate();
|
|
|
|
const complexesQuery = useQuery({
|
|
queryKey: ['my-complexes'],
|
|
queryFn: () => apiClient.complexes.listMine(),
|
|
});
|
|
|
|
const queryClient = useQueryClient();
|
|
|
|
const selectMutation = useMutation({
|
|
mutationFn: async (complexId: string) => {
|
|
const response = await apiClient.complexes.select({ complexId });
|
|
return response;
|
|
},
|
|
onSuccess: (data) => {
|
|
queryClient.setQueryData(['current-complex'], data);
|
|
navigate({ to: '/' });
|
|
},
|
|
});
|
|
|
|
const handleSelect = (complex: ComplexWithRole) => {
|
|
selectMutation.mutate(complex.id);
|
|
};
|
|
|
|
if (complexesQuery.isLoading) {
|
|
return (
|
|
<main className="flex min-h-screen w-full items-center justify-center px-3 sm:px-6">
|
|
<Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
|
|
</main>
|
|
);
|
|
}
|
|
|
|
if (complexesQuery.isError) {
|
|
return (
|
|
<main className="flex min-h-screen w-full items-center justify-center px-3 sm:px-6">
|
|
<div className="text-center">
|
|
<p className="text-destructive">Error al cargar tus complejos.</p>
|
|
<Button variant="link" className="mt-2" onClick={() => complexesQuery.refetch()}>
|
|
Reintentar
|
|
</Button>
|
|
</div>
|
|
</main>
|
|
);
|
|
}
|
|
|
|
const complexes = complexesQuery.data ?? [];
|
|
|
|
if (complexes.length === 0) {
|
|
return (
|
|
<main className="flex min-h-screen w-full items-center justify-center px-3 sm:px-6">
|
|
<div className="text-center">
|
|
<p className="text-muted-foreground">No tenés complejos asociados.</p>
|
|
</div>
|
|
</main>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<main className="flex min-h-screen w-full items-center justify-center px-3 sm:px-6">
|
|
<section className="w-full max-w-md space-y-6">
|
|
<div className="space-y-2">
|
|
<h1 className="text-2xl font-semibold">Seleccioná un complejo</h1>
|
|
<p className="text-sm text-muted-foreground">
|
|
Elegí el complejo con el que vas a trabajar.
|
|
</p>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
{complexes.map((complex) => (
|
|
<button
|
|
key={complex.id}
|
|
type="button"
|
|
className="flex w-full items-center gap-3 rounded-lg border p-4 text-left transition-colors hover:bg-accent"
|
|
onClick={() => handleSelect(complex)}
|
|
disabled={selectMutation.isPending}
|
|
>
|
|
<Building2 className="h-5 w-5 text-muted-foreground" />
|
|
<div className="flex-1">
|
|
<p className="font-medium">{complex.complexName}</p>
|
|
<p className="text-sm text-muted-foreground">
|
|
{complex.city ?? 'Sin ciudad'} · {complex.role}
|
|
</p>
|
|
</div>
|
|
{selectMutation.isPending && selectMutation.variables === complex.id && (
|
|
<Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
|
|
)}
|
|
</button>
|
|
))}
|
|
</div>
|
|
</section>
|
|
</main>
|
|
);
|
|
}
|