Fix certificate View link (wrong /study/certificate URL), certificates in My Account, name on certificate; v2.10.10
Publish Container / build (push) Successful in 15m29s
Publish Container / build (push) Successful in 15m29s
- Certificate URLs in the account overview and the issuance email pointed at /study/certificate/:token, which the router treated as a lesson page; now /certificate/:token (old links redirect) - My Account Certificates card lists every enrolled study: progress, Generate, View, Copy link, Download PNG, Share - Certificate canvas used a non-existent /api/study-account route and always printed 'Student'; now reads the account name - Panel no longer collapses after generating Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
899e715067
commit
7301982bb1
8 files changed
+123
-30
No files matched your search
@@ -11,6 +11,7 @@ interface CertificateStatus {
|
||||
|
||||
interface Props {
|
||||
studySlug: string
|
||||
onIssued?: () => void
|
||||
}
|
||||
|
||||
function formatDate(iso: string | null) {
|
||||
@@ -115,7 +116,7 @@ function drawCertificate(
|
||||
ctx.fillText('versebyversewithnate.us', W / 2, 490)
|
||||
}
|
||||
|
||||
export function StudyCertificate({ studySlug }: Props) {
|
||||
export function StudyCertificate({ studySlug, onIssued }: Props) {
|
||||
const [status, setStatus] = useState<CertificateStatus | null>(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [issuing, setIssuing] = useState(false)
|
||||
@@ -124,20 +125,27 @@ export function StudyCertificate({ studySlug }: Props) {
|
||||
const canvasRef = useRef<HTMLCanvasElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
fetch(`/api/study-certificate/${studySlug}`)
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
let cancelled = false
|
||||
async function load() {
|
||||
try {
|
||||
const res = await fetch(`/api/study-certificate/${studySlug}`)
|
||||
if (!res.ok) throw new Error('unavailable')
|
||||
const data = await res.json() as CertificateStatus
|
||||
if (cancelled) return
|
||||
setStatus(data)
|
||||
// Try to get display name from account
|
||||
return fetch('/api/study-account')
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data?.displayName) setDisplayName(data.displayName)
|
||||
else if (data?.username) setDisplayName(data.username)
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => setLoading(false))
|
||||
// The name printed on the certificate comes from the signed-in account
|
||||
const auth = await fetch('/api/study-auth/status').then(r => (r.ok ? r.json() : null)).catch(() => null)
|
||||
if (cancelled) return
|
||||
if (auth?.displayName) setDisplayName(auth.displayName)
|
||||
else if (auth?.username) setDisplayName(auth.username)
|
||||
} catch {
|
||||
// leave status null; the panel renders nothing
|
||||
} finally {
|
||||
if (!cancelled) setLoading(false)
|
||||
}
|
||||
}
|
||||
void load()
|
||||
return () => { cancelled = true }
|
||||
}, [studySlug])
|
||||
|
||||
useEffect(() => {
|
||||
@@ -159,6 +167,7 @@ export function StudyCertificate({ studySlug }: Props) {
|
||||
const data = await res.json()
|
||||
if (!res.ok) { setError(data.message ?? 'Failed to issue certificate.'); return }
|
||||
setStatus(prev => prev ? { ...prev, token: data.token, issuedAt: data.issuedAt } : prev)
|
||||
onIssued?.()
|
||||
} catch {
|
||||
setError('Network error. Please try again.')
|
||||
} finally {
|
||||
|
||||
Reference in new issue
Block a user