feat: update certificate handling and project management features

- Refactored CertificateHistory component to display dynamic certificate images.
- Modified CertificateNotAvailable component text for clarity on certificate publication.
- Enhanced CertificateForm to include file preview and clear functionality for uploaded images.
- Removed obsolete CertificatePage component to streamline mentor interface.
- Updated CertificateResult to handle project details and loading states more effectively.
- Improved HomeMentorPage structure by adjusting imports for better organization.
- Enhanced EligibleInternTable with navigation to results and improved error handling for certificate generation.
- Updated HomeMentorProject styles for consistency with design system.
- Added utility function to resolve image URLs for certificates.
- Introduced new hooks for generating certificates and managing notifications.
- Expanded project service functions to include project completion and assignable interns retrieval.
- Updated types for certificates and projects to reflect new data structures.
- Added user types for better type safety in user management.
This commit is contained in:
Kemas M. Aryadary Rasyad
2026-07-02 10:27:28 +07:00
parent 7fffc08912
commit 5dec77862c
23 changed files with 326 additions and 350 deletions
@@ -78,7 +78,8 @@ export default function EligibleInternTable({
};
const handleGenerate = async () => {
if (!project?.template_sertificate) {
// NOTE: DI RESPONSE GAK DIKASIH TAHU DIMANA SIMPAN TEMPLATE SERTIF NYA
if (!project?.certificate_template) {
setGenerateError("Template sertifikat belum diupload.");
return;
}
@@ -98,7 +99,7 @@ export default function EligibleInternTable({
await Promise.all(
selectedInterns.map(async (intern) => {
const blob = await generateCertificate(
project.template_sertificate,
project.certificate_template,
intern.full_name
);
// Nama file: "Sertifikat - Nama Intern.png"
@@ -286,7 +287,12 @@ export default function EligibleInternTable({
)}
{/* Bottom Action Bar */}
<div className="flex items-center justify-end">
<div className="flex items-center justify-between">
<button
className="text-gray-700 hover:underline"
onClick={()=> navigate(`/mentor/certificates/${project?.slug}/result`)}>
Ke Hasil
</button>
<button
onClick={handleGenerate}
disabled={generating || selected.size === 0}
@@ -304,6 +310,7 @@ export default function EligibleInternTable({
</>
)}
</button>
</div>
</div>
);