feat: add CertificateForm and CertificateResult components for managing intern certificates

- Implemented CertificateForm for uploading certificate templates and displaying project details.
- Created CertificateResult to show generated certificates with pagination and search functionality.
- Added EligibleInternTable component to display eligible interns and their progress.
- Updated CertificateListPage to reflect changes in project listing styles.
- Enhanced MentorProjectCard with dynamic icon rendering.
- Introduced useProjectInternProgress hook for fetching intern progress data.
- Modified ProjectService to include task details in project responses.
- Updated project types to accommodate new task structures.
This commit is contained in:
Kemas M. Aryadary Rasyad
2026-06-28 22:22:03 +07:00
parent 37e21a1f39
commit 732684200f
17 changed files with 612 additions and 371 deletions
+7 -9
View File
@@ -1,11 +1,11 @@
import { useNavigate } from "react-router-dom";
import { Home, ArrowLeft, Search } from "lucide-react";
import { Home, ArrowLeft } from "lucide-react";
export default function NotFoundPage() {
const navigate = useNavigate();
return (
<div className="min-h-screen bg-gradient-to-br from-slate-950 via-slate-900 to-red-950 flex items-center justify-center px-6 relative overflow-hidden">
<div className="min-h-screen bg-gradient-to-br from-slate-150 via-slate-300 to-gray-50 flex items-center justify-center px-6 relative overflow-hidden">
{/* Background decorative blobs */}
<div className="absolute top-0 left-1/4 w-96 h-96 bg-red-700 opacity-10 rounded-full blur-3xl pointer-events-none" />
<div className="absolute bottom-0 right-1/4 w-96 h-96 bg-red-500 opacity-10 rounded-full blur-3xl pointer-events-none" />
@@ -14,23 +14,21 @@ export default function NotFoundPage() {
{/* 404 Large Text */}
<div className="relative mb-4 select-none">
<span className="text-[160px] sm:text-[200px] font-black leading-none bg-gradient-to-b from-white/20 to-white/5 bg-clip-text text-transparent">
<span className="text-[160px] sm:text-[200px] font-black leading-none bg-gradient-to-b from-red to-red/10 bg-clip-text text-transparent">
404
</span>
<div className="absolute inset-0 flex items-center justify-center">
<Search className="w-20 h-20 sm:w-28 sm:h-28 text-red-500 opacity-80 drop-shadow-lg" />
</div>
</div>
{/* Title */}
<h1 className="text-3xl sm:text-4xl font-bold text-white mb-3 tracking-tight">
Halaman Tidak Ditemukan
Not Found
</h1>
{/* Description */}
<p className="text-slate-400 text-base sm:text-lg mb-10 max-w-md leading-relaxed">
Sepertinya halaman yang kamu cari tidak ada atau telah dipindahkan.
Coba kembali ke halaman sebelumnya atau beranda.
<p className="text-slate-800 text-base sm:text-lg mb-10 max-w-md leading-relaxed">
Sorry, the page you are looking for does not exist or has been moved. Let's get back on track.
</p>
{/* Divider */}
@@ -40,7 +38,7 @@ export default function NotFoundPage() {
<div className="flex flex-col sm:flex-row gap-4 w-full sm:w-auto">
<button
onClick={() => navigate(-1)}
className="flex items-center justify-center gap-2 px-6 py-3 rounded-xl border border-white/10 bg-white/5 hover:bg-white/10 text-white font-semibold text-sm transition-all active:scale-95 backdrop-blur-sm"
className="flex items-center justify-center gap-2 px-6 py-3 rounded-xl border border-white/10 bg-white/30 hover:bg-white/15 text-white font-semibold text-sm transition-all active:scale-95 backdrop-blur-sm"
>
<ArrowLeft className="w-4 h-4" />
Kembali