feat: make certificate page publicly accessible

- Add /certificate/* to public routes in root layout
- Display team leader name instead of current user
- Remove authentication requirement for viewing certificates
- Certificates now work without login

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Maulana Sodiqin
2025-12-10 21:30:28 +07:00
co-authored by Claude
parent c518784810
commit 59c1bb0366
2 changed files with 9 additions and 5 deletions
@@ -5,7 +5,6 @@ import { decodeCertificateId } from '../../../utils/certificate';
import { import {
useTeamById, useTeamById,
useTeamSubmission, useTeamSubmission,
useAuthStore,
} from '@imphnen-frontend-service/service'; } from '@imphnen-frontend-service/service';
import QRCode from 'qrcode'; import QRCode from 'qrcode';
import html2canvas from 'html2canvas'; import html2canvas from 'html2canvas';
@@ -18,7 +17,6 @@ interface DecodedCert {
const CertificatePage: FC = (): ReactElement => { const CertificatePage: FC = (): ReactElement => {
const { certId } = useParams<{ certId: string }>(); const { certId } = useParams<{ certId: string }>();
const navigate = useNavigate(); const navigate = useNavigate();
const { session } = useAuthStore();
const [decodedInfo, setDecodedInfo] = useState<DecodedCert | null>(null); const [decodedInfo, setDecodedInfo] = useState<DecodedCert | null>(null);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const teamNameRef = useRef<HTMLHeadingElement>(null); const teamNameRef = useRef<HTMLHeadingElement>(null);
@@ -100,7 +98,7 @@ const CertificatePage: FC = (): ReactElement => {
}, 0); }, 0);
return () => clearTimeout(timer); return () => clearTimeout(timer);
}, [team?.name, session?.user?.fullname]); }, [team?.name, team?.leader?.fullname]);
// Generate certificate canvas screenshot // Generate certificate canvas screenshot
useEffect(() => { useEffect(() => {
@@ -132,7 +130,7 @@ const CertificatePage: FC = (): ReactElement => {
}; };
generateCertificate(); generateCertificate();
}, [team, submission, qrCodeUrl, session?.user?.fullname]); }, [team, submission, qrCodeUrl]);
// Download certificate // Download certificate
const handleDownloadCertificate = () => { const handleDownloadCertificate = () => {
@@ -337,7 +335,7 @@ const CertificatePage: FC = (): ReactElement => {
margin: 0, margin: 0,
}} }}
> >
{session?.user?.fullname || 'N/A'} {team?.leader?.fullname || 'N/A'}
</h3> </h3>
</div> </div>
+6
View File
@@ -52,6 +52,12 @@ export default function RootLayout() {
return; return;
} }
// Certificate page - allow public access
if (pathname.startsWith('/certificate/')) {
setIsChecking(false);
return;
}
// Require authentication for all other routes // Require authentication for all other routes
if (!session) { if (!session) {
navigate('/auth/login', { replace: true }); navigate('/auth/login', { replace: true });