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:
co-authored by
Claude
parent
c518784810
commit
59c1bb0366
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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 });
|
||||||
|
|||||||
Reference in New Issue
Block a user