Update all hooks (Projects, Tasks, Certificates), implement backend for Projects. HomePage on Mentors
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
// hooks/useMahasiswa.ts
|
||||
import { useState, useEffect } from 'react';
|
||||
import type { Mahasiswa } from '../types/project.types';
|
||||
import { getMahasiswa } from '../services/MahasiswaService';
|
||||
|
||||
export const useMahasiswa = () => {
|
||||
const [mahasiswa, setMahasiswa] = useState<Mahasiswa[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
getMahasiswa()
|
||||
.then(setMahasiswa)
|
||||
.catch(() => setError('Gagal memuat data mahasiswa.'))
|
||||
.finally(() => setLoading(false));
|
||||
}, []);
|
||||
|
||||
return { mahasiswa, loading, error };
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
// hooks/useNotifications.ts
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import type { Notification } from "../types/certificate.types";
|
||||
import {
|
||||
getNotifications,
|
||||
markAllNotificationsRead,
|
||||
markNotificationRead,
|
||||
} from "../services/NotificationService";
|
||||
|
||||
export const useNotifications = () => {
|
||||
const [notifications, setNotifications] = useState<Notification[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const refetch = useCallback(() => {
|
||||
setLoading(true);
|
||||
getNotifications()
|
||||
.then(setNotifications)
|
||||
.catch(() => setError("Gagal memuat notifikasi."))
|
||||
.finally(() => setLoading(false));
|
||||
}, []);
|
||||
|
||||
useEffect(() => { refetch(); }, [refetch]);
|
||||
|
||||
const markAllRead = async () => {
|
||||
try {
|
||||
await markAllNotificationsRead();
|
||||
setNotifications(prev => prev.map(n => ({ ...n, is_read: true })));
|
||||
} catch { setError("Gagal menandai semua notifikasi."); }
|
||||
};
|
||||
|
||||
const markOneRead = async (id: number) => {
|
||||
try {
|
||||
await markNotificationRead(id);
|
||||
setNotifications(prev =>
|
||||
prev.map(n => n.id === id ? { ...n, is_read: true } : n)
|
||||
);
|
||||
} catch { setError("Gagal menandai notifikasi."); }
|
||||
};
|
||||
|
||||
const unreadCount = notifications.filter(n => !n.is_read).length;
|
||||
|
||||
return { notifications, unreadCount, loading, error, refetch, markAllRead, markOneRead };
|
||||
};
|
||||
@@ -0,0 +1,138 @@
|
||||
// hooks/useCertificates.ts
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import type { Certificate, CertificateVerifyResult } from "../types/certificate.types";
|
||||
import {
|
||||
claimCertificate,
|
||||
getMyCertificates,
|
||||
getAllCertificates,
|
||||
getCertificateDetail,
|
||||
getCertificatesByProject,
|
||||
verifyCertificate,
|
||||
verifyCertificateByUuid,
|
||||
uploadCertificateTemplate,
|
||||
} from "../services/CertificateService";
|
||||
|
||||
// GET /certificate-api/my-certificates
|
||||
export const useMyCertificates = () => {
|
||||
const [certificates, setCertificates] = useState<Certificate[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
getMyCertificates()
|
||||
.then(setCertificates)
|
||||
.catch(() => setError("Gagal memuat sertifikat."))
|
||||
.finally(() => setLoading(false));
|
||||
}, []);
|
||||
|
||||
return { certificates, loading, error };
|
||||
};
|
||||
|
||||
// GET /certificate-api/all
|
||||
export const useAllCertificates = () => {
|
||||
const [certificates, setCertificates] = useState<Certificate[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
getAllCertificates()
|
||||
.then(setCertificates)
|
||||
.catch(() => setError("Gagal memuat semua sertifikat."))
|
||||
.finally(() => setLoading(false));
|
||||
}, []);
|
||||
|
||||
return { certificates, loading, error };
|
||||
};
|
||||
|
||||
// GET /certificate-api/detail/{id}
|
||||
export const useCertificateDetail = (id: number) => {
|
||||
const [certificate, setCertificate] = useState<Certificate | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!id) return;
|
||||
getCertificateDetail(id)
|
||||
.then(setCertificate)
|
||||
.catch(() => setError("Gagal memuat detail sertifikat."))
|
||||
.finally(() => setLoading(false));
|
||||
}, [id]);
|
||||
|
||||
return { certificate, loading, error };
|
||||
};
|
||||
|
||||
// GET /certificate-api/project/{id_project}
|
||||
export const useProjectCertificates = (id_project: number) => {
|
||||
const [certificates, setCertificates] = useState<Certificate[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!id_project) return;
|
||||
getCertificatesByProject(id_project)
|
||||
.then(setCertificates)
|
||||
.catch(() => setError("Gagal memuat sertifikat project."))
|
||||
.finally(() => setLoading(false));
|
||||
}, [id_project]);
|
||||
|
||||
return { certificates, loading, error };
|
||||
};
|
||||
|
||||
// GET /certificate-api/verify & verify-uuid (public, on-demand)
|
||||
export const useVerifyCertificate = () => {
|
||||
const [result, setResult] = useState<CertificateVerifyResult | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const verifyByNo = useCallback(async (certificate_no: string) => {
|
||||
setLoading(true); setError(null);
|
||||
try {
|
||||
const res = await verifyCertificate(certificate_no);
|
||||
setResult(res);
|
||||
return res;
|
||||
} catch { setError("Sertifikat tidak valid atau tidak ditemukan."); return null; }
|
||||
finally { setLoading(false); }
|
||||
}, []);
|
||||
|
||||
const verifyByUuid = useCallback(async (uuid: string) => {
|
||||
setLoading(true); setError(null);
|
||||
try {
|
||||
const res = await verifyCertificateByUuid(uuid);
|
||||
setResult(res);
|
||||
return res;
|
||||
} catch { setError("Sertifikat tidak valid atau tidak ditemukan."); return null; }
|
||||
finally { setLoading(false); }
|
||||
}, []);
|
||||
|
||||
return { result, loading, error, verifyByNo, verifyByUuid };
|
||||
};
|
||||
|
||||
// POST /certificate-api/claim
|
||||
export const useClaimCertificate = () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const claim = async (id_project: number) => {
|
||||
setLoading(true); setError(null);
|
||||
try { return await claimCertificate(id_project); }
|
||||
catch { setError("Gagal claim sertifikat."); return null; }
|
||||
finally { setLoading(false); }
|
||||
};
|
||||
|
||||
return { claim, loading, error };
|
||||
};
|
||||
|
||||
// POST /certificate-api/projects/{id_project}/template
|
||||
export const useUploadCertificateTemplate = () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const upload = async (id_project: number, file: File) => {
|
||||
setLoading(true); setError(null);
|
||||
try { return await uploadCertificateTemplate(id_project, file); }
|
||||
catch { setError("Gagal upload template."); return null; }
|
||||
finally { setLoading(false); }
|
||||
};
|
||||
|
||||
return { upload, loading, error };
|
||||
};
|
||||
@@ -20,7 +20,7 @@ export const useProjectTasks = (projectId: string) => {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const refetch = useCallback(() => {
|
||||
if (!projectId) return;
|
||||
setLoading(true);
|
||||
getProjectTasks(projectId)
|
||||
@@ -29,7 +29,9 @@ export const useProjectTasks = (projectId: string) => {
|
||||
.finally(() => setLoading(false));
|
||||
}, [projectId]);
|
||||
|
||||
return { tasks, loading, error };
|
||||
useEffect(() => { refetch(); }, [refetch]);
|
||||
|
||||
return { tasks, loading, error, refetch }; // tambah refetch
|
||||
};
|
||||
|
||||
// GET /task-api/tasks/{id}
|
||||
|
||||
Reference in New Issue
Block a user