-
Menu
-
-
navigate("/dashboard")}
- >
-
-
-
Dashboard
-
-
navigate("/product-list")}
- >
-
-
Project
-
-
navigate("/lowongan-list")}
- >
-
-
-
Lowongan
-
-
navigate("/partnership-admin")}
- >
-
-
-
Partnership
-
-
navigate("/internships-list")}
- >
-
-
-
Pelamar
-
-
navigate("/feedback-list")}
- >
-
-
-
Feedback
-
-
navigate("/faq-list")}
- >
-
-
-
FAQ
-
+
+ {/* Main nav */}
+
+
+
+
+ {/* Preferences */}
+
+ PREFERENCES
+
+
+
+
);
-};
+}
-export default SidebarAdmin;
+
+export default SidebarIntern
diff --git a/src/Pages/internify/FAQpage.tsx b/src/Pages/internify/FAQpage.tsx
new file mode 100644
index 0000000..c2070e8
--- /dev/null
+++ b/src/Pages/internify/FAQpage.tsx
@@ -0,0 +1,69 @@
+import { useNavigate } from "react-router-dom";
+import { ChevronRight } from "lucide-react";
+
+const mockFAQData = [
+ {
+ id: 1,
+ question: "How do I generate internship certificates?",
+ answer: "Once an intern has completed all required project milestones and their final evaluation is approved by a manager, go to the 'Manage Certificates' tab. Select the intern's name, click 'Generate Certificate', and the system will automatically populate the official Internify template with their specific details."
+ },
+ {
+ id: 2,
+ question: "What are the technical requirements for interns?",
+ answer: "Internify is a web-based LMS. Interns simply need a modern web browser (Chrome, Firefox, or Safari) and a stable internet connection. Some engineering modules may require local development environments, which are detailed in the specific project onboarding documentation."
+ },
+ {
+ id: 3,
+ question: "How often is the project dashboard updated?",
+ answer: "The dashboard updates in real-time as interns submit tasks or participate in the forum. Weekly progress reports are automatically generated every Friday at 5:00 PM EST and can be exported as PDF files from the Dashboard view."
+ }
+];
+
+export default function FAQPage() {
+ const navigate = useNavigate();
+
+ return (
+
+ {/* Breadcrumb */}
+
+ navigate("/")}>Home
+
+ FAQ
+
+
+ {/* Header Title */}
+
+
FAQ
+
+ Quick answers to common questions about the Internify LMS platform.
+
+
+
+ {/* FAQ Lists */}
+
+ {mockFAQData.map((faq) => (
+
+
+ {/* Indikator Garis/Kotak Kecil Merah di Sisi Kiri sesuai gambar */}
+
+
+ {/* Item Question */}
+
+ {faq.question}
+
+
+ {/* Item Answer */}
+
+ {faq.answer}
+
+
+ {/* Divider Line tipis di bawah setiap item, kecuali item terakhir */}
+ {faq.id !== mockFAQData.length && (
+
+ )}
+
+ ))}
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/NotificationList.tsx b/src/Pages/internify/NotificationList.tsx
new file mode 100644
index 0000000..777de48
--- /dev/null
+++ b/src/Pages/internify/NotificationList.tsx
@@ -0,0 +1,169 @@
+import { useState } from "react";
+import { useNavigate } from "react-router-dom";
+import { ChevronRight, Check, Download, Info, Award } from "lucide-react";
+import { LuFileSpreadsheet } from "react-icons/lu"; // Alternatif icon task dari react-icons
+
+const initialNotifications = [
+ {
+ id: 1,
+ type: "new-task",
+ title: "New Task Assigned",
+ time: "Just now",
+ isNew: true,
+ group: "TODAY",
+ description: "Mentor Sarah Johnson has pushed a new task: User Persona Analysis"
+ },
+ {
+ id: 2,
+ type: "achievement",
+ title: "Certificate Ready",
+ time: "2 hours ago",
+ isNew: false,
+ group: "TODAY",
+ description: "Your certificate for UI Engineering Phase 1 is now available for download!"
+ },
+ {
+ id: 3,
+ type: "system",
+ title: "System Maintenance",
+ time: "2 days ago",
+ isNew: false,
+ group: "YESTERDAY",
+ description: "Internify will undergo scheduled maintenance this Sunday from 02:00 AM to 04:00 AM GMT+7."
+ }
+];
+
+export default function NotificationList() {
+ const navigate = useNavigate();
+ const [notifications, setNotifications] = useState(initialNotifications);
+
+ const handleMarkAllRead = () => {
+ setNotifications(prev => prev.map(n => ({ ...n, isNew: false })));
+ alert("All notifications marked as read!");
+ };
+
+ return (
+
+ {/* Breadcrumb */}
+
+ navigate("/")}>Home
+
+ Notification
+
+
+ {/* Header */}
+
+
+
Notifications
+
+ Keep track of your interns' progress and system updates.
+
+
+
+
+
+ {/* List Group Section */}
+
+
+ {/* Render Group TODAY */}
+
+ {notifications.filter(n => n.group === "TODAY").map((item) => (
+
+ {/* Icon Container */}
+
+ {item.type === 'new-task' && }
+ {item.type === 'achievement' && }
+
+
+ {/* Content text */}
+
+
+ {item.isNew && (
+
+ NEW
+
+ )}
+
{item.title}
+
+
+ {/* Custom description coloring logic */}
+
+ {item.type === 'new-task' ? (
+ <>Mentor Sarah Johnson has pushed a new task: User Persona Analysis>
+ ) : item.type === 'achievement' ? (
+ <>Your certificate for UI Engineering Phase 1 is now available for download!>
+ ) : item.description}
+
+
+ {/* Conditional Actions */}
+ {item.type === 'new-task' && (
+
+
+
+
+ )}
+
+ {item.type === 'achievement' && (
+
+ )}
+
+
+ {/* Time */}
+
+ {item.time}
+
+
+ ))}
+
+
+ {/* Header Section YESTERDAY */}
+
+
+ YESTERDAY
+
+
+ {notifications.filter(n => n.group === "YESTERDAY").map((item) => (
+
+
+
+
+
+
{item.title}
+
+ {item.description}
+
+
+
+ {item.time}
+
+
+ ))}
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/SettingsPage.tsx b/src/Pages/internify/SettingsPage.tsx
new file mode 100644
index 0000000..8d9349b
--- /dev/null
+++ b/src/Pages/internify/SettingsPage.tsx
@@ -0,0 +1,140 @@
+import { useState } from "react";
+import { useNavigate } from "react-router-dom";
+import { ChevronRight } from "lucide-react"; // dari lucide-react
+
+// Mock Data Profile awal
+const mockProfileData = {
+ fullName: "JonathanKristina",
+ email: "JonathanKristina@gmail.com",
+ bio: "UIUX holic"
+};
+
+export default function SettingsContent() {
+ const navigate = useNavigate();
+ const [formData, setFormData] = useState(mockProfileData);
+
+ const handleChange = (e: React.ChangeEvent
) => {
+ const { name, value } = e.target;
+ setFormData((prev) => ({ ...prev, [name]: value }));
+ };
+
+ const handleSaveChanges = (e: React.FormEvent) => {
+ e.preventDefault();
+ // Simulasi penyimpanan data sukses
+ alert("Changes saved successfully!");
+ console.log("Saved Data:", formData);
+ };
+
+ // Mendapatkan inisial huruf pertama untuk avatar profile gambar
+ const initialLetter = formData.fullName ? formData.fullName.charAt(0).toUpperCase() : "U";
+
+ return (
+
+ {/* Breadcrumb */}
+
+ navigate("/")}>Home
+
+ Settings
+
+
+ {/* Header Title */}
+
+
Settings
+
+ Manage and edit your profile and account information.
+
+
+
+ {/* White Card Container */}
+
+
+ {/* Card Header */}
+
+
Profile Information
+
+ Update your photo and personal details.
+
+
+
+ {/* Card Body & Form */}
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/intern/ProjectForum.tsx b/src/Pages/internify/intern/ForumTab.tsx
similarity index 100%
rename from src/Pages/internify/intern/ProjectForum.tsx
rename to src/Pages/internify/intern/ForumTab.tsx
diff --git a/src/Pages/internify/intern/HomeInternPage.tsx b/src/Pages/internify/intern/HomeInternPage.tsx
index 8c93a95..41e5b5f 100644
--- a/src/Pages/internify/intern/HomeInternPage.tsx
+++ b/src/Pages/internify/intern/HomeInternPage.tsx
@@ -1,7 +1,7 @@
import HomeHeader from "./components/HomeHeader";
import HomeProjectList from "./components/HomeProjectList";
import HomeCalendar from "./components/HomeCalendar";
-import TaskTimeline from "./components/TaskTImeline";
+import TaskTimeline from "./components/TaskTimeline";
// PR: tambahin breadcrumb
export default function HomeInternPage() {
diff --git a/src/Pages/internify/intern/ProjectParticipants.tsx b/src/Pages/internify/intern/ParticipantTab.tsx
similarity index 100%
rename from src/Pages/internify/intern/ProjectParticipants.tsx
rename to src/Pages/internify/intern/ParticipantTab.tsx
diff --git a/src/Pages/internify/intern/ProjectDetailPage.tsx b/src/Pages/internify/intern/ProjectDetailPage.tsx
index 961b10e..4a3d5d8 100644
--- a/src/Pages/internify/intern/ProjectDetailPage.tsx
+++ b/src/Pages/internify/intern/ProjectDetailPage.tsx
@@ -1,8 +1,8 @@
import { useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { mockProjects } from '../../../lib/mockData';
-import ForumTab from './ProjectForum';
-import ParticipantsTab from './ProjectParticipants';
+import ForumTab from './ForumTab';
+import ParticipantsTab from './ParticipantTab';
import { ChevronLeft } from 'lucide-react';
// ─── ProjectDetailPage ─────────────────────────────────────────────────────────
diff --git a/src/Pages/internify/intern/SertificatePage.tsx b/src/Pages/internify/intern/SertificatePage.tsx
index d2c1ad9..3c08812 100644
--- a/src/Pages/internify/intern/SertificatePage.tsx
+++ b/src/Pages/internify/intern/SertificatePage.tsx
@@ -1,18 +1,33 @@
+import { certificateData } from "../../../lib/mockData";
+import CertificateAvailable from "./components/CertificateAvailabe";
+import CertificateNotAvailable from "./components/CertificateNotAvailable";
+
const SertificatePage = () => {
+ const data = certificateData; // ganti isReceived di object atas
+
return (
-
+
+ {/* Header */}
+
Certificates
View and download internship certificates
-
-
-
-
+ {/* Content */}
+
+ {data.isReceived ? (
+
+ ) : (
+
+ )}
- )
-}
+ );
+};
+
export default SertificatePage
diff --git a/src/Pages/internify/intern/components/CertificateAvailabe.tsx b/src/Pages/internify/intern/components/CertificateAvailabe.tsx
new file mode 100644
index 0000000..040921a
--- /dev/null
+++ b/src/Pages/internify/intern/components/CertificateAvailabe.tsx
@@ -0,0 +1,142 @@
+import { useState } from "react";
+import { Download, History , Link, Award, Printer } from "lucide-react";
+import { type CertificateData, type CertificateHistory } from "../../../../lib/mockData";
+import certificateImg from "../../../../assets/certificate.png";
+
+export default function CertificateAvailable({ data }: { data: CertificateData }) {
+ const { certificate, history } = data;
+ const [copied, setCopied] = useState(false);
+
+ const handleCopyLink = () => {
+ navigator.clipboard.writeText(window.location.href);
+ setCopied(true);
+ setTimeout(() => setCopied(false), 2000);
+ };
+
+ return (
+
+ {/* LEFT: Certificate Preview + Actions */}
+
+ {/* Certificate Card */}
+
+

+
+
+ {/* Program Summary */}
+
+
+
+
Ringkasan Program
+
+
+ {[
+ { label: "Nama Program", value: certificate.programName },
+ { label: "Durasi", value: certificate.duration },
+ {
+ label: "Nilai Akhir",
+ value: (
+
+ {certificate.finalScore}/100 ({certificate.grade})
+
+ ),
+ },
+ {
+ label: "Status",
+ value: (
+
+ {certificate.status}
+
+ ),
+ },
+ ].map((row) => (
+
+ {row.label}
+ {row.value}
+
+ ))}
+
+
+
+
+
+
+ {/* Unduh Sertifikat */}
+
+
+ {/* Bagikan ke LinkedIn */}
+
+
+ {/* Cetak & Salin Link */}
+
+
+
+
+
+
+
+
+
+
+ {/* RIGHT: Certificate History */}
+
+
+
+
+
Certificate History
+
+
+
+ {history.map((item: CertificateHistory) => (
+
+
+

+
+
+
{item.month}
+
{item.title}
+
+ Grade: {item.grade}
+
+
+
+ ))}
+
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/intern/components/CertificateNotAvailable.tsx b/src/Pages/internify/intern/components/CertificateNotAvailable.tsx
new file mode 100644
index 0000000..ee2e00e
--- /dev/null
+++ b/src/Pages/internify/intern/components/CertificateNotAvailable.tsx
@@ -0,0 +1,43 @@
+import { Lock, Clock } from "lucide-react";
+
+export default function CertificateNotAvailable({ progress, remainingTasks }: { progress: number; remainingTasks: number }) {
+ return (
+
+ {/* Icon */}
+
+
+
Sertifikat Belum Tersedia
+
+ Anda harus menyelesaikan semua tugas proyek sebelum dapat mengunduh sertifikat kelulusan.
+ Silakan periksa kembali progres tugas Anda di menu Proyek.
+
+
+ {/* Progress Bar */}
+
+
+ Progres Proyek
+ {progress}%
+
+
+
+ Selesaikan {remainingTasks} tugas lagi untuk membuka akses.
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/intern/components/HomeCalendar.tsx b/src/Pages/internify/intern/components/HomeCalendar.tsx
index af11681..7ea27c5 100644
--- a/src/Pages/internify/intern/components/HomeCalendar.tsx
+++ b/src/Pages/internify/intern/components/HomeCalendar.tsx
@@ -83,7 +83,7 @@ const HomeCalendar = () => {
}
return (
-
+
{/* Header */}
diff --git a/src/Pages/internify/intern/components/HomeProjectList.tsx b/src/Pages/internify/intern/components/HomeProjectList.tsx
index 167a9e1..a094a59 100644
--- a/src/Pages/internify/intern/components/HomeProjectList.tsx
+++ b/src/Pages/internify/intern/components/HomeProjectList.tsx
@@ -1,15 +1,6 @@
-import { Code2, ChessKing, Beef } from 'lucide-react'
import { useNavigate } from 'react-router-dom'
import { mockProjects } from '../../../../lib/mockData'
-interface Project {
- name: string
- role: string
- logo: React.ElementType
- iconBg: string
- iconColor: string
-}
-
const HomeProjectList = () => {
const navigate = useNavigate();
return (
diff --git a/src/Pages/internify/intern/components/ProjectTimeline.tsx b/src/Pages/internify/intern/components/ProjectTimeline.tsx
index 3430820..e51a9ce 100644
--- a/src/Pages/internify/intern/components/ProjectTimeline.tsx
+++ b/src/Pages/internify/intern/components/ProjectTimeline.tsx
@@ -1,4 +1,5 @@
import type { Task } from "../../../../lib/mockData";
+import { ArrowDownNarrowWide } from "lucide-react";
const formatDate = (date: Date) =>
new Date(date).toLocaleDateString('id-ID', { day: 'numeric', month: 'short', year: 'numeric' });
@@ -9,10 +10,11 @@ export default function ProjectTimeline({ tasks }: { tasks: Task[] }) {
return (
-
+
diff --git a/src/Pages/internify/layout.tsx b/src/Pages/internify/layout.tsx
index 122cf7c..9941365 100644
--- a/src/Pages/internify/layout.tsx
+++ b/src/Pages/internify/layout.tsx
@@ -1,8 +1,8 @@
import { Outlet } from "react-router-dom";
-import Header from './Header';
+import Header from './mentor/components/Header';
import SidebarIntern from './intern/components/SidebarIntern';
import SidebarAdmin from '../../Layout/SidebarAdmin';
-import FooterIntern from './intern/components/FooterIntern';
+import FooterIntern from '../../Layout/Footer-Internify';
export const InternLayout = () => {
return (
diff --git a/src/Pages/internify/mentor/BaseProjectsPage.tsx b/src/Pages/internify/mentor/BaseProjectsPage.tsx
new file mode 100644
index 0000000..b3e2280
--- /dev/null
+++ b/src/Pages/internify/mentor/BaseProjectsPage.tsx
@@ -0,0 +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
+
+const MentorProjectsPage = () => {
+ const navigate = useNavigate()
+
+ const handleJoinProject = () => {
+ // Navigasi ke halaman tujuan, silakan ganti '/path-tujuan' sesuai rute kamu
+ navigate('/path-tujuan')
+ }
+
+ return (
+
+ {/* Breadcrumb simulasi sesuai gambar */}
+
+ Home > List Projects
+
+
+
+
List Projects
+
Create, manage, and monitor ongoing projects and assignments.
+
+
+
+ {/* Render List Project */}
+ {mockProjects.map(project => (
+
+ ))}
+
+ {/* Tombol "Join New Project" dengan Border Putus-putus */}
+
+
+
+ )
+}
+
+export default MentorProjectsPage
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/MentorCertificatePage.tsx b/src/Pages/internify/mentor/CertificatePage.tsx
similarity index 100%
rename from src/Pages/internify/mentor/MentorCertificatePage.tsx
rename to src/Pages/internify/mentor/CertificatePage.tsx
diff --git a/src/Pages/internify/mentor/HomeMentorPage.tsx b/src/Pages/internify/mentor/HomeMentorPage.tsx
deleted file mode 100644
index 87fcabb..0000000
--- a/src/Pages/internify/mentor/HomeMentorPage.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react'
-
-const HomeMentorPage = () => {
- return (
-
-
-
- )
-}
-
-export default HomeMentorPage
diff --git a/src/Pages/internify/mentor/HomePage.tsx b/src/Pages/internify/mentor/HomePage.tsx
new file mode 100644
index 0000000..5cb3bb9
--- /dev/null
+++ b/src/Pages/internify/mentor/HomePage.tsx
@@ -0,0 +1,24 @@
+import HomeHeader from '../intern/components/HomeHeader'
+import HomeCalendar from '../intern/components/HomeCalendar'
+import HomeMentorProject from './components/HomeMentorProject'
+
+const HomeMentorPage = () => {
+ return (
+
+ )
+}
+
+export default HomeMentorPage
diff --git a/src/Pages/internify/mentor/InternsPage.tsx b/src/Pages/internify/mentor/InternsPage.tsx
new file mode 100644
index 0000000..6791254
--- /dev/null
+++ b/src/Pages/internify/mentor/InternsPage.tsx
@@ -0,0 +1,5 @@
+export default function MentorInternPage() {
+ return(
+
+ )
+}
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/MentorDetailProject.tsx b/src/Pages/internify/mentor/MentorDetailProject.tsx
deleted file mode 100644
index d19c1d0..0000000
--- a/src/Pages/internify/mentor/MentorDetailProject.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react'
-
-const MentorDetailProject = () => {
- return (
-
-
-
- )
-}
-
-export default MentorDetailProject
diff --git a/src/Pages/internify/mentor/MentorInternPage.tsx b/src/Pages/internify/mentor/MentorInternPage.tsx
deleted file mode 100644
index e01ae40..0000000
--- a/src/Pages/internify/mentor/MentorInternPage.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react'
-
-const MentorInternPage = () => {
- return (
-
-
-
- )
-}
-
-export default MentorInternPage
diff --git a/src/Pages/internify/mentor/MentorProjectsPage.tsx b/src/Pages/internify/mentor/MentorProjectsPage.tsx
deleted file mode 100644
index f8f040d..0000000
--- a/src/Pages/internify/mentor/MentorProjectsPage.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react'
-
-const MentorProjectsPage = () => {
- return (
-
-
-
- )
-}
-
-export default MentorProjectsPage
diff --git a/src/Pages/internify/mentor/ProjectForumTab.tsx b/src/Pages/internify/mentor/ProjectForumTab.tsx
new file mode 100644
index 0000000..4806cf1
--- /dev/null
+++ b/src/Pages/internify/mentor/ProjectForumTab.tsx
@@ -0,0 +1,26 @@
+import type { Project } from '../../../lib/mockData';
+import ProjectTimeline from '../intern/components/ProjectTimeline';
+import HeroProject from '../intern/components/Hero-project';
+import MentorTaskCard from './components/MentorTaskCard';
+
+export default function MentorForumTab({ project }: { project: Project }) {
+ return (
+
+ {/* Hero banner */}
+
+
+ {/* Timeline + Task list */}
+
+
+
+
+ {project.tasks.map((task, idx) => (
+
+ ))}
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/ProjectsInternTab.tsx b/src/Pages/internify/mentor/ProjectsInternTab.tsx
new file mode 100644
index 0000000..1b65dd3
--- /dev/null
+++ b/src/Pages/internify/mentor/ProjectsInternTab.tsx
@@ -0,0 +1,45 @@
+import type { Project, Intern } from '../../../lib/mockData';
+
+export default function InternsTab({ project }: { project: Project }) {
+ return (
+
+ {/* Mentor */}
+
+
+ Mentor
+
+
+
+
+ {project.mentor}
+
+
+
+
+
+ {/* Members */}
+
+
+ Members
+
+ {project.interns.map((intern: Intern, idx: number) => (
+
+
+
+ {intern.email}
+
+
+
+ {intern.role}
+
+
+ ))}
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/ProjectsPage.tsx b/src/Pages/internify/mentor/ProjectsPage.tsx
new file mode 100644
index 0000000..bed7947
--- /dev/null
+++ b/src/Pages/internify/mentor/ProjectsPage.tsx
@@ -0,0 +1,83 @@
+import { useState } from 'react';
+import { useNavigate, useParams } from 'react-router-dom';
+import { mockProjects } from '../../../lib/mockData';
+import { ChevronLeft } from 'lucide-react';
+import MentorForumTab from './ProjectForumTab';
+import InternsTab from './ProjectsInternTab';
+import TaskTab from './TaskTab';
+
+// ─── ProjectDetailPage ─────────────────────────────────────────────────────────
+export default function ProjectDetailPage() {
+ const { id } = useParams<{ id: string }>();
+ const navigate = useNavigate();
+ const [activeTab, setActiveTab] = useState<'forum' | 'participants' | 'Task'>('forum');
+
+ const handleBack = () => {
+ if (window.history.length > 1) {
+ navigate(-1);
+ } else {
+ navigate('/intern/projects');
+ }
+ };
+
+ const project = mockProjects.find((p) => p.id === Number(id));
+
+ if (!project) {
+ return (
+
+ Project tidak ditemukan.
+
+ );
+ }
+
+ const tabClass = (tab: string) =>
+ `pr-0 py-2.5 mr-7 text-sm bg-transparent border-0 cursor-pointer transition-colors duration-150 border-b-2 ${activeTab === tab
+ ? 'font-bold text-[#C0392B] border-[#C0392B]'
+ : 'font-medium text-[#666] border-transparent'
+ }`;
+
+ return (
+
+
+
+ {/* Back Button */}
+
+
+ {/* Tabs */}
+
+
+
+
+
+
+ {/* Tab content */}
+ {(() => {
+ switch (activeTab) {
+ case 'forum':
+ return
;
+ case 'participants':
+ return
;
+ case 'Task':
+ return
; // Tambahkan komponen TaskTab di sini
+ default:
+ return null;
+ }
+ })()}
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/TaskTab.tsx b/src/Pages/internify/mentor/TaskTab.tsx
new file mode 100644
index 0000000..b985425
--- /dev/null
+++ b/src/Pages/internify/mentor/TaskTab.tsx
@@ -0,0 +1,79 @@
+import type { Project, Task } from '../../../lib/mockData';
+import { ClipboardList, Pencil, Trash2 } from 'lucide-react';
+
+export default function TaskTab({ project }: { project: Project }) {
+
+ const handleAddTask = () => {
+ console.log('Trigger modal / halaman tambah tugas');
+ };
+
+ const handleEditTask = (taskTitle: string) => {
+ console.log('Edit task:', taskTitle);
+ };
+
+ const handleDeleteTask = (taskTitle: string) => {
+ console.log('Delete task:', taskTitle);
+ };
+
+ return (
+
+ {/* Header Section */}
+
+
Tasks
+
+
+
+
+
+
+ {/* Task List Section */}
+
+ {project.tasks && project.tasks.length > 0 ? (
+ project.tasks.map((task: Task, idx: number) => (
+
+ {/* Task Title & Icon */}
+
+
+
+ {task.title}
+
+
+
+ {/* Action Buttons (Edit & Delete) */}
+
+
+
+
+
+ ))
+ ) : (
+
+ Belum ada tugas yang dibuat untuk proyek ini.
+
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/Header.tsx b/src/Pages/internify/mentor/components/Header.tsx
similarity index 91%
rename from src/Pages/internify/Header.tsx
rename to src/Pages/internify/mentor/components/Header.tsx
index c9190bf..8b8acb6 100644
--- a/src/Pages/internify/Header.tsx
+++ b/src/Pages/internify/mentor/components/Header.tsx
@@ -1,5 +1,5 @@
import { Bell } from "lucide-react"
-import humiclogo from "../../assets/logo.png";
+import humiclogo from "../../../../assets/logo.png";
const Header = () => {
return (
diff --git a/src/Pages/internify/mentor/components/HomeMentorProject.tsx b/src/Pages/internify/mentor/components/HomeMentorProject.tsx
new file mode 100644
index 0000000..6525d9d
--- /dev/null
+++ b/src/Pages/internify/mentor/components/HomeMentorProject.tsx
@@ -0,0 +1,39 @@
+import { useNavigate } from 'react-router-dom'
+import { mockProjects } from '../../../../lib/mockData'
+import { Plus } from 'lucide-react';
+
+const HomeMentorProject = () => {
+ const navigate = useNavigate();
+ return (
+
+
+
Projects
+
+
+
+ {mockProjects.map((project, index) => {
+ return (
+
navigate(`/intern/projects/${project.id}`)}
+ className="flex items-center gap-4 border border-gray-200 rounded-lg px-4 py-3 hover:bg-gray-50 cursor-pointer transition-colors duration-150"
+ >
+
+
+
+
+ )
+ })}
+
+
+ )
+}
+
+export default HomeMentorProject
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/components/MentorProjectCard.tsx b/src/Pages/internify/mentor/components/MentorProjectCard.tsx
new file mode 100644
index 0000000..c13cc20
--- /dev/null
+++ b/src/Pages/internify/mentor/components/MentorProjectCard.tsx
@@ -0,0 +1,63 @@
+import { Trash2, UsersRound } from 'lucide-react'
+import type { Intern } from '../../../../lib/mockData'
+import { useNavigate } from 'react-router-dom'
+
+interface ProjectCardProps {
+ id: number | string
+ name: string
+ interns: Intern[]
+ thumbnailUrl?: string
+}
+
+export default function MentorProjectCard({
+ id,
+ name,
+ interns,
+ thumbnailUrl
+}: ProjectCardProps) {
+ const navigate = useNavigate();
+ const handleCardClick = () => {
+ navigate(`/admin/projects/${id}`)
+ };
+
+ const handleDeleteClick = (e: React.MouseEvent) => {
+ e.stopPropagation()
+ console.log('Delete project dengan id:', id)
+ }
+ return (
+
+ {/* Thumbnail */}
+
+ {thumbnailUrl && (
+

+ )}
+
+
+ {/* Content*/}
+
+
+
+ {/* Interns Count */}
+
+
+
+ {interns.length}/{interns.length}
+
+
+
+
+ {/* Footer */}
+
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/components/MentorTaskCard.tsx b/src/Pages/internify/mentor/components/MentorTaskCard.tsx
new file mode 100644
index 0000000..060ae2d
--- /dev/null
+++ b/src/Pages/internify/mentor/components/MentorTaskCard.tsx
@@ -0,0 +1,34 @@
+import type { Task } from "../../../../lib/mockData";
+
+const formatDate = (date: Date) =>
+ new Date(date).toLocaleDateString('id-ID', { day: 'numeric', month: 'short', year: 'numeric' });
+
+export default function MentorTaskCard({ task }: { task: Task }) {
+ return (
+
+
+
+ Deadline : {formatDate(task.deadline.date)} at {task.deadline.time}
+
+
+ {task.title}
+
+
+ {task.description}
+
+
+
+
+
+ {task.submittedCount}/{task.totalInterns}
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/Pages/internify/mentor/SidebarMentor.tsx b/src/Pages/internify/mentor/components/SidebarMentor.tsx
similarity index 100%
rename from src/Pages/internify/mentor/SidebarMentor.tsx
rename to src/Pages/internify/mentor/components/SidebarMentor.tsx
diff --git a/src/Pages/internify/page.tsx b/src/Pages/internify/page.tsx
new file mode 100644
index 0000000..40b497b
--- /dev/null
+++ b/src/Pages/internify/page.tsx
@@ -0,0 +1,170 @@
+import { useState } from "react";
+import logo from "../../assets/logo.png";
+import { useNavigate } from "react-router-dom";
+import { Mail, Lock, Eye, EyeOff } from 'lucide-react';
+
+
+// Data user dummy untuk keperluan simulasi navigasi frontend
+const DataUsers = [
+ { "Name": "John Doe", "Email": "john@email.com", "Password": "password123", "role": "intern" },
+ { "Name": "Jane Smith", "Email": "jane@email.com", "Password": "password123", "role": "mentor" },
+];
+
+export default function InternifyLogin() {
+ const navigate = useNavigate();
+ const [email, setEmail] = useState("");
+ const [password, setPassword] = useState("");
+ const [showPassword, setShowPassword] = useState(false);
+ const [error, setError] = useState("");
+
+ const handleSignIn = (e: React.FormEvent) => {
+ e.preventDefault();
+ setError("");
+
+ if (!email || !password) {
+ setError("Email dan password wajib diisi.");
+ return;
+ }
+
+ const user = DataUsers.find(
+ (u) => u.Email.toLowerCase() === email.toLowerCase() && u.Password === password
+ );
+
+ if (user) {
+ // 3. Gunakan navigate() sesuai dengan role masing-masing
+ if (user.role === "admin") {
+ navigate("/admin");
+ } else if (user.role === "intern") {
+ navigate("/intern");
+ } else if (user.role === "mentor") {
+ navigate("/mentor");
+ } else {
+ setError("Role user tidak dikenali.");
+ }
+ } else {
+ setError("Email atau password salah.");
+ }
+ };
+
+ return (
+
+
+
+ {/* Main Container */}
+
+ {/* Logo Section */}
+
+
+

+
+
+ HUMIC LMS PORTAL
+
+
+
+ {/* Card Login */}
+
+
Welcome back
+
Access your dashboard with your credentials.
+
+
+
+ {/* Forgot Password */}
+
+
+ {/* Divider & Support */}
+
+
+
+
+
+
+
+
+ {/* Footer Section */}
+
+
© 2024 Internify. CoE Humic Engineering.
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/assets/certificate.png b/src/assets/certificate.png
new file mode 100644
index 0000000..4c7ef1c
Binary files /dev/null and b/src/assets/certificate.png differ
diff --git a/src/lib/mockData.ts b/src/lib/mockData.ts
index 5f9eb7c..d3fd989 100644
--- a/src/lib/mockData.ts
+++ b/src/lib/mockData.ts
@@ -24,6 +24,8 @@ export interface Task {
description: string;
deadline: Deadline;
isSubmitted: boolean;
+ submittedCount: number;
+ totalInterns: number;
}
export interface Intern {
@@ -57,24 +59,32 @@ export const mockProjects: Project[] = [
title: "Laporan tugas",
description: "Berisi design ulux, dan user flow dari aplikasi internify",
deadline: { date: new Date(2026, 4, 1), label: "Laporan tugas – 1 Mei", time: "23:59 PM" },
+ submittedCount: 6,
+ totalInterns: 6,
isSubmitted: true,
},
{
title: "Laporan tugas 1",
description: "Berisi design ulux, dan user flow dari aplikasi internify",
deadline: { date: new Date(2026, 4, 14), label: "Laporan tugas 1 – 14 Mei", time: "23:59 PM" },
+ submittedCount: 2,
+ totalInterns: 6,
isSubmitted: false,
},
{
title: "Laporan tugas 2",
description: "Berisi design ulux, dan user flow dari aplikasi internify",
deadline: { date: new Date(2026, 4, 28), label: "Laporan tugas 2 – 28 Mei", time: "23:59 PM" },
+ submittedCount: 3,
+ totalInterns: 6,
isSubmitted: false,
},
{
title: "Laporan tugas 3",
description: "Berisi wireframe halaman dashboard aplikasi internify",
deadline: { date: new Date(2026, 5, 5), label: "Laporan tugas 3 – 5 Jun", time: "23:59 PM" },
+ submittedCount: 0,
+ totalInterns: 6,
isSubmitted: false,
},
],
@@ -101,24 +111,32 @@ export const mockProjects: Project[] = [
title: "Analisis Kebutuhan Sistem",
description: "Dokumentasi kebutuhan fungsional dan non-fungsional platform rekrutmen",
deadline: { date: new Date(2026, 4, 5), label: "Analisis Kebutuhan – 5 Mei", time: "23:59 PM" },
+ submittedCount: 6,
+ totalInterns: 6,
isSubmitted: true,
},
{
title: "Desain Database Schema",
description: "Rancangan struktur database untuk kandidat, lowongan, dan proses seleksi",
deadline: { date: new Date(2026, 4, 10), label: "Desain Database – 10 Mei", time: "23:59 PM" },
+ submittedCount: 6,
+ totalInterns: 6,
isSubmitted: true,
},
{
title: "Implementasi Auth Module",
description: "Pengembangan sistem autentikasi dan otorisasi multi-role",
deadline: { date: new Date(2026, 4, 18), label: "Auth Module – 18 Mei", time: "23:59 PM" },
+ submittedCount: 3,
+ totalInterns: 6,
isSubmitted: true,
},
{
title: "Modul Posting Lowongan",
description: "Fitur buat, edit, dan publish lowongan pekerjaan",
deadline: { date: new Date(2026, 4, 25), label: "Posting Lowongan – 25 Mei", time: "23:59 PM" },
+ submittedCount: 0,
+ totalInterns: 6,
isSubmitted: false,
},
],
@@ -146,25 +164,33 @@ export const mockProjects: Project[] = [
title: "Setup Pipeline Data",
description: "Konfigurasi ETL pipeline dari database transaksi ke data warehouse",
deadline: { date: new Date(2026, 4, 3), label: "Setup Pipeline – 3 Mei", time: "23:59 PM" },
+ submittedCount: 6,
+ totalInterns: 6,
isSubmitted: true,
},
{
title: "Desain Komponen Chart",
description: "Pembuatan reusable chart component untuk berbagai tipe visualisasi data",
deadline: { date: new Date(2026, 4, 12), label: "Komponen Chart – 12 Mei", time: "23:59 PM" },
+ submittedCount: 6,
+ totalInterns: 6,
isSubmitted: true,
},
{
title: "Dashboard Overview Page",
description: "Halaman utama dengan ringkasan KPI dan metric utama bisnis",
deadline: { date: new Date(2026, 4, 20), label: "Overview Page – 20 Mei", time: "23:59 PM" },
- isSubmitted: true,
+ submittedCount: 0,
+ totalInterns: 6,
+ isSubmitted: false,
},
{
title: "Laporan Penjualan",
description: "Modul analitik penjualan dengan filter periode dan kategori produk",
deadline: { date: new Date(2026, 4, 28), label: "Laporan Penjualan – 28 Mei", time: "23:59 PM" },
- isSubmitted: true,
+ submittedCount: 0,
+ totalInterns: 6,
+ isSubmitted: false,
},
],
interns: [
@@ -182,8 +208,34 @@ export const mockProjects: Project[] = [
},
];
-export const certificateData = {
- isReceived: true, // ubah ke false untuk tampilan "belum tersedia"
+export interface Certificate {
+ id: string;
+ issuedDate: string;
+ recipientName: string;
+ programName: string;
+ duration: string;
+ finalScore: number;
+ grade: string;
+ status: string;
+}
+
+export interface CertificateHistory {
+ id: number;
+ month: string;
+ title: string;
+ grade: string;
+}
+
+export interface CertificateData {
+ isReceived: boolean;
+ projectProgress: number;
+ remainingTasks: number;
+ certificate: Certificate;
+ history: CertificateHistory[];
+}
+
+export const certificateData: CertificateData = {
+ isReceived: false, // ubah ke false untuk tampilan "belum tersedia"
projectProgress: 65,
remainingTasks: 3,
certificate: {
@@ -208,12 +260,6 @@ export const certificateData = {
month: "Maret 2023",
title: "UI/UX Design Essentials",
grade: "A",
- },
- {
- id: 3,
- month: "Januari 2023",
- title: "Data Analytics Bootcamp",
- grade: "B+",
- },
+ }
],
};