Prechádzať zdrojové kódy

Aggiunti templates e file keycloak + aggiornato requirements

Francesco 7 mesiacov pred
rodič
commit
0d5a64d42c

+ 289 - 0
Backend/keycloak.py

@@ -0,0 +1,289 @@
+from fastapi import FastAPI, Form, Request, Depends, HTTPException, Body
+from pydantic import BaseModel
+from fastapi.responses import JSONResponse, RedirectResponse, HTMLResponse
+from fastapi.templating import Jinja2Templates
+from fastapi.staticfiles import StaticFiles
+from fastapi.middleware.cors import CORSMiddleware
+from starlette.middleware.sessions import SessionMiddleware
+import secrets
+import uvicorn
+import logging
+import requests  # Import the requests library here
+from typing import Annotated, Dict, List #import typing
+
+# --- Keycloak Configuration ---
+KEYCLOAK_SERVER_URL = "http://165.22.75.145:8080"  # Double-check this! Changed to http
+KEYCLOAK_REALM = "Generation"
+KEYCLOAK_CLIENT_ID = "web-app-pw"
+KEYCLOAK_CLIENT_SECRET = "fQGWt8HSPn65cCKTOzE5FigqZhf8QTYW"
+KEYCLOAK_SCOPE = "codicefiscale email openid ruolo"
+
+# --- App Initialization ---
+app = FastAPI()
+
+# --- Logging Configuration ---
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+# --- CORS ---
+origins = [
+    "http://localhost:8000",
+    "http://localhost:3000/*",
+]
+
+app.add_middleware(
+    CORSMiddleware,
+    allow_origins=origins,
+    allow_credentials=True,
+    allow_methods=["*"],
+    allow_headers=["*"],
+)
+# --- Session ---
+app.add_middleware(SessionMiddleware, secret_key=secrets.token_hex(32))
+
+# --- Helper Functions (modified to be part of the API) ---
+
+# Function to get tokens from keycloak
+def get_token_from_keycloak(username, password) -> Dict:
+    """Retrieves access and refresh tokens from Keycloak."""
+    url = f"{KEYCLOAK_SERVER_URL}/realms/{KEYCLOAK_REALM}/protocol/openid-connect/token"
+    payload = f'grant_type=password&client_id={KEYCLOAK_CLIENT_ID}&scope={KEYCLOAK_SCOPE}&username={username}&password={password}&client_secret={KEYCLOAK_CLIENT_SECRET}'
+    headers = {
+        'Content-Type': 'application/x-www-form-urlencoded'
+    }
+    try:
+        response = requests.post(url, headers=headers, data=payload, timeout=10)
+        response.raise_for_status()  # Raise HTTPError for bad responses (4xx or 5xx)
+        return response.json()
+    except requests.exceptions.RequestException as e:
+        logger.error(f"Error getting token from Keycloak: {e}")
+        raise HTTPException(status_code=500, detail=f"Failed to get token from Keycloak: {e}") from e
+
+def refresh_token_from_keycloak(refresh_token: str) -> Dict:
+    """Refreshes the access token using the refresh token."""
+    url = f"{KEYCLOAK_SERVER_URL}/realms/{KEYCLOAK_REALM}/protocol/openid-connect/token"
+    payload = f'grant_type=refresh_token&client_id={KEYCLOAK_CLIENT_ID}&client_secret={KEYCLOAK_CLIENT_SECRET}&refresh_token={refresh_token}'
+    headers = {
+        'Content-Type': 'application/x-www-form-urlencoded'
+    }
+    try:
+        response = requests.post(url, headers=headers, data=payload, timeout=10)
+        response.raise_for_status()
+        return response.json()
+    except requests.exceptions.RequestException as e:
+        logger.error(f"Error refreshing token: {e}")
+        raise HTTPException(status_code=500, detail=f"Failed to refresh token: {e}") from e
+
+
+def introspect_keycloak_token_request(access_token: str) -> Dict:
+    """Introspects a Keycloak token to verify if it's active."""
+    url = f"{KEYCLOAK_SERVER_URL}/realms/{KEYCLOAK_REALM}/protocol/openid-connect/token/introspect"
+    payload = f'token={access_token}&client_id={KEYCLOAK_CLIENT_ID}&client_secret={KEYCLOAK_CLIENT_SECRET}'
+    headers = {
+        'Content-Type': 'application/x-www-form-urlencoded'
+    }
+    try:
+        response = requests.post(url, headers=headers, data=payload, verify=False, timeout=10)
+        response.raise_for_status()
+        return response.json()
+    except requests.exceptions.RequestException as e:
+        logger.error(f"Error introspecting token: {e}")
+        raise HTTPException(status_code=500, detail=f"Failed to introspect token: {e}") from e
+
+def get_user_info_from_keycloak(access_token: str) -> Dict:
+    """Gets user information from Keycloak using the access token."""
+    url = f"{KEYCLOAK_SERVER_URL}/realms/{KEYCLOAK_REALM}/protocol/openid-connect/userinfo"
+    headers = {
+        'Authorization': f'Bearer {access_token}'
+    }
+    try:
+        response = requests.get(url, headers=headers, timeout=10)
+        response.raise_for_status()
+        return response.json()
+    except requests.exceptions.RequestException as e:
+        logger.error(f"Error getting user info: {e}")
+        raise HTTPException(status_code=500, detail=f"Failed to get user info: {e}") from e
+
+def logout_keycloak(refresh_token:str):
+    url = f"{KEYCLOAK_SERVER_URL}/realms/{KEYCLOAK_REALM}/protocol/openid-connect/logout"
+
+    payload = f'refresh_token={refresh_token}&client_id={KEYCLOAK_CLIENT_ID}&client_secret={KEYCLOAK_CLIENT_SECRET}'
+    headers = {
+    'Content-Type': 'application/x-www-form-urlencoded'
+    }
+    try:
+        response = requests.request("POST", url, headers=headers, data=payload)
+        response.raise_for_status()
+        return response.json()
+    except requests.exceptions.RequestException as e:
+        logger.error(f"Error logging out user: {e}")
+        raise HTTPException(status_code=500, detail=f"Failed to logout user: {e}") from e
+
+#print(get_token_from_keycloak("testuserperpaginaprivata", "user"))
+# --- Routes ---
+
+#@app.get("/login")
+#async def login(request: Request):
+#    """
+#    Logs in a user by retrieving tokens from Keycloak.
+#    Stores the tokens and user info in the session.
+#    """
+#    try:
+#        #tokens = get_token_from_keycloak()
+#        ## Save tokens and information to the session
+#        #request.session["access_token"] = tokens["access_token"]
+#        #request.session["refresh_token"] = tokens["refresh_token"]
+##
+#        ## Get user info and save it to the session too
+#        #user_info = get_user_info_from_keycloak(tokens["access_token"])
+#        #request.session["user_info"] = user_info
+##
+#        #return {"message": "Login successful", "access_token": tokens["access_token"], "user_info": user_info}
+#
+#        if request.session["access_token"]:
+#            return RedirectResponse(url="localhost:3000/index")
+#        else:
+#            return RedirectResponse(url="localhost:3000/login")
+#    except HTTPException as e:
+#        return JSONResponse(content={"detail": e.detail}, status_code=e.status_code)
+#    except Exception as e:
+#        logger.error(f"An unexpected error occurred during login: {e}")
+#        return JSONResponse(content={"detail": "An unexpected error occurred"}, status_code=500)
+class Credenziali(BaseModel):
+    username: str
+    password: str
+
+#@app.get("/login")
+app.mount("/static", StaticFiles(directory="static"), name="static")
+templates = Jinja2Templates(directory="templates")
+
+@app.get("/access")
+async def access(request: Request):
+    return templates.TemplateResponse("login.html", context={"request": request, "title": "Accesso"})
+
+@app.post("/login")
+async def login(request: Request, credenziali: Credenziali = Body(...)):
+
+    """
+
+    Logs in a user by retrieving tokens from Keycloak.
+
+    Stores the tokens and user info in the session.
+
+    """
+    try:
+        tokens = get_token_from_keycloak(credenziali.username, credenziali.password)#request.body.json()["username"], request.json()["password"])
+        RedirectResponse(url="localhost:8000/callback")
+        # Save tokens and information to the session
+
+        request.session["access_token"] = tokens["access_token"]
+
+        request.session["refresh_token"] = tokens["refresh_token"]
+
+        #print(tokens["access_token"])
+
+        
+        # Get user info and save it to the session too
+
+        user_info = get_user_info_from_keycloak(tokens["access_token"])
+
+        request.session["user_info"] = user_info
+
+
+
+        return RedirectResponse(url="localhost:8000/callback")
+
+    except HTTPException as e:
+
+        return JSONResponse(content={"detail": e.detail}, status_code=e.status_code)
+
+    except Exception as e:
+
+        logger.error(f"An unexpected error occurred during login: {e}")
+
+        return JSONResponse(content={"detail": "An unexpected error occurred"}, status_code=500)
+
+@app.get("/refresh")
+async def refresh(request: Request):
+    """Refreshes the access token using the refresh token in the session."""
+    refresh_token = request.session.get("refresh_token")
+    if not refresh_token:
+        raise HTTPException(status_code=401, detail="Refresh token not found in session")
+
+    try:
+        new_tokens = refresh_token_from_keycloak(refresh_token)
+        request.session["access_token"] = new_tokens["access_token"]
+        request.session["refresh_token"] = new_tokens["refresh_token"]
+        new_user_info = get_user_info_from_keycloak(new_tokens["access_token"])
+        request.session["user_info"] = new_user_info
+        return {"message": "Token refreshed successfully", "access_token": new_tokens["access_token"], "user_info": new_user_info}
+    except HTTPException as e:
+        return JSONResponse(content={"detail": e.detail}, status_code=e.status_code)
+    except Exception as e:
+        logger.error(f"An unexpected error occurred during token refresh: {e}")
+        return JSONResponse(content={"detail": "An unexpected error occurred"}, status_code=500)
+
+
+@app.get("/introspect")
+async def introspect(request: Request):
+    """Introspects the access token in the session."""
+    access_token = request.session.get("access_token")
+    if not access_token:
+        raise HTTPException(status_code=401, detail="Access token not found in session")
+
+    try:
+        introspect_data = introspect_keycloak_token_request(access_token)
+        return {"message": "Token introspection successful", "introspect_data": introspect_data}
+    except HTTPException as e:
+        return JSONResponse(content={"detail": e.detail}, status_code=e.status_code)
+    except Exception as e:
+        logger.error(f"An unexpected error occurred during token introspection: {e}")
+        return JSONResponse(content={"detail": "An unexpected error occurred"}, status_code=500)
+
+@app.get("/userinfo")
+async def user_info(request: Request):
+    """Retrieves and returns user information stored in the session."""
+    user_info = request.session.get("user_info")
+    if not user_info:
+        raise HTTPException(status_code=401, detail="User info not found in session")
+    return {"message": "User information retrieved", "user_info": user_info}
+
+@app.get("/logout_keycloak")
+async def logout_user(request: Request):
+    """Logs out a user by revoking the refresh token."""
+    refresh_token = request.session.get("refresh_token")
+    if not refresh_token:
+        raise HTTPException(status_code=401, detail="Refresh token not found in session")
+    try:
+        logout_keycloak(refresh_token)
+        request.session.clear()
+        return {"message": "Logout successful"}
+    except HTTPException as e:
+        return JSONResponse(content={"detail": e.detail}, status_code=e.status_code)
+    except Exception as e:
+        logger.error(f"An unexpected error occurred during logout: {e}")
+        return JSONResponse(content={"detail": "An unexpected error occurred"}, status_code=500)
+
+@app.get("/protected")
+async def protected_endpoint(request: Request):
+    """A protected endpoint that requires a valid access token."""
+    access_token = request.session.get("access_token")
+    if not access_token:
+        raise HTTPException(status_code=401, detail="Access token not found in session")
+    try:
+        introspect_data = introspect_keycloak_token_request(access_token)
+        if not introspect_data.get("active"):
+            raise HTTPException(status_code=401, detail="Access token is not active")
+        return JSONResponse({"message": f"Hello, world! (Protected)", "introspect": introspect_data})
+    except HTTPException as e:
+        return JSONResponse(content={"detail": e.detail}, status_code=e.status_code)
+    except Exception as e:
+        logger.error(f"An unexpected error occurred during token introspection: {e}")
+        return JSONResponse(content={"detail": "An unexpected error occurred"}, status_code=500)
+    
+
+# --- Run the App ---
+if __name__ == "__main__":
+    uvicorn.run(app, host="localhost", port=8000)
+
+

BIN
Backend/requirements.txt


+ 746 - 0
Backend/templates/TFO.html

