diff --git a/src/Pages/internify/mentor/CertificateDetail.tsx b/src/Pages/internify/mentor/CertificateDetail.tsx
new file mode 100644
index 0000000..475cd02
--- /dev/null
+++ b/src/Pages/internify/mentor/CertificateDetail.tsx
@@ -0,0 +1,361 @@
+// src/pages/mentor/CertificateDetail.tsx
+import { useState } from "react";
+import { useNavigate } from "react-router-dom";
+import {
+ CalendarDays,
+ CheckCircle2,
+ AlertCircle,
+ Eye,
+ ChevronLeft,
+ ChevronRight,
+ Sparkles,
+ ArrowLeft,
+} from "lucide-react";
+
+// ─── Types ────────────────────────────────────────────────────────────────────
+type InternStatus = "ELIGIBLE" | "INCOMPLETE";
+
+interface Intern {
+ id: number;
+ name: string;
+ role: string;
+ initials: string;
+ taskProgress: number;
+ taskTotal: number;
+ status: InternStatus;
+}
+
+// ─── Mock Data ────────────────────────────────────────────────────────────────
+const mockProject = {
+ title: "Edge Computing Framework",
+ period: "Dec 2023 — Mar 2024",
+ status: "COMPLETED" as const,
+ scope:
+ "Advanced research and implementation of low-latency computing nodes at the network edge, focusing on real-time data processing for autonomous systems.",
+ totalInterns: 21,
+ eligibleInterns: 18,
+};
+
+const mockInterns: Intern[] = [
+ { id: 1, name: "Marcus Rodriguez", role: "Software Engineer Intern", initials: "MR", taskProgress: 10, taskTotal: 10, status: "ELIGIBLE" },
+ { id: 2, name: "Priya Sharma", role: "Frontend Developer Intern", initials: "PS", taskProgress: 8, taskTotal: 10, status: "INCOMPLETE" },
+ { id: 3, name: "James Smith", role: "QA Engineering Intern", initials: "JS", taskProgress: 10, taskTotal: 10, status: "ELIGIBLE" },
+ { id: 4, name: "Nina Castillo", role: "Mobile Development Intern", initials: "NC", taskProgress: 9, taskTotal: 10, status: "ELIGIBLE" },
+ { id: 5, name: "Derek Lim", role: "DevOps & Cloud Intern", initials: "DL", taskProgress: 7, taskTotal: 10, status: "INCOMPLETE" },
+ { id: 6, name: "Alex Johnson", role: "Backend Engineering Intern", initials: "AJ", taskProgress: 10, taskTotal: 10, status: "ELIGIBLE" },
+];
+
+const TOTAL_ENTRIES = 1284;
+const PER_PAGE = 3;
+
+// ─── Avatar ───────────────────────────────────────────────────────────────────
+const avatarColors: Record
= {
+ MR: "bg-blue-100 text-blue-700",
+ PS: "bg-purple-100 text-purple-700",
+ JS: "bg-green-100 text-green-700",
+ NC: "bg-pink-100 text-pink-700",
+ DL: "bg-teal-100 text-teal-700",
+ AJ: "bg-orange-100 text-orange-700",
+};
+
+function Avatar({ initials }: { initials: string }) {
+ const color = avatarColors[initials] ?? "bg-gray-100 text-gray-500";
+ return (
+
+ {initials}
+
+ );
+}
+
+// ─── Progress Bar ─────────────────────────────────────────────────────────────
+function ProgressBar({ value, total }: { value: number; total: number }) {
+ const pct = Math.round((value / total) * 100);
+ const isComplete = value === total;
+ return (
+
+
+
+ {value}/{total}
+
+
+ );
+}
+
+// ─── Status Badge ─────────────────────────────────────────────────────────────
+function StatusBadge({ status }: { status: InternStatus }) {
+ const isEligible = status === "ELIGIBLE";
+ return (
+
+ {isEligible
+ ?
+ :
}
+ {status}
+
+ );
+}
+
+// ─── Main Page ────────────────────────────────────────────────────────────────
+export default function CertificateDetail() {
+ const navigate = useNavigate();
+
+ // Selected interns (checked)
+ const initialSelected = new Set(
+ mockInterns.filter((i) => i.status === "ELIGIBLE").map((i) => i.id)
+ );
+ const [selected, setSelected] = useState>(initialSelected);
+ const [page, setPage] = useState(1);
+
+ const totalPages = Math.ceil(mockInterns.length / PER_PAGE);
+ const paginated = mockInterns.slice((page - 1) * PER_PAGE, page * PER_PAGE);
+
+ const eligibleIds = mockInterns.filter((i) => i.status === "ELIGIBLE").map((i) => i.id);
+ const allEligibleSelected = eligibleIds.every((id) => selected.has(id));
+
+ const toggleSelectAll = () => {
+ if (allEligibleSelected) {
+ setSelected(new Set());
+ } else {
+ setSelected(new Set(eligibleIds));
+ }
+ };
+
+ const toggleOne = (id: number, status: InternStatus) => {
+ if (status === "INCOMPLETE") return; // tidak bisa dipilih
+ setSelected((prev) => {
+ const next = new Set(prev);
+ next.has(id) ? next.delete(id) : next.add(id);
+ return next;
+ });
+ };
+
+ return (
+
+ {/* Breadcrumb */}
+
navigate("/mentor/certificates/all")}
+ >
+ Certificates ›
+
+
+ {/* Page Header */}
+
+
Certificates
+
+ Administrate, issue, and track professional certifications for all interns.
+
+
+
+ {/* ── Two-column layout ── */}
+
+
+ {/* ── LEFT: Project Info ── */}
+
+ {/* Status badge */}
+
+
+ COMPLETED
+
+
+ {/* Title */}
+
+ {mockProject.title}
+
+
+ {/* Period */}
+
+
+ {mockProject.period}
+
+
+ {/* Project Scope */}
+
+
+ Project Scope
+
+
+ {mockProject.scope}
+
+
+
+ {/* Stats: Total & Eligible */}
+
+
+
{mockProject.totalInterns}
+
Total Interns
+
+
+
{mockProject.eligibleInterns}
+
Eligible
+
+
+
+
+ {/* ── RIGHT: Intern Roster ── */}
+
+
+ {/* Roster Header */}
+
+
+
Intern Roster
+
+ Confirm completion status before final certificate generation.
+
+
+ {/* Select All button */}
+
+
+
+ {/* Column Headers */}
+
+
+
Intern Name
+
Task Progress
+
Status
+
Action
+
+
+ {/* Rows */}
+
+ {paginated.map((intern) => {
+ const isChecked = selected.has(intern.id);
+ const isIncomplete = intern.status === "INCOMPLETE";
+ return (
+
+ {/* Checkbox */}
+
+
+ {/* Name + role */}
+
+
+
+
{intern.name}
+
{intern.role}
+
+
+
+ {/* Task Progress */}
+
+
+ {/* Status */}
+
+
+
+
+ {/* Action */}
+
+ {isIncomplete ? (
+
+ ) : (
+
+ )}
+
+
+ );
+ })}
+
+
+ {/* Pagination Footer */}
+
+
+ Showing {(page - 1) * PER_PAGE + 1} to {Math.min(page * PER_PAGE, mockInterns.length)} of {TOTAL_ENTRIES.toLocaleString()} entries
+
+
+
+ {Array.from({ length: totalPages }, (_, i) => i + 1).map((n) => (
+
+ ))}
+
+
+
+
+
+
+ {/* ── Bottom Action Bar ── */}
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/CertificateGenerate.tsx b/src/Pages/internify/mentor/CertificateGenerate.tsx
new file mode 100644
index 0000000..1769de3
--- /dev/null
+++ b/src/Pages/internify/mentor/CertificateGenerate.tsx
@@ -0,0 +1,240 @@
+// src/pages/mentor/CertificateResult.tsx
+import { useState } from "react";
+import { useNavigate } from "react-router-dom";
+import {
+ CheckCircle2,
+ FolderArchive,
+ Search,
+ Eye,
+ Download,
+ Share2,
+ ChevronLeft,
+ ChevronRight,
+} from "lucide-react";
+
+// ─── Types ────────────────────────────────────────────────────────────────────
+interface InternCert {
+ id: number;
+ name: string;
+ role: string;
+ initials: string;
+ credentialId: string;
+}
+
+// ─── Mock Data ────────────────────────────────────────────────────────────────
+const mockCerts: InternCert[] = [
+ { id: 1, name: "Alex Johnson", role: "Backend Engineering", initials: "AJ", credentialId: "CERT-2023-0045" },
+ { id: 2, name: "Sarah Lin", role: "UI/UX Design Specialist",initials: "SL", credentialId: "CERT-2023-0046" },
+ { id: 3, name: "Marcus Kane", role: "Data Analytics", initials: "MK", credentialId: "CERT-2023-0047" },
+ { id: 4, name: "Priya Sharma", role: "Frontend Engineering", initials: "PS", credentialId: "CERT-2023-0048" },
+ { id: 5, name: "Derek Lim", role: "DevOps & Cloud", initials: "DL", credentialId: "CERT-2023-0049" },
+ { id: 6, name: "Nina Castillo", role: "Mobile Development", initials: "NC", credentialId: "CERT-2023-0050" },
+];
+
+const TOTAL_CERTS = 18;
+const PER_PAGE = 3;
+
+// ─── Avatar ───────────────────────────────────────────────────────────────────
+const avatarColors: Record = {
+ AJ: "bg-blue-100 text-blue-700",
+ SL: "bg-purple-100 text-purple-700",
+ MK: "bg-orange-100 text-orange-700",
+ PS: "bg-teal-100 text-teal-700",
+ DL: "bg-green-100 text-green-700",
+ NC: "bg-pink-100 text-pink-700",
+};
+
+function Avatar({ initials }: { initials: string }) {
+ const color = avatarColors[initials] ?? "bg-gray-100 text-gray-600";
+ return (
+
+ {initials}
+
+ );
+}
+
+// ─── Main Page ────────────────────────────────────────────────────────────────
+export default function CertificateResult() {
+ const navigate = useNavigate();
+ const [search, setSearch] = useState("");
+ const [page, setPage] = useState(1);
+
+ // Filter + paginate
+ const filtered = mockCerts.filter(
+ (c) =>
+ c.name.toLowerCase().includes(search.toLowerCase()) ||
+ c.role.toLowerCase().includes(search.toLowerCase())
+ );
+ const totalPages = Math.ceil(filtered.length / PER_PAGE);
+ const paginated = filtered.slice((page - 1) * PER_PAGE, page * PER_PAGE);
+
+ const handleSearch = (e: React.ChangeEvent) => {
+ setSearch(e.target.value);
+ setPage(1);
+ };
+
+ return (
+
+ {/* Breadcrumb */}
+
navigate("/mentor/certificates/all")}>
+ Certificates ›
+
+
+ {/* Page Header */}
+
+
Certificates
+
+ Administrate, issue, and track professional certifications for all interns.
+
+
+
+ {/* ── Success Hero ── */}
+
+ {/* Icon circle */}
+
+
+
+
+ {/* Headline */}
+
+ {TOTAL_CERTS} Certificates Successfully Generated!
+
+
+ {/* Subtext */}
+
+ The validation engine has processed all engineering credentials. You can now
+ publish them to the public registry or download the batch for offline distribution.
+
+
+ {/* Download CTA */}
+
+
+
+ {/* ── Bottom Section: Table + Preview Card ── */}
+
+
+ {/* Recipient Directory Table */}
+
+
+ {/* Table Header */}
+
+
Recipient Directory
+ {/* Search */}
+
+
+
+
+
+
+ {/* Column Headers */}
+
+ Intern Name
+ Credential ID
+ Actions
+
+
+ {/* Rows */}
+
+ {paginated.length === 0 ? (
+
+ No interns match your search.
+
+ ) : (
+ paginated.map((cert) => (
+
+ {/* Name + role */}
+
+
+
+
{cert.name}
+
{cert.role}
+
+
+
+ {/* Credential ID */}
+
{cert.credentialId}
+
+ {/* Actions */}
+
+
+
+
+
+
+ ))
+ )}
+
+
+ {/* Pagination Footer */}
+
+
+ Showing {filtered.length === 0 ? 0 : (page - 1) * PER_PAGE + 1} to{" "}
+ {Math.min(page * PER_PAGE, filtered.length)} of {TOTAL_CERTS} interns
+
+
+
+ {Array.from({ length: totalPages }, (_, i) => i + 1).map((n) => (
+
+ ))}
+
+
+
+
+
+ {/* Preview Card (placeholder — gambar belum diimplementasi) */}
+
+
+
+ Institutional Excellence
+
+
+ Certified via Mentor Portal v2.4
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/CertificateListPage.tsx b/src/Pages/internify/mentor/CertificateListPage.tsx
new file mode 100644
index 0000000..54420bd
--- /dev/null
+++ b/src/Pages/internify/mentor/CertificateListPage.tsx
@@ -0,0 +1,149 @@
+// src/pages/mentor/CertificateList.tsx
+import { useNavigate } from "react-router-dom";
+import {CalendarDays} from "lucide-react";
+
+// ─── Types ───────────────────────────────────────────────────────────────────
+type CertStatus = "COMPLETED" | "PENDING CERTS";
+
+interface Project {
+ id: number;
+ title: string;
+ period: string;
+ internCount: number;
+ status: CertStatus;
+}
+
+// ─── Mock Data ────────────────────────────────────────────────────────────────
+const mockProjects: Project[] = [
+ {
+ id: 1,
+ title: "Autonomous Navigation Systems",
+ period: "Jan 2024 - Apr 2024",
+ internCount: 14,
+ status: "COMPLETED",
+ },
+ {
+ id: 2,
+ title: "Full-Stack Fintech Solution",
+ period: "Feb 2024 - June 2024",
+ internCount: 8,
+ status: "PENDING CERTS",
+ },
+ {
+ id: 3,
+ title: "User Experience Audit 2024",
+ period: "Mar 2024 - May 2024",
+ internCount: 5,
+ status: "PENDING CERTS",
+ },
+ {
+ id: 4,
+ title: "Edge Computing Framework",
+ period: "Dec 2023 - Mar 2024",
+ internCount: 21,
+ status: "COMPLETED",
+ },
+];
+
+// ─── Sub Components ───────────────────────────────────────────────────────────
+
+/** Badge status: COMPLETED (hijau) vs PENDING CERTS (kuning) */
+function StatusBadge({ status }: { status: CertStatus }) {
+ const isCompleted = status === "COMPLETED";
+ return (
+
+ {status}
+
+ );
+}
+
+/** Satu card project */
+function ProjectCard({
+ project,
+ onClick,
+}: {
+ project: Project;
+ onClick: () => void;
+}) {
+ return (
+
+ {/* Top: icon + status */}
+
+
+
+
+ {/* Title + period */}
+
+
+ {project.title}
+
+
+
+ {project.period}
+
+
+
+
+
+ {/* Intern count + avatars */}
+
+
+
Interns
+
+ {project.internCount} {project.internCount === 1 ? "intern" : "Interns"}
+
+
+
+
+ );
+}
+
+// ─── Main Page ────────────────────────────────────────────────────────────────
+export default function CertificateList() {
+ const navigate = useNavigate();
+
+ const handleCardClick = (id: number) => {
+ navigate(`/mentor/certificates/${id}`);
+ };
+
+ return (
+
+ {/* Breadcrumb */}
+
+ Certificates ›
+
+
+ {/* Page Header */}
+
+
Certificates
+
+ Administrate, issue, and track professional certifications for all interns.
+
+
+
+ {/* Section: List Projects */}
+
+
List Projects
+
+
+ {mockProjects.map((project) => (
+
handleCardClick(project.id)}
+ />
+ ))}
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/CertificatePage.tsx b/src/Pages/internify/mentor/CertificatePage.tsx
index c899c97..a93cb7e 100644
--- a/src/Pages/internify/mentor/CertificatePage.tsx
+++ b/src/Pages/internify/mentor/CertificatePage.tsx
@@ -58,10 +58,9 @@ const MentorCertificatePage = () => {
{/* Main Grid Content */}
-