diff --git a/src/Pages/internify/mentor/BaseProjectsPage.tsx b/src/Pages/internify/mentor/BaseProjectsPage.tsx
index b3e2280..10c20f0 100644
--- a/src/Pages/internify/mentor/BaseProjectsPage.tsx
+++ b/src/Pages/internify/mentor/BaseProjectsPage.tsx
@@ -1,51 +1,51 @@
-import { mockProjects } from '../../../lib/mockData'
-import MentorProjectCard from './components/MentorProjectCard'
-import { Plus } from 'lucide-react'
-import { useNavigate } from 'react-router-dom' // Import useNavigate
+import { mockProjects } from '../../../lib/mockData';
+import MentorProjectCard from './components/MentorProjectCard';
+import { Plus } from 'lucide-react';
+import { useState } from 'react';
+import CreateProjectModal from './components/CreateProjectDialog';
-const MentorProjectsPage = () => {
- const navigate = useNavigate()
+export default function MentorProjectsPage(){
+ const [isModalOpen, setIsModalOpen] = useState(false);
- const handleJoinProject = () => {
- // Navigasi ke halaman tujuan, silakan ganti '/path-tujuan' sesuai rute kamu
- navigate('/path-tujuan')
- }
+ const openDialog = () => {
+ setIsModalOpen(true);
+ };
+
+ const closeDialog = () => {
+ setIsModalOpen(false);
+ };
return (
-
- {/* Breadcrumb simulasi sesuai gambar */}
-
- Home > List Projects
-
-
-
-
List Projects
-
Create, manage, and monitor ongoing projects and assignments.
+
+
+
+
List Projects
+
Create, manage, and monitor ongoing projects and assignments.
+
+
+ {/* Tombol pemicu buka modal */}
+
+
- {/* Render List Project */}
{mockProjects.map(project => (
))}
-
- {/* Tombol "Join New Project" dengan Border Putus-putus */}
-
-
- )
-}
-export default MentorProjectsPage
\ No newline at end of file
+ {isModalOpen && (
+
+ )}
+
+ );
+};
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/CertificatePage.tsx b/src/Pages/internify/mentor/CertificatePage.tsx
index 39e7621..5a0eb4f 100644
--- a/src/Pages/internify/mentor/CertificatePage.tsx
+++ b/src/Pages/internify/mentor/CertificatePage.tsx
@@ -1,11 +1,246 @@
-import React from 'react'
+import React, { useState } from 'react';
+import {
+ PlusCircle,
+ UploadCloud,
+ Eye,
+ Download,
+ Trash2,
+ ChevronLeft,
+ ChevronRight,
+ DownloadCloud
+} from 'lucide-react';
+import { LuHistory, LuSendHorizontal } from 'react-icons/lu';
+
+// Mock Data untuk Tabel Riwayat Sertifikat
+const initialHistoryData = [
+ { id: 1, name: "Jonathan Kristina", email: "JonathanKristina@gmail.com", project: "Internify Project", date: "24 Oct 2024", initials: "JK" },
+ { id: 2, name: "Ahmad Faisal", email: "ahmad.faisal@gmail.com", project: "Web Dev Fundamentals", date: "15 Sep 2024", initials: "AF" },
+ { id: 3, name: "Siti Rahma", email: "siti.rahma@gmail.com", project: "UI/UX Essentials", date: "10 Aug 2024", initials: "SR" },
+ { id: 4, name: "David Beckham", email: "david.b@gmail.com", project: "Engineering Intern 101", date: "05 Aug 2024", initials: "DB" },
+];
const MentorCertificatePage = () => {
+ // State Form Management
+ const [selectedIntern, setSelectedIntern] = useState("JonathanKristina@gmail.com");
+ const [selectedProject, setSelectedProject] = useState("Internify Project (Web Development)");
+ const [issueDate, setIssueDate] = useState("2024-10-24");
+ const [expiryDate, setExpiryDate] = useState("");
+
+ // State Data Tabel
+ const [historyData, setHistoryData] = useState(initialHistoryData);
+
+ const handleIssueCertificate = (e: React.FormEvent) => {
+ e.preventDefault();
+ const payload = {
+ intern: selectedIntern,
+ project: selectedProject,
+ issueDate,
+ expiryDate
+ };
+ console.log("Issuing Certificate:", payload);
+ alert("Certificate Issued Successfully!");
+ };
+
+ const handleDeleteHistory = (id: number) => {
+ if(confirm("Are you sure you want to delete this certificate log?")) {
+ setHistoryData(historyData.filter(item => item.id !== id));
+ }
+ };
+
return (
-
-
+
+ {/* Breadcrumb & Header Title */}
+
+
+ Certificates >
+
+
Certificates
+
+ Administrate, issue, and track professional certifications for all interns.
+
+
+
+ {/* Main Grid Content */}
+
+
+ {/* Kiri: Form Issue New Certificate (4 Kolom) */}
+
+
+
+
Issue New Certificate
+
+
+
+
+
+ {/* Kanan: Issued Certificates History (8 Kolom) */}
+
+
+ {/* Header Table */}
+
+
+
+
Issued Certificates History
+
+
+
+
+ {/* Responsive Table Wrapper */}
+
+
+
+
+ | Intern Name |
+ Project |
+ Issue Date |
+ Actions |
+
+
+
+ {historyData.map((row) => (
+
+ {/* Kolom Nama Intern + Avatar Ringkas */}
+
+
+
+ {row.initials}
+
+
+ {row.name}
+ {row.email}
+
+
+ |
+ {/* Kolom Nama Proyek */}
+
+ {row.project}
+ |
+ {/* Kolom Tanggal Terbit */}
+
+ {row.date}
+ |
+ {/* Kolom Deretan Aksi */}
+
+
+
+
+
+
+ |
+
+ ))}
+
+
+
+
+
+ {/* Bagian Footer Tabel & Paginasi */}
+
+
Showing 1 to {historyData.length} of 1,284 entries
+
+
+
+
+
+
+
+
+
+
+
+
+
- )
+ );
}
-export default MentorCertificatePage
+export default MentorCertificatePage;
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/HomePage.tsx b/src/Pages/internify/mentor/HomePage.tsx
index 5cb3bb9..a1dd97f 100644
--- a/src/Pages/internify/mentor/HomePage.tsx
+++ b/src/Pages/internify/mentor/HomePage.tsx
@@ -4,7 +4,7 @@ import HomeMentorProject from './components/HomeMentorProject'
const HomeMentorPage = () => {
return (
-
+
diff --git a/src/Pages/internify/mentor/InternsPage.tsx b/src/Pages/internify/mentor/InternsPage.tsx
index 6791254..65c0d47 100644
--- a/src/Pages/internify/mentor/InternsPage.tsx
+++ b/src/Pages/internify/mentor/InternsPage.tsx
@@ -1,5 +1,196 @@
-export default function MentorInternPage() {
- return(
-
- )
+import { useState, useMemo } from "react";
+import { Search, SlidersHorizontal, Plus, Trash2 } from "lucide-react";
+import { mockInternsData } from "../../../lib/mockData";
+
+
+export default function InternsManagement() {
+ // State Filter & Search
+ const [searchEmail, setSearchEmail] = useState("");
+ const [selectedProject, setSelectedProject] = useState("All Projects");
+
+ // Handler Aksi Kursor/Tombol
+ const handleAddAssignment = (id: number) => {
+ alert(`Assign/Add action clicked for intern ID: ${id}`);
+ };
+
+ const handleDeleteIntern = (id: number) => {
+ alert(`Deleted intern ID: ${id}`);
+ };
+
+ // Logic Filtering Data menggunakan useMemo
+ const filteredInterns = useMemo(() => {
+ return mockInternsData.filter((intern) => {
+ const matchesEmail = intern.email.toLowerCase().includes(searchEmail.toLowerCase());
+ const matchesProject =
+ selectedProject === "All Projects" ||
+ intern.projectName.toLowerCase() === selectedProject.toLowerCase();
+ return matchesEmail && matchesProject;
+ });
+ }, [searchEmail, selectedProject]);
+
+ return (
+
+ {/* Header Title */}
+
+
Interns Management
+
+ Manage role-based access and project assignments for active interns.
+
+
+
+ {/* Filter Row & Stats Grid */}
+
+ {/* Left Control Inputs */}
+
+
+ {/* Search Box Input */}
+
+
+
+
+ setSearchEmail(e.target.value)}
+ className="w-full pl-9 pr-4 py-2 bg-gray-100 border border-transparent rounded-lg text-sm placeholder-gray-400 text-gray-800 focus:outline-none focus:bg-white focus:border-gray-200 font-medium"
+ />
+
+
+ {/* Select Project Dropdown */}
+
+
+
+
+
+ {/* Icon Sliders / Filter Button */}
+
+
+
+ {/* Right Info Box Stats */}
+
+
+ 124
+
+ TOTAL INTERNS
+
+
+
+
+ 92
+
+ ACTIVE ASSIGNMENTS
+
+
+
+
+
+ {/* Main Table Container Block */}
+
+
+ {/* Red Table Header Block */}
+
+
Intern Details
+
Current Project
+
Actions
+
+
+ {/* Table Body Iteration Rows */}
+
+ {filteredInterns.length > 0 ? (
+ filteredInterns.map((intern, index) => {
+ const isUnassigned = intern.projectName === "Unassigned";
+
+ return (
+
+
+ {/* Column 1: Intern Details (Avatar + Name & Email) */}
+
+ {intern.avatar ? (
+

+ ) : (
+
+ {intern.name.charAt(0)}
+
+ )}
+
+
{intern.name}
+
{intern.email}
+
+
+
+ {/* Column 2: Current Project Title & Role Accent */}
+
+
+ {intern.projectName}
+
+
+ {intern.role}
+
+
+
+ {/* Column 3: Action Buttons Block Right aligned */}
+
+
+
+
+
+
+ );
+ })
+ ) : (
+
+ No interns found matching the filter criteria.
+
+ )}
+
+
+ {/* Red Table Pagination Bar Footer */}
+
+
+ Showing {filteredInterns.length} of 124 interns
+
+
+
+
+
+
+
+
+
+
+ );
}
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/components/AddInternsDialog.tsx b/src/Pages/internify/mentor/components/AddInternsDialog.tsx
new file mode 100644
index 0000000..595f705
--- /dev/null
+++ b/src/Pages/internify/mentor/components/AddInternsDialog.tsx
@@ -0,0 +1,109 @@
+import { useRef, useEffect, useState } from "react";
+import { X, Search, Plus, Trash2 } from "lucide-react";
+
+interface ManageInternsModalProps {
+ isOpen: boolean;
+ onClose: () => void;
+}
+
+export default function ManageInternsModal({ isOpen, onClose }: ManageInternsModalProps) {
+ const dialogRef = useRef
(null);
+ const [searchQuery, setSearchQuery] = useState("Jonathankristin@gmail.com");
+
+ // Data Intern Terundang (Simulasi list atas yang ada ikon sampah)
+ const [invitedList, setInvitedList] = useState([
+ { id: 1, email: "Jonathankristina@gmail.com", initials: "JK" }
+ ]);
+
+ // Data Rekomendasi/Hasil Pencarian (Simulasi list bawah yang ada ikon plus)
+ const [searchResult, setSearchResult] = useState([
+ { id: 2, email: "Jonathankristin@gmail.com", initials: "JK" }
+ ]);
+
+ useEffect(() => {
+ const dialog = dialogRef.current;
+ if (!dialog) return;
+
+ if (isOpen) {
+ dialog.showModal();
+ document.body.style.overflow = "hidden";
+ } else {
+ dialog.close();
+ document.body.style.overflow = "unset";
+ }
+
+ const handleCancel = (e: Event) => {
+ e.preventDefault();
+ onClose();
+ };
+
+ dialog.addEventListener("cancel", handleCancel);
+ return () => {
+ dialog.removeEventListener("cancel", handleCancel);
+ document.body.style.overflow = "unset";
+ };
+ }, [isOpen, onClose]);
+
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/components/CreateProjectDialog.tsx b/src/Pages/internify/mentor/components/CreateProjectDialog.tsx
new file mode 100644
index 0000000..bd86b66
--- /dev/null
+++ b/src/Pages/internify/mentor/components/CreateProjectDialog.tsx
@@ -0,0 +1,299 @@
+import { useRef, useEffect, useState } from "react";
+import { X, Calendar } from "lucide-react";
+import {
+ LuCode,
+ LuAlbum,
+ LuCloud,
+ LuSmartphone,
+ LuSettings,
+ LuUsers,
+ LuClipboardList,
+ LuPenTool,
+ LuLightbulb,
+ LuShield,
+ LuMail,
+ LuSendHorizontal
+} from "react-icons/lu";
+
+interface CreateProjectModalProps {
+ isOpen: boolean;
+ onClose: () => void;
+}
+
+export default function CreateProjectModal({ isOpen, onClose }: CreateProjectModalProps) {
+ const dialogRef = useRef(null);
+
+ // State Form Management
+ const [selectedIcon, setSelectedIcon] = useState("code");
+ const [projectName, setProjectName] = useState("");
+ const [projectDescription, setProjectDescription] = useState("");
+ const [emailInput, setEmailInput] = useState("");
+ const [invitedEmails, setInvitedEmails] = useState([
+ "alex.dev@gmail.com",
+ "sarah.engineer@gmail.com"
+ ]);
+ const [startDate, setStartDate] = useState("");
+ const [endDate, setEndDate] = useState("");
+
+ // Daftar Icon Pilihan di baris atas
+ const projectIcons = [
+ { id: "code", icon: LuCode },
+ { id: "chart", icon: LuAlbum },
+ { id: "cloud", icon: LuCloud },
+ { id: "mobile", icon: LuSmartphone },
+ { id: "settings", icon: LuSettings },
+ { id: "users", icon: LuUsers },
+ { id: "task", icon: LuClipboardList },
+ { id: "design", icon: LuPenTool },
+ { id: "idea", icon: LuLightbulb },
+ { id: "secure", icon: LuShield },
+ ];
+
+ useEffect(() => {
+ const dialog = dialogRef.current;
+ if (!dialog) return;
+
+ if (isOpen) {
+ dialog.showModal();
+ document.body.style.overflow = "hidden";
+ } else {
+ dialog.close();
+ document.body.style.overflow = "unset";
+ }
+
+ const handleCancel = (e: Event) => {
+ e.preventDefault();
+ onClose();
+ };
+
+ dialog.addEventListener("cancel", handleCancel);
+ return () => {
+ dialog.removeEventListener("cancel", handleCancel);
+ document.body.style.overflow = "unset";
+ };
+ }, [isOpen, onClose]);
+
+ // Fungsi menambah email undangan baru
+ const handleAddEmail = (e: React.FormEvent) => {
+ e.preventDefault();
+ if (emailInput.trim() && !invitedEmails.includes(emailInput.trim())) {
+ setInvitedEmails([...invitedEmails, emailInput.trim()]);
+ setEmailInput("");
+ }
+ };
+
+ // Fungsi menghapus email undangan
+ const handleRemoveEmail = (emailToRemove: string) => {
+ setInvitedEmails(invitedEmails.filter(email => email !== emailToRemove));
+ };
+
+ // Handler Submit Utama
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault();
+ const payload = {
+ icon: selectedIcon,
+ name: projectName,
+ description: projectDescription,
+ emails: invitedEmails,
+ startDate,
+ endDate
+ };
+ console.log("Launching Project:", payload);
+ alert("Project Launched Successfully!");
+ onClose();
+ };
+
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/components/CreateTaskDialog.tsx b/src/Pages/internify/mentor/components/CreateTaskDialog.tsx
new file mode 100644
index 0000000..d4753bf
--- /dev/null
+++ b/src/Pages/internify/mentor/components/CreateTaskDialog.tsx
@@ -0,0 +1,190 @@
+import { useRef, useEffect, useState } from "react";
+import { X, Calendar, Clock, FileText, Link } from "lucide-react";
+
+interface CreateTaskModalProps {
+ isOpen: boolean;
+ onClose: () => void;
+}
+
+export default function CreateTaskModal({ isOpen, onClose }: CreateTaskModalProps) {
+ const dialogRef = useRef(null);
+
+ // Form States
+ const [taskTitle, setTaskTitle] = useState("");
+ const [description, setDescription] = useState("");
+ const [deadlineDate, setDeadlineDate] = useState("");
+ const [specificTime, setSpecificTime] = useState("");
+ const [submissionType, setSubmissionType] = useState<"file" | "url">("file");
+
+ useEffect(() => {
+ const dialog = dialogRef.current;
+ if (!dialog) return;
+
+ if (isOpen) {
+ dialog.showModal();
+ document.body.style.overflow = "hidden";
+ } else {
+ dialog.close();
+ document.body.style.overflow = "unset";
+ }
+
+ const handleCancel = (e: Event) => {
+ e.preventDefault();
+ onClose();
+ };
+
+ dialog.addEventListener("cancel", handleCancel);
+ return () => {
+ dialog.removeEventListener("cancel", handleCancel);
+ document.body.style.overflow = "unset";
+ };
+ }, [isOpen, onClose]);
+
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault();
+ const payload = { taskTitle, description, deadlineDate, specificTime, submissionType };
+ console.log("Saving Task:", payload);
+ alert("Task Saved Successfully!");
+ onClose();
+ };
+
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/components/Header.tsx b/src/Pages/internify/mentor/components/Header.tsx
index 8b8acb6..49d5da3 100644
--- a/src/Pages/internify/mentor/components/Header.tsx
+++ b/src/Pages/internify/mentor/components/Header.tsx
@@ -1,25 +1,33 @@
-import { Bell } from "lucide-react"
+import { Bell, Menu } from "lucide-react"
import humiclogo from "../../../../assets/logo.png";
+import { useNavigate } from "react-router-dom";
-const Header = () => {
+export default function Header({ toggleSidebar }: { toggleSidebar: () => void }) {
+ const nav = useNavigate();
return (
-
-
-

+