@@ -0,0 +1,746 @@
+<!DOCTYPE html>
+<html lang="it">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Mappa con Bootstrap Italia e Overlay Edifici</title>
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"
+          integrity="sha512-9usAa10IRO0HhonpyAIVpjrylPvoDwiPUiKdWk5t3PyolY1cOd4DSE0Ga+ri4AuTroPR5aQvXU9xC6qOPnzFeg=="
+          crossorigin="anonymous" referrerpolicy="no-referrer" />
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.13.4/dist/css/bootstrap-italia.min.css" rel="stylesheet">
+    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css" />
+    <style>
+        /* Stile per la riga blu scuro */
+        .top-bar {
+            background-color: #004080; /* Blu scuro */
+            color: white;
+            padding: 0.5rem 0;
+            text-align: left; /* Allineamento a sinistra */
+            font-size: 0.9rem;
+        }
+        .table-responsive {
+            overflow-x: auto;
+            /* Aggiungi scroll orizzontale se la tabella è troppo larga */
+        }
+        .header, .footer {
+            background-color: #0066CC; /* Blu istituzionale */
+            color: white;
+            padding: 1rem 0;
+        }
+        .main-content {
+            background-color: #f8f9fa; /* Grigio chiaro */
+            padding: 2rem 0;
+        }
+        .logo {
+            font-family: 'Georgia', serif; /* Font diverso */
+            font-size: 1.5rem;
+            font-weight: bold;
+            display: inline-flex;
+            align-items: center;
+            justify-content: center;
+            width: 50px; /* Diametro del cerchio */
+            height: 50px; /* Diametro del cerchio */
+            background-color: white; /* Colore di sfondo del cerchio */
+            color: #0066CC; /* Colore del testo */
+            border-radius: 50%; /* Rende l'elemento un cerchio */
+            margin-right: 10px;
+        }
+        #map { height: 500px; width: 100%; }
+        #coordinate-inputs { margin-top: 10px; width: 50%; }
+
+        /* Stile per i link con sottolineatura solo al passaggio del mouse */
+        .link-underline-hover {
+            text-decoration: none; /* Rimuove la sottolineatura di base */
+        }
+        .link-underline-hover:hover {
+            text-decoration: underline; /* Aggiunge la sottolineatura solo al passaggio del mouse */
+        }
+
+        /* Aggiusta l'allineamento del logo e titolo */
+        .header-title {
+            font-size: 1.5rem;
+            display: inline-block;
+            margin-left: 10px;
+        }
+        .header-content {
+            display: flex;
+            align-items: center;
+        }
+        /* Stili per la tabella dei dati */
+        .data-table {
+            display: flex;
+            flex-direction: column;
+        }
+        .table th, .table td {
+            font-size: 16px; /* Riduce la dimensione del testo */
+        }
+        h2 {
+            font-size: 22px; /* Riduce la dimensione della scritta "Dati Inseriti" */
+        }
+        .d-flex {
+            display: flex;
+        }
+        .justify-content-end {
+            justify-content: flex-end;
+        }
+        .mt-2 {
+            margin-top: 0.5rem;
+        }
+        .mt-3 {
+            margin-top: 1rem;
+        }
+        .social-icons a {
+            color: white;
+            font-size: 24px;
+            margin-right: 10px;
+        }
+    </style>
+</head>
+<body>
+    <!-- Riga blu scuro con scritto "Project Work" allineata a sinistra -->
+    <div class="top-bar">
+        <div class="container">
+            Project Work
+        </div>
+    </div>
+    
+    <header class="header">
+        <div class="container">
+            <div class="row align-items-center">
+                <div class="col">
+                    <!-- Logo "PW" dentro un cerchio e titolo accanto -->
+                    <div class="col d-flex">
+                        <!-- Logo "PW" dentro un cerchio, ora cliccabile -->
+                        <a href="./mappa_logout.html" class="logo-link">
+                            <div class="logo">PW</div>
+                        </a>
+                        <h1 class="header-title">TFO - Terminazioni Fibra Ottica</h1>
+                    </div>
+                </div>
+                <div class="col-auto d-flex align-items-center">
+                    <a href="./ADMIN.html" class="text-white me-3 link-underline-hover">Gestione Dati Immobiliari</a>
+                    <a href="./TFO.html" class="text-white me-3 link-underline-hover">TFO</a>
+                    <a href="./buildings.html" class="text-white me-3 link-underline-hover">Registrazione degli Edifici</a>
+                    <a href="./mappa_login.html" class="btn btn-light">Logout</a>
+                </div>
+            </div>
+        </div>
+    </header>
+
+    <main>
+        <div class="container mt-4">
+            <h1 style="font-size: 1.5rem;">Registrazione delle terminazioni di fibra ottica</h1>
+
+            <!-- Barra di ricerca -->
+            <div class="row">
+                <div class="col-md-9">
+                    <div class="mb-3">
+                        <label for="addressInput" class="form-label">Indirizzo:</label>
+                        <input type="text" class="form-control" id="addressInput">
+                    </div>
+                </div>
+                <div class="col-md-3">
+                    <button type="button" class="btn btn-primary mt-4" id="searchButton">Cerca</button>
+                </div>
+            </div>
+
+            <div class="main-content">
+                <div class="container">
+                    <div class="row justify-content-center">
+                        <div class="col-md-12">
+                            <div id="map"></div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+            <p class="mt-4">Compila il modulo sottostante per registrare una nuova terminazione di fibra ottica:</p>
+            <fo class="container-fluid">
+                <div class="row justify-content-center">
+                    <div class="col-md-12">
+                        <div class="card">
+                            <div class="card-body">
+                                <div class="row">
+                                    <div class="col-md-9">
+                                        <div class="mb-3">
+                                            <label for="addressInputForm" class="form-label">Indirizzo:</label>
+                                            <input type="text" class="form-control" id="addressInputForm">
+                                        </div>
+                                    </div>
+                                    </div>
+                                    <div class="col-md-9"> 
+                                        <div class="mb-3">
+                                            <label for="latInput" class="form-label">Latitudine:</label>
+                                            <input type="number" class="form-control" id="latInput" min="-90" max="90"/>
+                                        </div>
+                                    </div>
+                                    <div class="col-md-9">
+                                        <div class="ms-md-6 mb-3">
+                                            <label for="lngInput" class="form-label">Longitudine:</label>
+                                            <input type="number" class="form-control" id="lngInput" min="-180" max="180"/>
+                                        </div>
+                                    </div>
+                                        
+                                    <div class="col-md-9">
+                                        <div class="ms-md-6 mb-3">
+                                            <label for="codiceCatastaleInput" class="form-label">Codice Catastale:</label>
+                                            <input type="text" class="form-control" id="codiceCatastaleInput">
+                                        </div>
+                                    </div>
+                                    <div class="col-md-9">
+                                        <div class="mb-3">
+                                            <label for="dataPredisposizione" class="form-label">Data Predisposizione</label>
+                                            <input type="date" class="form-control" id="dataPredisposizione">
+                                        </div>
+                                    </div>
+                                    <div class="col-md-9">
+                                        <div class="mb-3">
+                                            <label for="scala" class="form-label">Scala</label>
+                                            <input type="text" class="form-control" id="scala">
+                                        </div>
+                                    </div>
+                                    <div class="col-md-9">
+                                        <div class="mb-3">
+                                            <label for="piano" class="form-label">Piano</label>
+                                            <input type="text" class="form-control" id="piano">
+                                        </div>
+                                    </div>
+                                    <div class="col-md-9">
+                                        <div class="mb-3">
+                                            <label for="interno" class="form-label">Interno</label>
+                                            <input type="text" class="form-control" id="interno">
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-9">
+                                        <div class="mb-3">
+                                            <label for="operatore" class="form-label">Identificativo Operatore</label>
+                                            <select class="form-select" id="operatore">
+                                                <option value="1">Operatore 1</option>
+                                                <option value="2">Operatore 2</option>
+                                            </select>
+                                        </div>
+                                    </div>
+                                    <div class="col-md-9">
+                                        <div class="mb-3">
+                                            <label for="terminazione" class="form-label">Codice Terminazione</label>
+                                            <input type="text" class="form-control" id="terminazione">
+                                        </div>
+                                    </div>
+                                    <div class="col-md-9">
+                                        <div class="mb-3">
+                                            <label for="nota" class="form-label">Note</label>
+                                            <input type="text" class="form-control" id="nota">
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-2">
+                                        <button class="btn btn-primary w-100" onclick="aggiungiRiga()">Aggiungi</button>
+                                    </div>
+                                    <div class="col-md-2">
+                                        <button class="btn btn-secondary w-100" type="button" onclick="resettaForm()">Annulla</button>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="col-md-12 mt-4">
+                        <div class="data-table">
+                            <h2>Dati Inseriti</h2>
+                            <div class="table-responsive">
+                                <table class="table">
+                                    <thead>
+                                        <tr>
+                                            <th>Indirizzo</th>
+                                            <th>Latitudine</th>
+                                            <th>Longitudine</th>
+                                            <th>Codice Catastale</th>
+                                            <th>Data Predisposizione</th>
+                                            <th>Scala</th>
+                                            <th>Piano</th>
+                                            <th>Interno</th>
+                                            <th>Operatore</th>
+                                            <th>Terminazione</th>
+                                            <th>Note</th>
+                                            <th>Azioni</th>
+                                        </tr>
+                                    </thead>
+                                    <tbody id="buildingTableBody">
+                                        <!-- Le righe della tabella saranno aggiunte dinamicamente -->
+                                    </tbody>
+                                </table>
+                            </div>
+                            <!-- Contenitore per il pulsante "Invia" -->
+                            <div class="d-flex justify-content-end mt-3">
+                                <button class="btn btn-success">Invia</button>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <!-- Widget ElevenLabs ConvAI -->
+        <div id="ai-widget-container" style="position: fixed; bottom: 20px; right: 20px;">
+            <elevenlabs-convai agent-id="2MJWbkNuIGTHNI71hKfL"></elevenlabs-convai>
+        </div>
+    </main>
+
+    <footer id="footer" class="it-footer bg-black mt-5" role="contentinfo">
+        <div class="it-footer-main py-3">
+            <div class="container">
+                <section class="py-4">
+                    <div class="row">
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Esplora SINFI</h2>
+                                <ul id="footer-menu-col-1" class="link-list">
+                                    <li id="menu-item-sinfi-1" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/che-cose/">Cos'è SINFI</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-2" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Infrastrutture Registrate</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-3" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/riferimenti-normativi/">Normative di Riferimento</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-4" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Open Data SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Aiuto e Supporto</h2>
+                                <ul id="footer-menu-col-2" class="link-list">
+                                    <li id="menu-item-aiuto-1" class="menu-item">
+                                        <a class="list-item" href="./instructions.html">Istruzioni</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-2" class="menu-item">
+                                        <a class="list-item" href="./faq.html">FAQ - Domande Frequenti</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-3" class="menu-item">
+                                        <a class="list-item" href="./techsup.html">Segnalazioni e Supporto Tecnico</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <!-- Colonna "Community" con i loghi dei social -->
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Community</h2>
+                                <div class="social-icons">
+                                    <a href="https://www.linkedin.com" target="_blank" class="me-3"><i class="fab fa-linkedin"></i></a>
+                                    <a href="https://www.youtube.com" target="_blank" class="me-3"><i class="fab fa-youtube"></i></a>
+                                    <a href="https://www.facebook.com" target="_blank" class="me-3"><i class="fab fa-facebook"></i></a>
+                                    <a href="https://www.instagram.com" target="_blank" class="me-3"><i class="fab fa-instagram"></i></a>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">SINFI</h2>
+                                <ul id="footer-menu-col-4" class="link-list">
+                                    <li id="menu-item-377" class="menu-item">
+                                        <a target="_blank" href="https://sinfi.it/portal/">Vai al sito ufficiale SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+                </section>
+            </div>
+        </div>
+        <div class="it-footer-small-prints clearfix">
+            <div class="container">
+                <nav class="menu-footer-menu-ita-container" aria-label="link utili">
+                    <ul id="menu-footer-menu-ita" class="it-footer-small-prints-list list-inline mb-0 d-flex flex-column flex-md-row">
+                        <li id="menu-item-413" class="menu-item list-inline-item"><a href="/media-policy/">Media Policy</a></li>
+                        <li id="menu-item-453" class="menu-item list-inline-item"><a href="/note-legali/">Privacy Policy &amp; Note Legali</a></li>
+                        <li id="menu-item-1310" class="menu-item list-inline-item"><a target="_blank" href="https://form.agid.gov.it/view/9df3de50-7a42-11ef-8989-9dcab5eaa914">Dichiarazione di accessibilità</a></li>
+                        <li id="menu-item-411" class="menu-item list-inline-item"><a href="/mappa-del-sito/">Mappa del sito</a></li>
+                        <li id="menu-item-1277" class="menu-item list-inline-item"><a href="/open-data-spid/">Open Data SPID</a></li>
+                    </ul>
+                </nav>
+            </div>
+        </div>
+    </footer>
+
+    <!-- Scripts -->
+    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
+    <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.8.1/dist/js/bootstrap-italia.bundle.min.js"></script>
+    <!-- Includi lo script di ElevenLabs -->
+    <script src="https://elevenlabs.io/convai-widget/index.js" async type="text/javascript"></script>
+
+    <script>
+        // Inizializzazione Mappa
+        var map = L.map('map').setView([41.9028, 12.4964], 13);
+        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+            attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
+        }).addTo(map);
+
+        // Variabile per memorizzare il marker corrente
+        let marker;
+        var lastModifiedField = document.getElementById('addressInput');
+        var buildings = [];
+        var edificiLayer = L.layerGroup().addTo(map);
+        var zoomLivello = 16;
+
+        // Listener per il tasto Invio nel campo di ricerca
+        document.getElementById('addressInput').addEventListener('keydown', function (event) {
+            if (event.keyCode === 13) {
+                event.preventDefault();
+                document.getElementById('searchButton').click();
+            }
+});
+
+        document.getElementById('searchButton').addEventListener('click', function () {
+    const address = document.getElementById('addressInput').value;
+    if (address) {
+        fetch(`https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(address)}&format=json`)
+            .then(response => response.json())
+            .then(data => {
+                if (data && data.length > 0) {
+                    const lat = parseFloat(data[0].lat);
+                    const lon = parseFloat(data[0].lon);
+
+                    if (marker) {
+                        map.removeLayer(marker);
+                    }
+
+                    marker = L.marker([lat, lon]).addTo(map)
+                        .bindPopup(`Indirizzo: ${data[0].display_name}`)
+                        .openPopup();
+
+                    map.setView([lat, lon], 18);
+
+                    document.getElementById('latInput').value = lat;
+                    document.getElementById('lngInput').value = lon;
+
+                    // Copia l'indirizzo trovato nel campo sotto la mappa
+                    document.getElementById('addressInputForm').value = data[0].display_name;
+                } else {
+                    alert('Indirizzo non trovato.');
+                }
+            })
+            .catch(error => {
+                console.error('Errore durante la geocodifica:', error);
+                alert('Si è verificato un errore durante la ricerca dell\'indirizzo.');
+            });
+    } else {
+        alert('Inserisci un indirizzo.');
+    }
+});
+
+        // Gestione del click sulla mappa
+        map.on('click', function (e) {
+    const lat = e.latlng.lat;
+    const lng = e.latlng.lng;
+
+    // Rimuovi il marker precedente (se esiste)
+    if (marker) {
+        map.removeLayer(marker);
+    }
+
+    // Aggiungi un nuovo marker sulla mappa
+    marker = L.marker([lat, lng]).addTo(map)
+        .bindPopup(`Coordinate: ${lat}, ${lng}`)
+        .openPopup();
+
+    // Riempie i campi di input per latitudine e longitudine
+    document.getElementById('latInput').value = lat;
+    document.getElementById('lngInput').value = lng;
+
+    // Ottieni l'indirizzo dalle coordinate
+    getAddress(lat, lng);
+});
+
+        async function caricaEdifici() {
+            if (map.getZoom() >= 16) {
+                var bounds = map.getBounds();
+                var bbox = bounds.getSouthWest().lat + ',' + bounds.getSouthWest().lng + ',' + bounds.getNorthEast().lat + ',' + bounds.getNorthEast().lng;
+                var query = `
+                    [out:json];
+                    (
+                        way["building"](${bbox});
+                        relation["building"](${bbox});
+                    );
+                    out geom;
+                    out tags;
+                `;
+
+                try {
+                    const data = await $.ajax({
+                        url: 'https://overpass-api.de/api/interpreter',
+                        data: { data: query },
+                        dataType: 'json'
+                    });
+
+                    edificiLayer.clearLayers();
+                    data.elements.forEach(function(element) {
+                        if (element.type === 'way' && element.geometry) {
+                            var latlngs = element.geometry.map(function(coord) {
+                                return [coord.lat, coord.lon];
+                            });
+                            var polygon = L.polygon(latlngs).addTo(edificiLayer);
+
+                            // Genera un numero casuale tra 0 e 3
+                            var statoEdificio = true;
+
+                            // Assegna il colore in base allo stato
+                            var colorePoligono;
+                            switch (statoEdificio) {
+                                case false:
+                                    colorePoligono = 'yellow';
+                                    break;
+                                case true:
+                                    colorePoligono = 'green';
+                                    break;
+                            }
+
+                            // Applica lo stile al poligono
+                            polygon.setStyle({ fillColor: colorePoligono, color: colorePoligono });
+
+                            polygon.on('click', async function() {
+                                var buildingType = element.tags && element.tags.building ? element.tags.building : 'Sconosciuto';
+                                try {
+                                    await getAddress(latlngs[0][0], latlngs[0][1]);
+                                    var popupContent = 'Coordinate: ' + latlngs[0][0] + ', ' + latlngs[0][1] + '<br>' +
+                                        'Tipo edificio: ' + buildingType + '<br>' +
+                                        'Indirizzo: ' + document.getElementById('addressInput').value + '<br>' +
+                                        'Stato: ' + statoEdificio + '<br>' +
+                                        'Codice Catastale: nessuno';
+                                    polygon.bindPopup(popupContent).openPopup();
+                                } catch (error) {
+                                    console.error("Errore nel recupero dell'indirizzo:", error);
+                                    var popupContent = 'Coordinate: ' + latlngs[0][0] + ', ' + latlngs[0][1] + '<br>' +
+                                        'Tipo edificio: ' + buildingType + '<br>' +
+                                        'Indirizzo: Indirizzo non disponibile<br>' +
+                                        'Stato: ' + statoEdificio + '<br>' +
+                                        'Codice Catastale: nessuno';
+                                    polygon.bindPopup(popupContent).openPopup();
+                                }
+                                var codiceCatasto = element.tags && element.tags.codice_catasto ? element.tags.codice_catasto : "nessuno";
+                                document.getElementById('codiceCatastaleInput').value = codiceCatasto;
+                            });
+                        } else if (element.type === 'relation' && element.members) {
+                            // Gestione delle relazioni (edifici complessi)
+                            // Da implementare
+                        }
+                    });
+                } catch (error) {
+                    console.error('Errore durante il caricamento degli edifici:', error);
+                    // Gestisci l'errore (ad esempio, mostra un messaggio all'utente)
+                }
+            } else {
+                edificiLayer.clearLayers();
+            }
+        }
+
+        // Funzione per ottenere l'indirizzo dalle coordinate
+        async function getAddress(lat, lng) {
+    try {
+        const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${lng}`);
+        const data = await response.json();
+
+        if (data.address) {
+            const displayName = data.display_name;
+            document.getElementById('addressInput').value = displayName;
+            document.getElementById('addressInputForm').value = displayName; // Aggiorna anche il campo del form
+        } else {
+            document.getElementById('addressInput').value = "Indirizzo non trovato";
+            document.getElementById('addressInputForm').value = "Indirizzo non trovato"; // Aggiorna anche il campo del form
+        }
+    } catch (error) {
+        console.error("Errore nel geocoding inverso:", error);
+        document.getElementById('addressInput').value = "Errore nel geocoding inverso";
+        document.getElementById('addressInputForm').value = "Errore nel geocoding inverso"; // Aggiorna anche il campo del form
+    }
+}
+
+        async function prendiIndirizzo(lat, lng) {
+            try {
+                const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${lng}`);
+                const data = await response.json();
+
+                if (data.address) {
+                    return data.display_name;
+                } else {
+                    return "Indirizzo non trovato";
+                }
+            } catch (error) {
+                console.error("Errore nel geocoding inverso:", error);
+                return "Indirizzo non disponibile";
+            }
+        }
+
+        function debounce(func, delay) {
+            let timeoutId;
+            return function(...args) {
+                clearTimeout(timeoutId);
+                timeoutId = setTimeout(() => {
+                    func.apply(this, args);
+                }, delay);
+            };
+        }
+
+        const debouncedCaricaEdifici = debounce(caricaEdifici, 300);
+
+        // Gestione dell'input manuale delle coordinate
+        document.getElementById('latInput').addEventListener('blur', function () {
+            const lat = parseFloat(this.value);
+            const lng = parseFloat(document.getElementById('lngInput').value);
+            if (!isNaN(lat) && !isNaN(lng)) {
+                map.setView([lat, lng], 16);
+                if (marker) {
+                    map.removeLayer(marker);
+                }
+                marker = L.marker([lat, lng]).addTo(map)
+                    .bindPopup(`Coordinate: ${lat}, ${lng}`)
+                    .openPopup();
+                getAddress(lat, lng);
+            }
+        });
+
+        document.getElementById('lngInput').addEventListener('blur', function () {
+            const lat = parseFloat(document.getElementById('latInput').value);
+            const lng = parseFloat(this.value);
+            if (!isNaN(lat) && !isNaN(lng)) {
+                map.setView([lat, lng], 16);
+                if (marker) {
+                    map.removeLayer(marker);
+                }
+                marker = L.marker([lat, lng]).addTo(map)
+                    .bindPopup(`Coordinate: ${lat}, ${lng}`)
+                    .openPopup();
+                getAddress(lat, lng);
+            }
+        });
+
+        // Funzione per aggiungere una riga alla tabella
+        function aggiungiRiga() {
+    const indirizzo = document.getElementById('addressInput').value;
+    const latitudine = document.getElementById('latInput').value;
+    const longitudine = document.getElementById('lngInput').value;
+    const codiceCatastale = document.getElementById('codiceCatastaleInput').value;
+    const dataPredisposizione = document.getElementById('dataPredisposizione').value;
+    const scala = document.getElementById('scala').value;
+    const piano = document.getElementById('piano').value;
+    const interno = document.getElementById('interno').value;
+    const operatore = document.getElementById('operatore').value;
+    const terminazione = document.getElementById('terminazione').value;
+    const nota = document.getElementById('nota').value;
+
+    // Controllo se tutti i campi sono compilati
+    if (!indirizzo || !latitudine || !longitudine || !dataPredisposizione || 
+        !codiceCatastale || !scala || !piano || !interno || !operatore || !terminazione ) {
+        alert("Compila tutti i campi prima di aggiungere la TFO!");
+        return; // Blocca l'inserimento
+    }
+
+    // Crea una nuova riga nella tabella
+    const tabella = document.querySelector(".table tbody");
+    const nuovaRiga = tabella.insertRow();
+
+    // Crea le celle della riga e inserisci i valori
+    const celle = [];
+    for (let i = 0; i < 11; i++) {
+        celle.push(nuovaRiga.insertCell());
+    }
+
+    celle[0].textContent = indirizzo;
+    celle[1].textContent = latitudine;
+    celle[2].textContent = longitudine;
+    celle[3].textContent = codiceCatastale;
+    celle[4].textContent = dataPredisposizione;
+    celle[5].textContent = scala;
+    celle[6].textContent = piano;
+    celle[7].textContent = interno;
+    celle[8].textContent = operatore;
+    celle[9].textContent = terminazione;
+    celle[10].textContent = nota;
+
+    // Aggiungi i pulsanti di modifica e cancellazione
+    const azioniCell = nuovaRiga.insertCell();
+    azioniCell.innerHTML = `
+        <div class="d-flex gap-2">
+            <button class="btn btn-sm btn-primary" onclick="modificaRiga(this)"><i class="fas fa-edit"></i></button>
+            <button class="btn btn-sm btn-danger" onclick="cancellaDato(this)"><i class="fas fa-trash"></i></button>
+        </div>
+    `;
+
+    // Resetta i campi del form dopo l'inserimento
+    resettaForm();
+}
+
+ // Funzione per modificare una riga
+ function modificaRiga(button) {
+      const riga = button.closest('tr'); // Trova la riga più vicina al pulsante
+      const celle = riga.cells;
+
+    // Popola i campi del form con i dati della riga
+    document.getElementById("addressInput").value = celle[0].textContent;
+    document.getElementById("latInput").value = celle[1].textContent;
+    document.getElementById("lngInput").value = celle[2].textContent;
+    document.getElementById("codiceCatastaleInput").value = celle[3].textContent;
+    document.getElementById("dataPredisposizione").value = celle[4].textContent;
+    document.getElementById("scala").value = celle[5].textContent;
+    document.getElementById("piano").value = celle[6].textContent;
+    document.getElementById("interno").value = celle[7].textContent;
+    document.getElementById("operatore").value = celle[8].textContent;
+    document.getElementById("terminazione").value = celle[9].textContent;
+    document.getElementById("nota").value = celle[10].textContent;
+
+    // Rimuovi la riga dalla tabella
+    riga.remove();
+}
+      
+      // Funzione per cancellare una riga
+      function cancellaDato(button) {
+    // Chiedi conferma all'utente
+    if (confirm("Sei sicuro di voler eliminare questo dato?")) {
+        // L'utente ha confermato, procedi con l'eliminazione
+        const riga = button.closest("tr");
+        if (riga) {
+            riga.remove();
+            alert("Dato eliminato con successo.");
+        }
+    } else {
+        // L'utente ha annullato l'eliminazione
+        alert("Eliminazione annullata.");
+    }
+}
+
+
+        
+
+        // Funzione per resettare il form
+        function resettaForm() {
+    document.getElementById('addressInputForm').value = '';
+    document.getElementById('addressInput').value = '';
+    document.getElementById('latInput').value = '';
+    document.getElementById('lngInput').value = '';
+    document.getElementById('codiceCatastaleInput').value = '';
+    document.getElementById('dataPredisposizione').value = '';
+    document.getElementById('scala').value = '';
+    document.getElementById('piano').value = '';
+    document.getElementById('interno').value = '';
+    document.getElementById('operatore').value = '1';
+    document.getElementById('terminazione').value = '';
+    document.getElementById('nota').value = '';
+}
+
+        // Aggiungi un listener per il movimento della mappa
+        map.on('moveend', debouncedCaricaEdifici);
+
+        // Carica gli edifici iniziali
+        caricaEdifici();
+    </script>
+</body>
+</html>

+ 611 - 0
Backend/templates/buildings.html

