ok
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
// Dashboard.jsx
|
|
||||||
import React, { useState, useRef, useEffect } from "react";
|
import React, { useState, useRef, useEffect } from "react";
|
||||||
import styles from "./Dashboard.module.css";
|
import styles from "./Dashboard.module.css";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
@@ -25,6 +24,7 @@ const Dashboard = () => {
|
|||||||
const [totalFilesSentMonth, setTotalFilesSentMonth] = useState(0);
|
const [totalFilesSentMonth, setTotalFilesSentMonth] = useState(0);
|
||||||
const [totalFilesSentOverall, setTotalFilesSentOverall] = useState(0);
|
const [totalFilesSentOverall, setTotalFilesSentOverall] = useState(0);
|
||||||
const [officerPerformanceData, setOfficerPerformanceData] = useState([]);
|
const [officerPerformanceData, setOfficerPerformanceData] = useState([]);
|
||||||
|
const [officers, setOfficers] = useState([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const token = localStorage.getItem("token");
|
const token = localStorage.getItem("token");
|
||||||
@@ -55,20 +55,47 @@ const Dashboard = () => {
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
if (!response.ok || !data[0].payload.username) {
|
if (!response.ok || !data[0].payload.username) {
|
||||||
throw new Error("Unauthorized");
|
// throw new Error("Unauthorized");
|
||||||
|
console.log(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
setUser(data[0].payload);
|
setUser(data[0].payload);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Token tidak valid:", error.message);
|
console.error("Token tidak valid:", error.message);
|
||||||
localStorage.removeItem("token");
|
// localStorage.removeItem("token");
|
||||||
window.location.href = "/login";
|
// window.location.href = "/login";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
verifyTokenAndFetchData();
|
verifyTokenAndFetchData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchOfficers = async () => {
|
||||||
|
const token = localStorage.getItem("token");
|
||||||
|
try {
|
||||||
|
const response = await fetch(
|
||||||
|
"https://bot.kediritechnopark.com/webhook/list-user/psi",
|
||||||
|
{
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
setOfficers(data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Gagal memuat daftar officer:", error.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (user.role == "admin") {
|
||||||
|
fetchOfficers();
|
||||||
|
}
|
||||||
|
}, [user.role]);
|
||||||
|
|
||||||
const handleLogout = () => {
|
const handleLogout = () => {
|
||||||
localStorage.removeItem("token");
|
localStorage.removeItem("token");
|
||||||
localStorage.removeItem("user");
|
localStorage.removeItem("user");
|
||||||
@@ -121,6 +148,41 @@ const Dashboard = () => {
|
|||||||
document.addEventListener("mousedown", handleClickOutside);
|
document.addEventListener("mousedown", handleClickOutside);
|
||||||
return () => document.removeEventListener("mousedown", handleClickOutside);
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
||||||
}, []);
|
}, []);
|
||||||
|
const handleDeleteOfficer = async (id) => {
|
||||||
|
const confirmDelete = window.confirm(
|
||||||
|
"Apakah Anda yakin ingin menghapus petugas ini?"
|
||||||
|
);
|
||||||
|
if (!confirmDelete) return;
|
||||||
|
|
||||||
|
const token = localStorage.getItem("token");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(
|
||||||
|
`https://bot.kediritechnopark.com/webhook/psi/delete-officer`,
|
||||||
|
{
|
||||||
|
method: "DELETE",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
id,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (!response.ok || data.success === false) {
|
||||||
|
throw new Error(data.message || "Gagal menghapus officer");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hapus dari daftar tampilan
|
||||||
|
setOfficers((prev) => prev.filter((officer) => officer.id !== id));
|
||||||
|
} catch (error) {
|
||||||
|
alert("Gagal menghapus petugas: " + error.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.dashboardContainer}>
|
<div className={styles.dashboardContainer}>
|
||||||
@@ -187,7 +249,6 @@ const Dashboard = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.mainContent}>
|
<div className={styles.mainContent}>
|
||||||
{/* Summary Cards */}
|
|
||||||
<div className={styles.summaryCardsContainer}>
|
<div className={styles.summaryCardsContainer}>
|
||||||
<div className={styles.summaryCard}>
|
<div className={styles.summaryCard}>
|
||||||
<h3>Hari Ini</h3>
|
<h3>Hari Ini</h3>
|
||||||
@@ -203,10 +264,27 @@ const Dashboard = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Grid for Form (Admin) and Chart (Admin & Officer) */}
|
|
||||||
<div className={styles.dashboardGrid}>
|
<div className={styles.dashboardGrid}>
|
||||||
{user.role === "admin" && (
|
{user.role === "admin" && (
|
||||||
<div className={styles.formSection}>
|
<div className={styles.formSection}>
|
||||||
|
<h2>Daftar Petugas</h2>
|
||||||
|
<ul className={styles.officerList}>
|
||||||
|
{officers.map((officer) => (
|
||||||
|
<li key={officer.id} className={styles.officerItem}>
|
||||||
|
👤 <strong>{officer.username}</strong> —{" "}
|
||||||
|
<em>{officer.role}</em>
|
||||||
|
<button
|
||||||
|
onClick={() => handleDeleteOfficer(officer.id)}
|
||||||
|
className={styles.deleteButton}
|
||||||
|
title="Hapus Petugas"
|
||||||
|
>
|
||||||
|
❌
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<hr className={styles.separator} />
|
||||||
<h2>Tambah Petugas Baru</h2>
|
<h2>Tambah Petugas Baru</h2>
|
||||||
<form onSubmit={handleAddOfficer} className={styles.form}>
|
<form onSubmit={handleAddOfficer} className={styles.form}>
|
||||||
<label>
|
<label>
|
||||||
@@ -260,7 +338,6 @@ const Dashboard = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ✅ Tambahkan FileListComponent di sini */}
|
|
||||||
<FileListComponent
|
<FileListComponent
|
||||||
setTotalFilesSentToday={setTotalFilesSentToday}
|
setTotalFilesSentToday={setTotalFilesSentToday}
|
||||||
setTotalFilesSentMonth={setTotalFilesSentMonth}
|
setTotalFilesSentMonth={setTotalFilesSentMonth}
|
||||||
|
|||||||
@@ -508,6 +508,7 @@ const CameraCanvas = () => {
|
|||||||
border: "none",
|
border: "none",
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
}}
|
}}
|
||||||
|
onClick={() => navigate("/dashboard")}
|
||||||
>
|
>
|
||||||
<
|
<
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user