infoalloggi-monorepo/apps/infoalloggi/src/components/tables/ricerca-table.tsx

116 lines
3.2 KiB
TypeScript
Raw Normal View History

import { ChevronDownCircle, ChevronRightCircle, Package } from "lucide-react";
2025-08-28 18:27:07 +02:00
import { useState } from "react";
import { LoadingPage } from "~/components/loading";
import { ServizioContent } from "~/components/servizio/main";
import {
2025-08-28 18:27:07 +02:00
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "~/components/ui/collapsible";
import { cn } from "~/lib/utils";
2025-08-28 18:27:07 +02:00
import { ServizioProvider } from "~/providers/ServizioProvider";
import type { UsersId } from "~/schemas/public/Users";
import type { ServizioData } from "~/server/controllers/servizio.controller";
2025-08-28 18:27:07 +02:00
import { api } from "~/utils/api";
export const TabRicerca = ({
2025-08-28 18:27:07 +02:00
userId,
isAdmin,
}: {
2025-08-28 18:27:07 +02:00
userId: UsersId;
isAdmin: boolean;
}) => {
2025-08-28 18:27:07 +02:00
const { data, isLoading } = api.servizio.getAllServizioAnnunci.useQuery({
userId,
});
2025-08-28 18:27:07 +02:00
if (isLoading) return <LoadingPage />;
if (!data || data.length === 0) {
return (
<div className="m-4 rounded-md bg-yellow-100 p-4 text-yellow-900">
Nessun servizio attualmente inserito
</div>
);
}
const first_choice = data.findIndex((s) => !s.isInterrotto && s.isOkAcconto);
const second_choice = data.findIndex((s) => !s.isInterrotto);
const getDefaultOpen = (idx: number) => {
if (first_choice !== -1) return idx === first_choice;
if (second_choice !== -1) return idx === second_choice;
return idx === 0;
};
2025-08-28 18:27:07 +02:00
return (
<div className="flex flex-col gap-8">
2025-08-28 18:27:07 +02:00
{data.map((servizio, idx) => {
return (
<Row
defaultOpen={getDefaultOpen(idx)}
2025-08-29 16:18:32 +02:00
isAdmin={isAdmin}
key={servizio.servizio_id}
2025-08-28 18:27:07 +02:00
servizio={servizio}
userId={userId}
/>
);
})}
</div>
);
};
const Row = ({
2025-08-28 18:27:07 +02:00
servizio,
userId,
isAdmin,
defaultOpen = false,
}: {
2025-08-28 18:27:07 +02:00
servizio: ServizioData;
userId: UsersId;
isAdmin: boolean;
defaultOpen: boolean;
}) => {
2025-08-28 18:27:07 +02:00
const [isOpen, setIsOpen] = useState(defaultOpen);
return (
<ServizioProvider
isAdmin={isAdmin}
servizio={servizio}
2025-08-29 16:18:32 +02:00
servizioId={servizio.servizio_id}
userId={userId}
2025-08-28 18:27:07 +02:00
>
2025-08-29 16:18:32 +02:00
<Collapsible onOpenChange={setIsOpen} open={isOpen}>
<div
className={cn(
"flex items-center rounded-md border border-primary bg-secondary py-2 shadow-sm hover:shadow-md",
isOpen && "rounded-b-none",
)}
>
2025-12-02 15:03:51 +01:00
<CollapsibleTrigger className="grid w-full cursor-pointer grid-cols-8 items-center">
<div className="col-span-2 flex items-center justify-center text-primary sm:col-span-1">
{isOpen ? (
<ChevronDownCircle className="fill-background" />
) : (
<ChevronRightCircle className="fill-background" />
)}
2025-08-28 18:27:07 +02:00
</div>
2025-12-02 15:03:51 +01:00
<div className="col-span-6 flex items-center gap-2 font-semibold text-primary sm:text-lg">
<Package className="size-6" />
2025-08-28 18:27:07 +02:00
Affitto {servizio.tipologia}
</div>
2025-12-02 15:03:51 +01:00
<div className="hidden text-primary text-sm sm:col-span-2 sm:contents sm:text-base">
2025-08-28 18:27:07 +02:00
{servizio.created_at.toLocaleDateString("it", {
day: "2-digit",
2025-08-29 16:18:32 +02:00
month: "short",
2025-08-28 18:27:07 +02:00
})}
</div>
</CollapsibleTrigger>
</div>
<CollapsibleContent className="mt-0 overflow-hidden transition-all duration-300 ease-in-out data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down">
<ServizioContent />
2025-08-28 18:27:07 +02:00
</CollapsibleContent>
</Collapsible>
</ServizioProvider>
);
};