@@ -0,0 +1,611 @@
+<!DOCTYPE html>
+<html lang="it">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Mappa con Bootstrap Italia e Overlay Edifici</title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.13.4/dist/css/bootstrap-italia.min.css" rel="stylesheet">
+    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css"/>
+    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
+    <style>
+        /* Stile per i label "Tipo Edificio" e "Data di Predisposizione" */
+        label[for="buildingType"], label[for="preparationDate"] {
+            font-weight: bold; /* Grassetto */
+            font-family: inherit; /* Stesso font di "Codice Catastale Particella" */
+        }
+
+        /* Stile per i link con sottolineatura solo al passaggio del mouse */
+        .link-underline-hover {
+                text-decoration: none; /* Rimuove la sottolineatura di base */
+            }
+        .link-underline-hover:hover {
+            text-decoration: underline; /* Aggiunge la sottolineatura solo al passaggio del mouse */
+        }
+
+        #buildingType {
+            color: hsl(210, 17%, 44%); /* Colore del testo del select */
+        }
+
+        #buildingType option {
+            color: hsl(210, 17%, 44%); /* Colore del testo delle opzioni */
+        }
+
+        #div-select {
+            border-bottom: 1px solid hsl(210, 17%, 44%);
+            margin-bottom: 5px;
+        }
+
+        /* Stile per la riga blu scuro */
+        .top-bar {
+            background-color: #004080; /* Blu scuro */
+            color: white;
+            padding: 0.5rem 0;
+            text-align: left; /* Allineamento a sinistra */
+            font-size: 0.9rem;
+        }
+
+        /* Stile per l'header */
+        .header {
+            background-color: #0066CC; /* Blu chiaro */
+            color: white;
+            padding: 1rem 0;
+        }
+
+        /* Stile per il logo "PW" dentro un cerchio */
+        .logo {
+            font-family: 'Georgia', serif; /* Font diverso */
+            font-size: 1.5rem;
+            font-weight: bold;
+            display: inline-flex;
+            align-items: center;
+            justify-content: center;
+            width: 50px; /* Diametro del cerchio */
+            height: 50px; /* Diametro del cerchio */
+            background-color: white; /* Colore di sfondo del cerchio */
+            color: #0066CC; /* Colore del testo */
+            border-radius: 50%; /* Rende l'elemento un cerchio */
+            margin-right: 10px;
+        }
+
+        /* Stile per il titolo "Mappa" */
+        .header-title {
+            color: white;
+            font-size: 1.5rem; /* Stessa grandezza di "Segnalazioni e Supporto Tecnico" */
+            font-weight: bold;
+            display: inline-block;
+            vertical-align: middle;
+        }
+
+        .main-content {
+            background-color: #f8f9fa; /* Grigio chiaro */
+            padding: 2rem 0;
+        }
+
+        .table-responsive {
+            overflow-x: auto;
+            /* Aggiungi scroll orizzontale se la tabella è troppo larga */
+        }
+
+        .header, .footer {
+            background-color: #0066CC; /* Blu istituzionale */
+            color: white;
+            padding: 1rem 0;
+        }
+
+        .main-content {
+            background-color: #f8f9fa; /* Grigio chiaro */
+            padding: 2rem 0;
+        }
+
+        #map {
+            height: 500px;
+            width: 100%;
+        }
+
+        #coordinate-inputs {
+            margin-top: 10px;
+            width: 50%;
+        }
+    </style>
+</head>
+<body>
+    <!-- Riga blu scuro con scritto "Project Work" allineata a sinistra -->
+    <div class="top-bar">
+        <div class="container">
+            Project Work
+        </div>
+    </div>
+
+    <!-- Header -->
+    <header class="header">
+        <div class="container">
+            <div class="row align-items-center">
+                <div class="col d-flex">
+                    <!-- Logo "PW" dentro un cerchio, ora cliccabile -->
+                    <a href="./mappa_logout.html" class="logo-link">
+                        <div class="logo">PW</div>
+                    </a>
+                    <h1 class="header-title">Registrazione degli Edifici</h1>
+                </div>
+                <div class="col-auto d-flex align-items-center">
+                    <a href="./ADMIN.html" class="text-white me-3 link-underline-hover">Gestione Dati Immobiliari</a>
+                    <a href="./TFO.html" class="text-white me-3 link-underline-hover">TFO</a>
+                    <a href="./buildings.html" class="text-white me-3 link-underline-hover">Registrazione degli Edifici</a>
+                    <a href="./mappa_login.html" class="btn btn-light">Logout</a>
+                </div>
+            </div>
+        </div>
+    </header>
+
+    <!-- Contenuto principale -->
+    <div class="container mt-4">
+        <h1 style="font-size: 1.5rem;">Registrazione degli edifici predisposti alla banda ultralarga</h1>
+        <p>Compila il modulo sottostante per registrare un edificio predisposto alla banda ultralarga:</p>
+
+        <form id="buildingForm">
+            <div class="form-row">
+                <div class="form-group col-md-6">
+                    <label for="address" style="font-weight: bold; color: black;">Indirizzo</label>
+                    <br>
+                    <br>
+                    <input type="text" class="form-control" id="address" placeholder="Via, n. civico, comune">
+                </div>
+                <div class="form-group col-md-6">
+                    <button type="button" class="btn btn-primary" id="search">Cerca</button>
+                </div>
+            </div>
+            <div class="form-row">
+                <div id="map"></div>
+            </div>
+            <div class="form-row">
+                <div class="form-group col-md-3">
+                    <label for="latitude" style="font-weight: bold; color: black;">Latitudine</label>
+                    <br>
+                    <br>
+                    <input type="text" class="form-control" id="latitude" placeholder="Latitudine">
+                </div>
+                <div class="form-group col-md-3">
+                    <label for="latitude" style="font-weight: bold; color: black;">Longitudine</label>
+                    <br>
+                    <br>
+                    <input type="text" class="form-control" id="longitude" placeholder="Longitudine">
+                </div>
+            </div>
+            <div class="form-row">
+                <div class="form-group col-md-3">
+                    <label for="latitude" style="font-weight: bold; color: black;">Codice Comune</label>
+                    <br>
+                    <br>
+                    <input type="text" class="form-control" id="commonCode" placeholder="Codice comune" required>
+                </div>
+            </div>
+            <div class="form-row">
+                <div class="form-group col-md-3">
+                    <label for="latitude" style="font-weight: bold; color: black;">Codice Catastale Particella</label>
+                    <br>
+                    <br>
+                    <input type="text" class="form-control" id="cadastralCode" placeholder="Codice catastale" required>
+                </div>
+            </div>
+            <label for="buildingType">Tipo Edificio</label>
+            <br>
+            <br>
+            <div class="form-group col-md-3" id="div-select">
+                <select class="form-control" id="buildingType">
+                    <option>Seleziona tipo di edificio</option>
+                    <option>Residenziale</option>
+                    <option>Commerciale</option>
+                    <option>Industriale</option>
+                </select>
+            </div>
+            <br>
+            <label for="preparationDate">Data di Predisposizione</label>
+            <br>
+            <br>
+            <div class="form-group col-md-3">
+                <input type="date" class="form-control" id="preparationDate" required>
+            </div>
+            <button type="button" class="btn btn-primary" id="add">Aggiungi</button>
+            <button type="button" class="btn btn-secondary" id="cancellaRiga">Annulla</button>
+            
+        </form>
+
+        <div class="data-table d-flex flex-column">
+            <table class="table mt-4">
+                <thead>
+                    <tr>
+                        <th>Indirizzo</th>
+                        <th>Latitudine</th>
+                        <th>Longitudine</th>
+                        <th>Comune</th>
+                        <th>Codice Catastale</th>
+                        <th>Tipo Edificio</th>
+                        <th>Data Predisposizione</th>
+                        <th>Azione</th>
+                    </tr>
+                </thead>
+                <tbody id="buildingTableBody">
+                </tbody>
+            </table>
+        </div>
+        <div class="d-flex justify-content-end mt-3">
+            <button type="button" class="btn btn-success" id="submitButton">Invia</button>
+        </div>
+    </div>
+
+    <!-- Script per la mappa e funzionalità -->
+    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.3/dist/umd/popper.min.js"></script>
+    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
+    <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
+    <script>
+        // Inizializzazione Mappa
+        const map = L.map('map').setView([41.9028, 12.4964], 13);
+        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
+
+        // Layer edifici colorati
+        const edificiLayer = L.layerGroup().addTo(map);
+        let currentMarker = null;
+
+        // Funzione principale per caricare gli edifici
+        async function caricaEdifici() {
+            if (map.getZoom() >= 16) {
+                const bounds = map.getBounds();
+                const bbox = `${bounds.getSouthWest().lat},${bounds.getSouthWest().lng},${bounds.getNorthEast().lat},${bounds.getNorthEast().lng}`;
+                
+                const query = `[out:json];
+                    (
+                        way["building"](${bbox});
+                        relation["building"](${bbox});
+                    );
+                    out geom;
+                    out tags;`;
+
+                try {
+                    const response = await fetch(`https://overpass-api.de/api/interpreter?data=${encodeURIComponent(query)}`);
+                    const data = await response.json();
+
+                    edificiLayer.clearLayers();
+                    
+                    data.elements.forEach(element => {
+                        if (element.type === 'way' && element.geometry) {
+                            const latlngs = element.geometry.map(coord => [coord.lat, coord.lon]);
+                            var statoEdificio = false;
+                            let colorePoligono ;
+                            if (statoEdificio) colorePoligono = 'yellow';
+                            else colorePoligono = 'green';
+                            
+                            // const colori = ['#FF0000', '#00FF00'];
+                            const polygon = L.polygon(latlngs, {
+                                fillColor: colorePoligono,
+                                color: colorePoligono,
+                                fillOpacity: 0.5
+                            }).addTo(edificiLayer);
+
+                            polygon.on('click', async function() {
+                                var buildingType = element.tags && element.tags.building ? element.tags.building : 'Sconosciuto';
+                                try {
+                                    await getAddress(latlngs[0][0], latlngs[0][1]);
+                                    var popupContent = `
+                                        <b>Coordinate:</b> ${latlngs[0][0]}, ${latlngs[0][1]}<br>
+                                        <b>Tipo edificio:</b> ${buildingType}<br>
+                                        <b>Indirizzo:</b> ${document.getElementById('addressInput').value}<br>
+                                        <b>Stato:</b> ${statoEdificio}<br>
+                                        <b>Codice Catastale:</b> nessuno
+                                    `;
+                                    polygon.bindPopup(popupContent).openPopup();
+                                } catch (error) {
+                                    console.error("Errore nel recupero dell'indirizzo:", error);
+                                    var popupContent = `
+                                        <b>Coordinate:</b> ${latlngs[0][0]}, ${latlngs[0][1]}<br>
+                                        <b>Tipo edificio:</b> ${buildingType}<br>
+                                        <b>Indirizzo:</b> Indirizzo non disponibile<br>
+                                        <b>Stato:</b> ${statoEdificio}<br>
+                                        <b>Codice Catastale:</b> nessuno
+                                    `;
+                                    polygon.bindPopup(popupContent).openPopup();
+                                }
+                            });
+                        }
+                    });
+                } catch (error) {
+                    console.error("Errore nel caricamento edifici:", error);
+                }
+            } else {
+                edificiLayer.clearLayers();
+            }
+        }
+
+        // Carica gli edifici quando la mappa viene spostata o zoomata
+        map.on('moveend', caricaEdifici);
+        map.on('zoomend', caricaEdifici);
+
+        // Carica gli edifici all'avvio
+        caricaEdifici();
+// Listener per il click sulla mappa
+map.on('click', function(e) {
+    const lat = e.latlng.lat; // Latitudine del punto cliccato
+    const lng = e.latlng.lng; // Longitudine del punto cliccato
+
+    // Aggiorna i campi del form
+    document.getElementById('latitude').value = lat;
+    document.getElementById('longitude').value = lng;
+
+    // Ottieni l'indirizzo dalle coordinate
+    getAddress(lat, lng);
+
+    // Rimuovi il marker precedente (se esiste)
+    if (currentMarker) {
+        map.removeLayer(currentMarker);
+    }
+
+    // Aggiungi un nuovo marker sulla mappa
+    currentMarker = L.marker([lat, lng]).addTo(map)
+        .bindPopup(`Coordinate: ${lat}, ${lng}`)
+        .openPopup();
+});
+
+// Funzione per ottenere l'indirizzo dalle coordinate
+async function getAddress(lat, lng) {
+    try {
+        const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${lng}`);
+        const data = await response.json();
+
+        if (data.address) {
+            document.getElementById('address').value = data.display_name;
+        } else {
+            document.getElementById('address').value = "Indirizzo non trovato";
+        }
+    } catch (error) {
+        console.error("Errore nel geocoding inverso:", error);
+        document.getElementById('address').value = "Errore nel geocoding inverso";
+    }
+}
+        // Funzione per ottenere l'indirizzo dalle coordinate
+        async function getAddress(lat, lng) {
+            try {
+                const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${lng}`);
+                const data = await response.json();
+
+                if (data.address) {
+                    document.getElementById('address').value = data.display_name;
+                } else {
+                    document.getElementById('address').value = "Indirizzo non trovato";
+                }
+            } catch (error) {
+                console.error("Errore nel geocoding inverso:", error);
+                document.getElementById('address').value = "Errore nel geocoding inverso";
+            }
+        }
+
+        // Variabile per memorizzare il marker corrente
+        var marker;
+
+        // Gestione della ricerca dell'indirizzo
+        document.getElementById('search').addEventListener('click', function() {
+            var address = document.getElementById('address').value;
+            if (address) {
+                // Effettua una richiesta all'API di Nominatim per geocodificare l'indirizzo
+                fetch(`https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(address)}&format=json`)
+                    .then(response => response.json())
+                    .then(data => {
+                        if (data && data.length > 0) {
+                            var lat = parseFloat(data[0].lat); // Latitudine
+                            var lon = parseFloat(data[0].lon); // Longitudine
+
+                            // Rimuovi il marker precedente (se esiste)
+                            if (marker) {
+                                map.removeLayer(marker);
+                            }
+
+                            // Aggiungi un nuovo marker sulla mappa
+                            marker = L.marker([lat, lon]).addTo(map)
+                                .bindPopup(`Indirizzo: ${data[0].display_name}`)
+                                .openPopup();
+
+                            // Centra la mappa sulla nuova posizione
+                            map.setView([lat, lon], 16);
+
+                            // Riempie i campi di input per latitudine e longitudine
+                            document.getElementById('latitude').value = lat;
+                            document.getElementById('longitude').value = lon;
+                        } else {
+                            alert('Indirizzo non trovato.');
+                        }
+                    })
+                    .catch(error => {
+                        console.error('Errore durante la geocodifica:', error);
+                        alert('Si è verificato un errore durante la ricerca dell\'indirizzo.');
+                    });
+            } else {
+                alert('Inserisci un indirizzo.');
+            }
+        });
+
+        // Funzione per aggiungere una riga alla tabella con controllo dei campi
+        function aggiungiRiga() {
+            // Recupera i valori dai campi di input
+            const indirizzo = document.getElementById("address").value.trim();
+            const latitudine = document.getElementById("latitude").value.trim();
+            const longitudine = document.getElementById("longitude").value.trim();
+            const codiceComune = document.getElementById("commonCode").value.trim();
+            const codiceCatastale = document.getElementById("cadastralCode").value.trim();
+            const tipodiedificio = document.getElementById("buildingType").value.trim();
+            const datadipredisposizione = document.getElementById("preparationDate").value.trim();
+        
+            // Controllo se tutti i campi sono compilati
+            if (!indirizzo || !latitudine || !longitudine || !codiceComune || 
+                !codiceCatastale || !tipodiedificio || !datadipredisposizione) {
+                alert("Compila tutti i campi prima di aggiungere l'edificio!");
+                return; // Blocca l'inserimento
+            }
+        
+            // Crea una nuova riga nella tabella
+            const tabella = document.querySelector("#buildingTableBody");
+            const nuovaRiga = tabella.insertRow();
+        
+            // Crea le celle della riga e inserisci i valori
+            const celle = [];
+            for (let i = 0; i < 7; i++) {
+                celle.push(nuovaRiga.insertCell());
+            }
+        
+            celle[0].textContent = indirizzo;
+            celle[1].textContent = latitudine;
+            celle[2].textContent = longitudine;
+            celle[3].textContent = codiceComune;
+            celle[4].textContent = codiceCatastale;
+            celle[5].textContent = tipodiedificio;
+            celle[6].textContent = datadipredisposizione;
+        
+            // Aggiungi i pulsanti di modifica e cancellazione
+            const azioniCell = nuovaRiga.insertCell();
+            azioniCell.innerHTML = `
+                <button class="btn btn-sm btn-primary" onclick="modificaRiga(this)"><i class="fas fa-edit"></i></button>
+                <button class="btn btn-sm btn-danger" onclick="cancellaRiga(this)"><i class="fas fa-trash"></i></button>
+            `;
+        
+            // Resetta i campi del form dopo l'inserimento
+            document.getElementById("buildingForm").reset();
+        }
+
+
+        // Collega la funzione aggiungiRiga() al pulsante "Aggiungi"
+        document.getElementById('add').addEventListener('click', function() {
+            aggiungiRiga();
+        });
+
+        // Funzione per modificare una riga
+        function modificaRiga(button) {
+            const riga = button.parentNode.parentNode;
+            const celle = riga.cells;
+
+            // Popola i campi del form con i dati della riga
+            document.getElementById("address").value = celle[0].textContent;
+            document.getElementById("latitude").value = celle[1].textContent;
+            document.getElementById("longitude").value = celle[2].textContent;
+            document.getElementById("commonCode").value = celle[3].textContent;
+            document.getElementById("cadastralCode").value = celle[4].textContent;
+            document.getElementById("buildingType").value = celle[5].textContent;
+            document.getElementById("preparationDate").value = celle[6].textContent;
+
+            // Rimuovi la riga dalla tabella
+            riga.remove();
+        }
+
+        // Funzione per cancellare una riga con conferma
+function cancellaRiga(button) {
+    // Mostra un alert di conferma
+    const isConfirmed = confirm("Sei sicuro di voler eliminare questa riga?");
+    
+    // Se l'utente conferma, elimina la riga
+    if (isConfirmed) {
+        const riga = button.parentNode.parentNode;
+        riga.remove();
+    }
+}
+
+        // Gestione dell'invio dei dati
+        document.getElementById('submitButton').addEventListener('click', function() {
+            alert('Dati inviati!');
+        });
+
+        // Funzione per cancellare tutti i campi del modulo
+        function resetForm() {
+            document.getElementById("buildingForm").reset();
+        }
+    
+        // Aggiungi evento al pulsante "Annulla"
+        document.getElementById('cancellaRiga').addEventListener('click', function() {
+            resetForm();
+        });
+    </script>
+    <script src="https://elevenlabs.io/convai-widget/index.js" async type="text/javascript"></script>
+    <div id="ai-widget-container" style="position: fixed; bottom: 20px; right: 20px;">
+        <elevenlabs-convai agent-id="2MJWbkNuIGTHNI71hKfL"></elevenlabs-convai>
+    </div>
+    <!-- Footer -->
+    <footer id="footer" class="it-footer bg-black mt-5" role="contentinfo"></footer>
+    <footer id="footer" class="it-footer bg-black" role="contentinfo">
+        <div class="it-footer-main py-3">
+            <div class="container">
+                <section class="py-4">
+                    <div class="row">
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Esplora SINFI</h2>
+                                <ul id="footer-menu-col-1" class="link-list">
+                                    <li id="menu-item-sinfi-1" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/che-cose/">Cos'è SINFI</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-2" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Infrastrutture Registrate</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-3" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/riferimenti-normativi/">Normative di Riferimento</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-4" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Open Data SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Aiuto e Supporto</h2>
+                                <ul id="footer-menu-col-2" class="link-list">
+                                    <li id="menu-item-aiuto-1" class="menu-item">
+                                        <a class="list-item" href="./instructions.html">Istruzioni</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-2" class="menu-item">
+                                        <a class="list-item" href="./faq.html">FAQ - Domande Frequenti</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-3" class="menu-item">
+                                        <a class="list-item" href="./techsup.html">Segnalazioni e Supporto Tecnico</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <!-- Colonna "Community" con i loghi dei social -->
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Community</h2>
+                                <div class="social-icons">
+                                    <a href="https://www.linkedin.com" target="_blank" class="me-3"><i class="fab fa-linkedin"></i></a>
+                                    <a href="https://www.youtube.com" target="_blank" class="me-3"><i class="fab fa-youtube"></i></a>
+                                    <a href="https://www.facebook.com" target="_blank" class="me-3"><i class="fab fa-facebook"></i></a>
+                                    <a href="https://www.instagram.com" target="_blank" class="me-3"><i class="fab fa-instagram"></i></a>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">SINFI</h2>
+                                <ul id="footer-menu-col-4" class="link-list">
+                                    <li id="menu-item-377" class="menu-item">
+                                        <a target="_blank" href="https://sinfi.it/portal/">Vai al sito ufficiale SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+                </section>
+            </div>
+        </div>
+        <div class="it-footer-small-prints clearfix">
+            <div class="container">
+                <nav class="menu-footer-menu-ita-container" aria-label="link utili">
+                    <ul id="menu-footer-menu-ita" class="it-footer-small-prints-list list-inline mb-0 d-flex flex-column flex-md-row">
+                        <li id="menu-item-413" class="menu-item list-inline-item"><a href="/media-policy/">Media Policy</a></li>
+                        <li id="menu-item-453" class="menu-item list-inline-item"><a href="/note-legali/">Privacy Policy &amp; Note Legali</a></li>
+                        <li id="menu-item-1310" class="menu-item list-inline-item"><a target="_blank" href="https://form.agid.gov.it/view/9df3de50-7a42-11ef-8989-9dcab5eaa914">Dichiarazione di accessibilità</a></li>
+                        <li id="menu-item-411" class="menu-item list-inline-item"><a href="/mappa-del-sito/">Mappa del sito</a></li>
+                        <li id="menu-item-1277" class="menu-item list-inline-item"><a href="/open-data-spid/">Open Data SPID</a></li>
+                    </ul>
+                </nav>
+            </div>
+        </div>
+    </footer>
+</body>
+</html>

