diff --git a/apps/db/migrations/28_potenziali.up.sql b/apps/db/migrations/28_potenziali.up.sql
new file mode 100644
index 0000000..60139ea
--- /dev/null
+++ b/apps/db/migrations/28_potenziali.up.sql
@@ -0,0 +1,37 @@
+-- Potenziali table
+CREATE TABLE IF NOT EXISTS public.potenziali (
+ id UUID DEFAULT gen_random_uuid () NOT NULL,
+ name TEXT NOT NULL,
+ descrizione TEXT,
+ created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL,
+ userid UUID,
+ potenziali_group_id UUID NOT NULL
+);
+
+-- Primary Key
+DO $$
+BEGIN
+ IF NOT EXISTS (
+ SELECT 1 FROM pg_constraint
+ WHERE conname = 'potenziali_pkey'
+ AND conrelid = 'public.potenziali'::regclass
+ ) THEN
+ ALTER TABLE public.potenziali
+ ADD CONSTRAINT potenziali_pkey PRIMARY KEY (id);
+ END IF;
+END $$;
+
+-- Foreign Key to Users
+DO $$
+BEGIN
+ IF NOT EXISTS (
+ SELECT 1 FROM pg_constraint
+ WHERE conname = 'potenziali_assigned_user'
+ AND conrelid = 'public.potenziali'::regclass
+ ) THEN
+ ALTER TABLE public.potenziali
+ ADD CONSTRAINT potenziali_assigned_user
+ FOREIGN KEY (userid) REFERENCES public.users (id)
+ ON UPDATE CASCADE ON DELETE SET NULL;
+ END IF;
+END $$;
\ No newline at end of file
diff --git a/apps/db/migrations/29_potenziali_groups.up.sql b/apps/db/migrations/29_potenziali_groups.up.sql
new file mode 100644
index 0000000..1693320
--- /dev/null
+++ b/apps/db/migrations/29_potenziali_groups.up.sql
@@ -0,0 +1,45 @@
+-- Potenziali Groups Table
+CREATE TABLE IF NOT EXISTS public.potenziali_groups (
+ id UUID DEFAULT gen_random_uuid () NOT NULL,
+ name TEXT NOT NULL,
+ color TEXT DEFAULT 'blue' NOT NULL
+);
+-- Primary Key
+DO $$
+BEGIN
+ IF NOT EXISTS (
+ SELECT 1 FROM pg_constraint
+ WHERE conname = 'potenziali_groups_pkey'
+ AND conrelid = 'public.potenziali_groups'::regclass
+ ) THEN
+ ALTER TABLE public.potenziali_groups
+ ADD CONSTRAINT potenziali_groups_pkey PRIMARY KEY (id);
+ END IF;
+END $$;
+
+-- Foreign Key to Potenziali Groups
+DO $$
+BEGIN
+ IF NOT EXISTS (
+ SELECT 1 FROM pg_constraint
+ WHERE conname = 'potenziali_group_fk'
+ AND conrelid = 'public.potenziali'::regclass
+ ) THEN
+ ALTER TABLE public.potenziali
+ ADD CONSTRAINT potenziali_group_fk
+ FOREIGN KEY (potenziali_group_id) REFERENCES public.potenziali_groups (id)
+ ON UPDATE CASCADE ON DELETE CASCADE;
+ END IF;
+END $$;
+
+-- Create Index on Potenziali Group ID
+DO $$
+BEGIN
+ IF NOT EXISTS (
+ SELECT 1 FROM pg_indexes
+ WHERE indexname = 'idx_potenziali_group_id'
+ ) THEN
+ CREATE INDEX idx_potenziali_group_id
+ ON public.potenziali (potenziali_group_id);
+ END IF;
+END $$;
\ No newline at end of file
diff --git a/apps/infoalloggi/src/components/area-riservata/potenziali.tsx b/apps/infoalloggi/src/components/area-riservata/potenziali.tsx
index c047416..01a67b4 100644
--- a/apps/infoalloggi/src/components/area-riservata/potenziali.tsx
+++ b/apps/infoalloggi/src/components/area-riservata/potenziali.tsx
@@ -1,6 +1,8 @@
"use client";
import { format } from "date-fns";
+import { Plus } from "lucide-react";
+import { useState } from "react";
import {
KanbanBoard,
KanbanCard,
@@ -8,12 +10,9 @@ import {
KanbanHeader,
KanbanProvider,
} from "~/components/ui/kanban";
-import {
- type ElementoPotenziali,
- PotenzialiProvider,
- usePotenziali,
-} from "~/providers/PotenzialiProvider";
-import type { UsersId } from "~/schemas/public/Users";
+import { usePotenziali } from "~/providers/PotenzialiProvider";
+import type { PotenzialiGroupsId } from "~/schemas/public/PotenzialiGroups";
+import type { PotenzialeData } from "~/server/services/potenziali.service";
import {
Credenza,
CredenzaBody,
@@ -21,81 +20,27 @@ import {
CredenzaDescription,
CredenzaHeader,
CredenzaTitle,
+ CredenzaTrigger,
} from "../custom_ui/credenza";
-import {
- ContextMenu,
- ContextMenuContent,
- ContextMenuItem,
- ContextMenuTrigger,
-} from "../ui/context-menu";
-import {
- Dialog,
- DialogContent,
- DialogDescription,
- DialogHeader,
- DialogTitle,
-} from "../ui/dialog";
+import Input from "../custom_ui/input";
+import { Textarea } from "../custom_ui/textarea";
+import { Button } from "../ui/button";
+import { Label } from "../ui/label";
import { UserAvatar } from "../user_avatar";
-const columns = [
- { id: "todo", name: "To Do", color: "red" },
- { id: "inprogress", name: "In Progress", color: "blue" },
- { id: "done", name: "Done", color: "green" },
-];
-
-const SampleData: ElementoPotenziali[] = [
- {
- id: "1",
- name: "Mario Rossi",
- column: "todo",
- descrizione:
- "Single, cerca appartamento in centro da subito, budget 800 euro",
- createdAt: new Date(),
- owner: {
- userId: "019b9a25-eff1-420a-9017-b0add205d7b6" as UsersId,
- username: "Marco Pedone",
- },
- },
- {
- id: "2",
- name: "Luigi Bianchi",
- column: "inprogress",
- descrizione: "Coppia, cerca bilocale in periferia, budget 600 euro",
- createdAt: new Date(),
- owner: null,
- },
- {
- id: "3",
- name: "Giovanni Verdi",
- column: "done",
- descrizione:
- "Famiglia con 2 figli, cerca trilocale vicino a scuole, budget 1000 euro",
- createdAt: new Date(),
- owner: {
- userId: "019b9a25-eff1-420a-9017-b0add205d7b6" as UsersId,
- username: "Marco Pedone",
- },
- },
-];
-
-const Potenziali = () => {
- return (
-
-
-
- );
-};
-
-const Kaban = () => {
- const { data, updateData, setEditingId, editingId } = usePotenziali();
-
+export const Potenziali = () => {
+ const { data, columns, setData, updateCall, setEditingId, editingId } =
+ usePotenziali();
return (
<>
{
+ updateCall();
+ }}
>
{(column) => (
{
style={{ backgroundColor: column.color }}
/>
{column.name}
+
+
- {(data: ElementoPotenziali) => (
+ {(data: PotenzialeData) => (
{
setEditingId(data.id);
@@ -132,16 +79,16 @@ const Kaban = () => {
{data.descrizione}
- {data.owner && (
+ {data.userid && (
)}
- {format(data.createdAt, "dd/MM/yyyy HH:mm")}
+ {format(data.created_at, "dd/MM/yyyy HH:mm")}
)}
@@ -163,6 +110,101 @@ const Kaban = () => {
);
};
+export const NewColumn = () => {
+ const [newColumnName, setNewColumnName] = useState("");
+ const { addColumn } = usePotenziali();
+ return (
+
+
+
+
+
+
+
+ Nuova colonna
+
+ desc
+
+
+
+
+ setNewColumnName(e.target.value)}
+ type="string"
+ />
+
+
+
+
+ );
+};
+
+export const NewCard = ({ columnId }: { columnId: PotenzialiGroupsId }) => {
+ const [newItemName, setNewItemName] = useState("");
+ const [newItemDescrizione, setNewItemDescrizione] = useState("");
+ const { addItem } = usePotenziali();
+ return (
+
+
+
+
+
+
+
+ Nuova colonna
+
+ desc
+
+
+
+
+ setNewItemName(e.target.value)}
+ type="string"
+ />
+
+
+
+
+ );
+};
+
const EditingContent = () => {
const { getEditingItem } = usePotenziali();
const item = getEditingItem();
@@ -177,11 +219,9 @@ const EditingContent = () => {
Descrizione: {item.descrizione}
- Creato il: {format(item.createdAt, "dd/MM/yyyy HH:mm")}
- Utente Assegnato: {item.owner ? item.owner.username : "Nessuno"}
+ Creato il: {format(item.created_at, "dd/MM/yyyy HH:mm")}
+ Utente Assegnato: {item.userid ? item.username : "Nessuno"}
);
};
-
-export default Potenziali;
diff --git a/apps/infoalloggi/src/pages/area-riservata/admin/potenziali.tsx b/apps/infoalloggi/src/pages/area-riservata/admin/potenziali.tsx
index e7d2726..6dd5367 100644
--- a/apps/infoalloggi/src/pages/area-riservata/admin/potenziali.tsx
+++ b/apps/infoalloggi/src/pages/area-riservata/admin/potenziali.tsx
@@ -1,53 +1,43 @@
import dynamic from "next/dynamic";
+import { NewColumn } from "~/components/area-riservata/potenziali";
import { AreaRiservataLayout } from "~/components/Layout";
import { LoadingPage } from "~/components/loading";
import type { NextPageWithLayout } from "~/pages/_app";
+import { PotenzialiProvider } from "~/providers/PotenzialiProvider";
-const Potenziali = dynamic(
- () => import("~/components/area-riservata/potenziali"),
+const PotenzialiBoard = dynamic(
+ () =>
+ import("~/components/area-riservata/potenziali").then(
+ (mod) => mod.Potenziali,
+ ),
{
- loading: () => ,
ssr: false,
+ loading: () => ,
},
);
const AdminPotenziali: NextPageWithLayout = () => {
return (
-
-
-
-
+
);
};
export default AdminPotenziali;
-// export const getServerSideProps = (async (context) => {
-// const access_token = context.req.cookies.access_token;
-
-// const helpers = await TrpcAuthedFetchingIstance({ access_token });
-// if (helpers) {
-// await helpers.trpc.etichette.getAllEtichette.prefetch();
-// return {
-// props: {
-// trpcState: helpers.trpc.dehydrate(),
-// },
-// };
-// }
-// return {
-// props: {},
-// };
-// }) satisfies GetServerSideProps;
-
AdminPotenziali.getLayout = function getLayout(page) {
return
{page};
};
diff --git a/apps/infoalloggi/src/providers/PotenzialiProvider.tsx b/apps/infoalloggi/src/providers/PotenzialiProvider.tsx
index 100fcd4..a24fa70 100644
--- a/apps/infoalloggi/src/providers/PotenzialiProvider.tsx
+++ b/apps/infoalloggi/src/providers/PotenzialiProvider.tsx
@@ -1,56 +1,109 @@
import { createContext, useContext, useState } from "react";
-import type { UsersId } from "~/schemas/public/Users";
+import toast from "react-hot-toast";
+import type { NewPotenziali, PotenzialiId } from "~/schemas/public/Potenziali";
+import type { PotenzialiGroups } from "~/schemas/public/PotenzialiGroups";
+import type { PotenzialeData } from "~/server/services/potenziali.service";
+import { api } from "~/utils/api";
-export type ElementoPotenziali = {
- id: string;
- name: string;
- column: string;
- descrizione: string;
- createdAt: Date;
- owner: { userId: UsersId; username: string } | null;
-};
type PotenzialiContextType = {
- data: ElementoPotenziali[];
- editingId: string | null;
- updateData: (data: ElementoPotenziali[]) => void;
- setEditingId: (id: string | null) => void;
- getEditingItem: () => ElementoPotenziali | null;
- addItem: (item: ElementoPotenziali) => void;
- removeItem: (id: string) => void;
+ data: PotenzialeData[];
+ columns: PotenzialiGroups[];
+ editingId: PotenzialiId | null;
+ setData: (data: PotenzialeData[]) => void;
+ updateCall: () => void;
+ setEditingId: (id: PotenzialiId | null) => void;
+ getEditingItem: () => PotenzialeData | null;
+ addItem: (item: NewPotenziali) => void;
+ removeItem: (id: PotenzialiId) => void;
+ addColumn: (name: string) => void;
};
const PotenzialiContext = createContext
(null);
type PotenzialiProviderProps = {
children: React.ReactNode;
- data: ElementoPotenziali[];
};
-export const PotenzialiProvider = ({
- children,
- data: initial,
-}: PotenzialiProviderProps) => {
- const [data, setData] = useState(initial);
- const [editingId, setEditingId] = useState(null);
+export const PotenzialiProvider = ({ children }: PotenzialiProviderProps) => {
+ const { data } = api.potenziali.getPotenziali.useQuery();
+
+ const { data: columns } = api.potenziali.getPotenzialiGroups.useQuery();
+
+ const [editingId, setEditingId] = useState(null);
const getEditingItem = () => {
- return data.find((item) => item.id === editingId) || null;
+ return data?.find((item) => item.id === editingId) || null;
};
- const addItem = (item: ElementoPotenziali) => {
- setData((prev) => [...prev, item]);
+ const utils = api.useUtils();
+ const { mutate: addItemMutation } = api.potenziali.addPotenziale.useMutation({
+ onSuccess: async () => {
+ toast.success("Elemento aggiunto con successo");
+ await utils.potenziali.getPotenziali.invalidate();
+ await utils.potenziali.getPotenzialiGroups.invalidate();
+ },
+ });
+
+ const addItem = (item: NewPotenziali) => {
+ addItemMutation({
+ data: item,
+ });
};
- const removeItem = (id: string) => {
- setData((prev) => prev.filter((item) => item.id !== id));
+ const { mutate: removeItemMutation } =
+ api.potenziali.deletePotenziale.useMutation({
+ onSuccess: async () => {
+ toast.success("Elemento rimosso con successo");
+ await utils.potenziali.getPotenziali.invalidate();
+ await utils.potenziali.getPotenzialiGroups.invalidate();
+ },
+ });
+ const removeItem = (id: PotenzialiId) => {
+ removeItemMutation({
+ potenzialiId: id,
+ });
};
+ const setData = (newData: PotenzialeData[]) => {
+ utils.potenziali.getPotenziali.setData(undefined, newData);
+ };
+
+ const { mutate: updatePotenzialiMutation } =
+ api.potenziali.updatePotenziali.useMutation({
+ onSuccess: async () => {
+ await utils.potenziali.getPotenziali.invalidate();
+ },
+ });
+
+ const updateCall = () => {
+ updatePotenzialiMutation({
+ data: utils.potenziali.getPotenziali.getData() || [],
+ });
+ };
+
+ const { mutate: addColumnMutation } =
+ api.potenziali.addPotenzialeGroup.useMutation({
+ onSuccess: async () => {
+ toast.success("Colonna aggiunta con successo");
+ await utils.potenziali.getPotenziali.invalidate();
+ await utils.potenziali.getPotenzialiGroups.invalidate();
+ },
+ });
+ const addColumn = (name: string) => {
+ addColumnMutation({
+ name,
+ });
+ };
+
return (
{children}
diff --git a/apps/infoalloggi/src/schemas/public/Potenziali.ts b/apps/infoalloggi/src/schemas/public/Potenziali.ts
new file mode 100644
index 0000000..d0cd68f
--- /dev/null
+++ b/apps/infoalloggi/src/schemas/public/Potenziali.ts
@@ -0,0 +1,30 @@
+// @generated
+// This file is automatically generated by Kanel. Do not modify manually.
+
+import type { UsersId } from './Users';
+import type { PotenzialiGroupsId } from './PotenzialiGroups';
+import type { ColumnType, Selectable, Insertable, Updateable } from 'kysely';
+
+/** Identifier type for public.potenziali */
+export type PotenzialiId = string & { __brand: 'public.potenziali' };
+
+/** Represents the table public.potenziali */
+export default interface PotenzialiTable {
+ id: ColumnType;
+
+ name: ColumnType;
+
+ descrizione: ColumnType;
+
+ created_at: ColumnType;
+
+ userid: ColumnType;
+
+ potenziali_group_id: ColumnType;
+}
+
+export type Potenziali = Selectable;
+
+export type NewPotenziali = Insertable;
+
+export type PotenzialiUpdate = Updateable;
diff --git a/apps/infoalloggi/src/schemas/public/PotenzialiGroups.ts b/apps/infoalloggi/src/schemas/public/PotenzialiGroups.ts
new file mode 100644
index 0000000..48d7e9e
--- /dev/null
+++ b/apps/infoalloggi/src/schemas/public/PotenzialiGroups.ts
@@ -0,0 +1,22 @@
+// @generated
+// This file is automatically generated by Kanel. Do not modify manually.
+
+import type { ColumnType, Selectable, Insertable, Updateable } from 'kysely';
+
+/** Identifier type for public.potenziali_groups */
+export type PotenzialiGroupsId = string & { __brand: 'public.potenziali_groups' };
+
+/** Represents the table public.potenziali_groups */
+export default interface PotenzialiGroupsTable {
+ id: ColumnType;
+
+ name: ColumnType;
+
+ color: ColumnType;
+}
+
+export type PotenzialiGroups = Selectable;
+
+export type NewPotenzialiGroups = Insertable;
+
+export type PotenzialiGroupsUpdate = Updateable;
diff --git a/apps/infoalloggi/src/schemas/public/PublicSchema.ts b/apps/infoalloggi/src/schemas/public/PublicSchema.ts
index a283f7c..97b6ae3 100644
--- a/apps/infoalloggi/src/schemas/public/PublicSchema.ts
+++ b/apps/infoalloggi/src/schemas/public/PublicSchema.ts
@@ -11,6 +11,7 @@ import type { default as UsersStorageTable } from './UsersStorage';
import type { default as ServizioAnnunciTable } from './ServizioAnnunci';
import type { default as EmailsTable } from './Emails';
import type { default as PaymentsTable } from './Payments';
+import type { default as PotenzialiGroupsTable } from './PotenzialiGroups';
import type { default as ComuniTable } from './Comuni';
import type { default as EventQueueTable } from './EventQueue';
import type { default as OrdiniTable } from './Ordini';
@@ -21,6 +22,7 @@ import type { default as EtichetteTable } from './Etichette';
import type { default as MessagesTable } from './Messages';
import type { default as ProvincieTable } from './Provincie';
import type { default as UsersAnagraficaTable } from './UsersAnagrafica';
+import type { default as PotenzialiTable } from './Potenziali';
import type { default as VideosRefsTable } from './VideosRefs';
import type { default as BanlistTable } from './Banlist';
import type { default as NazioniTable } from './Nazioni';
@@ -49,6 +51,8 @@ export default interface PublicSchema {
payments: PaymentsTable;
+ potenziali_groups: PotenzialiGroupsTable;
+
comuni: ComuniTable;
event_queue: EventQueueTable;
@@ -69,6 +73,8 @@ export default interface PublicSchema {
users_anagrafica: UsersAnagraficaTable;
+ potenziali: PotenzialiTable;
+
videos_refs: VideosRefsTable;
banlist: BanlistTable;
diff --git a/apps/infoalloggi/src/server/api/root.ts b/apps/infoalloggi/src/server/api/root.ts
index 3631598..e9adf18 100644
--- a/apps/infoalloggi/src/server/api/root.ts
+++ b/apps/infoalloggi/src/server/api/root.ts
@@ -22,6 +22,7 @@ import { bannersRouter } from "./routers/banners";
import { catastoRouter } from "./routers/catasto";
import { etichetteRouter } from "./routers/etichette";
import { flagsRouter } from "./routers/flags";
+import { potenzialiRouter } from "./routers/potenziali";
import { revalidationRouter } from "./routers/revalidation";
import { stringsRouter } from "./routers/strings";
import { syncRouter } from "./routers/sync";
@@ -55,5 +56,6 @@ export const appRouter = createTRPCRouter({
etichette: etichetteRouter,
strings: stringsRouter,
revalidation: revalidationRouter,
+ potenziali: potenzialiRouter,
});
export type AppRouter = typeof appRouter;
diff --git a/apps/infoalloggi/src/server/api/routers/potenziali.ts b/apps/infoalloggi/src/server/api/routers/potenziali.ts
new file mode 100644
index 0000000..7f94c07
--- /dev/null
+++ b/apps/infoalloggi/src/server/api/routers/potenziali.ts
@@ -0,0 +1,121 @@
+import z from "zod";
+import type {
+ NewPotenziali,
+ PotenzialiId,
+ PotenzialiUpdate,
+} from "~/schemas/public/Potenziali";
+import type { PotenzialiGroupsId } from "~/schemas/public/PotenzialiGroups";
+import { adminProcedure, createTRPCRouter } from "~/server/api/trpc";
+import {
+ addPotenziale,
+ addPotenzialeGroup,
+ deletePotenziale,
+ deletePotenzialeGroup,
+ getPotenziali,
+ getPotenzialiGroups,
+ type PotenzialeData,
+ updatePotenziale,
+ updatePotenzialeGroup,
+ updatePotenziali,
+} from "~/server/services/potenziali.service";
+
+export const zPotenzialiId = z.custom(
+ (val) => typeof val === "string" && val.length > 0,
+ { message: "Invalid PotenzialiId" },
+);
+
+export const zNewPotenziali = z.custom(
+ (val) => {
+ return typeof val === "object" && val !== null;
+ },
+ { message: "Invalid NewPotenziali" },
+);
+
+export const zPotenzialiUpdate = z.custom(
+ (val) => {
+ return typeof val === "object" && val !== null;
+ },
+ { message: "Invalid PotenzialiUpdate" },
+);
+
+export const zPotenzialiGroupId = z.custom(
+ (val) => typeof val === "string" && val.length > 0,
+ { message: "Invalid PotenzialiGroupsId" },
+);
+
+export const potenzialiRouter = createTRPCRouter({
+ getPotenziali: adminProcedure.query(async () => {
+ return await getPotenziali();
+ }),
+ getPotenzialiGroups: adminProcedure.query(async () => {
+ return await getPotenzialiGroups();
+ }),
+ addPotenziale: adminProcedure
+ .input(
+ z.object({
+ data: zNewPotenziali,
+ }),
+ )
+ .mutation(async ({ input }) => {
+ return await addPotenziale(input.data);
+ }),
+ updatePotenziali: adminProcedure
+ .input(
+ z.object({
+ data: z.custom(),
+ }),
+ )
+ .mutation(async ({ input }) => {
+ return await updatePotenziali(input.data);
+ }),
+ updatePotenziale: adminProcedure
+ .input(
+ z.object({
+ potenzialiId: zPotenzialiId,
+ data: zPotenzialiUpdate,
+ }),
+ )
+ .mutation(async ({ input }) => {
+ return await updatePotenziale(input.potenzialiId, input.data);
+ }),
+ deletePotenziale: adminProcedure
+ .input(
+ z.object({
+ potenzialiId: zPotenzialiId,
+ }),
+ )
+ .mutation(async ({ input }) => {
+ return await deletePotenziale(input.potenzialiId);
+ }),
+
+ addPotenzialeGroup: adminProcedure
+ .input(
+ z.object({
+ name: z.string().min(1).max(255),
+ }),
+ )
+ .mutation(async ({ input }) => {
+ return await addPotenzialeGroup({ name: input.name });
+ }),
+ updatePotenzialeGroup: adminProcedure
+ .input(
+ z.object({
+ potenzialiGroupId: zPotenzialiGroupId,
+ name: z.string().min(1).max(255),
+ }),
+ )
+ .mutation(async ({ input }) => {
+ return await updatePotenzialeGroup(input.potenzialiGroupId, {
+ name: input.name,
+ });
+ }),
+ deletePotenzialeGroup: adminProcedure
+ .input(
+ z.object({
+ potenzialiGroupId: zPotenzialiGroupId,
+ }),
+ )
+ .mutation(async ({ input }) => {
+ return await deletePotenzialeGroup(input.potenzialiGroupId);
+ }),
+});
diff --git a/apps/infoalloggi/src/server/services/potenziali.service.ts b/apps/infoalloggi/src/server/services/potenziali.service.ts
new file mode 100644
index 0000000..6e64be0
--- /dev/null
+++ b/apps/infoalloggi/src/server/services/potenziali.service.ts
@@ -0,0 +1,185 @@
+import { TRPCError } from "@trpc/server";
+import type { Nullable } from "kysely";
+import type {
+ NewPotenziali,
+ Potenziali,
+ PotenzialiId,
+ PotenzialiUpdate,
+} from "~/schemas/public/Potenziali";
+import type {
+ NewPotenzialiGroups,
+ PotenzialiGroups,
+ PotenzialiGroupsId,
+ PotenzialiGroupsUpdate,
+} from "~/schemas/public/PotenzialiGroups";
+import type { Users } from "~/schemas/public/Users";
+import { db } from "../db";
+
+export type PotenzialeData = Omit & {
+ column: string;
+} & Nullable>;
+
+export const getPotenziali = async (): Promise => {
+ try {
+ const potenziali = await db
+ .selectFrom("potenziali")
+ .select([
+ "potenziali.id",
+ "potenziali.name",
+ "potenziali.created_at",
+ "potenziali.descrizione",
+ "potenziali.userid",
+ "potenziali.potenziali_group_id as column",
+ ])
+ .innerJoin(
+ "potenziali_groups",
+ "potenziali.potenziali_group_id",
+ "potenziali_groups.id",
+ )
+ .leftJoin("users", "potenziali.userid", "users.id")
+ .select("users.username")
+ .orderBy("potenziali_groups.name", "asc")
+ .orderBy("potenziali.created_at", "asc")
+ .execute();
+
+ return potenziali.map((data) => ({
+ ...data,
+ created_at: new Date(data.created_at),
+ }));
+ } catch (e) {
+ throw new TRPCError({
+ code: "INTERNAL_SERVER_ERROR",
+ message: `Failed to fetch potenziali, error: ${(e as Error).message}`,
+ });
+ }
+};
+
+export const getPotenzialiGroups = async (): Promise => {
+ try {
+ return await db.selectFrom("potenziali_groups").selectAll().execute();
+ } catch (e) {
+ throw new TRPCError({
+ code: "INTERNAL_SERVER_ERROR",
+ message: `Failed to fetch potenziali groups, error: ${(e as Error).message}`,
+ });
+ }
+};
+
+export const addPotenzialeGroup = async (data: NewPotenzialiGroups) => {
+ try {
+ await db.insertInto("potenziali_groups").values(data).execute();
+ return { status: "success" };
+ } catch (e) {
+ throw new TRPCError({
+ code: "INTERNAL_SERVER_ERROR",
+ message: `Failed to add potenziale group, error: ${(e as Error).message}`,
+ });
+ }
+};
+
+export const deletePotenzialeGroup = async (id: PotenzialiGroupsId) => {
+ try {
+ await db.deleteFrom("potenziali_groups").where("id", "=", id).execute();
+ return { status: "success" };
+ } catch (e) {
+ throw new TRPCError({
+ code: "INTERNAL_SERVER_ERROR",
+ message: `Failed to delete potenziale group, error: ${(e as Error).message}`,
+ });
+ }
+};
+
+export const updatePotenzialeGroup = async (
+ id: PotenzialiGroupsId,
+ data: PotenzialiGroupsUpdate,
+) => {
+ try {
+ await db
+ .updateTable("potenziali_groups")
+ .set(data)
+ .where("id", "=", id)
+ .execute();
+ return { status: "success" };
+ } catch (e) {
+ throw new TRPCError({
+ code: "INTERNAL_SERVER_ERROR",
+ message: `Failed to update potenziale group, error: ${(e as Error).message}`,
+ });
+ }
+};
+
+export const addPotenziale = async (data: NewPotenziali) => {
+ try {
+ await db.insertInto("potenziali").values(data).execute();
+ return { status: "success" };
+ } catch (e) {
+ throw new TRPCError({
+ code: "INTERNAL_SERVER_ERROR",
+ message: `Failed to add potenziale, error: ${(e as Error).message}`,
+ });
+ }
+};
+
+export const deletePotenziale = async (id: PotenzialiId) => {
+ try {
+ await db.deleteFrom("potenziali").where("id", "=", id).execute();
+ return { status: "success" };
+ } catch (e) {
+ throw new TRPCError({
+ code: "INTERNAL_SERVER_ERROR",
+ message: `Failed to delete potenziale, error: ${(e as Error).message}`,
+ });
+ }
+};
+
+export const updatePotenziale = async (
+ id: PotenzialiId,
+ data: PotenzialiUpdate,
+) => {
+ try {
+ await db.updateTable("potenziali").set(data).where("id", "=", id).execute();
+ return { status: "success" };
+ } catch (e) {
+ throw new TRPCError({
+ code: "INTERNAL_SERVER_ERROR",
+ message: `Failed to update potenziale, error: ${(e as Error).message}`,
+ });
+ }
+};
+
+export const updatePotenziali = async (data: PotenzialeData[]) => {
+ try {
+ const db_mappings = await db
+ .selectFrom("potenziali")
+ .select(["id", "potenziali_group_id"])
+ .execute();
+
+ const updates = data
+ .map((item) => {
+ const db_item = db_mappings.find((db_item) => db_item.id === item.id);
+ if (db_item && db_item.potenziali_group_id !== item.column) {
+ const { column, username: _username, ...rest } = item;
+ return {
+ ...rest,
+ potenziali_group_id: column as PotenzialiGroupsId,
+ };
+ }
+ return null;
+ })
+ .filter((item) => item !== null);
+
+ for (const item of updates) {
+ await db
+ .updateTable("potenziali")
+ .set(item)
+ .where("id", "=", item.id)
+ .execute();
+ }
+ return { status: "success" };
+ } catch (e) {
+ throw new TRPCError({
+ code: "INTERNAL_SERVER_ERROR",
+ message: `Failed to update potenziali, error: ${(e as Error).message}`,
+ });
+ }
+};