From 8b20c118224ab067296b121ea4c6d5b5f30a1686 Mon Sep 17 00:00:00 2001 From: "Kemas M. Aryadary Rasyad" <112590882+aryadary0706@users.noreply.github.com> Date: Tue, 16 Jun 2026 11:47:47 +0700 Subject: [PATCH] feat: update routing parameters, add header component, and refactor project details; enhance breadcrumb labels and task timeline --- src/App.tsx | 7 +- .../Header-internify.tsx} | 6 +- src/Pages/internify/Breadcumbs.tsx | 10 +- src/Pages/internify/intern/ParticipantTab.tsx | 2 +- .../internify/intern/ProjectDetailPage.tsx | 16 +- .../intern/components/TaskTimeline.tsx | 56 ++--- src/Pages/internify/layout.tsx | 2 +- src/Pages/internify/mentor/ProjectsPage.tsx | 4 +- src/lib/mockData.ts | 2 +- src/lib/mockDeadline.ts | 41 ++-- src/lib/mockInterns.ts | 59 +++++ src/lib/mockProjects.ts | 203 ++++++++++++++++++ 12 files changed, 318 insertions(+), 90 deletions(-) rename src/{Pages/internify/mentor/components/Header.tsx => Layout/Header-internify.tsx} (84%) create mode 100644 src/lib/mockInterns.ts diff --git a/src/App.tsx b/src/App.tsx index d0ddcd5..bdbdd16 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -83,13 +83,12 @@ function App() { } /> - {/* // Endpoints for intern-specific pages */} }> } /> } /> } /> - } /> - } /> + } /> + } /> } /> } /> } /> @@ -100,7 +99,7 @@ function App() { } /> } /> } /> - } /> + } /> } /> } /> } /> diff --git a/src/Pages/internify/mentor/components/Header.tsx b/src/Layout/Header-internify.tsx similarity index 84% rename from src/Pages/internify/mentor/components/Header.tsx rename to src/Layout/Header-internify.tsx index 49d5da3..976913b 100644 --- a/src/Pages/internify/mentor/components/Header.tsx +++ b/src/Layout/Header-internify.tsx @@ -1,11 +1,11 @@ import { Bell, Menu } from "lucide-react" -import humiclogo from "../../../../assets/logo.png"; +import humiclogo from "../assets/logo.png"; import { useNavigate } from "react-router-dom"; export default function Header({ toggleSidebar }: { toggleSidebar: () => void }) { const nav = useNavigate(); return ( - + {/* Tombol Burger Menu: Hanya muncul di layar < md */} void }) nav('/intern')}> - + diff --git a/src/Pages/internify/Breadcumbs.tsx b/src/Pages/internify/Breadcumbs.tsx index a3ef985..cfcb985 100644 --- a/src/Pages/internify/Breadcumbs.tsx +++ b/src/Pages/internify/Breadcumbs.tsx @@ -6,19 +6,17 @@ const breadcrumbRoutes = [ // --- AREA INTERN --- { path: '/intern', breadcrumb: 'Home' }, { path: '/intern/projects', breadcrumb: 'Projects' }, - { path: '/intern/projects/:id', breadcrumb: 'Detail Project' }, // Otomatis handle ID dinamis + { path: '/intern/projects/:id', breadcrumb: 'Forum' }, { path: '/intern/certificates', breadcrumb: 'Certificates' }, - { path: '/intern/tasks', breadcrumb: 'Tasks' }, - { path: '/intern/tasks/:id', breadcrumb: 'Detail Task' }, - { path: '/intern/tasks/:id/submit', breadcrumb: 'Submit Task' }, + { path: '/intern/projects/:id/submit', breadcrumb: 'Submit Task' }, { path: '/intern/faq', breadcrumb: 'FAQ' }, { path: '/intern/notifications', breadcrumb: 'Notifications' }, { path: '/intern/settings', breadcrumb: 'Settings' }, // --- AREA MENTOR / ADMIN --- { path: '/mentor', breadcrumb: 'Home' }, - { path: '/mentor/projects', breadcrumb: 'Managed Projects' }, - { path: '/mentor/projects/:id', breadcrumb: 'Project Overview' }, + { path: '/mentor/projects', breadcrumb: 'List Projects' }, + { path: '/mentor/projects/:id', breadcrumb: 'Forum' }, { path: '/mentor/certificates', breadcrumb: 'Approve Certificates' }, { path: '/mentor/intern', breadcrumb: 'List Intern' }, { path: '/mentor/faq', breadcrumb: 'FAQ' }, diff --git a/src/Pages/internify/intern/ParticipantTab.tsx b/src/Pages/internify/intern/ParticipantTab.tsx index 5e71a80..b7d13dd 100644 --- a/src/Pages/internify/intern/ParticipantTab.tsx +++ b/src/Pages/internify/intern/ParticipantTab.tsx @@ -31,7 +31,7 @@ export default function ParticipantsTab({ project }: { project: Project }) { > - {intern.email} + {intern.name} diff --git a/src/Pages/internify/intern/ProjectDetailPage.tsx b/src/Pages/internify/intern/ProjectDetailPage.tsx index 4f208b1..ad43772 100644 --- a/src/Pages/internify/intern/ProjectDetailPage.tsx +++ b/src/Pages/internify/intern/ProjectDetailPage.tsx @@ -1,25 +1,15 @@ import { useState } from 'react'; -import { useNavigate, useParams } from 'react-router-dom'; +import { useParams } from 'react-router-dom'; import { mockProjects } from '../../../lib/mockData'; import ForumTab from './ForumTab'; import ParticipantsTab from './ParticipantTab'; -import { ChevronLeft } from 'lucide-react'; // ─── ProjectDetailPage ───────────────────────────────────────────────────────── export default function ProjectDetailPage() { - const { id } = useParams<{ id: string }>(); - const navigate = useNavigate(); + const { slug } = useParams<{ slug: string }>(); const [activeTab, setActiveTab] = useState<'forum' | 'participants'>('forum'); - const handleBack = () => { - if (window.history.length > 1) { - navigate(-1); - } else { - navigate('/intern/projects'); - } - }; - - const project = mockProjects.find((p) => p.id === Number(id)); + const project = mockProjects.find((p) => p.name === slug); if (!project) { return ( diff --git a/src/Pages/internify/intern/components/TaskTimeline.tsx b/src/Pages/internify/intern/components/TaskTimeline.tsx index cdb85d6..5947724 100644 --- a/src/Pages/internify/intern/components/TaskTimeline.tsx +++ b/src/Pages/internify/intern/components/TaskTimeline.tsx @@ -1,58 +1,44 @@ -import type { TaskTimelineProps } from "../../../../lib/mockDeadline" -import { defaultTasks } from "../../../../lib/mockDeadline" +import { DEADLINES } from "../../../../lib/mockDeadline"; +import type { Deadline } from "../../../../lib/mockDeadline"; -const TaskTimeline = ({ tasks = defaultTasks }: TaskTimelineProps) => { -const today = new Date() +const TaskTimeline = () => { + const today = new Date(); + + const isOverdue = (date: Date) => { + return date < today; + }; - const isOverdue = (tanggal: string) => { - const deadline = new Date(tanggal) - return deadline < today - } - - const upcomingIndex = tasks.findIndex( - task => new Date(task.tanggal) >= today - ) return ( Task Timeline - - {/* Vertical line */} - - + - {tasks.map((task, index) => { - const overdue = isOverdue(task.tanggal) - const isRedDot = overdue || index === upcomingIndex - + {DEADLINES.map((item: Deadline, index: number) => { + const overdue = isOverdue(item.date); return ( - {/* Dot */} - - {/* Content */} - {task.tanggal} + {item.date.toLocaleDateString("id-ID")} - {task.title} - {task.description} + {item.label} + {item.time} - ) + ); })} - ) -} + ); +}; -export default TaskTimeline \ No newline at end of file +export default TaskTimeline; \ No newline at end of file diff --git a/src/Pages/internify/layout.tsx b/src/Pages/internify/layout.tsx index 046bb0b..5da88f8 100644 --- a/src/Pages/internify/layout.tsx +++ b/src/Pages/internify/layout.tsx @@ -1,6 +1,6 @@ import { Outlet } from "react-router-dom"; import { useState } from "react"; -import Header from './mentor/components/Header'; +import Header from '../../Layout/Header-internify'; import SidebarIntern from './intern/components/SidebarIntern'; import SidebarMentor from './mentor/components/SidebarMentor'; import FooterIntern from '../../Layout/Footer-Internify'; diff --git a/src/Pages/internify/mentor/ProjectsPage.tsx b/src/Pages/internify/mentor/ProjectsPage.tsx index bed7947..5ddd195 100644 --- a/src/Pages/internify/mentor/ProjectsPage.tsx +++ b/src/Pages/internify/mentor/ProjectsPage.tsx @@ -8,7 +8,7 @@ import TaskTab from './TaskTab'; // ─── ProjectDetailPage ───────────────────────────────────────────────────────── export default function ProjectDetailPage() { - const { id } = useParams<{ id: string }>(); + const { slug } = useParams<{ slug: string }>(); const navigate = useNavigate(); const [activeTab, setActiveTab] = useState<'forum' | 'participants' | 'Task'>('forum'); @@ -20,7 +20,7 @@ export default function ProjectDetailPage() { } }; - const project = mockProjects.find((p) => p.id === Number(id)); + const project = mockProjects.find((p) => p.name === slug); if (!project) { return ( diff --git a/src/lib/mockData.ts b/src/lib/mockData.ts index 4b1782f..b9ad130 100644 --- a/src/lib/mockData.ts +++ b/src/lib/mockData.ts @@ -101,7 +101,7 @@ export const mockProjects: Project[] = [ { name: "Dewa Aditya", role: "UI/UX", email: "jonathankristina@gmail.com" }, { name: "Eka Pratiwi", role: "UI/UX", email: "jonathankristina@gmail.com" }, ], - mentor: "jonathankristina@gmail.com", + mentor: "jonathankristina", progress: 12, tasksDone: 1, tasksTotal: 8, diff --git a/src/lib/mockDeadline.ts b/src/lib/mockDeadline.ts index 9b4dc02..0a74ae2 100644 --- a/src/lib/mockDeadline.ts +++ b/src/lib/mockDeadline.ts @@ -1,27 +1,20 @@ -interface Task { - tanggal: string - title: string - description: string +export interface Deadline { + date: Date; + label: string; + time: string; } -export interface TaskTimelineProps { - tasks?: Task[] -} +export const DEADLINES: Deadline[] = [ + { + date: new Date(2025, 4, 4), + label: "Laporan Progress 1 Internify – 4 Juni", + time: "23:59 PM", + }, + { + date: new Date(2026, 5, 5), + label: "Laporan Progress 2 Internify - 5 May", + time: "23:59 PM", + }, +]; -export const defaultTasks: Task[] = [ - { - tanggal: '2026-05-14T23:59:00', - title: 'Laporan tugas 1', - description: 'Berisi design uiux, dan user flow dari aplikasi internify', - }, - { - tanggal: '2026-05-15T23:59:00', - title: 'Laporan tugas 1', - description: 'Berisi design uiux, dan user flow dari aplikasi internify', - }, - { - tanggal: '2026-06-20T21:00:00', - title: 'Laporan tugas 1', - description: 'Berisi design uiux, dan user flow dari aplikasi internify', - }, -] \ No newline at end of file +export const deadlineDates: Date[] = DEADLINES.map((d) => d.date); \ No newline at end of file diff --git a/src/lib/mockInterns.ts b/src/lib/mockInterns.ts new file mode 100644 index 0000000..c96f0e9 --- /dev/null +++ b/src/lib/mockInterns.ts @@ -0,0 +1,59 @@ +export interface InternData { + id: number; + name: string; + email: string; + projectName: string; + role: string; + avatar: string; +} + +export const mockInternsData: InternData[] = [ + { + id: 1, + name: "Alex Rivera", + email: "alex.rivera@internify.edu", + projectName: "Internify Project", + role: "UI/UX", + avatar: "https://images.unsplash.com/photo-1534528741775-53994a69daeb?auto=format&fit=crop&w=100&q=80", + }, + { + id: 2, + name: "Sarah Jenkins", + email: "s.jenkins@internify.edu", + projectName: "Internify Project", + role: "Frontend", + avatar: "https://images.unsplash.com/photo-1494790108377-be9c29b29330?auto=format&fit=crop&w=100&q=80", + }, + { + id: 3, + name: "Michael Chen", + email: "m.chen@internify.edu", + projectName: "MBG Project", + role: "Backend", + avatar: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&w=100&q=80", + }, + { + id: 4, + name: "Elena Rodriguez", + email: "e.rod@internify.edu", + projectName: "Unassigned", + role: "-", + avatar: "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?auto=format&fit=crop&w=100&q=80", + }, + { + id: 5, + name: "Alex Rivera", + email: "alex.rivera@internify.edu", + projectName: "Internify Project", + role: "UI/UX", + avatar: "", + }, + { + id: 6, + name: "Sarah Jenkins", + email: "s.jenkins@internify.edu", + projectName: "Internify Project", + role: "Backend", + avatar: "", + }, +]; \ No newline at end of file diff --git a/src/lib/mockProjects.ts b/src/lib/mockProjects.ts index e69de29..5b59301 100644 --- a/src/lib/mockProjects.ts +++ b/src/lib/mockProjects.ts @@ -0,0 +1,203 @@ +import type { Deadline } from "./mockDeadline"; + +export interface Task { + id: number; + title: string; + description: string; + deadline: Deadline; + isSubmitted: boolean; + submittedCount: number; + totalInterns: number; +} + +export interface Intern { + name: string; + role: string; + email: string; +} + +export interface Project { + id: number; + name: string; + description: string; + tasks: Task[]; + interns: Intern[]; + mentor: string; + avatarUrl?: string; + thumbnailUrl?: string; + progress: number; + tasksDone: number; + tasksTotal: number; +} + +export const mockProjects: Project[] = [ + { + id: 1, + name: "Internify Project", + description: + "Internify merupakan website Human Capital (HUMC) yang dirancang sebagai platform pendaftaran dan pengelolaan program magang secara digital. Sistem ini dibuat untuk membantu proses rekrutmen peserta magang mulai dari pendaftaran, seleksi, hingga monitoring aktivitas peserta selama program berlangsung.\n\nFokus utama dari pengembangan Internify adalah pembuatan Learning Management System (LMS) yang digunakan untuk mendukung kegiatan pembelajaran dan pengelolaan peserta magang. LMS pada Internify menyediakan fitur seperti akses materi pembelajaran, pengumpulan tugas, monitoring progress peserta, absensi, sertifikat, hingga komunikasi antara mentor dan peserta magang.", + tasks: [ + { + id: 1, + 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, + }, + { + id: 2, + 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, + }, + { + id: 3, + 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, + }, + { + id: 4, + 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, + }, + ], + interns: [ + { name: "Jonathan Kristina", role: "Backend", email: "jonathankristina@gmail.com" }, + { name: "Anisa Rahmawati", role: "Backend", email: "jonathankristina@gmail.com" }, + { name: "Budi Santoso", role: "Frontend", email: "jonathankristina@gmail.com" }, + { name: "Cindy Permata", role: "Frontend", email: "jonathankristina@gmail.com" }, + { name: "Dewa Aditya", role: "UI/UX", email: "jonathankristina@gmail.com" }, + { name: "Eka Pratiwi", role: "UI/UX", email: "jonathankristina@gmail.com" }, + ], + mentor: "jonathankristina@gmail.com", + progress: 12, + tasksDone: 1, + tasksTotal: 8, + }, + { + id: 2, + name: "Rekrutmen Digital Platform", + description: + "Platform digital yang memudahkan proses rekrutmen karyawan baru secara end-to-end. Mulai dari posting lowongan, screening CV otomatis, penjadwalan wawancara, hingga onboarding karyawan baru.\n\nSistem ini mengintegrasikan berbagai modul HR seperti manajemen data kandidat, penilaian kompetensi berbasis AI, dan dashboard analytics untuk tim HR dalam mengambil keputusan rekrutmen yang lebih efektif dan efisien.", + tasks: [ + { + id: 1, + 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, + }, + { + id: 2, + 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, + }, + { + id: 3, + 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, + }, + { + id: 4, + 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, + }, + ], + interns: [ + { name: "Fajar Nugroho", role: "Backend", email: "fajarnugroho@gmail.com" }, + { name: "Gita Melinda", role: "Backend", email: "gitamelinda@gmail.com" }, + { name: "Hendra Wijaya", role: "Frontend", email: "hendrawijaya@gmail.com" }, + { name: "Indira Sari", role: "Frontend", email: "indirasari@gmail.com" }, + { name: "Joko Purnomo", role: "UI/UX", email: "jokopurnomo@gmail.com" }, + { name: "Kartika Dewi", role: "QA", email: "kartikadewi@gmail.com" }, + { name: "Lukman Hakim", role: "QA", email: "lukmanhakim@gmail.com" }, + ], + mentor: "seniormHR@company.com", + progress: 37, + tasksDone: 3, + tasksTotal: 8, + }, + { + id: 3, + name: "E-Commerce Analytics Dashboard", + description: + "Dashboard analitik komprehensif untuk platform e-commerce yang menyajikan insight real-time tentang performa penjualan, perilaku pelanggan, dan efektivitas kampanye marketing.\n\nProyek ini mencakup pengembangan pipeline data dari berbagai sumber transaksi, visualisasi interaktif menggunakan chart library modern, serta fitur export laporan dalam berbagai format untuk kebutuhan manajemen bisnis.", + tasks: [ + { + id: 1, + 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, + }, + { + id: 2, + 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, + }, + { + id: 3, + 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" }, + submittedCount: 0, + totalInterns: 6, + isSubmitted: false, + }, + { + id: 4, + 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" }, + submittedCount: 0, + totalInterns: 6, + isSubmitted: false, + }, + ], + interns: [ + { name: "Maya Anggraeni", role: "Backend", email: "mayaanggraeni@gmail.com" }, + { name: "Nando Pratama", role: "Backend", email: "nandopratama@gmail.com" }, + { name: "Olivia Susanto", role: "Frontend", email: "oliviasusanto@gmail.com" }, + { name: "Pandu Kusuma", role: "Frontend", email: "pandukukusuma@gmail.com" }, + { name: "Qori Ramadhan", role: "Data Analyst", email: "qoriramadhan@gmail.com" }, + { name: "Rini Handayani", role: "UI/UX", email: "rinihandayani@gmail.com" }, + ], + mentor: "leadanalyst@company.com", + progress: 50, + tasksDone: 4, + tasksTotal: 8, + }, +]; \ No newline at end of file
- {task.tanggal} + {item.date.toLocaleDateString("id-ID")}
{task.title}
{task.description}
{item.label}
{item.time}