+ 314 - 0
Backend/templates/faq.html

@@ -0,0 +1,314 @@
+<!DOCTYPE html>
+<html lang="it">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Pagina di Aiuto - FAQ</title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.13.4/dist/css/bootstrap-italia.min.css" rel="stylesheet">
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
+    <style>
+        /* Stile per la riga blu scuro */
+        .top-bar {
+            background-color: #004080; /* Blu scuro */
+            color: white;
+            padding: 0.5rem 0;
+            text-align: left; /* Allineamento a sinistra */
+            font-size: 0.9rem;
+        }
+
+        /* Stile per l'header */
+        .header {
+            background-color: #0066CC; /* Blu chiaro */
+            color: white;
+            padding: 1rem 0;
+        }
+
+        /* Stile per il logo "PW" dentro un cerchio */
+        .logo {
+            font-family: 'Georgia', serif; /* Font diverso */
+            font-size: 1.5rem;
+            font-weight: bold;
+            display: inline-flex;
+            align-items: center;
+            justify-content: center;
+            width: 50px; /* Diametro del cerchio */
+            height: 50px; /* Diametro del cerchio */
+            background-color: white; /* Colore di sfondo del cerchio */
+            color: #0066CC; /* Colore del testo */
+            border-radius: 50%; /* Rende l'elemento un cerchio */
+            margin-right: 10px;
+        }
+
+        /* Stile per il titolo "FAQ - Domande Frequenti" */
+        .header-title {
+            color: white;
+            font-size: 1.5rem; /* Stessa grandezza di "Segnalazioni e Supporto Tecnico" */
+            font-weight: bold;
+            display: inline-block;
+            vertical-align: middle;
+        }
+
+        /* Stile per il contenuto principale */
+        .main-content {
+            background-color: #f8f9fa; /* Grigio chiaro */
+            padding: 2rem 0;
+        }
+
+        /* Aggiungi margine ai lati del contenitore principale */
+        .container {
+            padding-left: 2rem;
+            padding-right: 2rem;
+        }
+
+        /* Aggiungi margine ai lati del footer */
+        .it-footer-main .container {
+            padding-left: 2rem;
+            padding-right: 2rem;
+        }
+    </style>
+         <style>
+            /* Stile per i link con sottolineatura solo al passaggio del mouse */
+            .link-underline-hover {
+                text-decoration: none; /* Rimuove la sottolineatura di base */
+            }
+            .link-underline-hover:hover {
+                text-decoration: underline; /* Aggiunge la sottolineatura solo al passaggio del mouse */
+            }
+        </style>
+</head>
+<body>
+    <!-- Riga blu scuro con scritto "Project Work" allineata a sinistra -->
+    <div class="top-bar">
+        <div class="container">
+            Project Work
+        </div>
+    </div>
+
+    <!-- Header --FAQ - Domande Frequenti-->
+<!-- Header -->
+<header class="header">
+    <div class="container">
+        <div class="row align-items-center">
+            <div class="col d-flex">
+                <!-- Logo "PW" dentro un cerchio, ora cliccabile -->
+                <a href="./mappa_logout.html" class="logo-link">
+                    <div class="logo">PW</div>
+                </a>
+                <h1 class="header-title">FAQ - Domande Frequenti</h1> <!-- Titolo "Mappa" con la stessa grandezza -->
+            </div>
+            <div class="col-auto d-flex align-items-center">
+                <a href="./ADMIN.html" class="text-white me-3 link-underline-hover">Gestione Dati Immobiliari</a>
+                <a href="./TFO.html" class="text-white me-3 link-underline-hover">TFO</a>
+                <a href="./buildings.html" class="text-white me-3 link-underline-hover">Registrazione degli Edifici</a>
+                <a href="./mappa_login.html" class="btn btn-light">Logout</a>
+            </div>
+        </div>
+    </div>
+</header>
+
+    <!-- Sezione principale -->
+    <section id="faq" class="it-card-wrapper mt-5 main-content">
+        <div class="container">
+            <div class="it-card">
+                <div class="it-card-header">
+                    <h5 class="it-card-title">Domande Frequenti (FAQ)</h5>
+                </div>
+                <div class="it-card-body">
+                    <div class="accordion" id="accordionFAQ">
+                        <div class="accordion-item">
+                            <h2 class="accordion-header" id="headingOne">
+                                <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
+                                    Cos'è il Sistema SINFI?
+                                </button>
+                            </h2>
+                            <div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="headingOne" data-bs-parent="#accordionFAQ">
+                                <div class="accordion-body">
+                                    Il Sistema Informativo Nazionale per la Banda Ultralarga (SINFI) è un sistema di gestione delle informazioni relative alle infrastrutture di telecomunicazione, utile per la pianificazione e il monitoraggio della diffusione della banda ultralarga in Italia.
+                                </div>
+                            </div>
+                        </div>
+                        <div class="accordion-item">
+                            <h2 class="accordion-header" id="headingTwo">
+                                <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
+                                    Come posso registrare un edificio predisposto a banda ultralarga?
+                                </button>
+                            </h2>
+                            <div id="collapseTwo" class="accordion-collapse collapse" aria-labelledby="headingTwo" data-bs-parent="#accordionFAQ">
+                                <div class="accordion-body">
+                                    Per registrare un edificio, è necessario accedere al sistema con le credenziali fornite e compilare il modulo con i dati richiesti, come l'indirizzo, il codice catastale e la data di predisposizione alla banda ultralarga.
+                                </div>
+                            </div>
+                        </div>
+                        <div class="accordion-item">
+                            <h2 class="accordion-header" id="headingThree">
+                                <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
+                                    Chi può accedere al Sistema SINFI?
+                                </button>
+                            </h2>
+                            <div id="collapseThree" class="accordion-collapse collapse" aria-labelledby="headingThree" data-bs-parent="#accordionFAQ">
+                                <div class="accordion-body">
+                                    L'accesso al Sistema SINFI è riservato agli operatori, alle amministrazioni pubbliche e ai cittadini. Gli utenti sono divisi in categorie a seconda del loro ruolo (operatore, amministratore, cittadino).
+                                </div>
+                            </div>
+                        </div>
+                        <div class="accordion-item">
+                            <h2 class="accordion-header" id="headingFour">
+                                <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseFour" aria-expanded="false" aria-controls="collapseFour">
+                                    Quali sono i vantaggi dell'utilizzo del SINFI?
+                                </button>
+                            </h2>
+                            <div id="collapseFour" class="accordion-collapse collapse" aria-labelledby="headingFour" data-bs-parent="#accordionFAQ">
+                                <div class="accordion-body">
+                                    Il SINFI permette di avere una visione completa e aggiornata delle infrastrutture di banda ultralarga, facilitando la pianificazione degli interventi, riducendo i costi e i tempi di realizzazione delle nuove reti e migliorando la qualità dei servizi per i cittadini.
+                                </div>
+                            </div>
+                        </div>
+                        <div class="accordion-item">
+                            <h2 class="accordion-header" id="headingFive">
+                                <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseFive" aria-expanded="false" aria-controls="collapseFive">
+                                    Come posso ottenere assistenza per l'utilizzo del SINFI?
+                                </button>
+                            </h2>
+                            <div id="collapseFive" class="accordion-collapse collapse" aria-labelledby="headingFive" data-bs-parent="#accordionFAQ">
+                                <div class="accordion-body">
+                                    Per ottenere assistenza, è possibile consultare la documentazione disponibile sul sito web del SINFI, contattare il supporto tecnico tramite email o telefono, oppure partecipare ai corsi di formazione organizzati dal sistema.
+                                </div>
+                            </div>
+                        </div>
+                        <div class="accordion-item">
+                            <h2 class="accordion-header" id="headingSix">
+                                <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseSix" aria-expanded="false" aria-controls="collapseSix">
+                                    Come posso verificare lo stato della mia richiesta?
+                                </button>
+                            </h2>
+                            <div id="collapseSix" class="accordion-collapse collapse" aria-labelledby="headingSix" data-bs-parent="#accordionFAQ">
+                                <div class="accordion-body">
+                                    Puoi verificare lo stato della tua richiesta accedendo alla sezione "Le mie richieste" nella tua dashboard. Troverai un aggiornamento in tempo reale sullo stato di avanzamento.
+                                </div>
+                            </div>
+                        </div>
+                        <div class="accordion-item">
+                            <h2 class="accordion-header" id="headingSeven">
+                                <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseSeven" aria-expanded="false" aria-controls="collapseSeven">
+                                    È possibile scaricare report o dati dal sistema?
+                                </button>
+                            </h2>
+                            <div id="collapseSeven" class="accordion-collapse collapse" aria-labelledby="headingSeven" data-bs-parent="#accordionFAQ">
+                                <div class="accordion-body">
+                                    Sì, è possibile scaricare report e dati in formato CSV o PDF dalla sezione "Report" del sistema. I dati sono disponibili per gli utenti autorizzati.
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </section>
+        <!-- Widget ElevenLabs ConvAI -->
+    <div id="ai-widget-container" style="position: fixed; bottom: 20px; right: 20px;">
+        <elevenlabs-convai agent-id="2MJWbkNuIGTHNI71hKfL"></elevenlabs-convai>
+    </div>
+
+        <!-- Footer -->
+        <footer id="footer" class="it-footer bg-black" role="contentinfo">
+            <div class="it-footer-main py-3">
+                <div class="container">
+                    <section class="py-4">
+                        <div class="row">
+                            <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                                <div class="link-list-wrapper">
+                                    <h2 class="h5">Esplora SINFI</h2>
+                                    <ul id="footer-menu-col-1" class="link-list">
+                                        <li id="menu-item-sinfi-1" class="menu-item">
+                                            <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/che-cose/">Cos'è SINFI</a>
+                                        </li>
+                                        <li id="menu-item-sinfi-2" class="menu-item">
+                                            <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Infrastrutture Registrate</a>
+                                        </li>
+                                        <li id="menu-item-sinfi-3" class="menu-item">
+                                            <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/riferimenti-normativi/">Normative di Riferimento</a>
+                                        </li>
+                                        <li id="menu-item-sinfi-4" class="menu-item">
+                                            <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Open Data SINFI</a>
+                                        </li>
+                                    </ul>
+                                </div>
+                            </div>
+                            <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                                <div class="link-list-wrapper">
+                                    <h2 class="h5">Aiuto e Supporto</h2>
+                                    <ul id="footer-menu-col-2" class="link-list">
+                                        <li id="menu-item-aiuto-1" class="menu-item">
+                                            <a class="list-item" href="./instructions.html">Istruzioni</a>
+                                        </li>
+                                        <li id="menu-item-aiuto-2" class="menu-item">
+                                            <a class="list-item" href="./faq.html">FAQ - Domande Frequenti</a>
+                                        </li>
+                                        <li id="menu-item-aiuto-3" class="menu-item">
+                                            <a class="list-item" href="./techsup.html">Segnalazioni e Supporto Tecnico</a>
+                                        </li>
+                                    </ul>
+                                </div>
+                            </div>
+                            <!-- Colonna "Community" con i loghi dei social -->
+                            <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                                <div class="link-list-wrapper">
+                                    <h2 class="h5">Community</h2>
+                                    <div class="social-icons">
+                                        <a href="https://www.linkedin.com" target="_blank" class="me-3"><i class="fab fa-linkedin"></i></a>
+                                        <a href="https://www.youtube.com" target="_blank" class="me-3"><i class="fab fa-youtube"></i></a>
+                                        <a href="https://www.facebook.com" target="_blank" class="me-3"><i class="fab fa-facebook"></i></a>
+                                        <a href="https://www.instagram.com" target="_blank" class="me-3"><i class="fab fa-instagram"></i></a>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                                <div class="link-list-wrapper">
+                                    <h2 class="h5">SINFI</h2>
+                                    <ul id="footer-menu-col-4" class="link-list">
+                                        <li id="menu-item-377" class="menu-item">
+                                            <a target="_blank" href="https://sinfi.it/portal/">Vai al sito ufficiale SINFI</a>
+                                        </li>
+                                    </ul>
+                                </div>
+                            </div>
+                        </div>
+                    </section>
+                </div>
+            </div>
+            <div class="it-footer-small-prints clearfix">
+                <div class="container">
+                    <nav class="menu-footer-menu-ita-container" aria-label="link utili">
+                        <ul id="menu-footer-menu-ita" class="it-footer-small-prints-list list-inline mb-0 d-flex flex-column flex-md-row">
+                            <li id="menu-item-413" class="menu-item list-inline-item"><a href="/media-policy/">Media Policy</a></li>
+                            <li id="menu-item-453" class="menu-item list-inline-item"><a href="/note-legali/">Privacy Policy &amp; Note Legali</a></li>
+                            <li id="menu-item-1310" class="menu-item list-inline-item"><a target="_blank" href="https://form.agid.gov.it/view/9df3de50-7a42-11ef-8989-9dcab5eaa914">Dichiarazione di accessibilità</a></li>
+                            <li id="menu-item-411" class="menu-item list-inline-item"><a href="/mappa-del-sito/">Mappa del sito</a></li>
+                            <li id="menu-item-1277" class="menu-item list-inline-item"><a href="/open-data-spid/">Open Data SPID</a></li>
+                        </ul>
+                    </nav>
+                </div>
+            </div>
+        </footer>
+    </div>
+
+    <!-- Includi il file JavaScript di Bootstrap -->
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+    <script>
+        // Eseguiamo alcune personalizzazioni per migliorare l'interattività
+        document.addEventListener('DOMContentLoaded', function () {
+            // Inizializza i componenti di Bootstrap come gli Accordion
+            var accordion = new bootstrap.Collapse(document.getElementById('accordionFAQ'), {
+                toggle: false
+            });
+        });
+
+        // Eseguiamo alcune personalizzazioni per migliorare l'interattività
+document.addEventListener('DOMContentLoaded', function () {
+    // Inizializza i componenti di Bootstrap come gli Accordion
+    var accordion = new bootstrap.Accordion(document.getElementById('accordionFAQ'));
+});
+    </script>
+    <!-- Includi lo script di ElevenLabs -->
+    <script src="https://elevenlabs.io/convai-widget/index.js" async type="text/javascript"></script>
+</body>
+</html>

+ 525 - 0
Backend/templates/instructions.html

