Merge branch <prisma> to <main> #6

Merged
llmad merged 8 commits from prisma into main 2025-11-23 09:59:46 +00:00
6 changed files with 35 additions and 105 deletions
Showing only changes of commit 07ae4170fc - Show all commits

View file

@ -1,32 +1,26 @@
FROM node:22-alpine AS base
# Dipendenze necessarie per Alpine (Prisma richiede OpenSSL)
RUN apk add --no-cache libc6-compat openssl
WORKDIR /app
# --- STAGE 1: Installazione Dipendenze ---
# --- STAGE 1 ---
FROM base AS deps
# Copia solo i file dei pacchetti per sfruttare la cache di Docker
COPY package.json ./
# Usa 'npm ci' invece di 'install' per build riproducibili e più veloci
RUN npm install
# --- STAGE 2: Build dell'applicazione ---
# --- STAGE 2 ---
FROM base AS builder
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Genera il client Prisma PRIMA del build
RUN npx prisma generate
# Disabilita la telemetria di Next.js durante il build
ENV NEXT_TELEMETRY_DISABLED=1
# Esegue il build (che userà output: standalone)
RUN npm run build
# --- STAGE 3: Immagine di Produzione (Runner) ---
# --- STAGE 3 ---
FROM base AS runner
WORKDIR /app
@ -35,20 +29,14 @@ ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
# Crea un utente non-root per sicurezza
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Copia la cartella public (immagini, favicon, ecc.)
COPY --from=builder /app/public ./public
# --- GESTIONE PRISMA E STANDALONE ---
# Copia la cartella .next/standalone (il server ridotto)
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
# Copia gli asset statici (.next/static) nella posizione corretta
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
# Passa all'utente limitato
USER nextjs
EXPOSE 3000

View file

@ -4,9 +4,9 @@ import ClientCard from "@/components/client-card";
import DeviceCard from "@/components/device-card";
import { Cliente, Intervento, Registratore } from "@/generated/prisma";
import { useSearchParams } from "next/navigation";
import { useEffect, useState } from "react";
import { useEffect, useState, Suspense } from "react";
export default function Page() {
function ClientComponent() {
const searchParams = useSearchParams();
const id = searchParams.get("client");
const [cliente, setCliente] = useState<Cliente>();
@ -23,85 +23,6 @@ export default function Page() {
getCliente();
}, [id]);
const clienti = [
{
name: "Savoldi Ettore",
email: "savoldi.ettore@gmail.com",
ragione_sociale: "Acconciature Uomo",
p_iva: "13407520172",
telefono: "0301547854",
sede: "Via Umberto I 60/T, Flero (BS)",
sede_url: "https://maps.app.goo.gl/9uNbw2a62ZCCjkQc7",
contratto: "https://google.com",
registratori: [
{
seriale: "80E100548745",
acquisto: "15/10/2019",
ultima_verifica: "15/10/2025",
prossima_verifica: "15/10/2026",
interventi: [
{
id: "0001",
data: "15/10/2025",
lavoro: "VERIFICA FISCALE - AGGIORNAMENTO FIRMWARE",
fattura: true,
},
{
id: "0002",
data: "28/05/2025",
lavoro: "SOSTITUZIONE DGFE",
fattura: false,
},
{
id: "0003",
data: "08/10/2024",
lavoro: "VERIFICA FISCALE",
fattura: true,
},
],
},
],
},
{
name: "Forno Tagliaferri",
email: "info@tagliaferri.it",
ragione_sociale: "Forno Tagliaferri",
p_iva: "12901475639",
telefono: "0309183573",
sede: "Via Corso dei Martiri 11, Brescia (BS)",
sede_url: "https://maps.app.goo.gl/9uNbw2a62ZCCjkQc7",
contratto: "https://google.com",
registratori: [
{
seriale: "80E1002587545",
acquisto: "24/02/2020",
ultima_verifica: "24/02/2025",
prossima_verifica: "24/02/2026",
interventi: [
{
id: "0004",
data: "24/02/2025",
lavoro: "VERIFICA FISCALE",
fattura: true,
},
{
id: "0005",
data: "06/04/2025",
lavoro: "SOSTITUZIONE DGFE",
fattura: false,
},
{
id: "0006",
data: "24/02/2025",
lavoro: "VERIFICA FISCALE - AGGIORNAMENTO FIRMWARE",
fattura: true,
},
],
},
],
},
];
return (
<div className="flex flex-1 flex-col gap-4 p-4">
<div className="*:data-[slot=card]:from-primary/5 *:data-[slot=card]:to-card dark:*:data-[slot=card]:bg-card grid grid-cols-1 gap-4 px-4 *:data-[slot=card]:bg-gradient-to-t *:data-[slot=card]:shadow-xs lg:px-6 @xl/main:grid-cols-2 @5xl/main:grid-cols-4">
@ -117,3 +38,13 @@ export default function Page() {
</div>
);
}
export default function Page() {
return (
<Suspense
fallback={<div className="p-8 text-center">Caricamento cliente...</div>}
>
<ClientComponent />
</Suspense>
);
}

View file

@ -28,7 +28,6 @@ import {
} from "@/components/ui/table";
import { cn } from "@/lib/utils";
import { Checkbox } from "@/components/ui/checkbox";
import { useSearchParams } from "next/navigation";
export default function Page() {
return (

View file

@ -2,10 +2,10 @@
import dynamic from "next/dynamic";
import { useSearchParams } from "next/navigation";
import { useEffect, useState } from "react";
import { useEffect, useState, Suspense } from "react";
import { Cliente } from "@/generated/prisma";
export default function Page() {
function MapContent() {
const MapWithNoSSR = dynamic(() => import("../../components/map"), {
ssr: false,
});
@ -32,3 +32,11 @@ export default function Page() {
</div>
);
}
export default function Page() {
return (
<Suspense fallback={<div>Caricamento mappa...</div>}>
<MapContent />
</Suspense>
);
}

View file

@ -15,6 +15,7 @@ import { Button } from "@/components/ui/button";
import { useState } from "react";
const AddClientDialog = () => {
const [open, setOpen] = useState<Boolean>(false);
const [nome, setNome] = useState("");
const [ragione_sociale, setRagione_sociale] = useState("");
const [partita_iva, setPartita_iva] = useState("");
@ -26,7 +27,7 @@ const AddClientDialog = () => {
return (
<div>
<Dialog>
<Dialog open={open} onOpenChange={setOpen}>
<form className="z-10">
<DialogTrigger asChild>
<Button variant="outline">Aggiungi cliente</Button>
@ -118,8 +119,8 @@ const AddClientDialog = () => {
<Button variant="outline">Cancella</Button>
</DialogClose>
<Button
onClick={async () =>
await fetch("/api/clienti", {
onClick={async () => {
const res = await fetch("/api/clienti", {
method: "POST",
body: JSON.stringify({
nome: nome,
@ -131,8 +132,12 @@ const AddClientDialog = () => {
sede_url: sede_url,
contratto: contratto,
}),
})
});
if (res.status == 200) {
setOpen(false);
}
}}
type="submit"
>
Aggiungi

View file

@ -26,7 +26,6 @@ import { Button } from "@/components/ui/button";
import { Edit, Plus } from "lucide-react";
import { Checkbox } from "@/components/ui/checkbox";
import { cn } from "@/lib/utils";
import { useSearchParams } from "next/navigation";
import { Cliente, Registratore } from "@/generated/prisma";
import AddInterventoDialog from "./add-intervento";