Ajout du responsive dashboard
This commit is contained in:
parent
0cfd237f07
commit
ae94dc9339
@ -78,8 +78,8 @@ public class QueryDeleteObject {
|
|||||||
.put("id", row.getInteger("id"))
|
.put("id", row.getInteger("id"))
|
||||||
.put("object_id", row.getInteger("object_id"))
|
.put("object_id", row.getInteger("object_id"))
|
||||||
.put("requested_by", row.getInteger("requested_by"))
|
.put("requested_by", row.getInteger("requested_by"))
|
||||||
.put("requested_at", row.getLocalDateTime("requested_at").toString()); // si tu as un champ
|
.put("requested_at", row.getLocalDateTime("requested_at").toString());
|
||||||
// de type timestamp
|
|
||||||
jsonArray.add(json);
|
jsonArray.add(json);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -352,7 +352,7 @@ function AdminObjet() {
|
|||||||
{deleteRequests.map((request) => (
|
{deleteRequests.map((request) => (
|
||||||
<tr key={request.id}>
|
<tr key={request.id}>
|
||||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{request.id}</td>
|
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{request.id}</td>
|
||||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{request.object_id}</td>
|
<td className="px-6 py-4 whitespace-nowrap text-sm"><a className="text-indigo-600 hover:underline" href={`/objet?id=${request.object_id}`}>Objet n°{request.object_id}</a></td>
|
||||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{request.requested_by}</td>
|
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{request.requested_by}</td>
|
||||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{request.request_date}</td>
|
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{request.request_date}</td>
|
||||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 flex gap-2">
|
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 flex gap-2">
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState,useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import Sidebar from "./sidebar.jsx";
|
import Sidebar from "./sidebar.jsx";
|
||||||
import { RadioTower, ArrowRight, BadgePlus, Settings } from "lucide-react";
|
import { RadioTower, ArrowRight, BadgePlus, Settings } from "lucide-react";
|
||||||
import { API_BASE_URL } from "../../config.js";
|
import { API_BASE_URL } from "../../config.js";
|
||||||
@ -17,11 +17,7 @@ const exportCSV = () => {
|
|||||||
const csvContent =
|
const csvContent =
|
||||||
"\uFEFF" +
|
"\uFEFF" +
|
||||||
[headers, ...rows]
|
[headers, ...rows]
|
||||||
.map((row) =>
|
.map((row) => row.map((val) => `"${val.replace(/"/g, '""')}"`).join(","))
|
||||||
row
|
|
||||||
.map((val) => `"${val.replace(/"/g, '""')}"`)
|
|
||||||
.join(",")
|
|
||||||
)
|
|
||||||
.join("\n");
|
.join("\n");
|
||||||
|
|
||||||
const blob = new Blob([csvContent], {
|
const blob = new Blob([csvContent], {
|
||||||
@ -35,19 +31,18 @@ const exportCSV = () => {
|
|||||||
link.click();
|
link.click();
|
||||||
document.body.removeChild(link);
|
document.body.removeChild(link);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const initialWidgets = [
|
const initialWidgets = [
|
||||||
{ id: 1, type: "summary" },
|
{ id: 1, type: "summary" },
|
||||||
{ id: 2, type: "users" },
|
{ id: 2, type: "users" },
|
||||||
{ id: 3, type: "reporting" },
|
{ id: 3, type: "reporting" },
|
||||||
{ id: 4, type: "adminobjet" },
|
{ id: 4, type: "adminobjet" },
|
||||||
{ id: 5, type: "objects" },
|
{ id: 5, type: "objects" },
|
||||||
{ id: 6, type: "requestObject" }
|
{ id: 6, type: "requestObject" },
|
||||||
];
|
];
|
||||||
|
|
||||||
function Dashboard() {
|
function Dashboard() {
|
||||||
const [users, setUsers] = useState([])
|
const [users, setUsers] = useState([]);
|
||||||
|
|
||||||
const [logs, setLogs] = useState([
|
const [logs, setLogs] = useState([
|
||||||
{
|
{
|
||||||
@ -74,38 +69,10 @@ function Dashboard() {
|
|||||||
|
|
||||||
axios.get(`${API_BASE_URL}/demandeSuppression`).then((response) => {
|
axios.get(`${API_BASE_URL}/demandeSuppression`).then((response) => {
|
||||||
setRequestDeleteObject(response.data);
|
setRequestDeleteObject(response.data);
|
||||||
})
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const [adminObjects, setAdminObjects] = useState([
|
const [adminObjects, setAdminObjects] = useState([]);
|
||||||
{
|
|
||||||
id: 101,
|
|
||||||
nom: "Objet A",
|
|
||||||
description: "Description A",
|
|
||||||
type: "Type A",
|
|
||||||
localisation: "Localisation A",
|
|
||||||
proprietaire: "Propriétaire A",
|
|
||||||
status: "active",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 102,
|
|
||||||
nom: "Objet B",
|
|
||||||
description: "Description B",
|
|
||||||
type: "Type B",
|
|
||||||
localisation: "Localisation B",
|
|
||||||
proprietaire: "Propriétaire B",
|
|
||||||
status: "inactive",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 103,
|
|
||||||
nom: "Objet C",
|
|
||||||
description: "Description C",
|
|
||||||
type: "Type C",
|
|
||||||
localisation: "Localisation C",
|
|
||||||
proprietaire: "Propriétaire C",
|
|
||||||
status: "active",
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const [manageMode, setManageMode] = useState(false);
|
const [manageMode, setManageMode] = useState(false);
|
||||||
const [widgets, setWidgets] = useState(initialWidgets);
|
const [widgets, setWidgets] = useState(initialWidgets);
|
||||||
@ -119,7 +86,7 @@ function Dashboard() {
|
|||||||
const openAddWidgetModal = () => {
|
const openAddWidgetModal = () => {
|
||||||
setShowAddWidgetModal(true);
|
setShowAddWidgetModal(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleWidgetSelection = (widgetType) => {
|
const handleWidgetSelection = (widgetType) => {
|
||||||
const newWidget = { id: Date.now(), type: widgetType };
|
const newWidget = { id: Date.now(), type: widgetType };
|
||||||
setWidgets([...widgets, newWidget]);
|
setWidgets([...widgets, newWidget]);
|
||||||
@ -131,16 +98,22 @@ function Dashboard() {
|
|||||||
<Sidebar />
|
<Sidebar />
|
||||||
<main className="flex-1 bg-gradient-to-br from-blue-50 to-indigo-50 p-8 overflow-auto">
|
<main className="flex-1 bg-gradient-to-br from-blue-50 to-indigo-50 p-8 overflow-auto">
|
||||||
<div className="flex items-center justify-between mb-6">
|
<div className="flex items-center justify-between mb-6">
|
||||||
<h1 className="text-3xl font-bold">Dashboard</h1>
|
<h1 className="text-3xl font-bold truncate mr-2">Dashboard</h1>
|
||||||
<button
|
<button
|
||||||
onClick={() => setManageMode(!manageMode)}
|
onClick={() => setManageMode(!manageMode)}
|
||||||
className="flex items-center px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded-md"
|
className="flex items-center justify-center rounded-md hover:bg-gray-300"
|
||||||
|
aria-label={
|
||||||
|
manageMode ? "Terminer la gestion" : "Gérer les widgets"
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Settings className="mr-2" size={20} />
|
<span className="p-2 sm:bg-gray-200 sm:px-4 sm:py-2 sm:rounded-md flex items-center">
|
||||||
{manageMode ? "Terminer la gestion" : "Gérer les widgets"}
|
<Settings size={20} className="sm:mr-2" />
|
||||||
|
<span className="hidden sm:inline">
|
||||||
|
{manageMode ? "Terminer la gestion" : "Gérer les widgets"}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
{widgets.map((widget) => (
|
{widgets.map((widget) => (
|
||||||
@ -290,30 +263,37 @@ function Dashboard() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{widget.type ==="requestObject" && (
|
{widget.type === "requestObject" && (
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-xl font-semibold mb-4">Requête suppression objets</h2>
|
<h2 className="text-xl font-semibold mb-4">
|
||||||
|
Requête suppression objets
|
||||||
|
</h2>
|
||||||
|
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<p className="text-gray-700 mb-2">Générer des rapports d'utilisation :</p>
|
<p className="text-gray-700 mb-2">
|
||||||
<div className="flex gap-4">
|
Générer des rapports d'utilisation :
|
||||||
<button
|
</p>
|
||||||
className="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700"
|
<div className="flex gap-4">
|
||||||
onClick={() => exportCSV()}
|
<button
|
||||||
>
|
className="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700"
|
||||||
Requête objets
|
onClick={() => exportCSV()}
|
||||||
</button>
|
>
|
||||||
|
Requête objets
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
)}
|
)}
|
||||||
{widget.type === "reporting" && (
|
{widget.type === "reporting" && (
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-xl font-semibold mb-4">Rapports et Statistiques</h2>
|
<h2 className="text-xl font-semibold mb-4">
|
||||||
|
Rapports et Statistiques
|
||||||
|
</h2>
|
||||||
|
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<p className="text-gray-700 mb-2">Générer des rapports d'utilisation :</p>
|
<p className="text-gray-700 mb-2">
|
||||||
|
Générer des rapports d'utilisation :
|
||||||
|
</p>
|
||||||
<div className="flex gap-4">
|
<div className="flex gap-4">
|
||||||
<button
|
<button
|
||||||
className="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700"
|
className="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700"
|
||||||
@ -326,15 +306,25 @@ function Dashboard() {
|
|||||||
|
|
||||||
<div className="mt-4 space-y-2">
|
<div className="mt-4 space-y-2">
|
||||||
<div>
|
<div>
|
||||||
<h4 className="text-md font-medium">Consommation énergétique totale</h4>
|
<h4 className="text-md font-medium">
|
||||||
<p className="text-gray-600">1372 kWh cumulés (estimation)</p>
|
Consommation énergétique totale
|
||||||
|
</h4>
|
||||||
|
<p className="text-gray-600">
|
||||||
|
1372 kWh cumulés (estimation)
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4 className="text-md font-medium">Taux de connexion des utilisateurs</h4>
|
<h4 className="text-md font-medium">
|
||||||
<p className="text-gray-600">87% des utilisateurs actifs ce mois-ci</p>
|
Taux de connexion des utilisateurs
|
||||||
|
</h4>
|
||||||
|
<p className="text-gray-600">
|
||||||
|
87% des utilisateurs actifs ce mois-ci
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4 className="text-md font-medium">Services les plus utilisés</h4>
|
<h4 className="text-md font-medium">
|
||||||
|
Services les plus utilisés
|
||||||
|
</h4>
|
||||||
<ul className="list-disc ml-6 text-gray-600">
|
<ul className="list-disc ml-6 text-gray-600">
|
||||||
<li>Consultation des données météo</li>
|
<li>Consultation des données météo</li>
|
||||||
<li>Alertes et suivi de consommation</li>
|
<li>Alertes et suivi de consommation</li>
|
||||||
@ -393,16 +383,16 @@ function Dashboard() {
|
|||||||
<button
|
<button
|
||||||
onClick={() => handleWidgetSelection("reporting")}
|
onClick={() => handleWidgetSelection("reporting")}
|
||||||
className="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded-md text-left"
|
className="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded-md text-left"
|
||||||
>
|
>
|
||||||
Rapports et Statistiques
|
Rapports et Statistiques
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleWidgetSelection("requestObject")}
|
onClick={() => handleWidgetSelection("requestObject")}
|
||||||
className="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded-md text-left"
|
className="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded-md text-left"
|
||||||
>
|
>
|
||||||
Demande de suppression d'objets
|
Demande de suppression d'objets
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={() => setShowAddWidgetModal(false)}
|
onClick={() => setShowAddWidgetModal(false)}
|
||||||
className="mt-4 px-4 py-2 bg-red-500 text-white rounded-md w-full"
|
className="mt-4 px-4 py-2 bg-red-500 text-white rounded-md w-full"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user