@@ -0,0 +1,525 @@
+<!DOCTYPE html>
+<html lang="it">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Istruzioni</title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.13.4/dist/css/bootstrap-italia.min.css" rel="stylesheet">
+    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
+    <style>
+        /* Stile per la riga blu scuro */
+        .top-bar {
+            background-color: #004080; /* Blu scuro */
+            color: white;
+            padding: 0.5rem 0;
+            text-align: left;
+            font-size: 0.9rem;
+        }
+
+        /* Stile per l'header */
+        .header {
+            background-color: #0066CC; /* Blu chiaro */
+            color: white;
+            padding: 1rem 0;
+        }
+
+        /* Stile per il logo "PW" dentro un cerchio */
+        .logo {
+            font-family: 'Georgia', serif;
+            font-size: 1.5rem;
+            font-weight: bold;
+            display: inline-flex;
+            align-items: center;
+            justify-content: center;
+            width: 50px;
+            height: 50px;
+            background-color: white;
+            color: #0066CC;
+            border-radius: 50%;
+            margin-right: 10px;
+        }
+
+        /* Stile per il titolo "Segnalazioni e Supporto Tecnico" */
+        .header-title {
+            color: white;
+            font-size: 1.5rem;  /* Ridotto per il titolo principale */
+            font-weight: bold;
+            display: inline-block;
+            vertical-align: middle;
+        }
+
+        /* Stile per la barra di ricerca */
+        .search-bar {
+            margin-top: 20px;
+            margin-bottom: 30px;  /* Aggiunto margine inferiore per spazio tra la barra di ricerca e il titolo */
+            display: flex;
+            justify-content: space-between;
+            max-width: 600px;
+            margin-left: auto;
+            margin-right: auto;
+        }
+
+        .search-bar input {
+            width: 80%;
+            padding: 0.5rem;
+            border: 1px solid #ccc;
+            border-radius: 4px;
+        }
+
+        .search-bar button {
+            padding: 0.5rem 1rem;
+            background-color: #0066CC;
+            color: white;
+            border: none;
+            border-radius: 4px;
+            cursor: pointer;
+        }
+
+        /* Stile per il contenuto principale */
+        .main-content {
+            background-color: #f8f9fa;
+            padding: 2rem 0;
+        }
+
+        /* Aggiungi margine ai lati del contenitore principale */
+        .container {
+            padding-left: 2rem;
+            padding-right: 2rem;
+        }
+
+        /* Footer */
+        .footer {
+            background-color: #0066CC;
+            color: white;
+            padding: 1rem 0;
+            text-align: center;
+        }
+
+        /* Stile per la sezione delle istruzioni */
+        .istruzioni {
+            padding: 1rem;
+            background-color: #ffffff;
+            border-radius: 4px;
+            margin-bottom: 2rem;
+            font-size: 0.8rem; /* Carattere più piccolo per le istruzioni */
+            line-height: 1.4; /* Migliora la leggibilità */
+        }
+
+        .clickable {
+            cursor: pointer;
+            color: #0066CC;
+            text-decoration: underline;
+            font-size: 1rem; /* Dimensione ridotta per i titoli */
+            margin-bottom: 0.5rem; /* Riduci lo spazio sotto il titolo */
+        }
+
+        .clickable.active {
+            font-size: 0.9rem; /* Dimensione ridotta quando il titolo è cliccato */
+        }
+
+        /* Ridurre la dimensione dei titoli delle sezioni */
+        h1 {
+            font-size: 1.25rem;  /* Titolo principale della guida */
+        }
+
+        h2 {
+            font-size: 1rem;  /* Titoli delle sezioni più piccoli */
+        }
+
+        h3 {
+            font-size: 0.9rem;  /* Sottotitoli più piccoli */
+            margin-top: 0.5rem; /* Riduci lo spazio sopra i sottotitoli */
+        }
+
+        /* Stile per i paragrafi e le liste dentro le istruzioni */
+        .istruzioni p, .istruzioni ol, .istruzioni ul {
+            font-size: 0.8rem; /* Riduci ulteriormente la dimensione del testo */
+            margin-bottom: 0.5rem; /* Riduci lo spazio tra i paragrafi e le liste */
+        }
+
+        /* Stile per gli elementi delle liste */
+        .istruzioni li {
+            font-size: 0.8rem; /* Riduci ulteriormente la dimensione del testo */
+        }
+
+        /* Pulsante torna su */
+        .back-to-top {
+            position: fixed;
+            bottom: 20px;
+            right: 20px;
+            background-color: #0066CC;
+            color: white;
+            padding: 0.7rem 1rem;
+            border: none;
+            border-radius: 50%;
+            cursor: pointer;
+            display: none;
+        }
+    </style>
+     <style>
+        /* Stile per i link con sottolineatura solo al passaggio del mouse */
+        .link-underline-hover {
+            text-decoration: none; /* Rimuove la sottolineatura di base */
+        }
+
+        .link-underline-hover:hover {
+            text-decoration: underline; /* Aggiunge la sottolineatura solo al passaggio del mouse */
+        }
+    </style>
+</head>
+<body>
+
+    <!-- Riga blu scuro con scritto "Project Work" allineata a sinistra -->
+    <div class="top-bar">
+        <div class="container">
+            Project Work
+        </div>
+    </div>
+
+<!-- Header -->
+<header class="header">
+    <div class="container">
+        <div class="row align-items-center">
+            <div class="col d-flex">
+                <!-- Logo "PW" dentro un cerchio, ora cliccabile -->
+                <a href="./mappa_logout.html" class="logo-link">
+                    <div class="logo">PW</div>
+                </a>
+                <h1 class="header-title">Istruzioni</h1> <!-- Titolo "Mappa" con la stessa grandezza -->
+            </div>
+            <div class="col-auto d-flex align-items-center">
+                <a href="./ADMIN.html" class="text-white me-3 link-underline-hover">Gestione Dati Immobiliari</a>
+                <a href="./TFO.html" class="text-white me-3 link-underline-hover">TFO</a>
+                <a href="./buildings.html" class="text-white me-3 link-underline-hover">Registrazione degli Edifici</a>
+                <a href="./mappa_login.html" class="btn btn-light">Logout</a>
+            </div>
+        </div>
+    </div>
+</header>
+
+    <!-- Barra di ricerca -->
+    <div class="search-bar">
+        <input type="text" id="searchInput" placeholder="Cerca per parola chiave">
+        <button onclick="search()">Cerca</button>
+    </div>
+
+    <div class="container">
+        <h1>Guida all'Uso del Sistema SINFI</h1>
+        <p>Questa guida ti aiuterà a comprendere il funzionamento del sistema e a risolvere eventuali dubbi.</p>
+
+        <!-- Sezione 1: Accesso al Sistema -->
+        <section>
+            <h2 class="clickable">1. Accesso al Sistema</h2>
+            <div class="istruzioni" style="display:none;">
+                <p>Per utilizzare il sistema è necessario autenticarsi con le proprie credenziali.</p>
+                <h3>Login</h3>
+                <ol>
+                    <li>Inserisci il tuo Codice Fiscale e la Password nei rispettivi campi.</li>
+                    <li>Clicca su "Accedi".</li>
+                    <li>Se le credenziali sono corrette, verrai reindirizzato alla Dashboard.</li>
+                </ol>
+                <h3>In caso di errore:</h3>
+                <ul>
+                    <li>Verifica che il Codice Fiscale e la Password siano corretti.</li>
+                    <li>Se hai dimenticato la password, contatta l’amministratore per il recupero.</li>
+                    <li>Se il problema persiste, controlla la connessione o riprova più tardi.</li>
+                </ul>
+            </div>
+        </section>
+
+        <!-- Sezione 2: Registrazione di un Edificio Predisposto alla Banda Ultralarga -->
+        <section>
+            <h2 class="clickable">2. Registrazione di un Edificio Predisposto alla Banda Ultralarga</h2>
+            <div class="istruzioni" style="display:none;">
+                <h3>A cosa serve?</h3>
+                <p>Questa funzionalità permette di registrare edifici che sono stati predisposti per la banda ultralarga.</p>
+                <h3>Come registrare un nuovo edificio</h3>
+                <ol>
+                    <li>Accedi alla sezione "Edifici Infrastrutturati" dal menu principale.</li>
+                    <li>Clicca su "Aggiungi Nuovo Edificio".</li>
+                    <li>Compila il modulo con i seguenti dati:
+                        <ul>
+                            <li>Indirizzo completo dell’edificio.</li>
+                            <li>Coordinate geografiche (centroide e poligono) → Puoi selezionare la posizione dalla mappa.</li>
+                            <li>Codice catastale → Inserisci il codice univoco dell’edificio.</li>
+                            <li>Tipologia dell’edificio → Seleziona tra residenziale, commerciale, industriale, ecc.</li>
+                            <li>Data di predisposizione → Indica quando l’edificio è stato predisposto per la banda ultralarga.</li>
+                        </ul>
+                    </li>
+                    <li>Dopo aver compilato tutti i campi, clicca su "Salva".</li>
+                </ol>
+                <h3>Problemi comuni e soluzioni</h3>
+                <ul>
+                    <li>Non trovo l’edificio sulla mappa dopo la registrazione:
+                        <ul>
+                            <li>Controlla che le coordinate inserite siano corrette.</li>
+                            <li>Aggiorna la pagina per ricaricare i dati.</li>
+                        </ul>
+                    </li>
+                    <li>Errore durante il salvataggio dell’edificio:
+                        <ul>
+                            <li>Assicurati di aver compilato tutti i campi obbligatori.</li>
+                            <li>Controlla la connessione internet.</li>
+                            <li>Se il problema persiste, contatta l’assistenza.</li>
+                        </ul>
+                    </li>
+                </ul>
+            </div>
+        </section>
+
+        <!-- Sezione 3: Registrazione di una Terminazione Ottica (TFO) -->
+        <section>
+            <h2 class="clickable">3. Registrazione di una Terminazione Ottica (TFO)</h2>
+            <div class="istruzioni" style="display:none;">
+                <h3>A cosa serve?</h3>
+                <p>Questa funzionalità permette di registrare le terminazioni ottiche (punti di connessione della fibra ottica) all’interno di un edificio.</p>
+                <h3>Come registrare una nuova TFO</h3>
+                <ol>
+                    <li>Accedi alla sezione "Terminazioni Ottiche (TFO)".</li>
+                    <li>Clicca su "Aggiungi Nuova TFO".</li>
+                    <li>Inserisci i dati richiesti:
+                        <ul>
+                            <li>Codice catastale dell’edificio → Deve corrispondere a un edificio già registrato.</li>
+                            <li>Identificativo Operatore → Indica il proprietario della rete.</li>
+                            <li>Codice univoco TFO → Numero identificativo della terminazione.</li>
+                            <li>Piano, Scala, Interno → Specifica l’ubicazione esatta della TFO nell’edificio.</li>
+                            <li>Posizione precisa → Seleziona sulla mappa la posizione della terminazione ottica.</li>
+                        </ul>
+                    </li>
+                    <li>Clicca su "Salva" per completare la registrazione.</li>
+                </ol>
+                <h3>Problemi comuni e soluzioni</h3>
+                <ul>
+                    <li>Non riesco a trovare il codice catastale dell’edificio:
+                        <ul>
+                            <li>Verifica che l’edificio sia stato registrato nella sezione "Edifici Infrastrutturati".</li>
+                            <li>Contatta l’amministratore per verificare i dati catastali.</li>
+                        </ul>
+                    </li>
+                    <li>Errore durante il salvataggio della TFO:
+                        <ul>
+                            <li>Controlla che tutti i campi siano compilati correttamente.</li>
+                            <li>Se l’errore persiste, prova a ricaricare la pagina.</li>
+                        </ul>
+                    </li>
+                </ul>
+            </div>
+        </section>
+
+        <!-- Sezione 4: Mappa Interattiva degli Edifici -->
+        <section>
+            <h2 class="clickable">4. Mappa Interattiva degli Edifici</h2>
+            <div class="istruzioni" style="display:none;">
+                <p>La mappa visualizza gli edifici e le infrastrutture registrate.</p>
+                <h3>Funzionalità della mappa</h3>
+                <ul>
+                    <li>Selezione di un edificio: Clicca su un edificio per visualizzarne i dettagli.</li>
+                    <li>Filtri di visualizzazione: Puoi filtrare gli edifici in base allo stato di infrastrutturazione.</li>
+                    <li>Colori della mappa:
+                        <ul>
+                            <li>Rosso → Edificio non predisposto alla banda ultralarga.</li>
+                            <li>Giallo → Edificio predisposto.</li>
+                        </ul>
+                    </li>
+                </ul>
+                <h3>Problemi comuni e soluzioni</h3>
+                <ul>
+                    <li>Non vedo gli edifici sulla mappa:
+                        <ul>
+                            <li>Assicurati di avere una connessione internet attiva.</li>
+                            <li>Verifica che la registrazione degli edifici sia stata completata correttamente.</li>
+                            <li>Ricarica la pagina per aggiornare i dati.</li>
+                        </ul>
+                    </li>
+                </ul>
+            </div>
+        </section>
+
+        <!-- Sezione 5: Gestione Utenti e Accesso -->
+        <section>
+            <h2 class="clickable">5. Gestione Utenti e Accesso</h2>
+            <div class="istruzioni" style="display:none;">
+                <h3>Ruoli Utente</h3>
+                <ul>
+                    <li>Operatore → Può registrare e modificare solo gli edifici e le TFO di sua competenza.</li>
+                    <li>Amministratore → Può visualizzare e gestire tutte le pratiche.</li>
+                </ul>
+                <h3>Accesso e Autenticazione</h3>
+                <ul>
+                    <li>Il sistema utilizza un login sicuro con autenticazione tramite Keycloak.</li>
+                    <li>Gli utenti vengono registrati direttamente nel database e non possono creare account autonomamente.</li>
+                    <li>Se hai bisogno di un accesso, contatta l’amministratore.</li>
+                </ul>
+                <h3>Problemi comuni e soluzioni</h3>
+                <ul>
+                    <li>Non riesco ad accedere:
+                        <ul>
+                            <li>Verifica che il Codice Fiscale e la Password siano corretti.</li>
+                            <li>Contatta l’amministratore per il recupero della password.</li>
+                        </ul>
+                    </li>
+                    <li>Non vedo alcune funzioni nel menu:
+                        <ul>
+                            <li>Potresti avere restrizioni in base al tuo ruolo.</li>
+                        </ul>
+                    </li>
+                </ul>
+            </div>
+        </section>
+
+        <!-- Sezione Supporto e Assistenza -->
+        <section>
+            <h2 class="clickable">Supporto e Assistenza</h2>
+            <div class="istruzioni" style="display:none;">
+                <p>Se riscontri problemi tecnici o hai domande sul sistema, puoi:</p>
+                <ul>
+                    <li>Consultare questa guida.</li>
+                    <li>Contattare l’amministratore del sistema.</li>
+                    <li>Verificare eventuali aggiornamenti sulla piattaforma.</li>
+                </ul>
+                <p>Email Assistenza: <a href="mailto:supporto@sinfi.gov.it">supporto@sinfi.gov.it</a></p>
+                <p>Numero di Supporto: 800-123-456</p>
+            </div>
+        </section>
+    </div>
+
+    <button class="back-to-top" onclick="scrollToTop()">Torna su</button>
+
+    <script>
+        // Funzione per la ricerca
+        function search() {
+            var searchTerm = document.getElementById('searchInput').value.toLowerCase();
+            var sections = document.querySelectorAll('section');
+
+            sections.forEach(function(section) {
+                var title = section.querySelector('h2').textContent.toLowerCase();
+                var content = section.querySelector('.istruzioni').textContent.toLowerCase();
+
+                if (title.includes(searchTerm) || content.includes(searchTerm)) {
+                    section.querySelector('.istruzioni').style.display = 'block';
+                    section.querySelector('h2').classList.add('active');
+                } else {
+                    section.querySelector('.istruzioni').style.display = 'none';
+                    section.querySelector('h2').classList.remove('active');
+                }
+            });
+        }
+
+        // Gestione del click sui titoli delle sezioni
+        document.querySelectorAll('.clickable').forEach(function(title) {
+            title.addEventListener('click', function() {
+                var istruzioni = this.nextElementSibling;
+                if (istruzioni.style.display === 'none') {
+                    istruzioni.style.display = 'block';
+                    this.classList.add('active'); // Aggiunge la classe per ridurre la dimensione del carattere
+                } else {
+                    istruzioni.style.display = 'none';
+                    this.classList.remove('active'); // Rimuove la classe per ripristinare la dimensione originale
+                }
+            });
+        });
+
+        // Mostra/Nascondi il pulsante "Torna su"
+        window.onscroll = function() {
+            var backToTopButton = document.querySelector('.back-to-top');
+            if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
+                backToTopButton.style.display = 'block';
+            } else {
+                backToTopButton.style.display = 'none';
+            }
+        };
+
+        // Funzione per tornare in cima alla pagina
+        function scrollToTop() {
+            document.body.scrollTop = 0;
+            document.documentElement.scrollTop = 0;
+        }
+    </script>
+    <!-- Includi lo script di ElevenLabs -->
+    <script src="https://elevenlabs.io/convai-widget/index.js" async type="text/javascript"></script>
+    <!-- Widget ElevenLabs ConvAI -->
+    <div id="ai-widget-container" style="position: fixed; bottom: 20px; right: 20px;">
+        <elevenlabs-convai agent-id="2MJWbkNuIGTHNI71hKfL"></elevenlabs-convai>
+    </div>
+    <footer id="footer" class="it-footer bg-black" role="contentinfo">
+        <div class="it-footer-main py-3">
+            <div class="container">
+                <section class="py-4">
+                    <div class="row">
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Esplora SINFI</h2>
+                                <ul id="footer-menu-col-1" class="link-list">
+                                    <li id="menu-item-sinfi-1" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/che-cose/">Cos'è SINFI</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-2" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Infrastrutture Registrate</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-3" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/riferimenti-normativi/">Normative di Riferimento</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-4" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Open Data SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Aiuto e Supporto</h2>
+                                <ul id="footer-menu-col-2" class="link-list">
+                                    <li id="menu-item-aiuto-1" class="menu-item">
+                                        <a class="list-item" href="./instructions.html">Istruzioni</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-2" class="menu-item">
+                                        <a class="list-item" href="./faq.html">FAQ - Domande Frequenti</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-3" class="menu-item">
+                                        <a class="list-item" href="./techsup.html">Segnalazioni e Supporto Tecnico</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <!-- Colonna "Community" con i loghi dei social -->
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Community</h2>
+                                <div class="social-icons">
+                                    <a href="https://www.linkedin.com" target="_blank" class="me-3"><i class="fab fa-linkedin"></i></a>
+                                    <a href="https://www.youtube.com" target="_blank" class="me-3"><i class="fab fa-youtube"></i></a>
+                                    <a href="https://www.facebook.com" target="_blank" class="me-3"><i class="fab fa-facebook"></i></a>
+                                    <a href="https://www.instagram.com" target="_blank" class="me-3"><i class="fab fa-instagram"></i></a>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">SINFI</h2>
+                                <ul id="footer-menu-col-4" class="link-list">
+                                    <li id="menu-item-377" class="menu-item">
+                                        <a target="_blank" href="https://sinfi.it/portal/">Vai al sito ufficiale SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+                </section>
+            </div>
+        </div>
+        <div class="it-footer-small-prints clearfix">
+            <div class="container">
+                <nav class="menu-footer-menu-ita-container" aria-label="link utili">
+                    <ul id="menu-footer-menu-ita" class="it-footer-small-prints-list list-inline mb-0 d-flex flex-column flex-md-row">
+                        <li id="menu-item-413" class="menu-item list-inline-item"><a href="/media-policy/">Media Policy</a></li>
+                        <li id="menu-item-453" class="menu-item list-inline-item"><a href="/note-legali/">Privacy Policy &amp; Note Legali</a></li>
+                        <li id="menu-item-1310" class="menu-item list-inline-item"><a target="_blank" href="https://form.agid.gov.it/view/9df3de50-7a42-11ef-8989-9dcab5eaa914">Dichiarazione di accessibilità</a></li>
+                        <li id="menu-item-411" class="menu-item list-inline-item"><a href="/mappa-del-sito/">Mappa del sito</a></li>
+                        <li id="menu-item-1277" class="menu-item list-inline-item"><a href="/open-data-spid/">Open Data SPID</a></li>
+                    </ul>
+                </nav>
+            </div>
+        </div>
+    </footer>
+</body>
+</html>

+ 234 - 0
Backend/templates/login.html

@@ -0,0 +1,234 @@
+<!DOCTYPE html>
+<html lang="it">
+<head>
+    <title>Login</title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.8.1/dist/css/bootstrap-italia.min.css" rel="stylesheet">
+    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
+    <style>
+        /* Stile per la riga blu scuro */
+        .top-bar {
+            background-color: #004080; /* Blu scuro */
+            color: white;
+            padding: 0.5rem 0;
+            text-align: left; /* Allineamento a sinistra */
+            font-size: 0.9rem;
+        }
+
+        /* Stile per l'header */
+        .header {
+            background-color: #0066CC; /* Blu chiaro */
+            color: white;
+            padding: 1rem 0;
+        }
+
+        /* Stile per il logo "PW" dentro un cerchio */
+        .logo {
+            font-family: 'Georgia', serif; /* Font diverso */
+            font-size: 1.5rem;
+            font-weight: bold;
+            display: inline-flex;
+            align-items: center;
+            justify-content: center;
+            width: 50px; /* Diametro del cerchio */
+            height: 50px; /* Diametro del cerchio */
+            background-color: white; /* Colore di sfondo del cerchio */
+            color: #0066CC; /* Colore del testo */
+            border-radius: 50%; /* Rende l'elemento un cerchio */
+            margin-right: 10px;
+        }
+
+        /* Stile per il titolo "Mappa" */
+        .header-title {
+            color: white;
+            font-size: 1.5rem; /* Stessa grandezza di "Segnalazioni e Supporto Tecnico" */
+            font-weight: bold;
+            display: inline-block;
+            vertical-align: middle;
+        }
+
+        /* Stile per i link con sottolineatura solo al passaggio del mouse */
+        .link-underline-hover {
+            text-decoration: none; /* Rimuove la sottolineatura di base */
+        }
+        .link-underline-hover:hover {
+            text-decoration: underline; /* Aggiunge la sottolineatura solo al passaggio del mouse */
+        }
+
+        /* Sfondo della pagina */
+        body {
+            background-color: #0066CC; /* Stesso colore dell'header */
+            margin: 0;
+            padding: 0;
+        }
+
+        /* Riquadro bianco per il login */
+        .login-box {
+            background-color: white;
+            border-radius: 10px;
+            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
+            padding: 2rem;
+            max-width: 400px;
+            margin: 2rem auto;
+        }
+
+        /* Stile per il titolo del login */
+        .login-title {
+            font-size: 1.5rem;
+            font-weight: bold;
+            text-align: center;
+            margin-bottom: 1.5rem;
+        }
+
+        /* Stile per i campi del form */
+        .form-control {
+            margin-bottom: 1rem;
+        }
+
+        /* Stile per il pulsante di accesso */
+        .btn-primary {
+            width: 100%;
+            padding: 0.75rem;
+            font-size: 1rem;
+        }
+
+        /* Stile per le icone dei social nel footer */
+        .social-icons a i {
+            color: white; /* Colore bianco per le icone */
+        }
+    </style>
+</head>
+<body>
+    <!-- Riga blu scuro con scritto "Project Work" allineata a sinistra -->
+    <div class="top-bar">
+        <div class="container">
+            Project Work
+        </div>
+    </div>    
+
+    <!-- Header -->
+    <header class="header">
+        <div class="container">
+            <div class="row align-items-center">
+                <div class="col">
+                    <!-- Logo "PW" dentro un cerchio -->
+                    <div class="logo">PW</div>
+                    <h1 class="header-title">Accedi</h1> <!-- Titolo "registrazione degli Edifici" con la stessa grandezza -->
+                </div>
+             
+                   
+                </div>
+            </div>
+        </div>
+    </header>
+
+    <!-- Riquadro bianco per il login -->
+    <div class="login-box">
+        <h2 class="login-title">Login</h2>
+        <form id="login-form">
+            <div class="mb-3">
+                <label for="username" class="form-label">Username:</label>
+                <input type="text" class="form-control" id="username" name="username" required>
+            </div>
+            <div class="mb-3">
+                <label for="password" class="form-label">Password:</label>
+                <input type="password" class="form-control" id="password" name="password" required>
+            </div>
+            <div class="mb-3">
+                <label for="role" class="form-label">Ruolo:</label>
+                <select class="form-select" id="role" name="role">
+                    <option value="admin">Amministratore</option>
+                    <option value="operator">Operatore</option>
+                </select>
+            </div>
+            <div class="d-grid">
+                <button type="submit" class="btn btn-primary">Accedi</button>
+            </div>
+        </form>
+        <div id="error-message" class="mt-3 text-danger text-center"></div>
+    </div>
+
+    <!-- Footer -->
+    <footer id="footer" class="it-footer bg-black" role="contentinfo">
+        <div class="it-footer-main py-3">
+            <div class="container">
+                <section class="py-4">
+                    <div class="row">
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Esplora SINFI</h2>
+                                <ul id="footer-menu-col-1" class="link-list">
+                                    <li id="menu-item-sinfi-1" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/che-cose/">Cos'è SINFI</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-2" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Infrastrutture Registrate</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-3" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/riferimenti-normativi/">Normative di Riferimento</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-4" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Open Data SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Aiuto e Supporto</h2>
+                                <ul id="footer-menu-col-2" class="link-list">
+                                    <li id="menu-item-aiuto-1" class="menu-item">
+                                        <a class="list-item" href="./login.html">Istruzioni</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-2" class="menu-item">
+                                        <a class="list-item" href="./login.html">FAQ - Domande Frequenti</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-3" class="menu-item">
+                                        <a class="list-item" href="./login.html">Segnalazioni e Supporto Tecnico</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <!-- Colonna "Community" con i loghi dei social -->
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Community</h2>
+                                <div class="social-icons">
+                                    <a href="https://www.linkedin.com" target="_blank" class="me-3"><i class="fab fa-linkedin"></i></a>
+                                    <a href="https://www.youtube.com" target="_blank" class="me-3"><i class="fab fa-youtube"></i></a>
+                                    <a href="https://www.facebook.com" target="_blank" class="me-3"><i class="fab fa-facebook"></i></a>
+                                    <a href="https://www.instagram.com" target="_blank" class="me-3"><i class="fab fa-instagram"></i></a>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">SINFI</h2>
+                                <ul id="footer-menu-col-4" class="link-list">
+                                    <li id="menu-item-377" class="menu-item">
+                                        <a target="_blank" href="https://sinfi.it/portal/">Vai al sito ufficiale SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+                </section>
+            </div>
+        </div>
+        <div class="it-footer-small-prints clearfix">
+            <div class="container">
+                <nav class="menu-footer-menu-ita-container" aria-label="link utili">
+                    <ul id="menu-footer-menu-ita" class="it-footer-small-prints-list list-inline mb-0 d-flex flex-column flex-md-row">
+                        <li id="menu-item-413" class="menu-item list-inline-item"><a href="/media-policy/">Media Policy</a></li>
+                        <li id="menu-item-453" class="menu-item list-inline-item"><a href="/note-legali/">Privacy Policy &amp; Note Legali</a></li>
+                        <li id="menu-item-1310" class="menu-item list-inline-item"><a target="_blank" href="https://form.agid.gov.it/view/9df3de50-7a42-11ef-8989-9dcab5eaa914">Dichiarazione di accessibilità</a></li>
+                        <li id="menu-item-411" class="menu-item list-inline-item"><a href="/mappa-del-sito/">Mappa del sito</a></li>
+                        <li id="menu-item-1277" class="menu-item list-inline-item"><a href="/open-data-spid/">Open Data SPID</a></li>
+                    </ul>
+                </nav>
+            </div>
+        </div>
+    </footer>
+
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
+</body>
+</html>

