feat: add Overseer integration with capture functionality and update tsconfig for global type definitions

This commit is contained in:
Marco Pedone 2026-03-18 17:39:06 +01:00
parent 37b5c01846
commit 3ecbc54515
4 changed files with 131 additions and 67 deletions

View file

@ -34,7 +34,6 @@
"!*compose.yml", "!*compose.yml",
"!.kanelrc.js", "!.kanelrc.js",
"!TODO", "!TODO",
"!*.d.ts",
"!src/i18n/comuni.ts", "!src/i18n/comuni.ts",
"!src/i18n/nazioni.ts", "!src/i18n/nazioni.ts",
"!src/i18n/provincie.ts", "!src/i18n/provincie.ts",

25
apps/infoalloggi/global.d.ts vendored Normal file
View file

@ -0,0 +1,25 @@
declare global {
type OverseerData = {
cognome?: string;
nome?: string;
cf?: string;
telefono?: string;
email?: string;
data_nascita?: string;
luogo_nascita?: string;
naz_residenza?: string;
provincia_residenza?: string;
cap_residenza?: string;
comune_residenza?: string;
indirizzo_residenza?: string;
civico_residenza?: string;
};
type OverseerCapture = {
capture: (data: OverseerData) => void;
};
interface Window {
OverseerCapture?: OverseerCapture;
}
}
export {};

View file

@ -1,5 +1,6 @@
import { format } from "date-fns"; import { format } from "date-fns";
import { import {
CloudSync,
ExternalLink, ExternalLink,
Mail, Mail,
MessagesSquare, MessagesSquare,
@ -13,7 +14,7 @@ import {
import Link from "next/link"; import Link from "next/link";
import { usePathname } from "next/navigation"; import { usePathname } from "next/navigation";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { useState } from "react"; import { useEffect, useState } from "react";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import LoadingButton from "~/components/custom_ui/loading-button"; import LoadingButton from "~/components/custom_ui/loading-button";
import { Textarea } from "~/components/custom_ui/textarea"; import { Textarea } from "~/components/custom_ui/textarea";
@ -85,6 +86,7 @@ export const UserViewHeader = () => {
</Button> </Button>
</Confirm> </Confirm>
<NoteUtenteDialog /> <NoteUtenteDialog />
<OverseerButton />
</div> </div>
<div className="flex flex-row flex-wrap gap-2"> <div className="flex flex-row flex-wrap gap-2">
<Link href={`/area-riservata/admin/user-view/edit-user/${data.id}`}> <Link href={`/area-riservata/admin/user-view/edit-user/${data.id}`}>
@ -173,6 +175,49 @@ export const UserViewHeader = () => {
); );
}; };
const OverseerButton = () => {
const data = useUserViewContext();
const [overseer, setOverseer] = useState<OverseerCapture | null>(null);
useEffect(() => {
if (typeof window !== "undefined" && window.OverseerCapture) {
setOverseer(window.OverseerCapture);
}
}, []);
const handleSendToOverseer = () => {
if (overseer) {
overseer.capture({
cognome: data.cognome,
nome: data.nome,
cf: data.codice_fiscale || undefined,
telefono: data.telefono,
email: data.email,
data_nascita: data.data_nascita?.toISOString() || undefined,
luogo_nascita: data.luogo_nascita || undefined,
naz_residenza: data.nazione_residenza || undefined,
provincia_residenza: data.provincia_residenza || undefined,
cap_residenza: data.cap_residenza || undefined,
comune_residenza: data.comune_residenza || undefined,
indirizzo_residenza: data.via_residenza || undefined,
civico_residenza: data.civico_residenza || undefined,
});
} else {
console.warn("Overseer extension not installed");
}
};
return (
<Button
disabled={!overseer}
onClick={handleSendToOverseer}
size="sm"
variant="outline"
>
<CloudSync />
</Button>
);
};
const VOCALI = ["A", "E", "I", "O", "U"] as const; const VOCALI = ["A", "E", "I", "O", "U"] as const;
const IntestazioneMaker = () => { const IntestazioneMaker = () => {

View file

@ -1,67 +1,62 @@
{ {
"compilerOptions": { "compilerOptions": {
"allowJs": true, "allowJs": true,
/* Path Aliases */ /* Path Aliases */
"baseUrl": ".", "baseUrl": ".",
"checkJs": true, "checkJs": true,
/* Base Options: */ /* Base Options: */
"esModuleInterop": true, "esModuleInterop": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"incremental": true, "incremental": true,
"isolatedModules": true, "isolatedModules": true,
"jsx": "react-jsx", "jsx": "react-jsx",
/* Bundled projects */ /* Bundled projects */
"lib": [ "lib": ["dom", "dom.iterable", "esnext"],
"dom", "module": "ESNext",
"dom.iterable", "moduleDetection": "force",
"esnext" "moduleResolution": "Bundler",
], "noEmit": true,
"module": "ESNext", "noUncheckedIndexedAccess": true,
"moduleDetection": "force", "paths": {
"moduleResolution": "Bundler", "~/*": ["./src/*"]
"noEmit": true, },
"noUncheckedIndexedAccess": true, "plugins": [
"paths": { {
"~/*": [ "name": "next"
"./src/*" }
] ],
}, "resolveJsonModule": true,
"plugins": [ "skipLibCheck": true,
{ /* Strictness */
"name": "next" "strict": true,
} "target": "esnext"
], },
"resolveJsonModule": true, "exclude": [
"skipLibCheck": true, "node_modules",
/* Strictness */ "out",
"strict": true, "dist",
"target": "esnext" "headers",
}, "kyselyRules",
"exclude": [ ".kanelrc.js"
"node_modules", ],
"out", "include": [
"dist", "src",
"headers", "global.d.ts",
"kyselyRules", "next-env.d.ts",
".kanelrc.js" "next.config.ts",
], "postcss.config.cjs",
"include": [ "reset.d.ts",
"src", "TypeHelpers.type.ts",
"next-env.d.ts", "public",
"next.config.ts", "emails",
"postcss.config.cjs", ".next/types/**/*.ts",
"reset.d.ts", "tests"
"TypeHelpers.type.ts", ],
"public", "ts-node": {
"emails", // these options are overrides used only by ts-node
".next/types/**/*.ts", // same as the --compilerOptions flag and the TS_NODE_COMPILER_OPTIONS environment variable
"tests" "compilerOptions": {
], "module": "commonjs"
"ts-node": { }
// these options are overrides used only by ts-node }
// same as the --compilerOptions flag and the TS_NODE_COMPILER_OPTIONS environment variable
"compilerOptions": {
"module": "commonjs"
}
}
} }