This commit is contained in:
MOCH. PASHA ARDYAN PUTRA
2025-07-01 04:16:36 +00:00
parent b9b4e4c859
commit 8284d1a91f
3 changed files with 60 additions and 52 deletions

View File

@@ -8,10 +8,8 @@ const Dashboard = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const [isMenuOpen, setIsMenuOpen] = useState(false); const [isMenuOpen, setIsMenuOpen] = useState(false);
const menuRef = useRef(null); const menuRef = useRef(null);
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
const [selectedRole, setSelectedRole] = useState("officer");
const [successMessage, setSuccessMessage] = useState(""); const [successMessage, setSuccessMessage] = useState("");
const [errorMessage, setErrorMessage] = useState(""); const [errorMessage, setErrorMessage] = useState("");
const [user, setUser] = useState({}); const [user, setUser] = useState({});
@@ -67,7 +65,6 @@ const Dashboard = () => {
if (data[0].payload.officerPerformance) { if (data[0].payload.officerPerformance) {
setOfficerPerformanceData(data[0].payload.officerPerformance); setOfficerPerformanceData(data[0].payload.officerPerformance);
} }
} catch (error) { } catch (error) {
console.error("Token tidak valid:", error.message); console.error("Token tidak valid:", error.message);
localStorage.removeItem("token"); localStorage.removeItem("token");
@@ -102,7 +99,6 @@ const Dashboard = () => {
body: JSON.stringify({ body: JSON.stringify({
username, username,
password, password,
role: selectedRole,
}), }),
} }
); );
@@ -116,7 +112,6 @@ const Dashboard = () => {
setSuccessMessage("Officer berhasil ditambahkan"); setSuccessMessage("Officer berhasil ditambahkan");
setUsername(""); setUsername("");
setPassword(""); setPassword("");
setSelectedRole("officer");
setErrorMessage(""); setErrorMessage("");
// Pertimbangkan untuk memuat ulang data performa jika penambahan officer baru mempengaruhi grafik // Pertimbangkan untuk memuat ulang data performa jika penambahan officer baru mempengaruhi grafik
} catch (error) { } catch (error) {
@@ -144,7 +139,9 @@ const Dashboard = () => {
</div> </div>
<div className={styles.dropdownContainer} ref={menuRef}> <div className={styles.dropdownContainer} ref={menuRef}>
<span className={styles.userDisplayName}>{user.username || "Guest"}</span> <span className={styles.userDisplayName}>
{user.username || "Guest"}
</span>
<button <button
onClick={() => setIsMenuOpen(!isMenuOpen)} onClick={() => setIsMenuOpen(!isMenuOpen)}
className={styles.dropdownToggle} className={styles.dropdownToggle}
@@ -156,13 +153,19 @@ const Dashboard = () => {
{isMenuOpen && ( {isMenuOpen && (
<div className={styles.dropdownMenu}> <div className={styles.dropdownMenu}>
<button <button
onClick={() => { navigate("/profile"); setIsMenuOpen(false); }} /* Tutup menu setelah klik */ onClick={() => {
navigate("/profile");
setIsMenuOpen(false);
}} /* Tutup menu setelah klik */
className={styles.dropdownItem} className={styles.dropdownItem}
> >
Profile Profile
</button> </button>
<button <button
onClick={() => { handleLogout(); setIsMenuOpen(false); }} /* Tutup menu setelah klik */ onClick={() => {
handleLogout();
setIsMenuOpen(false);
}} /* Tutup menu setelah klik */
className={styles.dropdownItem} className={styles.dropdownItem}
> >
Logout Logout
@@ -191,7 +194,7 @@ const Dashboard = () => {
{/* Grid for Form (Admin) and Chart (Admin & Officer) */} {/* Grid for Form (Admin) and Chart (Admin & Officer) */}
<div className={styles.dashboardGrid}> <div className={styles.dashboardGrid}>
{user.role === "admin" && ( /* Render form hanya jika admin */ {user.role === "admin" /* Render form hanya jika admin */ && (
<div className={styles.formSection}> <div className={styles.formSection}>
<h2>Tambah Officer Baru</h2> <h2>Tambah Officer Baru</h2>
<form onSubmit={handleAddOfficer} className={styles.form}> <form onSubmit={handleAddOfficer} className={styles.form}>
@@ -213,23 +216,14 @@ const Dashboard = () => {
required required
/> />
</label> </label>
<label>
Role:
<select
value={selectedRole}
onChange={(e) => setSelectedRole(e.target.value)}
required
>
<option value="officer">Officer</option>
<option value="admin">Admin</option>
</select>
</label>
<button type="submit" className={styles.submitButton}> <button type="submit" className={styles.submitButton}>
Add Add
</button> </button>
</form> </form>
{successMessage && <p className={styles.success}>{successMessage}</p>} {successMessage && (
<p className={styles.success}>{successMessage}</p>
)}
{errorMessage && <p className={styles.error}>{errorMessage}</p>} {errorMessage && <p className={styles.error}>{errorMessage}</p>}
</div> </div>
)} )}
@@ -253,11 +247,13 @@ const Dashboard = () => {
</ResponsiveContainer> </ResponsiveContainer>
*/ */
<div className={styles.chartPlaceholder}> <div className={styles.chartPlaceholder}>
Grafik performa petugas akan ditampilkan di sini. Grafik performa petugas akan ditampilkan di sini. (Integrasikan
(Integrasikan library grafik seperti Recharts/Chart.js) library grafik seperti Recharts/Chart.js)
</div> </div>
) : ( ) : (
<p className={styles.warning}>Tidak ada data performa petugas untuk ditampilkan.</p> <p className={styles.warning}>
Tidak ada data performa petugas untuk ditampilkan.
</p>
)} )}
</div> </div>
</div> </div>

View File

@@ -49,7 +49,7 @@ const Login = () => {
<div className={styles.loginContainer}> <div className={styles.loginContainer}>
<div className={styles.loginBox}> <div className={styles.loginBox}>
<img src="/dermalounge.jpg" alt="Logo" className={styles.logo} /> <img src="/dermalounge.jpg" alt="Logo" className={styles.logo} />
<h1 className={styles.h1}>Dermalounge AI Admin Login</h1> <h1 className={styles.h1}>PSI Admin Login</h1>
<p className={styles.subtitle}> <p className={styles.subtitle}>
Silakan masuk untuk melanjutkan ke dashboard Silakan masuk untuk melanjutkan ke dashboard
</p> </p>

View File

@@ -1,73 +1,85 @@
.loginContainer { .loginContainer {
font-family: "Inter", sans-serif;
background-color: #f0f5ff;
display: flex; display: flex;
align-items: center;
justify-content: center; justify-content: center;
align-items: center;
height: 100vh; height: 100vh;
background: #f0f2f5; margin: 0;
width: 100vw;
} }
.loginBox { .loginBox {
background: #fff; background-color: #ffffff;
border-radius: 16px;
padding: 40px; padding: 40px;
border-radius: 10px; box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.05);
box-shadow: 0 4px 25px rgba(0, 0, 0, 0.1); width: 300px;
text-align: center; text-align: center;
width: 100%;
max-width: 400px;
} }
.logo { .logo {
width: 80px; width: 80px;
height: auto;
margin-bottom: 20px; margin-bottom: 20px;
} }
.h1 { .h1 {
font-size: 28px;
font-weight: 700;
margin-bottom: 10px; margin-bottom: 10px;
font-size: 24px; color: #d22129; /* 🔴 Warna merah PSI */
color: #333;
} }
.subtitle { .subtitle {
font-size: 14px; font-size: 14px;
color: #777; color: #6b7280;
margin-bottom: 30px; margin-bottom: 20px;
} }
.form { .form {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 15px;
text-align: left;
} }
.input { .input {
padding: 10px 15px; width: 100%;
margin-bottom: 15px; padding: 12px 15px;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 16px; font-size: 16px;
color: #1f2937;
background-color: #f8f9fa;
border: 1px solid #d1d5db;
border-radius: 8px;
box-sizing: border-box;
} }
.button { .button {
background-color: #337f83; background-color: #d22129; /* 🔴 Warna merah PSI */
color: white; color: #ffffff;
border: none; padding: 12px 24px;
padding: 12px; border-radius: 24px;
border-radius: 6px; font-size: 18px;
font-size: 16px; font-weight: 600;
cursor: pointer; cursor: pointer;
border: none;
width: 100%;
transition: background-color 0.3s;
} }
.button:hover { .button:hover {
background-color: #3c9a9f; background-color: #b71c1c; /* versi lebih gelap saat hover */
} }
.error { .error {
color: red; color: red;
margin-bottom: 10px; font-size: 14px;
text-align: left;
margin-top: -10px;
} }
.footer { .footer {
margin-top: 20px; margin-top: 30px;
font-size: 12px; font-size: 12px;
color: #aaa; color: #9ca3af;
} }