+ 352 - 0
Backend/templates/mappa_home.html

@@ -0,0 +1,352 @@
+<!DOCTYPE html>
+<html lang="it">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Mappa Interattiva con Layer Colorati</title>
+    
+    <!-- Fogli di stile -->
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.13.4/dist/css/bootstrap-italia.min.css">
+    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css">
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css"/>
+    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
+    
+    <style>
+        .top-bar { background-color: #004080; color: white; padding: 0.5rem 0; }
+        .header { background-color: #0066CC; color: white; padding: 1rem 0; }
+        .logo { 
+            font-family: 'Georgia', serif; 
+            font-size: 1.5rem; 
+            width: 50px; height: 50px; 
+            background-color: white; 
+            color: #0066CC; 
+            border-radius: 50%; 
+            margin-right: 10px; 
+            display: inline-flex; 
+            align-items: center; 
+            justify-content: center; 
+        }
+        .header-title { color: white; font-size: 1.5rem; font-weight: bold; }
+        .main-content { background-color: #f8f9fa; padding: 2rem 0; }
+        #map { height: 500px; width: 100%; border-radius: 8px; }
+        .search-container { margin: 20px 0; }
+        .search-box { display: flex; gap: 10px; max-width: 600px; margin: 0 auto; }
+        .coordinate-box { background: white; padding: 15px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-top: 20px; }
+    </style>
+</head>
+<body>
+    <!-- Header -->
+    <div class="top-bar">
+        <div class="container">Project Work</div>
+    </div>
+
+     <!-- Header -->
+     <header class="header">
+        <div class="container">
+            <div class="row align-items-center">
+                <div class="col d-flex">
+                    <!-- Logo "PW" dentro un cerchio, ora cliccabile -->
+                    <a href="./login.html" class="logo-link">
+                        <div class="logo">PW</div>
+                    </a>
+                    <h1 class="header-title">Mappa</h1> <!-- Titolo "Mappa" con la stessa grandezza -->
+                </div>
+                <div class="col-auto">
+                    <a href="./login.html" class="btn btn-light">Login</a>
+                </div>
+            </div>
+        </div>
+    </header>
+
+    <main class="main-content">
+        <div class="container">
+            <!-- Barra di ricerca -->
+            <div class="search-container">
+                <div class="search-box">
+                    <input type="text" 
+                           id="address" 
+                           class="form-control" 
+                           placeholder="Inserisci l'indirizzo"
+                           style="flex-grow: 1;">
+                    <button id="searchBtn" class="btn btn-primary">
+                        <i class="fas fa-search"></i> Cerca
+                    </button>
+                </div>
+            </div>
+
+            <!-- Mappa -->
+            <div id="map"></div>
+
+            <!-- Dati geografici -->
+            <div class="coordinate-box">
+                <div class="row">
+                    <div class="col-md-4 mb-3">
+                        <label class="form-label">Latitudine:</label>
+                        <input type="number" id="latInput" class="form-control" readonly>
+                    </div>
+                    <div class="col-md-4 mb-3">
+                        <label class="form-label">Longitudine:</label>
+                        <input type="number" id="lngInput" class="form-control" readonly>
+                    </div>
+                    <div class="col-md-4 mb-3">
+                        <label class="form-label">Indirizzo:</label>
+                        <input type="text" id="addressInput" class="form-control" readonly>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </main>
+
+    <!-- Footer -->
+    <footer id="footer" class="it-footer bg-black" role="contentinfo">
+        <!-- Contenuto footer mantenuto uguale -->
+    </footer>
+
+    <!-- Script -->
+    <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
+    <script>
+        // Inizializzazione Mappa
+        const map = L.map('map').setView([41.9028, 12.4964], 13);
+        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
+
+        // Layer edifici colorati
+        const edificiLayer = L.layerGroup().addTo(map);
+        let currentMarker = null;
+
+        // Funzione principale per caricare gli edifici
+        async function caricaEdifici() {
+            if (map.getZoom() >= 16) {
+                const bounds = map.getBounds();
+                const bbox = `${bounds.getSouthWest().lat},${bounds.getSouthWest().lng},${bounds.getNorthEast().lat},${bounds.getNorthEast().lng}`;
+                
+                const query = `[out:json];
+                    (
+                        way["building"](${bbox});
+                        relation["building"](${bbox});
+                    );
+                    out geom;
+                    out tags;`;
+
+                try {
+                    const response = await fetch(`https://overpass-api.de/api/interpreter?data=${encodeURIComponent(query)}`);
+                    const data = await response.json();
+
+                    edificiLayer.clearLayers();
+                    
+                    data.elements.forEach(element => {
+                        if (element.type === 'way' && element.geometry) {
+                            const latlngs = element.geometry.map(coord => [coord.lat, coord.lon]);
+                            var statoEdificio = false;
+                            let colorePoligono ;
+                            if (statoEdificio) colorePoligono = 'yellow';
+                            else colorePoligono = 'green';
+                            
+                            // const colori = ['#FF0000', '#00FF00'];
+                            const polygon = L.polygon(latlngs, {
+                                fillColor: colorePoligono,
+                                color: colorePoligono,
+                                fillOpacity: 0.5
+                            }).addTo(edificiLayer);
+
+                            polygon.on('click', async function() {
+                                var buildingType = element.tags && element.tags.building ? element.tags.building : 'Sconosciuto';
+                                try {
+                                    await getAddress(latlngs[0][0], latlngs[0][1]);
+                                    var popupContent = `
+                                        <b>Coordinate:</b> ${latlngs[0][0]}, ${latlngs[0][1]}<br>
+                                        <b>Tipo edificio:</b> ${buildingType}<br>
+                                        <b>Indirizzo:</b> ${document.getElementById('addressInput').value}<br>
+                                        <b>Stato:</b> ${statoEdificio}<br>
+                                        <b>Codice Catastale:</b> nessuno
+                                    `;
+                                    polygon.bindPopup(popupContent).openPopup();
+                                } catch (error) {
+                                    console.error("Errore nel recupero dell'indirizzo:", error);
+                                    var popupContent = `
+                                        <b>Coordinate:</b> ${latlngs[0][0]}, ${latlngs[0][1]}<br>
+                                        <b>Tipo edificio:</b> ${buildingType}<br>
+                                        <b>Indirizzo:</b> Indirizzo non disponibile<br>
+                                        <b>Stato:</b> ${statoEdificio}<br>
+                                        <b>Codice Catastale:</b> nessuno
+                                    `;
+                                    polygon.bindPopup(popupContent).openPopup();
+                                }
+                            });
+                        }
+                    });
+                } catch (error) {
+                    console.error("Errore nel caricamento edifici:", error);
+                }
+            } else {
+                edificiLayer.clearLayers();
+            }
+        }
+        async function getAddress(lat, lng) {
+            console.log(typeof(lat));
+            console.log(typeof(lng));
+
+            try {
+                const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${lng}`);
+                const data = await response.json();
+
+                if (data.address) {
+                    document.getElementById('addressInput').value = data.display_name;
+                } else {
+                    document.getElementById('addressInput').value = "Indirizzo non trovato";
+                }
+            } catch (error) {
+                console.error("Errore nel geocoding inverso:", error);
+                document.getElementById('addressInput').value = "Errore nel geocoding inverso";
+            }
+        }
+
+        // Funzioni di gestione posizione
+        async function updatePosition(lat, lng) {
+            try {
+                const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}`);
+                const data = await response.json();
+                
+                document.getElementById('latInput').value = lat;
+                document.getElementById('lngInput').value = lng;
+                document.getElementById('addressInput').value = data.display_name || "Indirizzo non disponibile";
+                
+                if (currentMarker) map.removeLayer(currentMarker);
+                currentMarker = L.marker([lat, lng]).addTo(map);
+                
+            } catch (error) {
+                console.error("Errore di geocoding inverso:", error);
+            }
+        }
+
+        // Ricerca indirizzo
+        async function searchAddress() {
+            const address = document.getElementById('address').value;
+            if (!address) return;
+
+            try {
+                const response = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(address)}`);
+                const data = await response.json();
+                
+                if (data.length === 0) {
+                    alert("Indirizzo non trovato");
+                    return;
+                }
+
+                const { lat, lon: lng } = data[0];
+                map.setView([lat, lng], 18);
+                updatePosition(lat, lng);
+                
+            } catch (error) {
+                console.error("Errore di ricerca:", error);
+            }
+        }
+
+        // Event listeners
+        document.getElementById('searchBtn').addEventListener('click', searchAddress);
+        document.getElementById('address').addEventListener('keypress', (e) => {
+            if (e.key === 'Enter') searchAddress();
+        });
+
+        map.on('click', (e) => {
+            const { lat, lng } = e.latlng;
+            updatePosition(lat, lng);
+        });
+
+        map.on('moveend', caricaEdifici);
+        map.on('zoomend', caricaEdifici);
+        caricaEdifici();
+    </script>
+
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.8.1/dist/js/bootstrap-italia.bundle.min.js"></script>
+
+    <!-- Includi lo script di ElevenLabs -->
+    <script src="https://elevenlabs.io/convai-widget/index.js" async type="text/javascript"></script>
+
+    <!-- Widget ElevenLabs ConvAI -->
+    <div id="ai-widget-container" style="position: fixed; bottom: 20px; right: 20px;">
+        <elevenlabs-convai agent-id="2MJWbkNuIGTHNI71hKfL"></elevenlabs-convai>
+    </div>
+
+    <footer id="footer" class="it-footer bg-black" role="contentinfo">
+        <div class="it-footer-main py-3">
+            <div class="container">
+                <section class="py-4">
+                    <div class="row">
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Esplora SINFI</h2>
+                                <ul id="footer-menu-col-1" class="link-list">
+                                    <li id="menu-item-sinfi-1" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/che-cose/">Cos'è SINFI</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-2" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Infrastrutture Registrate</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-3" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/riferimenti-normativi/">Normative di Riferimento</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-4" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Open Data SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Aiuto e Supporto</h2>
+                                <ul id="footer-menu-col-2" class="link-list">
+                                    <li id="menu-item-aiuto-1" class="menu-item">
+                                        <a class="list-item" href="./login.html">Istruzioni</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-2" class="menu-item">
+                                        <a class="list-item" href="./login.html">FAQ - Domande Frequenti</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-3" class="menu-item">
+                                        <a class="list-item"href="./login.html">Segnalazioni e Supporto Tecnico</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <!-- Colonna "Community" con i loghi dei social -->
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Community</h2>
+                                <div class="social-icons">
+                                    <a href="https://www.linkedin.com" target="_blank" class="me-3"><i class="fab fa-linkedin"></i></a>
+                                    <a href="https://www.youtube.com" target="_blank" class="me-3"><i class="fab fa-youtube"></i></a>
+                                    <a href="https://www.facebook.com" target="_blank" class="me-3"><i class="fab fa-facebook"></i></a>
+                                    <a href="https://www.instagram.com" target="_blank" class="me-3"><i class="fab fa-instagram"></i></a>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">SINFI</h2>
+                                <ul id="footer-menu-col-4" class="link-list">
+                                    <li id="menu-item-377" class="menu-item">
+                                        <a target="_blank" href="https://sinfi.it/portal/">Vai al sito ufficiale SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+                </section>
+            </div>
+        </div>
+        <div class="it-footer-small-prints clearfix">
+            <div class="container">
+                <nav class="menu-footer-menu-ita-container" aria-label="link utili">
+                    <ul id="menu-footer-menu-ita" class="it-footer-small-prints-list list-inline mb-0 d-flex flex-column flex-md-row">
+                        <li id="menu-item-413" class="menu-item list-inline-item"><a href="/media-policy/">Media Policy</a></li>
+                        <li id="menu-item-453" class="menu-item list-inline-item"><a href="/note-legali/">Privacy Policy &amp; Note Legali</a></li>
+                        <li id="menu-item-1310" class="menu-item list-inline-item"><a target="_blank" href="https://form.agid.gov.it/view/9df3de50-7a42-11ef-8989-9dcab5eaa914">Dichiarazione di accessibilità</a></li>
+                        <li id="menu-item-411" class="menu-item list-inline-item"><a href="/mappa-del-sito/">Mappa del sito</a></li>
+                        <li id="menu-item-1277" class="menu-item list-inline-item"><a href="/open-data-spid/">Open Data SPID</a></li>
+                    </ul>
+                </nav>
+            </div>
+        </div>
+    </footer>
+</body>
+</html>

+ 357 - 0
Backend/templates/mappa_logout.html

@@ -0,0 +1,357 @@
+<!DOCTYPE html>
+<html lang="it">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Mappa Interattiva con Layer Colorati</title>
+    
+    <!-- Fogli di stile -->
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.13.4/dist/css/bootstrap-italia.min.css">
+    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css">
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css"/>
+    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
+    
+    <style>
+        .top-bar { background-color: #004080; color: white; padding: 0.5rem 0; }
+        .header { background-color: #0066CC; color: white; padding: 1rem 0; }
+        .logo { 
+            font-family: 'Georgia', serif; 
+            font-size: 1.5rem; 
+            width: 50px; height: 50px; 
+            background-color: white; 
+            color: #0066CC; 
+            border-radius: 50%; 
+            margin-right: 10px; 
+            display: inline-flex; 
+            align-items: center; 
+            justify-content: center; 
+        }
+        .header-title { color: white; font-size: 1.5rem; font-weight: bold; }
+        .main-content { background-color: #f8f9fa; padding: 2rem 0; }
+        #map { height: 500px; width: 100%; border-radius: 8px; }
+        .search-container { margin: 20px 0; }
+        .search-box { display: flex; gap: 10px; max-width: 600px; margin: 0 auto; }
+        .coordinate-box { background: white; padding: 15px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-top: 20px; }
+    </style>
+</head>
+<body>
+    <!-- Header -->
+    <div class="top-bar">
+        <div class="container">Project Work</div>
+    </div>
+
+     <!-- Header -->
+     <header class="header">
+        <div class="container">
+            <div class="row align-items-center">
+                <div class="col d-flex">
+                    <!-- Logo "PW" dentro un cerchio, ora cliccabile -->
+                    <a href="./mappa_logout.html" class="logo-link">
+                        <div class="logo">PW</div>
+                    </a>
+                    <h1 class="header-title">Mappa</h1>
+                </div>
+                <div class="col-auto d-flex align-items-center">
+                    <a href="./ADMIN.html" class="text-white me-3 link-underline-hover">Gestione Dati Immobiliari</a>
+                    <a href="./TFO.html" class="text-white me-3 link-underline-hover">TFO</a>
+                    <a href="./buildings.html" class="text-white me-3 link-underline-hover">Registrazione degli Edifici</a>
+                    <a href="./mappa_login.html" class="btn btn-light">Logout</a>
+                </div>
+            </div>
+        </div>
+    </header>
+
+    <main class="main-content">
+        <div class="container">
+            <!-- Barra di ricerca -->
+            <div class="search-container">
+                <div class="search-box">
+                    <input type="text" 
+                           id="address" 
+                           class="form-control" 
+                           placeholder="Inserisci l'indirizzo"
+                           style="flex-grow: 1;">
+                    <button id="searchBtn" class="btn btn-primary">
+                        <i class="fas fa-search"></i> Cerca
+                    </button>
+                </div>
+            </div>
+
+            <!-- Mappa -->
+            <div id="map"></div>
+
+            <!-- Dati geografici -->
+            <div class="coordinate-box">
+                <div class="row">
+                    <div class="col-md-4 mb-3">
+                        <label class="form-label">Latitudine:</label>
+                        <input type="number" id="latInput" class="form-control" readonly>
+                    </div>
+                    <div class="col-md-4 mb-3">
+                        <label class="form-label">Longitudine:</label>
+                        <input type="number" id="lngInput" class="form-control" readonly>
+                    </div>
+                    <div class="col-md-4 mb-3">
+                        <label class="form-label">Indirizzo:</label>
+                        <input type="text" id="addressInput" class="form-control" readonly>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </main>
+
+    <!-- Footer -->
+    <footer id="footer" class="it-footer bg-black" role="contentinfo">
+        <!-- Contenuto footer mantenuto uguale -->
+    </footer>
+
+    <!-- Script -->
+     <!-- Includi lo script di ElevenLabs -->
+    
+    <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
+    <script>
+        // Inizializzazione Mappa
+        const map = L.map('map').setView([41.9028, 12.4964], 13);
+        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
+
+        // Layer edifici colorati
+        const edificiLayer = L.layerGroup().addTo(map);
+        let currentMarker = null;
+
+        // Funzione principale per caricare gli edifici
+        async function caricaEdifici() {
+            if (map.getZoom() >= 16) {
+                const bounds = map.getBounds();
+                const bbox = `${bounds.getSouthWest().lat},${bounds.getSouthWest().lng},${bounds.getNorthEast().lat},${bounds.getNorthEast().lng}`;
+                
+                const query = `[out:json];
+                    (
+                        way["building"](${bbox});
+                        relation["building"](${bbox});
+                    );
+                    out geom;
+                    out tags;`;
+
+                try {
+                    const response = await fetch(`https://overpass-api.de/api/interpreter?data=${encodeURIComponent(query)}`);
+                    const data = await response.json();
+
+                    edificiLayer.clearLayers();
+                    
+                    data.elements.forEach(element => {
+                        if (element.type === 'way' && element.geometry) {
+                            const latlngs = element.geometry.map(coord => [coord.lat, coord.lon]);
+                            var statoEdificio = false;
+                            let colorePoligono ;
+                            if (statoEdificio) colorePoligono = 'yellow';
+                            else colorePoligono = 'green';
+                            
+                            // const colori = ['#FF0000', '#00FF00'];
+                            const polygon = L.polygon(latlngs, {
+                                fillColor: colorePoligono,
+                                color: colorePoligono,
+                                fillOpacity: 0.5
+                            }).addTo(edificiLayer);
+
+                            polygon.on('click', async function() {
+                                var buildingType = element.tags && element.tags.building ? element.tags.building : 'Sconosciuto';
+                                try {
+                                    await getAddress(latlngs[0][0], latlngs[0][1]);
+                                    var popupContent = `
+                                        <b>Coordinate:</b> ${latlngs[0][0]}, ${latlngs[0][1]}<br>
+                                        <b>Tipo edificio:</b> ${buildingType}<br>
+                                        <b>Indirizzo:</b> ${document.getElementById('addressInput').value}<br>
+                                        <b>Stato:</b> ${statoEdificio}<br>
+                                        <b>Codice Catastale:</b> nessuno
+                                    `;
+                                    polygon.bindPopup(popupContent).openPopup();
+                                } catch (error) {
+                                    console.error("Errore nel recupero dell'indirizzo:", error);
+                                    var popupContent = `
+                                        <b>Coordinate:</b> ${latlngs[0][0]}, ${latlngs[0][1]}<br>
+                                        <b>Tipo edificio:</b> ${buildingType}<br>
+                                        <b>Indirizzo:</b> Indirizzo non disponibile<br>
+                                        <b>Stato:</b> ${statoEdificio}<br>
+                                        <b>Codice Catastale:</b> nessuno
+                                    `;
+                                    polygon.bindPopup(popupContent).openPopup();
+                                }
+                            });
+                        }
+                    });
+                } catch (error) {
+                    console.error("Errore nel caricamento edifici:", error);
+                }
+            } else {
+                edificiLayer.clearLayers();
+            }
+        }
+        async function getAddress(lat, lng) {
+            console.log(typeof(lat));
+            console.log(typeof(lng));
+
+            try {
+                const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${lng}`);
+                const data = await response.json();
+
+                if (data.address) {
+                    document.getElementById('addressInput').value = data.display_name;
+                } else {
+                    document.getElementById('addressInput').value = "Indirizzo non trovato";
+                }
+            } catch (error) {
+                console.error("Errore nel geocoding inverso:", error);
+                document.getElementById('addressInput').value = "Errore nel geocoding inverso";
+            }
+        }
+
+        // Funzioni di gestione posizione
+        async function updatePosition(lat, lng) {
+            try {
+                const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}`);
+                const data = await response.json();
+                
+                document.getElementById('latInput').value = lat;
+                document.getElementById('lngInput').value = lng;
+                document.getElementById('addressInput').value = data.display_name || "Indirizzo non disponibile";
+                
+                if (currentMarker) map.removeLayer(currentMarker);
+                currentMarker = L.marker([lat, lng]).addTo(map);
+                
+            } catch (error) {
+                console.error("Errore di geocoding inverso:", error);
+            }
+        }
+
+        // Ricerca indirizzo
+        async function searchAddress() {
+            const address = document.getElementById('address').value;
+            if (!address) return;
+
+            try {
+                const response = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(address)}`);
+                const data = await response.json();
+                
+                if (data.length === 0) {
+                    alert("Indirizzo non trovato");
+                    return;
+                }
+
+                const { lat, lon: lng } = data[0];
+                map.setView([lat, lng], 18);
+                updatePosition(lat, lng);
+                
+            } catch (error) {
+                console.error("Errore di ricerca:", error);
+            }
+        }
+
+        // Event listeners
+        document.getElementById('searchBtn').addEventListener('click', searchAddress);
+        document.getElementById('address').addEventListener('keypress', (e) => {
+            if (e.key === 'Enter') searchAddress();
+        });
+
+        map.on('click', (e) => {
+            const { lat, lng } = e.latlng;
+            updatePosition(lat, lng);
+        });
+
+        map.on('moveend', caricaEdifici);
+        map.on('zoomend', caricaEdifici);
+        caricaEdifici();
+    </script>
+
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.8.1/dist/js/bootstrap-italia.bundle.min.js"></script>
+
+    <!-- Includi lo script di ElevenLabs -->
+    <script src="https://elevenlabs.io/convai-widget/index.js" async type="text/javascript"></script>
+
+    <!-- Widget ElevenLabs ConvAI -->
+    <div id="ai-widget-container" style="position: fixed; bottom: 20px; right: 20px;">
+        <elevenlabs-convai agent-id="2MJWbkNuIGTHNI71hKfL"></elevenlabs-convai>
+    </div>
+
+    <footer id="footer" class="it-footer bg-black" role="contentinfo">
+        <div class="it-footer-main py-3">
+            <div class="container">
+                <section class="py-4">
+                    <div class="row">
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Esplora SINFI</h2>
+                                <ul id="footer-menu-col-1" class="link-list">
+                                    <li id="menu-item-sinfi-1" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/che-cose/">Cos'è SINFI</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-2" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Infrastrutture Registrate</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-3" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/riferimenti-normativi/">Normative di Riferimento</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-4" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Open Data SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Aiuto e Supporto</h2>
+                                <ul id="footer-menu-col-2" class="link-list">
+                                    <li id="menu-item-aiuto-1" class="menu-item">
+                                        <a class="list-item" href="./instructions.html">Istruzioni</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-2" class="menu-item">
+                                        <a class="list-item" href="./faq.html">FAQ - Domande Frequenti</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-3" class="menu-item">
+                                        <a class="list-item" href="./techsup.html">Segnalazioni e Supporto Tecnico</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <!-- Colonna "Community" con i loghi dei social -->
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Community</h2>
+                                <div class="social-icons">
+                                    <a href="https://www.linkedin.com" target="_blank" class="me-3"><i class="fab fa-linkedin"></i></a>
+                                    <a href="https://www.youtube.com" target="_blank" class="me-3"><i class="fab fa-youtube"></i></a>
+                                    <a href="https://www.facebook.com" target="_blank" class="me-3"><i class="fab fa-facebook"></i></a>
+                                    <a href="https://www.instagram.com" target="_blank" class="me-3"><i class="fab fa-instagram"></i></a>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">SINFI</h2>
+                                <ul id="footer-menu-col-4" class="link-list">
+                                    <li id="menu-item-377" class="menu-item">
+                                        <a target="_blank" href="https://sinfi.it/portal/">Vai al sito ufficiale SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+                </section>
+            </div>
+        </div>
+        <div class="it-footer-small-prints clearfix">
+            <div class="container">
+                <nav class="menu-footer-menu-ita-container" aria-label="link utili">
+                    <ul id="menu-footer-menu-ita" class="it-footer-small-prints-list list-inline mb-0 d-flex flex-column flex-md-row">
+                        <li id="menu-item-413" class="menu-item list-inline-item"><a href="/media-policy/">Media Policy</a></li>
+                        <li id="menu-item-453" class="menu-item list-inline-item"><a href="/note-legali/">Privacy Policy &amp; Note Legali</a></li>
+                        <li id="menu-item-1310" class="menu-item list-inline-item"><a target="_blank" href="https://form.agid.gov.it/view/9df3de50-7a42-11ef-8989-9dcab5eaa914">Dichiarazione di accessibilità</a></li>
+                        <li id="menu-item-411" class="menu-item list-inline-item"><a href="/mappa-del-sito/">Mappa del sito</a></li>
+                        <li id="menu-item-1277" class="menu-item list-inline-item"><a href="/open-data-spid/">Open Data SPID</a></li>
+                    </ul>
+                </nav>
+            </div>
+        </div>
+    </footer>
+</body>
+</html>

+ 278 - 0
Backend/templates/techsup.html

@@ -0,0 +1,278 @@
+<!DOCTYPE html>
+<html lang="it">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Segnalazioni e Supporto Tecnico</title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.13.4/dist/css/bootstrap-italia.min.css" rel="stylesheet">
+    <!-- Aggiungi Font Awesome CDN nel <head> -->
+    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
+    <style>
+        /* Stile per la riga blu scuro */
+        .top-bar {
+            background-color: #004080; /* Blu scuro */
+            color: white;
+            padding: 0.5rem 0;
+            text-align: left; /* Allineamento a sinistra */
+            font-size: 0.9rem;
+        }
+
+        /* Stile per l'header */
+        .header {
+            background-color: #0066CC; /* Blu chiaro */
+            color: white;
+            padding: 1rem 0;
+        }
+
+        /* Stile per il logo "PW" dentro un cerchio */
+        .logo {
+            font-family: 'Georgia', serif; /* Font diverso */
+            font-size: 1.5rem;
+            font-weight: bold;
+            display: inline-flex;
+            align-items: center;
+            justify-content: center;
+            width: 50px; /* Diametro del cerchio */
+            height: 50px; /* Diametro del cerchio */
+            background-color: white; /* Colore di sfondo del cerchio */
+            color: #0066CC; /* Colore del testo */
+            border-radius: 50%; /* Rende l'elemento un cerchio */
+            margin-right: 10px;
+        }
+
+        /* Stile per il titolo "Segnalazioni e Supporto Tecnico" */
+        .header-title {
+            color: white;
+            font-size: 1.5rem; /* Stessa grandezza di "Segnalazioni e Supporto Tecnico" */
+            font-weight: bold;
+            display: inline-block;
+            vertical-align: middle;
+        }
+
+        /* Stile per il contenuto principale */
+        .main-content {
+            background-color: #f8f9fa; /* Grigio chiaro */
+            padding: 2rem 0;
+        }
+
+        /* Stile per il banner di conferma */
+        .banner-confirm {
+            display: none; /* Nascondi il banner inizialmente */
+            background-color: #28a745;
+            color: white;
+            padding: 1rem;
+            margin-top: 1rem;
+            border-radius: 4px;
+            text-align: center;
+            transition: opacity 0.5s ease-in-out; /* Transizione per la dissolvenza */
+            opacity: 1; /* Inizialmente visibile */
+        }
+
+        /* Aggiungi margine ai lati del contenitore principale */
+        .container {
+            padding-left: 2rem;
+            padding-right: 2rem;
+        }
+
+        /* Aggiungi margine ai lati del footer */
+        .it-footer-main .container {
+            padding-left: 2rem;
+            padding-right: 2rem;
+        }
+    </style>
+         <style>
+            /* Stile per i link con sottolineatura solo al passaggio del mouse */
+            .link-underline-hover {
+                text-decoration: none; /* Rimuove la sottolineatura di base */
+            }
+            .link-underline-hover:hover {
+                text-decoration: underline; /* Aggiunge la sottolineatura solo al passaggio del mouse */
+            }
+        </style>
+</head>
+<body>
+    <!-- Riga blu scuro con scritto "Project Work" allineata a sinistra -->
+    <div class="top-bar">
+        <div class="container">
+            Project Work
+        </div>
+    </div>
+
+<!-- Header -->
+<header class="header">
+    <div class="container">
+        <div class="row align-items-center">
+            <div class="col d-flex">
+                <!-- Logo "PW" dentro un cerchio, ora cliccabile -->
+                <a href="./mappa_logout.html" class="logo-link">
+                    <div class="logo">PW</div>
+                </a>
+                <h1 class="header-title">Segnalazioni e Supporto Tecnico</h1> <!-- Titolo "Mappa" con la stessa grandezza -->
+            </div>
+            <div class="col-auto d-flex align-items-center">
+                <a href="./ADMIN.html" class="text-white me-3 link-underline-hover">Gestione Dati Immobiliari</a>
+                <a href="./TFO.html" class="text-white me-3 link-underline-hover">TFO</a>
+                <a href="./buildings.html" class="text-white me-3 link-underline-hover">Registrazione degli Edifici</a>
+                <a href="./mappa_login.html" class="btn btn-light">Logout</a>
+            </div>
+        </div>
+    </div>
+</header>
+
+    <!-- Sezione principale -->
+    <section class="it-card-wrapper mt-5 main-content">
+        <div class="container">
+            <div class="it-card">
+                <div class="it-card-header">
+                    <h5 class="it-card-title">Segnalazioni e Supporto Tecnico</h5>
+                </div>
+                <div class="it-card-body">
+                    <!-- Descrizione della pagina -->
+                    <p>
+                        Utilizza questa pagina per segnalare problemi tecnici o richiedere supporto. Compila il modulo sottostante con i dettagli del problema e ti risponderemo via mail entro <strong>48 ore</strong>.
+                        Nel frattempo ti consigliamo di consultare la sezione inerente alle <strong> Domande Frequenti (FAQ)</strong> per chiarire eventuali dubbi.
+                    </p>
+
+                    <!-- Form di segnalazione -->
+                    <form id="segnalazioneForm">
+                        <div class="mb-3">
+                            <label for="nome" class="form-label">Nome</label>
+                            <input type="text" class="form-control" id="nome" required>
+                        </div>
+                        <div class="mb-3">
+                            <label for="cognome" class="form-label">Cognome</label>
+                            <input type="text" class="form-control" id="cognome" required>
+                        </div>
+                        <div class="mb-3">
+                            <label for="email" class="form-label">Email</label>
+                            <input type="email" class="form-control" id="email" required>
+                        </div>
+                        <div class="mb-3">
+                            <label for="problema" class="form-label">Descrizione del problema</label>
+                            <textarea class="form-control" id="problema" rows="5" required></textarea>
+                        </div>
+                        <button type="submit" class="btn btn-primary">Invia Segnalazione</button>
+                    </form>
+
+                    <!-- Banner di conferma -->
+                    <div id="bannerConfirm" class="banner-confirm mt-3">
+                        Grazie per la tua segnalazione! Riceverai una risposta entro 48 ore.
+                    </div>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- Widget ElevenLabs ConvAI -->
+    <div id="ai-widget-container" style="position: fixed; bottom: 20px; right: 20px;">
+        <elevenlabs-convai agent-id="2MJWbkNuIGTHNI71hKfL"></elevenlabs-convai>
+    </div>
+    <!-- Footer -->
+    <footer id="footer" class="it-footer bg-black" role="contentinfo">
+        <div class="it-footer-main py-3">
+            <div class="container">
+                <section class="py-4">
+                    <div class="row">
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Esplora SINFI</h2>
+                                <ul id="footer-menu-col-1" class="link-list">
+                                    <li id="menu-item-sinfi-1" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/che-cose/">Cos'è SINFI</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-2" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Infrastrutture Registrate</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-3" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/riferimenti-normativi/">Normative di Riferimento</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-4" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Open Data SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Aiuto e Supporto</h2>
+                                <ul id="footer-menu-col-2" class="link-list">
+                                    <li id="menu-item-aiuto-1" class="menu-item">
+                                        <a class="list-item" href="./instructions.html">Istruzioni</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-2" class="menu-item">
+                                        <a class="list-item" href="./faq.html">FAQ - Domande Frequenti</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-3" class="menu-item">
+                                        <a class="list-item" href="./techsup.html">Segnalazioni e Supporto Tecnico</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <!-- Colonna "Community" con i loghi dei social -->
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Community</h2>
+                                <div class="social-icons">
+                                    <a href="https://www.linkedin.com" target="_blank" class="me-3"><i class="fab fa-linkedin"></i></a>
+                                    <a href="https://www.youtube.com" target="_blank" class="me-3"><i class="fab fa-youtube"></i></a>
+                                    <a href="https://www.facebook.com" target="_blank" class="me-3"><i class="fab fa-facebook"></i></a>
+                                    <a href="https://www.instagram.com" target="_blank" class="me-3"><i class="fab fa-instagram"></i></a>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">SINFI</h2>
+                                <ul id="footer-menu-col-4" class="link-list">
+                                    <li id="menu-item-377" class="menu-item">
+                                        <a target="_blank" href="https://sinfi.it/portal/">Vai al sito ufficiale SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+                </section>
+            </div>
+        </div>
+        <div class="it-footer-small-prints clearfix">
+            <div class="container">
+                <nav class="menu-footer-menu-ita-container" aria-label="link utili">
+                    <ul id="menu-footer-menu-ita" class="it-footer-small-prints-list list-inline mb-0 d-flex flex-column flex-md-row">
+                        <li id="menu-item-413" class="menu-item list-inline-item"><a href="/media-policy/">Media Policy</a></li>
+                        <li id="menu-item-453" class="menu-item list-inline-item"><a href="/note-legali/">Privacy Policy &amp; Note Legali</a></li>
+                        <li id="menu-item-1310" class="menu-item list-inline-item"><a target="_blank" href="https://form.agid.gov.it/view/9df3de50-7a42-11ef-8989-9dcab5eaa914">Dichiarazione di accessibilità</a></li>
+                        <li id="menu-item-411" class="menu-item list-inline-item"><a href="/mappa-del-sito/">Mappa del sito</a></li>
+                        <li id="menu-item-1277" class="menu-item list-inline-item"><a href="/open-data-spid/">Open Data SPID</a></li>
+                    </ul>
+                </nav>
+            </div>
+        </div>
+    </footer>
+
+    <!-- Includi il file JavaScript di Bootstrap -->
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+    <script>
+        // Gestione del form
+        document.getElementById('segnalazioneForm').addEventListener('submit', function (event) {
+            event.preventDefault(); // Impedisce l'invio del form
+
+            // Mostra il banner di conferma
+            const banner = document.getElementById('bannerConfirm');
+            banner.style.display = 'block';
+            banner.style.opacity = '1';
+
+            // Nascondi il banner dopo 5 secondi con effetto di dissolvenza
+            setTimeout(() => {
+                banner.style.opacity = '0'; // Inizia la dissolvenza
+                setTimeout(() => {
+                    banner.style.display = 'none'; // Nascondi dopo la dissolvenza
+                }, 500); // Tempo della dissolvenza (deve corrispondere alla durata della transizione CSS)
+            }, 5000); // Tempo prima di iniziare la dissolvenza
+
+            // Resetta il form (opzionale)
+            document.getElementById('segnalazioneForm').reset();
+        });
+    </script>
+    <!-- Includi lo script di ElevenLabs -->
+    <script src="https://elevenlabs.io/convai-widget/index.js" async type="text/javascript"></script>
+</body>
+</html>

+ 578 - 0
Backend/templates/visualizza_pratiche.html

@@ -0,0 +1,578 @@
+<!DOCTYPE html>
+<html lang="it">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Gestione Dati Immobiliari</title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap-italia@2.13.4/dist/css/bootstrap-italia.min.css"
+        rel="stylesheet">
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
+    <style>
+        /* Stile per la riga blu scuro */
+        .top-bar {
+            background-color: #004080;
+            /* Blu scuro */
+            color: white;
+            padding: 0.5rem 0;
+            text-align: left;
+            /* Allineamento a sinistra */
+            font-size: 0.9rem;
+        }
+
+
+        /* Stile per l'header */
+        .header {
+            background-color: #0066CC;
+            /* Blu chiaro */
+            color: white;
+            padding: 1rem 0;
+        }
+
+        /* Stile per il logo "PW" dentro un cerchio */
+        .logo {
+            font-family: 'Georgia', serif;
+            /* Font diverso */
+            font-size: 1.5rem;
+            font-weight: bold;
+            display: inline-flex;
+            align-items: center;
+            justify-content: center;
+            width: 50px;
+            /* Diametro del cerchio */
+            height: 50px;
+            /* Diametro del cerchio */
+            background-color: white;
+            /* Colore di sfondo del cerchio */
+            color: #0066CC;
+            /* Colore del testo */
+            border-radius: 50%;
+            /* Rende l'elemento un cerchio */
+            margin-right: 10px;
+        }
+
+        /* Stile per il titolo "Segnalazioni e Supporto Tecnico" */
+        .header-title {
+            color: white;
+            font-size: 1.5rem;
+            /* Stessa grandezza di "Segnalazioni e Supporto Tecnico" */
+            font-weight: bold;
+            display: inline-block;
+            vertical-align: middle;
+        }
+
+        /* Stile per il contenuto principale */
+        .main-content {
+            background-color: #f8f9fa;
+            /* Grigio chiaro */
+            padding: 2rem 0;
+        }
+
+        /* Stile per il banner di conferma */
+        .banner-confirm {
+            display: none;
+            /* Nascondi il banner inizialmente */
+            background-color: #28a745;
+            color: white;
+            padding: 1rem;
+            margin-top: 1rem;
+            border-radius: 4px;
+            text-align: center;
+            transition: opacity 0.5s ease-in-out;
+            /* Transizione per la dissolvenza */
+            opacity: 1;
+            /* Inizialmente visibile */
+        }
+
+        /* Aggiungi margine ai lati del contenitore principale */
+        .container {
+            padding-left: 2rem;
+            padding-right: 2rem;
+        }
+        .it-footer-main {
+            background-color: #004D99;
+            padding-left: 2rem;
+            padding-right: 2rem;
+        }
+        /* Aggiungi margine ai lati del footer */
+        .it-footer-main .container {
+            background-color: #004D99;
+            padding-left: 2rem;
+            padding-right: 2rem;
+        }
+
+        /* Stile per i link con sottolineatura solo al passaggio del mouse */
+        .link-underline-hover {
+            text-decoration: none;
+            /* Rimuove la sottolineatura di base */
+        }
+
+        .link-underline-hover:hover {
+            text-decoration: underline;
+            /* Aggiunge la sottolineatura solo al passaggio del mouse */
+        }
+
+        /* Stile per il footer */
+        .data-table {
+            margin-top: 20px;
+        }
+
+        .filter-section {
+            margin-bottom: 20px;
+        }
+
+        .pagination {
+            margin-top: 20px;
+        }
+        .form-modifica *  {
+            font-size: 12px;
+        }
+    </style>
+</head>
+
+<body>
+    <!-- Riga blu scuro con scritto "Project Work" allineata a sinistra -->
+    <div class="top-bar">
+        <div class="container">
+            Project Work
+        </div>
+    </div>
+    <!-- Header  è troppo stretto segue la linea della pagina  -->
+    <header class="header">
+        <div class="container">
+            <div class="row align-items-center">
+                <div class="col d-flex">
+                    <!-- Logo "PW" dentro un cerchio, ora cliccabile -->
+                    <a href="./mappa_logout.html" class="logo-link">
+                        <div class="logo">PW</div>
+                    </a>
+                    <h1 class="header-title">Gestione Dati Immobiliari</h1>
+                    <!-- Titolo "Mappa" con la stessa grandezza -->
+                </div>
+                <div class="col-auto d-flex align-items-center">
+                    <a href="./ADMIN.html" class="text-white me-3 link-underline-hover">Gestione Dati Immobiliari</a>
+                    <a href="./TFO.html" class="text-white me-3 link-underline-hover">TFO</a>
+                    <a href="./buildings.html" class="text-white me-3 link-underline-hover">Registrazione degli Edifici</a>
+                    <a href="./mappa_login.html" class="btn btn-light">Logout</a>
+                </div>
+            </div>
+        </div>
+    </header>
+    <div class="container mt-4">
+        <div class="filter-section">
+            <div class="row mt-3 mb-3">
+                <!-- Filtro per codice utente (solo per amministratore) -->
+                <div class="col-md-4 flex-column gap-4" id="userFilterSection" style="display: none;">
+                    <label for="userFilter">Filtra per Codice Utente</label>
+                    <input type="text" class="form-control" id="userFilter" placeholder="Inserisci codice utente">
+                </div>
+                <!-- Filtro per indirizzo -->
+                <div class="col-md-4 d-flex flex-column gap-4">
+                    <label for="addressFilter">Filtra per Indirizzo</label>
+                    <input type="text" class="form-control" id="addressFilter" placeholder="Inserisci indirizzo">
+                </div>
+                <!-- Filtro per data -->
+                <div class="col-md-4 d-flex flex-column gap-4">
+                    <label for="dateFilter">Filtra per Data</label>
+                    <input type="date" class="form-control" id="dateFilter">
+                </div>
+            </div>
+            <div class="container mt-4">
+                <div class="filter-section">
+                    <div class="row mt-3 mb-3">
+                        </div>
+                    <button class="btn btn-primary" onclick="filtraDati()">Applica Filtri</button>
+                    <button class="btn btn-secondary" onclick="azzeraFiltri()">Azzera Filtri</button> </div>
+            
+                </div>
+        </div>
+
+        <table class="table data-table">
+            <thead>
+                <tr>
+                    <th>ID Utente</th>
+                    <th>Indirizzo</th>
+                    <th>Latitudine</th>
+                    <th>Longitudine</th>
+                    <th>Codice Catastale</th>
+                    <th>Data Predisposizione</th>
+                    <th>Azioni</th>
+                </tr>
+            </thead>
+            <tbody id="dataTableBody">
+                <!-- Dati verranno caricati qui dinamicamente -->
+            </tbody>
+        </table>
+
+        <!-- Paginazione -->
+        <nav aria-label="Paginazione">
+            <ul class="pagination" id="pagination">
+                <!-- Pulsanti di paginazione verranno aggiunti qui dinamicamente -->
+            </ul>
+        </nav>
+    </div>
+    <!-- Widget ElevenLabs ConvAI -->
+    <div id="ai-widget-container" style="position: fixed; bottom: 20px; right: 20px;">
+        <elevenlabs-convai agent-id="GlBWa9xJ6GdD7bAve6Yq"></elevenlabs-convai>
+    </div>
+    <!-- Footer -->
+    <footer id="footer" class="it-footer bg-black" role="contentinfo">
+        <div class="it-footer-main py-3">
+            <div class="container">
+                <section class="py-4">
+                    <div class="row">
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Esplora SINFI</h2>
+                                <ul id="footer-menu-col-1" class="link-list">
+                                    <li id="menu-item-sinfi-1" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/portal/sinfi-menu/che-cose/">Cos'è
+                                            SINFI</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-2" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Infrastrutture Registrate</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-3" class="menu-item">
+                                        <a class="list-item"
+                                            href="https://sinfi.it/portal/sinfi-menu/riferimenti-normativi/">Normative
+                                            di Riferimento</a>
+                                    </li>
+                                    <li id="menu-item-sinfi-4" class="menu-item">
+                                        <a class="list-item" href="https://sinfi.it/realms/master/protocol/openid-connect/auth?client_id=sinfi_user_service&response_type=code&redirect_uri=https://sinfi.it/sinfi_gateway/labs_keycloak/post_login/&scope=email&state=">Open Data SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Aiuto e Supporto</h2>
+                                <ul id="footer-menu-col-2" class="link-list">
+                                    <li id="menu-item-aiuto-1" class="menu-item">
+                                        <a class="list-item" href="./instructions.html">Istruzioni</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-2" class="menu-item">
+                                        <a class="list-item" href="./faq.html">FAQ - Domande Frequenti</a>
+                                    </li>
+                                    <li id="menu-item-aiuto-3" class="menu-item">
+                                        <a class="list-item" href="./techsup.html">Segnalazioni e Supporto Tecnico</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <!-- Colonna "Community" con i loghi dei social -->
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">Community</h2>
+                                <div class="social-icons">
+                                    <a href="https://www.linkedin.com" target="_blank" class="me-3"><i
+                                            class="fab fa-linkedin"></i></a>
+                                    <a href="https://www.youtube.com" target="_blank" class="me-3"><i
+                                            class="fab fa-youtube"></i></a>
+                                    <a href="https://www.facebook.com" target="_blank" class="me-3"><i
+                                            class="fab fa-facebook"></i></a>
+                                    <a href="https://www.instagram.com" target="_blank" class="me-3"><i
+                                            class="fab fa-instagram"></i></a>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-lg-3 col-md-3 col-sm-6 pb-2">
+                            <div class="link-list-wrapper">
+                                <h2 class="h5">SINFI</h2>
+                                <ul id="footer-menu-col-4" class="link-list">
+                                    <li id="menu-item-377" class="menu-item">
+                                        <a target="_blank" href="https://sinfi.it/portal/">Vai al sito ufficiale
+                                            SINFI</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+                </section>
+            </div>
+        </div>
+        <div class="it-footer-small-prints clearfix">
+            <div class="container">
+                <nav class="menu-footer-menu-ita-container" aria-label="link utili">
+                    <ul id="menu-footer-menu-ita"
+                        class="it-footer-small-prints-list list-inline mb-0 d-flex flex-column flex-md-row">
+                        <li id="menu-item-413" class="menu-item list-inline-item"><a href="/media-policy/">Media
+                                Policy</a></li>
+                        <li id="menu-item-453" class="menu-item list-inline-item"><a href="/note-legali/">Privacy Policy
+                                &amp; Note Legali</a></li>
+                        <li id="menu-item-1310" class="menu-item list-inline-item"><a target="_blank"
+                                href="https://form.agid.gov.it/view/9df3de50-7a42-11ef-8989-9dcab5eaa914">Dichiarazione
+                                di accessibilità</a></li>
+                        <li id="menu-item-411" class="menu-item list-inline-item"><a href="/mappa-del-sito/">Mappa del
+                                sito</a></li>
+                        <li id="menu-item-1277" class="menu-item list-inline-item"><a href="/open-data-spid/">Open Data
+                                SPID</a></li>
+                    </ul>
+                </nav>
+            </div>
+        </div>
+    </footer>
+
+
+
+    <script>
+        // Dati di esempio (simulazione di un database)
+        const dati = [
+            { idUtente: 1, indirizzo: "Via Roma 1", latitudine: "41.9028", longitudine: "12.4964", codiceCatastale: "A123", dataPredisposizione: "2023-10-01" },
+            { idUtente: 2, indirizzo: "Via Milano 2", latitudine: "45.4642", longitudine: "9.1900", codiceCatastale: "B456", dataPredisposizione: "2023-10-02" },
+            { idUtente: 1, indirizzo: "Via Napoli 3", latitudine: "40.8522", longitudine: "14.2681", codiceCatastale: "C789", dataPredisposizione: "2023-10-03" },
+            { idUtente: 3, indirizzo: "Via Torino 4", latitudine: "45.0703", longitudine: "7.6869", codiceCatastale: "D012", dataPredisposizione: "2023-10-04" },
+            { idUtente: 2, indirizzo: "Via Firenze 5", latitudine: "43.7696", longitudine: "11.2558", codiceCatastale: "E345", dataPredisposizione: "2023-10-05" },
+            { idUtente: 1, indirizzo: "Via Venezia 6", latitudine: "45.4408", longitudine: "12.3155", codiceCatastale: "F678", dataPredisposizione: "2023-10-06" },
+        ];
+
+        // Simulazione del ruolo utente (1 = operatore, 2 = amministratore)
+        const ruoloUtente = 2; // Cambia questo valore per testare
+        const idUtenteCorrente = 1; // ID dell'utente corrente (solo per operatori)
+
+        // Mostra/nascondi il filtro per codice utente in base al ruolo
+        if (ruoloUtente === 2) {
+            document.getElementById('userFilterSection').style.display = 'flex';
+        }
+
+        // Variabili per la paginazione
+        const righePerPagina = 3; // Numero di righe da visualizzare per pagina
+        let paginaCorrente = 1;
+
+        // Funzione per filtrare i dati
+        function filtraDati() {
+            const userFilter = document.getElementById('userFilter').value.toLowerCase();
+            const addressFilter = document.getElementById('addressFilter').value.toLowerCase();
+            const dateFilter = document.getElementById('dateFilter').value;
+
+            const datiFiltrati = dati.filter(item => {
+                const matchUser = ruoloUtente === 2 ? item.idUtente.toString().includes(userFilter) : item.idUtente === idUtenteCorrente;
+                const matchAddress = item.indirizzo.toLowerCase().includes(addressFilter);
+                const matchDate = dateFilter ? item.dataPredisposizione === dateFilter : true;
+
+                return matchUser && matchAddress && matchDate;
+            });
+
+            caricaDatiInTabella(datiFiltrati);
+            aggiornaPaginazione(datiFiltrati);
+        }
+
+        // Funzione per caricare i dati nella tabella
+        function caricaDatiInTabella(dati) {
+            const tbody = document.getElementById('dataTableBody');
+            tbody.innerHTML = ''; // Svuota la tabella
+
+            const inizio = (paginaCorrente - 1) * righePerPagina;
+            const fine = inizio + righePerPagina;
+            const datiPagina = dati.slice(inizio, fine);
+
+            datiPagina.forEach(item => {
+                const row = `
+                    <tr>
+                        <td>${item.idUtente}</td>
+                        <td>${item.indirizzo}</td>
+                        <td>${item.latitudine}</td>
+                        <td>${item.longitudine}</td>
+                        <td>${item.codiceCatastale}</td>
+                        <td>${item.dataPredisposizione}</td>
+                        <td>
+                            <button class="btn btn-sm btn-primary" onclick="modificaDato(${item.idUtente})"><i class="fas fa-edit"></i></button>
+                            <button class="btn btn-sm btn-danger" onclick="cancellaDato(${item.idUtente})"><i class="fas fa-trash"></i></button>
+                        </td>
+                    </tr>
+                `;
+                tbody.innerHTML += row;
+            });
+        }
+
+        // Funzione per aggiornare la paginazione
+        function aggiornaPaginazione(dati) {
+            const pagination = document.getElementById('pagination');
+            pagination.innerHTML = ''; // Svuota la paginazione
+
+            const totalePagine = Math.ceil(dati.length / righePerPagina);
+
+            // Pulsante "Precedente"
+            pagination.innerHTML += `
+                <li class="page-item ${paginaCorrente === 1 ? 'disabled' : ''}">
+                    <a class="page-link" href="#" onclick="cambiaPagina(${paginaCorrente - 1})">Precedente</a>
+                </li>
+            `;
+
+            // Numeri di pagina
+            for (let i = 1; i <= totalePagine; i++) {
+                pagination.innerHTML += `
+                    <li class="page-item ${i === paginaCorrente ? 'active' : ''}">
+                        <a class="page-link" href="#" onclick="cambiaPagina(${i})">${i}</a>
+                    </li>
+                `;
+            }
+
+            // Pulsante "Successivo"
+            pagination.innerHTML += `
+                <li class="page-item ${paginaCorrente === totalePagine ? 'disabled' : ''}">
+                    <a class="page-link" href="#" onclick="cambiaPagina(${paginaCorrente + 1})">Successivo</a>
+                </li>
+            `;
+        }
+
+        // Funzione per cambiare pagina
+        function cambiaPagina(nuovaPagina) {
+            paginaCorrente = nuovaPagina;
+            filtraDati();
+        }
+
+        // Funzioni di esempio per modifica e cancellazione
+        function modificaDato(idUtente) {
+    const riga = document.querySelector(`tr[data-id="${idUtente}"]`);
+    if (!riga) return;
+
+    const celle = riga.cells;
+    const dati = {
+        idUtente: celle[0].textContent,
+        indirizzo: celle[1].textContent,
+        latitudine: celle[2].textContent,
+        longitudine: celle[3].textContent,
+        codiceCatastale: celle[4].textContent,
+        dataPredisposizione: celle[5].textContent,
+    };
+
+    const formModifica = `
+        <td colspan="6">
+            <form class="form-modifica d-flex">
+                <div class="row flex-nowrap">
+                    <div class="col-md-2 d-flex flex-column gap-1">
+                        <label for="modificaIdUtente">Id</label>
+                        <input type="text" class="form-control" id="modificaIdUtente" ${ruoloUtente === 2 ? '' : 'disabled'} value="${dati.idUtente}">
+                    </div>
+                    <div class="col-md-2 d-flex flex-column gap-1">
+                        <label for="modificaIndirizzo">Indirizzo</label>
+                        <input type="text" class="form-control" id="modificaIndirizzo" value="${dati.indirizzo}">
+                    </div>
+                    <div class="col-md-2 d-flex flex-column gap-1">
+                        <label for="modificaLatitudine">Latitudine</label>
+                        <input type="text" class="form-control" id="modificaLatitudine" value="${dati.latitudine}">
+                    </div>
+                    <div class="col-md-2 d-flex flex-column gap-1">
+                        <label for="modificaLongitudine">Longitudine</label>
+                        <input type="text" class="form-control" id="modificaLongitudine" value="${dati.longitudine}">
+                    </div>
+                    <div class="col-md-2 d-flex flex-column gap-1">
+                        <label for="modificaCodiceCatastale">Codice Catastale</label>
+                        <input type="text" class="form-control" id="modificaCodiceCatastale" value="${dati.codiceCatastale}">
+                    </div>
+                    <div class="col-md-2 d-flex flex-column gap-1">
+                        <label for="modificaData">Data Predisposizione</label>
+                        <input type="date" class="form-control" id="modificaData" value="${dati.dataPredisposizione}">
+                    </div>
+                    <div class="text-right col-md-1">
+                        <button type="button" class="btn btn-success btn-sm" onclick="confermaModifica(${idUtente})">Conferma</button>
+                    </div>
+                </div>
+            </form>
+        </td>
+    `;
+
+    riga.innerHTML = formModifica;
+}
+        // Funzione per confermare la modifica
+        function confermaModifica(idUtente) {
+    // Trova la riga della tabella corrispondente all'ID utente
+    const riga = document.querySelector(`tr[data-id="${idUtente}"]`);
+    if (!riga) return;
+
+    let NewidUtente = idUtente;
+    // Recupera i valori modificati dal form
+    if (ruoloUtente === 2) {
+        NewidUtente = document.getElementById('modificaIdUtente').value;
+    }
+
+    const indirizzo = document.getElementById('modificaIndirizzo').value;
+    const latitudine = document.getElementById('modificaLatitudine').value;
+    const longitudine = document.getElementById('modificaLongitudine').value;
+    const codiceCatastale = document.getElementById('modificaCodiceCatastale').value;
+    const dataPredisposizione = document.getElementById('modificaData').value;
+
+    // Aggiorna l'array `dati` con i nuovi valori
+    const indice = dati.findIndex(item => item.idUtente === idUtente);
+    if (indice !== -1) {
+        dati[indice] = {
+            idUtente: parseInt(NewidUtente),
+            indirizzo,
+            latitudine,
+            longitudine,
+            codiceCatastale,
+            dataPredisposizione
+        };
+    }
+
+    // Ricarica la tabella per riflettere le modifiche
+    filtraDati();
+}
+// Funzione per azzerare i filtri
+function azzeraFiltri() {
+    document.getElementById('userFilter').value = '';
+    document.getElementById('addressFilter').value = '';
+    document.getElementById('dateFilter').value = '';
+    paginaCorrente = 1; // Resetta la pagina corrente
+    filtraDati(); // Ricarica i dati senza filtri
+}
+function caricaDatiInTabella(dati) {
+    const tbody = document.getElementById('dataTableBody');
+    tbody.innerHTML = ''; // Svuota la tabella
+
+    const inizio = (paginaCorrente - 1) * righePerPagina;
+    const fine = inizio + righePerPagina;
+    const datiPagina = dati.slice(inizio, fine);
+
+    datiPagina.forEach(item => {
+        const row = `
+            <tr data-id="${item.idUtente}">
+                <td>${item.idUtente}</td>
+                <td>${item.indirizzo}</td>
+                <td>${item.latitudine}</td>
+                <td>${item.longitudine}</td>
+                <td>${item.codiceCatastale}</td>
+                <td>${item.dataPredisposizione}</td>
+                <td>
+                    <button class="btn btn-sm btn-primary" onclick="modificaDato(${item.idUtente})"><i class="fas fa-edit"></i></button>
+                    <button class="btn btn-sm btn-danger" onclick="cancellaDato(${item.idUtente})"><i class="fas fa-trash"></i></button>
+                </td>
+            </tr>
+        `;
+        tbody.innerHTML += row;
+    });
+}
+        // Funzione per cancellare un dato
+        function cancellaDato(idUtente) {
+            if (confirm("Sei sicuro di voler eliminare questo dato?")) {
+                // L'utente ha confermato l'eliminazione
+                // 1. Rimuovi la riga dalla tabella
+                const riga = document.querySelector(`tr[data-id="${idUtente}"]`);
+                if (riga) {
+                    riga.remove();
+                }
+
+                // 2. Aggiorna l'array 'dati' rimuovendo l'elemento corrispondente
+                const indice = dati.findIndex(item => item.idUtente === idUtente);
+                if (indice !== -1) {
+                    dati.splice(indice, 1);
+                }
+
+                // 3. Aggiorna la paginazione e la visualizzazione della tabella
+                aggiornaPaginazione(dati);
+                caricaDatiInTabella(dati);
+                alert(`Cancella dato per utente ${idUtente}`);
+            } else {
+                // L'utente ha annullato l'eliminazione
+                alert("Eliminazione annullata.");
+            }
+        }
+
+        // Carica i dati iniziali
+        filtraDati();
+    </script>
+    <!-- Includi lo script di ElevenLabs -->
+    <script src="https://elevenlabs.io/convai-widget/index.js" async type="text/javascript"></script>
+</body>
+
+</html>