[TEST DONE] Checking Sertification generation for mentor/admin and view on intern
This commit is contained in:
@@ -5,10 +5,10 @@ import CertificateAvailable from "./components/CertificateAvailabe";
|
||||
import CertificateNotAvailable from "./components/CertificateNotAvailable";
|
||||
import SertificateHistory from "./components/CertificateHistory";
|
||||
|
||||
import { useClaimCertificate } from "../../../hooks/useCertificates";
|
||||
// import { useClaimCertificate } from "../../../hooks/useCertificates";
|
||||
import { useProjectDetail } from "../../../hooks/useProjects";
|
||||
|
||||
import { useProjectCertificates } from "../../../hooks/useCertificates";
|
||||
import { useMyCertificates } from "../../../hooks/useCertificates";
|
||||
import type { Project } from "../../../types/project.types";
|
||||
|
||||
export default function InternCertificateDetail () {
|
||||
@@ -17,8 +17,8 @@ export default function InternCertificateDetail () {
|
||||
const projectFromList = location.state?.project as Project | undefined;
|
||||
|
||||
const { project: projectDetail, loading: projectLoading } = useProjectDetail(slug ?? "");
|
||||
const { certificates, loading: certLoading, refetch: refetchCertificates } = useProjectCertificates(projectDetail?.id ?? 0);
|
||||
const { claim, loading: claiming, error: claimError } = useClaimCertificate();
|
||||
const { certificates, loading: certLoading, refetch: refetchCertificates } = useMyCertificates();
|
||||
// const { claim, loading: claiming, error: claimError } = useClaimCertificate();
|
||||
|
||||
const myCertificateForProject = useMemo(() => {
|
||||
if (!projectDetail) return null;
|
||||
@@ -43,13 +43,13 @@ export default function InternCertificateDetail () {
|
||||
const remainingTasks = project ? project.total_tasks - project.task_done : 0;
|
||||
const isLoading = projectLoading || certLoading;
|
||||
|
||||
const handleClaim = async () => {
|
||||
if (!project?.id) return;
|
||||
const result = await claim(project.id);
|
||||
if (result) {
|
||||
refetchCertificates();
|
||||
}
|
||||
};
|
||||
// const handleClaim = async () => {
|
||||
// if (!project?.id) return;
|
||||
// const result = await claim(project.id);
|
||||
// if (result) {
|
||||
// refetchCertificates();
|
||||
// }
|
||||
// };
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
@@ -78,9 +78,9 @@ export default function InternCertificateDetail () {
|
||||
progress={progress}
|
||||
remainingTasks={remainingTasks}
|
||||
allTasksDone={allTasksDone}
|
||||
onClaim={handleClaim}
|
||||
claiming={claiming}
|
||||
claimError={claimError}
|
||||
// onClaim={handleClaim}
|
||||
// claiming={claiming}
|
||||
// claimError={claimError}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -22,7 +22,7 @@ export default function CertificateAvailable({ project, certificate, templateUrl
|
||||
useEffect(() => {
|
||||
if (!templateUrl) return;
|
||||
|
||||
generateCertificate(resolveImageUrl(templateUrl), certificate.user.full_name)
|
||||
generateCertificate(resolveImageUrl(templateUrl), certificate.user.full_name, certificate.project.project_name, certificate.certificate_no, certificate.uuid)
|
||||
.then((blob) => {
|
||||
const url = URL.createObjectURL(blob);
|
||||
setPreviewUrl(url);
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { History, Loader2, AlertCircle } from "lucide-react";
|
||||
import type { Certificate } from "../../../../types/certificate.types";
|
||||
import { useMyCertificates } from "../../../../hooks/useCertificates";
|
||||
|
||||
export default function SertificateHistory() {
|
||||
const navigate = useNavigate();
|
||||
const { certificates, loading, error } = useMyCertificates();
|
||||
const displayed = certificates.slice(0, 2);
|
||||
const displayed = certificates.slice(0, 3);
|
||||
|
||||
return (
|
||||
<div className="bg-box-primary rounded-2xl border border-box-border shadow-sm p-5">
|
||||
@@ -56,15 +54,6 @@ export default function SertificateHistory() {
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="w-full my-3 flex justify-end">
|
||||
<button
|
||||
onClick={() => navigate('/intern/certificates/all')}
|
||||
className="text-sm text-red-700 font-semibold hover:underline"
|
||||
>
|
||||
See more
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -5,18 +5,18 @@ interface CertificateNotAvailableProps {
|
||||
progress: number;
|
||||
remainingTasks: number;
|
||||
allTasksDone?: boolean;
|
||||
onClaim: () => void;
|
||||
claiming: boolean;
|
||||
claimError: string | null;
|
||||
// onClaim: () => void;
|
||||
// claiming: boolean;
|
||||
// claimError: string | null;
|
||||
}
|
||||
|
||||
export default function CertificateNotAvailable({
|
||||
progress,
|
||||
remainingTasks,
|
||||
allTasksDone = false,
|
||||
onClaim,
|
||||
claiming,
|
||||
claimError,
|
||||
// onClaim,
|
||||
// claiming,
|
||||
// claimError,
|
||||
}: CertificateNotAvailableProps) {
|
||||
return (
|
||||
<div className="bg-box-primary w-full h-full rounded-2xl border border-box-border shadow-sm px-24 py-12 flex flex-col items-center justify-center">
|
||||
@@ -54,14 +54,14 @@ export default function CertificateNotAvailable({
|
||||
<div className="h-full bg-green-500 rounded-full transition-all duration-700 w-full" />
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
{/* <button
|
||||
onClick={onClaim}
|
||||
disabled={claiming}
|
||||
className="mt-0 px-6 py-2.5 bg-green-600 hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed text-white font-semibold rounded-lg transition-colors duration-200"
|
||||
>
|
||||
{claiming ? "Memproses..." : "Klaim Sertifikat"}
|
||||
</button>
|
||||
{claimError && <p className="text-red-500 text-sm mt-2">{claimError}</p>}
|
||||
{claimError && <p className="text-red-500 text-sm mt-2">{claimError}</p>} */}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
|
||||
@@ -65,7 +65,7 @@ export default function SidebarIntern({ isOpen, closeSidebar }: SidebarProps) {
|
||||
{/* Main nav */}
|
||||
<nav className="flex flex-col gap-0.5">
|
||||
{navItems.map(({ label, icon: Icon, path }) => {
|
||||
const isActive = location.pathname === path || location.pathname.startsWith(path + "/");
|
||||
const isActive = location.pathname === path || location.pathname.startsWith(path + "/intern");
|
||||
return (
|
||||
<button
|
||||
key={path}
|
||||
|
||||
@@ -65,7 +65,7 @@ export default function TaskFormFile({ taskId, projectId, deadline, initialSubmi
|
||||
if (ok) { setFiles([]); setIsEditing(false); }
|
||||
};
|
||||
|
||||
// Sudah ada submission dan tidak sedang edit → tampilkan status
|
||||
// Sudah ada submission dan tidak sedang edit -> tampilkan status
|
||||
if (submission && !isEditing) {
|
||||
return (
|
||||
<SubmitStatusTable
|
||||
|
||||
Reference in New Issue
Block a user