feat: add admin appunti management page and related functionality
- Introduced a new page for managing appunti in the admin area. - Created AppuntiProvider to manage appunti state and API interactions. - Added schemas for appunti and appunti groups. - Implemented CRUD operations for appunti and appunti groups in the API. - Removed potenziali related files and services as part of the refactor. - Updated the public schema to include appunti and appunti groups. - Improved error handling in the appunti service. Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
parent
984b1d7ae5
commit
b3c70bfa1a
23 changed files with 582 additions and 591 deletions
|
|
@ -5,7 +5,7 @@ SET message = ''
|
||||||
WHERE message IS NULL;
|
WHERE message IS NULL;
|
||||||
|
|
||||||
ALTER TABLE IF EXISTS public.messages
|
ALTER TABLE IF EXISTS public.messages
|
||||||
ALTER COLUMN IF EXISTS message SET NOT NULL;
|
ALTER COLUMN message SET NOT NULL;
|
||||||
|
|
||||||
ALTER TABLE IF EXISTS public.messages
|
ALTER TABLE IF EXISTS public.messages
|
||||||
ADD COLUMN IF NOT EXISTS reply_to_id UUID REFERENCES messages(messageid) ON DELETE SET NULL,
|
ADD COLUMN IF NOT EXISTS reply_to_id UUID REFERENCES messages(messageid) ON DELETE SET NULL,
|
||||||
|
|
|
||||||
33
apps/db/migrations/49_potenziali_to_appunti.up.sql
Normal file
33
apps/db/migrations/49_potenziali_to_appunti.up.sql
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
-- 1. Rename Tables
|
||||||
|
IF EXISTS (SELECT FROM pg_tables WHERE schemaname = 'public' AND tablename = 'potenziali') THEN
|
||||||
|
ALTER TABLE public.potenziali RENAME TO appunti;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF EXISTS (SELECT FROM pg_tables WHERE schemaname = 'public' AND tablename = 'potenziali_groups') THEN
|
||||||
|
ALTER TABLE public.potenziali_groups RENAME TO appunti_groups;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- 2. Rename Column (IF EXISTS is supported here in PG 10+)
|
||||||
|
IF EXISTS (SELECT FROM information_schema.columns WHERE table_name='appunti' AND column_name='potenziali_group_id') THEN
|
||||||
|
ALTER TABLE public.appunti RENAME COLUMN potenziali_group_id TO appunti_group_id;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- 3. Rename Constraints (Requires manual check because RENAME CONSTRAINT IF EXISTS doesn't exist)
|
||||||
|
IF EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'potenziali_pkey') THEN
|
||||||
|
ALTER TABLE public.appunti RENAME CONSTRAINT potenziali_pkey TO appunti_pkey;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'potenziali_assigned_user') THEN
|
||||||
|
ALTER TABLE public.appunti RENAME CONSTRAINT potenziali_assigned_user TO appunti_assigned_user;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'potenziali_group_fk') THEN
|
||||||
|
ALTER TABLE public.appunti RENAME CONSTRAINT potenziali_group_fk TO appunti_group_fk;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'potenziali_groups_pkey') THEN
|
||||||
|
ALTER TABLE public.appunti_groups RENAME CONSTRAINT potenziali_groups_pkey TO appunti_groups_pkey;
|
||||||
|
END IF;
|
||||||
|
END $$;
|
||||||
|
|
@ -132,7 +132,6 @@ function zodUpdateInsertionDatesFix(path, lines) {
|
||||||
insideUpdateOrInsert = true;
|
insideUpdateOrInsert = true;
|
||||||
}
|
}
|
||||||
if (insideUpdateOrInsert && line.includes("z.date()")) {
|
if (insideUpdateOrInsert && line.includes("z.date()")) {
|
||||||
console.log(`Fixing line in ${path}: ${line}`);
|
|
||||||
return line.replace("z.date()", "z.union([z.date(), z.string()]).pipe(z.coerce.date())");
|
return line.replace("z.date()", "z.union([z.date(), z.string()]).pipe(z.coerce.date())");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import {
|
||||||
MessageSquareText,
|
MessageSquareText,
|
||||||
MessagesSquare,
|
MessagesSquare,
|
||||||
Milestone,
|
Milestone,
|
||||||
|
NotebookPen,
|
||||||
Paperclip,
|
Paperclip,
|
||||||
Pointer,
|
Pointer,
|
||||||
Search,
|
Search,
|
||||||
|
|
@ -102,6 +103,7 @@ const iconOptions = [
|
||||||
"bell",
|
"bell",
|
||||||
"target",
|
"target",
|
||||||
"thumbs-up",
|
"thumbs-up",
|
||||||
|
"note"
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export type IconType = (typeof iconOptions)[number];
|
export type IconType = (typeof iconOptions)[number];
|
||||||
|
|
@ -202,6 +204,8 @@ export const IconMatrix = ({ type, ...rest }: IconMatrixProps) => {
|
||||||
return <Target {...rest} />;
|
return <Target {...rest} />;
|
||||||
case "thumbs-up":
|
case "thumbs-up":
|
||||||
return <ThumbsUp {...rest} />;
|
return <ThumbsUp {...rest} />;
|
||||||
|
case "note":
|
||||||
|
return <NotebookPen {...rest} />;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Invalid icon type: ${type satisfies never}`);
|
throw new Error(`Invalid icon type: ${type satisfies never}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@ import {
|
||||||
KanbanProvider,
|
KanbanProvider,
|
||||||
} from "~/components/ui/kanban";
|
} from "~/components/ui/kanban";
|
||||||
import { ScrollArea, ScrollBar } from "~/components/ui/scroll-area";
|
import { ScrollArea, ScrollBar } from "~/components/ui/scroll-area";
|
||||||
import { usePotenziali } from "~/providers/PotenzialiProvider";
|
import { useAppunti } from "~/providers/AppuntiProvider";
|
||||||
import type { PotenzialiGroupsId } from "~/schemas/public/PotenzialiGroups";
|
import type { AppuntiGroupsId } from "~/schemas/public/AppuntiGroups";
|
||||||
import type { UsersId } from "~/schemas/public/Users";
|
import type { UsersId } from "~/schemas/public/Users";
|
||||||
import type { PotenzialeData } from "~/server/services/potenziali.service";
|
import type { AppuntiData } from "~/server/services/appunti.service";
|
||||||
import { api } from "~/utils/api";
|
import { api } from "~/utils/api";
|
||||||
import { Confirm } from "../confirm";
|
import { Confirm } from "../confirm";
|
||||||
import {
|
import {
|
||||||
|
|
@ -43,8 +43,8 @@ import {
|
||||||
import { Textarea } from "../ui/textarea";
|
import { Textarea } from "../ui/textarea";
|
||||||
import { UserAvatar } from "../user_avatar";
|
import { UserAvatar } from "../user_avatar";
|
||||||
|
|
||||||
export const Potenziali = () => {
|
export const Appunti = () => {
|
||||||
const { data, columns, setData, updateCall, removeColumn } = usePotenziali();
|
const { data, columns, setData, updateCall, removeColumn } = useAppunti();
|
||||||
return (
|
return (
|
||||||
<ScrollArea className="w-screen pr-2 sm:w-full">
|
<ScrollArea className="w-screen pr-2 sm:w-full">
|
||||||
<KanbanProvider
|
<KanbanProvider
|
||||||
|
|
@ -85,8 +85,8 @@ export const Potenziali = () => {
|
||||||
</div>
|
</div>
|
||||||
</KanbanHeader>
|
</KanbanHeader>
|
||||||
<KanbanCards className="mx-auto w-68" id={column.id}>
|
<KanbanCards className="mx-auto w-68" id={column.id}>
|
||||||
{(data: PotenzialeData) => (
|
{(data: AppuntiData) => (
|
||||||
<PotenzialeCardItem
|
<AppuntiCardItem
|
||||||
columnId={column.id}
|
columnId={column.id}
|
||||||
data={data}
|
data={data}
|
||||||
key={data.id}
|
key={data.id}
|
||||||
|
|
@ -101,11 +101,11 @@ export const Potenziali = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
// 1. Extract the card logic into a separate component
|
// 1. Extract the card logic into a separate component
|
||||||
const PotenzialeCardItem = ({
|
const AppuntiCardItem = ({
|
||||||
data,
|
data,
|
||||||
columnId,
|
columnId,
|
||||||
}: {
|
}: {
|
||||||
data: PotenzialeData;
|
data: AppuntiData;
|
||||||
columnId: string;
|
columnId: string;
|
||||||
}) => {
|
}) => {
|
||||||
const [isEditingOpen, setIsEditingOpen] = useState(false);
|
const [isEditingOpen, setIsEditingOpen] = useState(false);
|
||||||
|
|
@ -155,7 +155,7 @@ const PotenzialeCardItem = ({
|
||||||
|
|
||||||
export const NewColumn = () => {
|
export const NewColumn = () => {
|
||||||
const [newColumnName, setNewColumnName] = useState("");
|
const [newColumnName, setNewColumnName] = useState("");
|
||||||
const { addColumn } = usePotenziali();
|
const { addColumn } = useAppunti();
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
return (
|
return (
|
||||||
<Credenza onOpenChange={setOpen} open={open}>
|
<Credenza onOpenChange={setOpen} open={open}>
|
||||||
|
|
@ -194,11 +194,11 @@ export const NewColumn = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const NewCard = ({ columnId }: { columnId: PotenzialiGroupsId }) => {
|
const NewCard = ({ columnId }: { columnId: AppuntiGroupsId }) => {
|
||||||
const [newItemName, setNewItemName] = useState("");
|
const [newItemName, setNewItemName] = useState("");
|
||||||
const [newItemDescrizione, setNewItemDescrizione] = useState("");
|
const [newItemDescrizione, setNewItemDescrizione] = useState("");
|
||||||
const [newItemUserid, setNewItemUserid] = useState<UsersId | null>(null);
|
const [newItemUserid, setNewItemUserid] = useState<UsersId | null>(null);
|
||||||
const { addItem } = usePotenziali();
|
const { addItem } = useAppunti();
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const resetState = () => {
|
const resetState = () => {
|
||||||
|
|
@ -210,7 +210,7 @@ const NewCard = ({ columnId }: { columnId: PotenzialiGroupsId }) => {
|
||||||
addItem({
|
addItem({
|
||||||
name: newItemName,
|
name: newItemName,
|
||||||
descrizione: newItemDescrizione,
|
descrizione: newItemDescrizione,
|
||||||
potenziali_group_id: columnId,
|
appunti_group_id: columnId,
|
||||||
userid: newItemUserid,
|
userid: newItemUserid,
|
||||||
});
|
});
|
||||||
resetState();
|
resetState();
|
||||||
|
|
@ -319,11 +319,11 @@ const EditingItem = ({
|
||||||
}: {
|
}: {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
setOpen: (open: boolean) => void;
|
setOpen: (open: boolean) => void;
|
||||||
data: PotenzialeData;
|
data: AppuntiData;
|
||||||
}) => {
|
}) => {
|
||||||
const { updateItem, removeItem } = usePotenziali();
|
const { updateItem, removeItem } = useAppunti();
|
||||||
|
|
||||||
const [state, setState] = useState<PotenzialeData>(data);
|
const [state, setState] = useState<AppuntiData>(data);
|
||||||
const [hasChanges, setHasChanges] = useState(false);
|
const [hasChanges, setHasChanges] = useState(false);
|
||||||
const { data: admins, isLoading } = api.users.getAdmins.useQuery();
|
const { data: admins, isLoading } = api.users.getAdmins.useQuery();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -656,7 +656,7 @@ export const en: LangDict = {
|
||||||
{
|
{
|
||||||
icon: "cog",
|
icon: "cog",
|
||||||
items: [
|
items: [
|
||||||
{ href: "/area-riservata/admin/potenziali", title: "Potenziali" },
|
{ href: "/area-riservata/admin/appunti", title: "Appunti" },
|
||||||
{ href: "/area-riservata/admin/utenti", title: "Users" },
|
{ href: "/area-riservata/admin/utenti", title: "Users" },
|
||||||
{ href: "/area-riservata/admin/richieste", title: "Requests" },
|
{ href: "/area-riservata/admin/richieste", title: "Requests" },
|
||||||
{ href: "/area-riservata/admin/chats", title: "Chat List" },
|
{ href: "/area-riservata/admin/chats", title: "Chat List" },
|
||||||
|
|
@ -741,9 +741,9 @@ export const en: LangDict = {
|
||||||
title: "Dashboard",
|
title: "Dashboard",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
href: "/area-riservata/admin/potenziali",
|
href: "/area-riservata/admin/appunti",
|
||||||
icon: { className: "", icon: "contact" },
|
icon: { className: "", icon: "note" },
|
||||||
title: "Potenziali",
|
title: "Notes",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
href: "/area-riservata/admin/utenti",
|
href: "/area-riservata/admin/utenti",
|
||||||
|
|
|
||||||
|
|
@ -661,7 +661,7 @@ export const it: LangDict = {
|
||||||
{
|
{
|
||||||
icon: "cog",
|
icon: "cog",
|
||||||
items: [
|
items: [
|
||||||
{ href: "/area-riservata/admin/potenziali", title: "Potenziali" },
|
{ href: "/area-riservata/admin/appunti", title: "Appunti" },
|
||||||
{ href: "/area-riservata/admin/utenti", title: "Utenti" },
|
{ href: "/area-riservata/admin/utenti", title: "Utenti" },
|
||||||
{ href: "/area-riservata/admin/richieste", title: "Richieste" },
|
{ href: "/area-riservata/admin/richieste", title: "Richieste" },
|
||||||
{ href: "/area-riservata/admin/chats", title: "Lista Chat" },
|
{ href: "/area-riservata/admin/chats", title: "Lista Chat" },
|
||||||
|
|
@ -737,9 +737,9 @@ export const it: LangDict = {
|
||||||
title: "Dashboard",
|
title: "Dashboard",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
href: "/area-riservata/admin/potenziali",
|
href: "/area-riservata/admin/Appunti",
|
||||||
icon: { className: "", icon: "contact" },
|
icon: { className: "", icon: "note" },
|
||||||
title: "Potenziali",
|
title: "Appunti",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
href: "/area-riservata/admin/utenti",
|
href: "/area-riservata/admin/utenti",
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,14 @@
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { NewColumn } from "~/components/area-riservata/potenziali";
|
import { NewColumn } from "~/components/area-riservata/appunti";
|
||||||
import { AreaRiservataLayout } from "~/components/Layout";
|
import { AreaRiservataLayout } from "~/components/Layout";
|
||||||
import { LoadingPage } from "~/components/loading";
|
import { LoadingPage } from "~/components/loading";
|
||||||
import type { NextPageWithLayout } from "~/pages/_app";
|
import type { NextPageWithLayout } from "~/pages/_app";
|
||||||
import { PotenzialiProvider } from "~/providers/PotenzialiProvider";
|
import { AppuntiProvider } from "~/providers/AppuntiProvider";
|
||||||
|
|
||||||
const PotenzialiBoard = dynamic(
|
const AppuntiBoard = dynamic(
|
||||||
() =>
|
() =>
|
||||||
import("~/components/area-riservata/potenziali").then(
|
import("~/components/area-riservata/appunti").then((mod) => mod.Appunti),
|
||||||
(mod) => mod.Potenziali,
|
|
||||||
),
|
|
||||||
{
|
{
|
||||||
ssr: false,
|
ssr: false,
|
||||||
loading: () => <LoadingPage />,
|
loading: () => <LoadingPage />,
|
||||||
|
|
@ -18,33 +16,33 @@ const PotenzialiBoard = dynamic(
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pagina di gestione potenziali per admin: /area-riservata/admin/potenziali
|
* Pagina di gestione appunti per admin: /area-riservata/admin/appunti
|
||||||
*/
|
*/
|
||||||
const AdminPotenziali: NextPageWithLayout = () => {
|
const AdminAppunti: NextPageWithLayout = () => {
|
||||||
return (
|
return (
|
||||||
<PotenzialiProvider>
|
<AppuntiProvider>
|
||||||
<Head>
|
<Head>
|
||||||
<title>Potenziali - Infoalloggi.it</title>
|
<title>Appunti - Infoalloggi.it</title>
|
||||||
</Head>
|
</Head>
|
||||||
<div className="mx-1 w-full flex-1">
|
<div className="mx-1 w-full flex-1">
|
||||||
<div className="mx-auto w-full pt-4">
|
<div className="mx-auto w-full pt-4">
|
||||||
<div className="mx-3 flex flex-wrap items-start justify-between pb-5">
|
<div className="mx-3 flex flex-wrap items-start justify-between pb-5">
|
||||||
<div className="flex max-w-lg items-center gap-3">
|
<div className="flex max-w-lg items-center gap-3">
|
||||||
<h3 className="font-bold text-accent-foreground text-xl sm:text-2xl">
|
<h3 className="font-bold text-accent-foreground text-xl sm:text-2xl">
|
||||||
Potenziali
|
Appunti
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<NewColumn />
|
<NewColumn />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<PotenzialiBoard />
|
<AppuntiBoard />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PotenzialiProvider>
|
</AppuntiProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default AdminPotenziali;
|
export default AdminAppunti;
|
||||||
|
|
||||||
AdminPotenziali.getLayout = function getLayout(page) {
|
AdminAppunti.getLayout = function getLayout(page) {
|
||||||
return <AreaRiservataLayout>{page}</AreaRiservataLayout>;
|
return <AreaRiservataLayout>{page}</AreaRiservataLayout>;
|
||||||
};
|
};
|
||||||
|
|
@ -265,11 +265,7 @@ const SezioneComuni = () => {
|
||||||
<DialogDescription className="sr-only">desc</DialogDescription>
|
<DialogDescription className="sr-only">desc</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<FormComuni
|
<FormComuni
|
||||||
handleRemove={() =>
|
handleRemove={() => deleteComune(selectedComune.id)}
|
||||||
deleteComune({
|
|
||||||
id: selectedComune.id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
initialValues={selectedComune}
|
initialValues={selectedComune}
|
||||||
submitMutation={(values) => {
|
submitMutation={(values) => {
|
||||||
editComune({
|
editComune({
|
||||||
|
|
@ -580,11 +576,7 @@ const SezioneProvincie = () => {
|
||||||
<DialogDescription className="sr-only">desc</DialogDescription>
|
<DialogDescription className="sr-only">desc</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<FormProvincie
|
<FormProvincie
|
||||||
handleRemove={() =>
|
handleRemove={() => deleteProvincia(selectedProvincia.id)}
|
||||||
deleteProvincia({
|
|
||||||
id: selectedProvincia.id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
initialValues={selectedProvincia}
|
initialValues={selectedProvincia}
|
||||||
submitMutation={(values) => {
|
submitMutation={(values) => {
|
||||||
editProvincia({
|
editProvincia({
|
||||||
|
|
@ -865,11 +857,7 @@ const SezioneNazioni = () => {
|
||||||
<DialogDescription className="sr-only">desc</DialogDescription>
|
<DialogDescription className="sr-only">desc</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<FormNazioni
|
<FormNazioni
|
||||||
handleRemove={() =>
|
handleRemove={() => deleteNazione(selectedNazione.id)}
|
||||||
deleteNazione({
|
|
||||||
id: selectedNazione.id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
initialValues={selectedNazione}
|
initialValues={selectedNazione}
|
||||||
submitMutation={(values) => {
|
submitMutation={(values) => {
|
||||||
editNazione({
|
editNazione({
|
||||||
|
|
|
||||||
151
apps/infoalloggi/src/providers/AppuntiProvider.tsx
Normal file
151
apps/infoalloggi/src/providers/AppuntiProvider.tsx
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
import { createContext, useContext } from "react";
|
||||||
|
import toast from "react-hot-toast";
|
||||||
|
import type { AppuntiId, NewAppunti } from "~/schemas/public/Appunti";
|
||||||
|
import type {
|
||||||
|
AppuntiGroups,
|
||||||
|
AppuntiGroupsId,
|
||||||
|
} from "~/schemas/public/AppuntiGroups";
|
||||||
|
|
||||||
|
import type { AppuntiData } from "~/server/services/appunti.service";
|
||||||
|
import { api } from "~/utils/api";
|
||||||
|
|
||||||
|
type AppuntiContextType = {
|
||||||
|
data: AppuntiData[];
|
||||||
|
columns: AppuntiGroups[];
|
||||||
|
setData: (data: AppuntiData[]) => void;
|
||||||
|
updateCall: () => void;
|
||||||
|
addItem: (item: NewAppunti) => void;
|
||||||
|
removeItem: (id: AppuntiId) => void;
|
||||||
|
removeColumn: (id: AppuntiGroupsId) => void;
|
||||||
|
addColumn: (name: string) => void;
|
||||||
|
updateItem: (item: AppuntiData) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const AppuntiContext = createContext<AppuntiContextType | null>(null);
|
||||||
|
|
||||||
|
type AppuntiProviderProps = {
|
||||||
|
children: React.ReactNode;
|
||||||
|
};
|
||||||
|
export const AppuntiProvider = ({ children }: AppuntiProviderProps) => {
|
||||||
|
const { data, isError } = api.appunti.getAppunti.useQuery(undefined, {
|
||||||
|
refetchInterval: 30000,
|
||||||
|
refetchIntervalInBackground: true,
|
||||||
|
refetchOnWindowFocus: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isError) {
|
||||||
|
console.error("Errore nel caricamento dei potenziali");
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data: columns } = api.appunti.getAppuntiGroups.useQuery();
|
||||||
|
|
||||||
|
const utils = api.useUtils();
|
||||||
|
const { mutate: addItemMutation } = api.appunti.addAppunti.useMutation({
|
||||||
|
onSuccess: async () => {
|
||||||
|
toast.success("Elemento aggiunto con successo");
|
||||||
|
await utils.appunti.getAppunti.invalidate();
|
||||||
|
await utils.appunti.getAppuntiGroups.invalidate();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const addItem = (item: NewAppunti) => {
|
||||||
|
addItemMutation({
|
||||||
|
data: item,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const { mutate: removeItemMutation } = api.appunti.deleteAppunti.useMutation({
|
||||||
|
onSuccess: async () => {
|
||||||
|
toast.success("Elemento rimosso con successo");
|
||||||
|
await utils.appunti.getAppunti.invalidate();
|
||||||
|
await utils.appunti.getAppuntiGroups.invalidate();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const removeItem = (id: AppuntiId) => {
|
||||||
|
removeItemMutation(id);
|
||||||
|
};
|
||||||
|
const setData = (newData: AppuntiData[]) => {
|
||||||
|
utils.appunti.getAppunti.setData(undefined, newData);
|
||||||
|
};
|
||||||
|
|
||||||
|
const { mutate: updateAppuntiMutation } =
|
||||||
|
api.appunti.updateAppunti.useMutation({
|
||||||
|
onSuccess: async () => {
|
||||||
|
await utils.appunti.getAppunti.invalidate();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateCall = () => {
|
||||||
|
updateAppuntiMutation({
|
||||||
|
data: utils.appunti.getAppunti.getData() || [],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const { mutate: addColumnMutation } = api.appunti.addAppuntiGroup.useMutation(
|
||||||
|
{
|
||||||
|
onSuccess: async () => {
|
||||||
|
toast.success("Colonna aggiunta con successo");
|
||||||
|
await utils.appunti.getAppunti.invalidate();
|
||||||
|
await utils.appunti.getAppuntiGroups.invalidate();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const addColumn = (name: string) => {
|
||||||
|
addColumnMutation({
|
||||||
|
name,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const { mutate: updateItemMutation } = api.appunti.updateAppunto.useMutation({
|
||||||
|
onSuccess: async () => {
|
||||||
|
toast.success("Elemento aggiornato con successo");
|
||||||
|
await utils.appunti.getAppunti.invalidate();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const updateItem = (item: AppuntiData) => {
|
||||||
|
const { column, username: _username, ...rest } = item;
|
||||||
|
updateItemMutation({
|
||||||
|
appuntiId: item.id,
|
||||||
|
data: {
|
||||||
|
...rest,
|
||||||
|
appunti_group_id: column as AppuntiGroupsId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const { mutate: removeColumnMutation } =
|
||||||
|
api.appunti.deleteAppuntiGroup.useMutation({
|
||||||
|
onSuccess: async () => {
|
||||||
|
toast.success("Colonna rimossa con successo");
|
||||||
|
await utils.appunti.getAppunti.invalidate();
|
||||||
|
await utils.appunti.getAppuntiGroups.invalidate();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const removeColumn = (id: AppuntiGroupsId) => {
|
||||||
|
removeColumnMutation(id);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AppuntiContext.Provider
|
||||||
|
value={{
|
||||||
|
data: data || [],
|
||||||
|
columns: columns || [],
|
||||||
|
setData,
|
||||||
|
updateCall,
|
||||||
|
addItem,
|
||||||
|
removeItem,
|
||||||
|
addColumn,
|
||||||
|
updateItem,
|
||||||
|
removeColumn,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</AppuntiContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export const useAppunti = () => {
|
||||||
|
const context = useContext(AppuntiContext);
|
||||||
|
if (!context) {
|
||||||
|
throw new Error("useAppunti must be used within a AppuntiProvider");
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
};
|
||||||
|
|
@ -1,155 +0,0 @@
|
||||||
import { createContext, useContext } from "react";
|
|
||||||
import toast from "react-hot-toast";
|
|
||||||
import type { NewPotenziali, PotenzialiId } from "~/schemas/public/Potenziali";
|
|
||||||
import type {
|
|
||||||
PotenzialiGroups,
|
|
||||||
PotenzialiGroupsId,
|
|
||||||
} from "~/schemas/public/PotenzialiGroups";
|
|
||||||
import type { PotenzialeData } from "~/server/services/potenziali.service";
|
|
||||||
import { api } from "~/utils/api";
|
|
||||||
|
|
||||||
type PotenzialiContextType = {
|
|
||||||
data: PotenzialeData[];
|
|
||||||
columns: PotenzialiGroups[];
|
|
||||||
setData: (data: PotenzialeData[]) => void;
|
|
||||||
updateCall: () => void;
|
|
||||||
addItem: (item: NewPotenziali) => void;
|
|
||||||
removeItem: (id: PotenzialiId) => void;
|
|
||||||
removeColumn: (id: PotenzialiGroupsId) => void;
|
|
||||||
addColumn: (name: string) => void;
|
|
||||||
updateItem: (item: PotenzialeData) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const PotenzialiContext = createContext<PotenzialiContextType | null>(null);
|
|
||||||
|
|
||||||
type PotenzialiProviderProps = {
|
|
||||||
children: React.ReactNode;
|
|
||||||
};
|
|
||||||
export const PotenzialiProvider = ({ children }: PotenzialiProviderProps) => {
|
|
||||||
const { data, isError } = api.potenziali.getPotenziali.useQuery(undefined, {
|
|
||||||
refetchInterval: 30000,
|
|
||||||
refetchIntervalInBackground: true,
|
|
||||||
refetchOnWindowFocus: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isError) {
|
|
||||||
console.error("Errore nel caricamento dei potenziali");
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data: columns } = api.potenziali.getPotenzialiGroups.useQuery();
|
|
||||||
|
|
||||||
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 { 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,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const { mutate: updateItemMutation } =
|
|
||||||
api.potenziali.updatePotenziale.useMutation({
|
|
||||||
onSuccess: async () => {
|
|
||||||
toast.success("Elemento aggiornato con successo");
|
|
||||||
await utils.potenziali.getPotenziali.invalidate();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const updateItem = (item: PotenzialeData) => {
|
|
||||||
const { column, username: _username, ...rest } = item;
|
|
||||||
updateItemMutation({
|
|
||||||
potenzialiId: item.id,
|
|
||||||
data: {
|
|
||||||
...rest,
|
|
||||||
potenziali_group_id: column as PotenzialiGroupsId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const { mutate: removeColumnMutation } =
|
|
||||||
api.potenziali.deletePotenzialeGroup.useMutation({
|
|
||||||
onSuccess: async () => {
|
|
||||||
toast.success("Colonna rimossa con successo");
|
|
||||||
await utils.potenziali.getPotenziali.invalidate();
|
|
||||||
await utils.potenziali.getPotenzialiGroups.invalidate();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const removeColumn = (id: PotenzialiGroupsId) => {
|
|
||||||
removeColumnMutation({
|
|
||||||
potenzialiGroupId: id,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PotenzialiContext.Provider
|
|
||||||
value={{
|
|
||||||
data: data || [],
|
|
||||||
columns: columns || [],
|
|
||||||
setData,
|
|
||||||
updateCall,
|
|
||||||
addItem,
|
|
||||||
removeItem,
|
|
||||||
addColumn,
|
|
||||||
updateItem,
|
|
||||||
removeColumn,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</PotenzialiContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
export const usePotenziali = () => {
|
|
||||||
const context = useContext(PotenzialiContext);
|
|
||||||
if (!context) {
|
|
||||||
throw new Error("usePotenziali must be used within a PotenzialiProvider");
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
};
|
|
||||||
57
apps/infoalloggi/src/schemas/public/Appunti.ts
Normal file
57
apps/infoalloggi/src/schemas/public/Appunti.ts
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
import { usersId, type UsersId } from './Users';
|
||||||
|
import { appuntiGroupsId, type AppuntiGroupsId } from './AppuntiGroups';
|
||||||
|
import type { ColumnType, Selectable, Insertable, Updateable } from 'kysely';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
/** Identifier type for public.appunti */
|
||||||
|
export type AppuntiId = string & { __brand: 'public.appunti' };
|
||||||
|
|
||||||
|
/** Represents the table public.appunti */
|
||||||
|
export default interface AppuntiTable {
|
||||||
|
id: ColumnType<AppuntiId, AppuntiId | undefined, AppuntiId>;
|
||||||
|
|
||||||
|
name: ColumnType<string, string, string>;
|
||||||
|
|
||||||
|
descrizione: ColumnType<string | null, string | null, string | null>;
|
||||||
|
|
||||||
|
created_at: ColumnType<Date, Date | string | undefined, Date | string>;
|
||||||
|
|
||||||
|
userid: ColumnType<UsersId | null, UsersId | null, UsersId | null>;
|
||||||
|
|
||||||
|
appunti_group_id: ColumnType<AppuntiGroupsId, AppuntiGroupsId, AppuntiGroupsId>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Appunti = Selectable<AppuntiTable>;
|
||||||
|
|
||||||
|
export type NewAppunti = Insertable<AppuntiTable>;
|
||||||
|
|
||||||
|
export type AppuntiUpdate = Updateable<AppuntiTable>;
|
||||||
|
|
||||||
|
export const appuntiId = z.uuid().transform(value => value as AppuntiId);
|
||||||
|
|
||||||
|
export const AppuntiSchema = z.object({
|
||||||
|
id: appuntiId,
|
||||||
|
name: z.string(),
|
||||||
|
descrizione: z.string().nullable(),
|
||||||
|
created_at: z.date(),
|
||||||
|
userid: usersId.nullable(),
|
||||||
|
appunti_group_id: appuntiGroupsId,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const NewAppuntiSchema = z.object({
|
||||||
|
id: appuntiId.optional(),
|
||||||
|
name: z.string(),
|
||||||
|
descrizione: z.string().optional().nullable(),
|
||||||
|
created_at: z.union([z.date(), z.string()]).pipe(z.coerce.date()).optional(),
|
||||||
|
userid: usersId.optional().nullable(),
|
||||||
|
appunti_group_id: appuntiGroupsId,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const AppuntiUpdateSchema = z.object({
|
||||||
|
id: appuntiId.optional(),
|
||||||
|
name: z.string().optional(),
|
||||||
|
descrizione: z.string().optional().nullable(),
|
||||||
|
created_at: z.union([z.date(), z.string()]).pipe(z.coerce.date()).optional(),
|
||||||
|
userid: usersId.optional().nullable(),
|
||||||
|
appunti_group_id: appuntiGroupsId.optional(),
|
||||||
|
});
|
||||||
40
apps/infoalloggi/src/schemas/public/AppuntiGroups.ts
Normal file
40
apps/infoalloggi/src/schemas/public/AppuntiGroups.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
import type { ColumnType, Selectable, Insertable, Updateable } from 'kysely';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
/** Identifier type for public.appunti_groups */
|
||||||
|
export type AppuntiGroupsId = string & { __brand: 'public.appunti_groups' };
|
||||||
|
|
||||||
|
/** Represents the table public.appunti_groups */
|
||||||
|
export default interface AppuntiGroupsTable {
|
||||||
|
id: ColumnType<AppuntiGroupsId, AppuntiGroupsId | undefined, AppuntiGroupsId>;
|
||||||
|
|
||||||
|
name: ColumnType<string, string, string>;
|
||||||
|
|
||||||
|
color: ColumnType<string, string | undefined, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AppuntiGroups = Selectable<AppuntiGroupsTable>;
|
||||||
|
|
||||||
|
export type NewAppuntiGroups = Insertable<AppuntiGroupsTable>;
|
||||||
|
|
||||||
|
export type AppuntiGroupsUpdate = Updateable<AppuntiGroupsTable>;
|
||||||
|
|
||||||
|
export const appuntiGroupsId = z.uuid().transform(value => value as AppuntiGroupsId);
|
||||||
|
|
||||||
|
export const AppuntiGroupsSchema = z.object({
|
||||||
|
id: appuntiGroupsId,
|
||||||
|
name: z.string(),
|
||||||
|
color: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const NewAppuntiGroupsSchema = z.object({
|
||||||
|
id: appuntiGroupsId.optional(),
|
||||||
|
name: z.string(),
|
||||||
|
color: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const AppuntiGroupsUpdateSchema = z.object({
|
||||||
|
id: appuntiGroupsId.optional(),
|
||||||
|
name: z.string().optional(),
|
||||||
|
color: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
import { usersId, type UsersId } from './Users';
|
|
||||||
import { potenzialiGroupsId, type PotenzialiGroupsId } from './PotenzialiGroups';
|
|
||||||
import type { ColumnType, Selectable, Insertable, Updateable } from 'kysely';
|
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
/** Identifier type for public.potenziali */
|
|
||||||
export type PotenzialiId = string & { __brand: 'public.potenziali' };
|
|
||||||
|
|
||||||
/** Represents the table public.potenziali */
|
|
||||||
export default interface PotenzialiTable {
|
|
||||||
id: ColumnType<PotenzialiId, PotenzialiId | undefined, PotenzialiId>;
|
|
||||||
|
|
||||||
name: ColumnType<string, string, string>;
|
|
||||||
|
|
||||||
descrizione: ColumnType<string | null, string | null, string | null>;
|
|
||||||
|
|
||||||
created_at: ColumnType<Date, Date | string | undefined, Date | string>;
|
|
||||||
|
|
||||||
userid: ColumnType<UsersId | null, UsersId | null, UsersId | null>;
|
|
||||||
|
|
||||||
potenziali_group_id: ColumnType<PotenzialiGroupsId, PotenzialiGroupsId, PotenzialiGroupsId>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Potenziali = Selectable<PotenzialiTable>;
|
|
||||||
|
|
||||||
export type NewPotenziali = Insertable<PotenzialiTable>;
|
|
||||||
|
|
||||||
export type PotenzialiUpdate = Updateable<PotenzialiTable>;
|
|
||||||
|
|
||||||
export const potenzialiId = z.uuid().transform(value => value as PotenzialiId);
|
|
||||||
|
|
||||||
export const PotenzialiSchema = z.object({
|
|
||||||
id: potenzialiId,
|
|
||||||
name: z.string(),
|
|
||||||
descrizione: z.string().nullable(),
|
|
||||||
created_at: z.date(),
|
|
||||||
userid: usersId.nullable(),
|
|
||||||
potenziali_group_id: potenzialiGroupsId,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const NewPotenzialiSchema = z.object({
|
|
||||||
id: potenzialiId.optional(),
|
|
||||||
name: z.string(),
|
|
||||||
descrizione: z.string().optional().nullable(),
|
|
||||||
created_at: z.union([z.date(), z.string()]).pipe(z.coerce.date()).optional(),
|
|
||||||
userid: usersId.optional().nullable(),
|
|
||||||
potenziali_group_id: potenzialiGroupsId,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const PotenzialiUpdateSchema = z.object({
|
|
||||||
id: potenzialiId.optional(),
|
|
||||||
name: z.string().optional(),
|
|
||||||
descrizione: z.string().optional().nullable(),
|
|
||||||
created_at: z.union([z.date(), z.string()]).pipe(z.coerce.date()).optional(),
|
|
||||||
userid: usersId.optional().nullable(),
|
|
||||||
potenziali_group_id: potenzialiGroupsId.optional(),
|
|
||||||
});
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
import type { ColumnType, Selectable, Insertable, Updateable } from 'kysely';
|
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
/** 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<PotenzialiGroupsId, PotenzialiGroupsId | undefined, PotenzialiGroupsId>;
|
|
||||||
|
|
||||||
name: ColumnType<string, string, string>;
|
|
||||||
|
|
||||||
color: ColumnType<string, string | undefined, string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PotenzialiGroups = Selectable<PotenzialiGroupsTable>;
|
|
||||||
|
|
||||||
export type NewPotenzialiGroups = Insertable<PotenzialiGroupsTable>;
|
|
||||||
|
|
||||||
export type PotenzialiGroupsUpdate = Updateable<PotenzialiGroupsTable>;
|
|
||||||
|
|
||||||
export const potenzialiGroupsId = z.uuid().transform(value => value as PotenzialiGroupsId);
|
|
||||||
|
|
||||||
export const PotenzialiGroupsSchema = z.object({
|
|
||||||
id: potenzialiGroupsId,
|
|
||||||
name: z.string(),
|
|
||||||
color: z.string(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const NewPotenzialiGroupsSchema = z.object({
|
|
||||||
id: potenzialiGroupsId.optional(),
|
|
||||||
name: z.string(),
|
|
||||||
color: z.string().optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const PotenzialiGroupsUpdateSchema = z.object({
|
|
||||||
id: potenzialiGroupsId.optional(),
|
|
||||||
name: z.string().optional(),
|
|
||||||
color: z.string().optional(),
|
|
||||||
});
|
|
||||||
|
|
@ -5,11 +5,11 @@ import type { default as UsersTable } from './Users';
|
||||||
import type { default as ChatsEtichetteTable } from './ChatsEtichette';
|
import type { default as ChatsEtichetteTable } from './ChatsEtichette';
|
||||||
import type { default as TestiEStringheTable } from './TestiEStringhe';
|
import type { default as TestiEStringheTable } from './TestiEStringhe';
|
||||||
import type { default as UserEtichetteTable } from './UserEtichette';
|
import type { default as UserEtichetteTable } from './UserEtichette';
|
||||||
|
import type { default as AppuntiTable } from './Appunti';
|
||||||
import type { default as UsersStorageTable } from './UsersStorage';
|
import type { default as UsersStorageTable } from './UsersStorage';
|
||||||
import type { default as ServizioAnnunciTable } from './ServizioAnnunci';
|
import type { default as ServizioAnnunciTable } from './ServizioAnnunci';
|
||||||
import type { default as UserInvitesTable } from './UserInvites';
|
import type { default as UserInvitesTable } from './UserInvites';
|
||||||
import type { default as EmailsTable } from './Emails';
|
import type { default as EmailsTable } from './Emails';
|
||||||
import type { default as PotenzialiGroupsTable } from './PotenzialiGroups';
|
|
||||||
import type { default as ComuniTable } from './Comuni';
|
import type { default as ComuniTable } from './Comuni';
|
||||||
import type { default as RinnoviTable } from './Rinnovi';
|
import type { default as RinnoviTable } from './Rinnovi';
|
||||||
import type { default as EventQueueTable } from './EventQueue';
|
import type { default as EventQueueTable } from './EventQueue';
|
||||||
|
|
@ -21,10 +21,10 @@ import type { default as EtichetteTable } from './Etichette';
|
||||||
import type { default as MessagesTable } from './Messages';
|
import type { default as MessagesTable } from './Messages';
|
||||||
import type { default as UsersAnagraficaTable } from './UsersAnagrafica';
|
import type { default as UsersAnagraficaTable } from './UsersAnagrafica';
|
||||||
import type { default as ProvincieTable } from './Provincie';
|
import type { default as ProvincieTable } from './Provincie';
|
||||||
import type { default as PotenzialiTable } from './Potenziali';
|
|
||||||
import type { default as VideosRefsTable } from './VideosRefs';
|
import type { default as VideosRefsTable } from './VideosRefs';
|
||||||
import type { default as BanlistTable } from './Banlist';
|
import type { default as BanlistTable } from './Banlist';
|
||||||
import type { default as NazioniTable } from './Nazioni';
|
import type { default as NazioniTable } from './Nazioni';
|
||||||
|
import type { default as AppuntiGroupsTable } from './AppuntiGroups';
|
||||||
import type { default as ImagesRefsTable } from './ImagesRefs';
|
import type { default as ImagesRefsTable } from './ImagesRefs';
|
||||||
import type { default as BannersTable } from './Banners';
|
import type { default as BannersTable } from './Banners';
|
||||||
import type { default as ServizioTable } from './Servizio';
|
import type { default as ServizioTable } from './Servizio';
|
||||||
|
|
@ -45,6 +45,8 @@ export default interface PublicSchema {
|
||||||
|
|
||||||
user_etichette: UserEtichetteTable;
|
user_etichette: UserEtichetteTable;
|
||||||
|
|
||||||
|
appunti: AppuntiTable;
|
||||||
|
|
||||||
users_storage: UsersStorageTable;
|
users_storage: UsersStorageTable;
|
||||||
|
|
||||||
servizio_annunci: ServizioAnnunciTable;
|
servizio_annunci: ServizioAnnunciTable;
|
||||||
|
|
@ -53,8 +55,6 @@ export default interface PublicSchema {
|
||||||
|
|
||||||
emails: EmailsTable;
|
emails: EmailsTable;
|
||||||
|
|
||||||
potenziali_groups: PotenzialiGroupsTable;
|
|
||||||
|
|
||||||
comuni: ComuniTable;
|
comuni: ComuniTable;
|
||||||
|
|
||||||
rinnovi: RinnoviTable;
|
rinnovi: RinnoviTable;
|
||||||
|
|
@ -77,14 +77,14 @@ export default interface PublicSchema {
|
||||||
|
|
||||||
provincie: ProvincieTable;
|
provincie: ProvincieTable;
|
||||||
|
|
||||||
potenziali: PotenzialiTable;
|
|
||||||
|
|
||||||
videos_refs: VideosRefsTable;
|
videos_refs: VideosRefsTable;
|
||||||
|
|
||||||
banlist: BanlistTable;
|
banlist: BanlistTable;
|
||||||
|
|
||||||
nazioni: NazioniTable;
|
nazioni: NazioniTable;
|
||||||
|
|
||||||
|
appunti_groups: AppuntiGroupsTable;
|
||||||
|
|
||||||
images_refs: ImagesRefsTable;
|
images_refs: ImagesRefsTable;
|
||||||
|
|
||||||
banners: BannersTable;
|
banners: BannersTable;
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,12 @@ import { stripeReportsRouter } from "~/server/api/routers/stripe_reports";
|
||||||
import { testRouter } from "~/server/api/routers/test";
|
import { testRouter } from "~/server/api/routers/test";
|
||||||
import { usersRouter } from "~/server/api/routers/users";
|
import { usersRouter } from "~/server/api/routers/users";
|
||||||
import { createTRPCRouter } from "~/server/api/trpc";
|
import { createTRPCRouter } from "~/server/api/trpc";
|
||||||
|
import { appuntiRouter } from "./routers/appunti";
|
||||||
import { bannersRouter } from "./routers/banners";
|
import { bannersRouter } from "./routers/banners";
|
||||||
import { catastoRouter } from "./routers/catasto";
|
import { catastoRouter } from "./routers/catasto";
|
||||||
import { etichetteRouter } from "./routers/etichette";
|
import { etichetteRouter } from "./routers/etichette";
|
||||||
import { flagsRouter } from "./routers/flags";
|
import { flagsRouter } from "./routers/flags";
|
||||||
import { inviteRouter } from "./routers/invite";
|
import { inviteRouter } from "./routers/invite";
|
||||||
import { potenzialiRouter } from "./routers/potenziali";
|
|
||||||
import { revalidationRouter } from "./routers/revalidation";
|
import { revalidationRouter } from "./routers/revalidation";
|
||||||
import { stringsRouter } from "./routers/strings";
|
import { stringsRouter } from "./routers/strings";
|
||||||
|
|
||||||
|
|
@ -54,7 +54,7 @@ export const appRouter = createTRPCRouter({
|
||||||
etichette: etichetteRouter,
|
etichette: etichetteRouter,
|
||||||
strings: stringsRouter,
|
strings: stringsRouter,
|
||||||
revalidation: revalidationRouter,
|
revalidation: revalidationRouter,
|
||||||
potenziali: potenzialiRouter,
|
appunti: appuntiRouter,
|
||||||
invite: inviteRouter,
|
invite: inviteRouter,
|
||||||
});
|
});
|
||||||
export type AppRouter = typeof appRouter;
|
export type AppRouter = typeof appRouter;
|
||||||
|
|
|
||||||
76
apps/infoalloggi/src/server/api/routers/appunti.ts
Normal file
76
apps/infoalloggi/src/server/api/routers/appunti.ts
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
import z from "zod";
|
||||||
|
import {
|
||||||
|
AppuntiUpdateSchema,
|
||||||
|
appuntiId,
|
||||||
|
NewAppuntiSchema,
|
||||||
|
} from "~/schemas/public/Appunti";
|
||||||
|
import { appuntiGroupsId } from "~/schemas/public/AppuntiGroups";
|
||||||
|
|
||||||
|
import { adminProcedure, createTRPCRouter } from "~/server/api/trpc";
|
||||||
|
import {
|
||||||
|
type AppuntiData,
|
||||||
|
addAppunti,
|
||||||
|
addAppuntiGroup,
|
||||||
|
deleteAppunti,
|
||||||
|
deleteAppuntiGroup,
|
||||||
|
getAppunti,
|
||||||
|
getAppuntiGroups,
|
||||||
|
updateAppunti,
|
||||||
|
updateAppunto,
|
||||||
|
} from "~/server/services/appunti.service";
|
||||||
|
|
||||||
|
export const appuntiRouter = createTRPCRouter({
|
||||||
|
getAppunti: adminProcedure.query(async () => {
|
||||||
|
return await getAppunti();
|
||||||
|
}),
|
||||||
|
getAppuntiGroups: adminProcedure.query(async () => {
|
||||||
|
return await getAppuntiGroups();
|
||||||
|
}),
|
||||||
|
addAppunti: adminProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
data: NewAppuntiSchema,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
return await addAppunti(input.data);
|
||||||
|
}),
|
||||||
|
updateAppunti: adminProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
data: z.custom<AppuntiData[]>(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
return await updateAppunti(input.data);
|
||||||
|
}),
|
||||||
|
updateAppunto: adminProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
appuntiId: appuntiId,
|
||||||
|
data: AppuntiUpdateSchema,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
return await updateAppunto(input.appuntiId, input.data);
|
||||||
|
}),
|
||||||
|
deleteAppunti: adminProcedure.input(appuntiId).mutation(async ({ input }) => {
|
||||||
|
return await deleteAppunti(input);
|
||||||
|
}),
|
||||||
|
|
||||||
|
addAppuntiGroup: adminProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
name: z.string().min(1).max(255),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
return await addAppuntiGroup({ name: input.name });
|
||||||
|
}),
|
||||||
|
|
||||||
|
deleteAppuntiGroup: adminProcedure
|
||||||
|
.input(appuntiGroupsId)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
return await deleteAppuntiGroup(input);
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
@ -54,14 +54,8 @@ export const catastoRouter = createTRPCRouter({
|
||||||
const { id, data } = input;
|
const { id, data } = input;
|
||||||
return await editComune({ id, data });
|
return await editComune({ id, data });
|
||||||
}),
|
}),
|
||||||
deleteComune: adminProcedure
|
deleteComune: adminProcedure.input(comuniId).mutation(async ({ input }) => {
|
||||||
.input(
|
return await deleteComune(input);
|
||||||
z.object({
|
|
||||||
id: comuniId,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.mutation(async ({ input }) => {
|
|
||||||
return await deleteComune(input.id);
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getProvincie: publicProcedure.query(async () => {
|
getProvincie: publicProcedure.query(async () => {
|
||||||
|
|
@ -84,13 +78,9 @@ export const catastoRouter = createTRPCRouter({
|
||||||
return await editProvincia({ id, data });
|
return await editProvincia({ id, data });
|
||||||
}),
|
}),
|
||||||
deleteProvincia: adminProcedure
|
deleteProvincia: adminProcedure
|
||||||
.input(
|
.input(provincieId)
|
||||||
z.object({
|
|
||||||
id: provincieId,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
return await deleteProvincia(input.id);
|
return await deleteProvincia(input);
|
||||||
}),
|
}),
|
||||||
getNazioni: publicProcedure.query(async () => {
|
getNazioni: publicProcedure.query(async () => {
|
||||||
return await getNazioni();
|
return await getNazioni();
|
||||||
|
|
@ -111,13 +101,7 @@ export const catastoRouter = createTRPCRouter({
|
||||||
const { id, data } = input;
|
const { id, data } = input;
|
||||||
return await editNazione({ id, data });
|
return await editNazione({ id, data });
|
||||||
}),
|
}),
|
||||||
deleteNazione: adminProcedure
|
deleteNazione: adminProcedure.input(nazioniId).mutation(async ({ input }) => {
|
||||||
.input(
|
return await deleteNazione(input);
|
||||||
z.object({
|
|
||||||
id: nazioniId,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.mutation(async ({ input }) => {
|
|
||||||
return await deleteNazione(input.id);
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
import z from "zod";
|
|
||||||
import {
|
|
||||||
NewPotenzialiSchema,
|
|
||||||
PotenzialiUpdateSchema,
|
|
||||||
potenzialiId,
|
|
||||||
} from "~/schemas/public/Potenziali";
|
|
||||||
|
|
||||||
import { potenzialiGroupsId } from "~/schemas/public/PotenzialiGroups";
|
|
||||||
import { adminProcedure, createTRPCRouter } from "~/server/api/trpc";
|
|
||||||
import {
|
|
||||||
addPotenziale,
|
|
||||||
addPotenzialeGroup,
|
|
||||||
deletePotenziale,
|
|
||||||
deletePotenzialeGroup,
|
|
||||||
getPotenziali,
|
|
||||||
getPotenzialiGroups,
|
|
||||||
type PotenzialeData,
|
|
||||||
updatePotenziale,
|
|
||||||
updatePotenziali,
|
|
||||||
} from "~/server/services/potenziali.service";
|
|
||||||
|
|
||||||
export const potenzialiRouter = createTRPCRouter({
|
|
||||||
getPotenziali: adminProcedure.query(async () => {
|
|
||||||
return await getPotenziali();
|
|
||||||
}),
|
|
||||||
getPotenzialiGroups: adminProcedure.query(async () => {
|
|
||||||
return await getPotenzialiGroups();
|
|
||||||
}),
|
|
||||||
addPotenziale: adminProcedure
|
|
||||||
.input(
|
|
||||||
z.object({
|
|
||||||
data: NewPotenzialiSchema,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.mutation(async ({ input }) => {
|
|
||||||
return await addPotenziale(input.data);
|
|
||||||
}),
|
|
||||||
updatePotenziali: adminProcedure
|
|
||||||
.input(
|
|
||||||
z.object({
|
|
||||||
data: z.custom<PotenzialeData[]>(),
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.mutation(async ({ input }) => {
|
|
||||||
return await updatePotenziali(input.data);
|
|
||||||
}),
|
|
||||||
updatePotenziale: adminProcedure
|
|
||||||
.input(
|
|
||||||
z.object({
|
|
||||||
potenzialiId: potenzialiId,
|
|
||||||
data: PotenzialiUpdateSchema,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.mutation(async ({ input }) => {
|
|
||||||
return await updatePotenziale(input.potenzialiId, input.data);
|
|
||||||
}),
|
|
||||||
deletePotenziale: adminProcedure
|
|
||||||
.input(
|
|
||||||
z.object({
|
|
||||||
potenzialiId: potenzialiId,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.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 });
|
|
||||||
}),
|
|
||||||
|
|
||||||
deletePotenzialeGroup: adminProcedure
|
|
||||||
.input(
|
|
||||||
z.object({
|
|
||||||
potenzialiGroupId: potenzialiGroupsId,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.mutation(async ({ input }) => {
|
|
||||||
return await deletePotenzialeGroup(input.potenzialiGroupId);
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
162
apps/infoalloggi/src/server/services/appunti.service.ts
Normal file
162
apps/infoalloggi/src/server/services/appunti.service.ts
Normal file
|
|
@ -0,0 +1,162 @@
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import type { Nullable } from "kysely";
|
||||||
|
import type {
|
||||||
|
Appunti,
|
||||||
|
AppuntiId,
|
||||||
|
AppuntiUpdate,
|
||||||
|
NewAppunti,
|
||||||
|
} from "~/schemas/public/Appunti";
|
||||||
|
import type {
|
||||||
|
AppuntiGroups,
|
||||||
|
AppuntiGroupsId,
|
||||||
|
NewAppuntiGroups,
|
||||||
|
} from "~/schemas/public/AppuntiGroups";
|
||||||
|
import type { Users } from "~/schemas/public/Users";
|
||||||
|
import { db } from "../db";
|
||||||
|
|
||||||
|
export type AppuntiData = Omit<Appunti, "appunti_group_id"> & {
|
||||||
|
column: string;
|
||||||
|
} & Nullable<Pick<Users, "username">>;
|
||||||
|
|
||||||
|
export const getAppunti = async (): Promise<AppuntiData[]> => {
|
||||||
|
try {
|
||||||
|
const appunti = await db
|
||||||
|
.selectFrom("appunti")
|
||||||
|
.select([
|
||||||
|
"appunti.id",
|
||||||
|
"appunti.name",
|
||||||
|
"appunti.created_at",
|
||||||
|
"appunti.descrizione",
|
||||||
|
"appunti.userid",
|
||||||
|
"appunti.appunti_group_id as column",
|
||||||
|
])
|
||||||
|
.innerJoin(
|
||||||
|
"appunti_groups",
|
||||||
|
"appunti.appunti_group_id",
|
||||||
|
"appunti_groups.id",
|
||||||
|
)
|
||||||
|
.leftJoin("users", "appunti.userid", "users.id")
|
||||||
|
.select("users.username")
|
||||||
|
.orderBy("appunti_groups.name", "asc")
|
||||||
|
.orderBy("appunti.created_at", "asc")
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
return appunti.map((data) => ({
|
||||||
|
...data,
|
||||||
|
created_at: new Date(data.created_at),
|
||||||
|
}));
|
||||||
|
} catch (e) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
|
message: `Failed to fetch Appunti, error: ${(e as Error).message}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getAppuntiGroups = async (): Promise<AppuntiGroups[]> => {
|
||||||
|
try {
|
||||||
|
return await db.selectFrom("appunti_groups").selectAll().execute();
|
||||||
|
} catch (e) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
|
message: `Failed to fetch Appunti groups, error: ${(e as Error).message}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const addAppuntiGroup = async (data: NewAppuntiGroups) => {
|
||||||
|
try {
|
||||||
|
await db.insertInto("appunti_groups").values(data).execute();
|
||||||
|
return { status: "success" };
|
||||||
|
} catch (e) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
|
message: `Failed to add Appunti group, error: ${(e as Error).message}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteAppuntiGroup = async (id: AppuntiGroupsId) => {
|
||||||
|
try {
|
||||||
|
await db.deleteFrom("appunti_groups").where("id", "=", id).execute();
|
||||||
|
return { status: "success" };
|
||||||
|
} catch (e) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
|
message: `Failed to delete Appunti group, error: ${(e as Error).message}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const addAppunti = async (data: NewAppunti) => {
|
||||||
|
try {
|
||||||
|
await db.insertInto("appunti").values(data).execute();
|
||||||
|
return { status: "success" };
|
||||||
|
} catch (e) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
|
message: `Failed to add Appunti, error: ${(e as Error).message}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteAppunti = async (id: AppuntiId) => {
|
||||||
|
try {
|
||||||
|
await db.deleteFrom("appunti").where("id", "=", id).execute();
|
||||||
|
return { status: "success" };
|
||||||
|
} catch (e) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
|
message: `Failed to delete Appunti, error: ${(e as Error).message}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateAppunto = async (id: AppuntiId, data: AppuntiUpdate) => {
|
||||||
|
try {
|
||||||
|
await db.updateTable("appunti").set(data).where("id", "=", id).execute();
|
||||||
|
return { status: "success" };
|
||||||
|
} catch (e) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
|
message: `Failed to update Appunti, error: ${(e as Error).message}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateAppunti = async (data: AppuntiData[]) => {
|
||||||
|
try {
|
||||||
|
const db_mappings = await db
|
||||||
|
.selectFrom("appunti")
|
||||||
|
.select(["id", "appunti_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.appunti_group_id !== item.column) {
|
||||||
|
const { column, username: _username, ...rest } = item;
|
||||||
|
return {
|
||||||
|
...rest,
|
||||||
|
appunti_group_id: column as AppuntiGroupsId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.filter((item) => item !== null);
|
||||||
|
|
||||||
|
for (const item of updates) {
|
||||||
|
await db
|
||||||
|
.updateTable("appunti")
|
||||||
|
.set(item)
|
||||||
|
.where("id", "=", item.id)
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
return { status: "success" };
|
||||||
|
} catch (e) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
|
message: `Failed to update appunti, error: ${(e as Error).message}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -1,165 +0,0 @@
|
||||||
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,
|
|
||||||
} from "~/schemas/public/PotenzialiGroups";
|
|
||||||
import type { Users } from "~/schemas/public/Users";
|
|
||||||
import { db } from "../db";
|
|
||||||
|
|
||||||
export type PotenzialeData = Omit<Potenziali, "potenziali_group_id"> & {
|
|
||||||
column: string;
|
|
||||||
} & Nullable<Pick<Users, "username">>;
|
|
||||||
|
|
||||||
export const getPotenziali = async (): Promise<PotenzialeData[]> => {
|
|
||||||
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<PotenzialiGroups[]> => {
|
|
||||||
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 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}`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -48,3 +48,5 @@ export const MessageUpdateEventSchema = z.discriminatedUnion("eventType", [
|
||||||
}),
|
}),
|
||||||
z.object({ eventType: z.literal("read_receipt"), data: z.null() }), // all unread messages in this chat are now read
|
z.object({ eventType: z.literal("read_receipt"), data: z.null() }), // all unread messages in this chat are now read
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue