Hide Enroll for planned studies (Coming soon) and reject planned enrollments server-side; v2.8.3
Publish Container / build (push) Has been cancelled

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-10-07 14:56:17 -04:00
1 parent b1695b2b59
commit db1737baf3
3 files changed
+20 -9

No files matched your search

+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "siteforge", "name": "siteforge",
"private": true, "private": true,
"version": "2.8.2", "version": "2.8.3",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
+5
View File
@@ -59,6 +59,11 @@ export function register(app) {
const enrolled = Array.isArray(user.enrolledStudySlugs) ? user.enrolledStudySlugs : [] const enrolled = Array.isArray(user.enrolledStudySlugs) ? user.enrolledStudySlugs : []
if (!enrolled.includes(studySlug)) { if (!enrolled.includes(studySlug)) {
const catalogEntry = getStudyCatalog().find(study => study.slug === studySlug)
if (catalogEntry?.status === 'planned') {
res.status(400).json({ message: 'This study is not open for enrollment yet.' })
return
}
user.enrolledStudySlugs = [...enrolled, studySlug].slice(0, MAX_STUDY_ENROLLMENTS_PER_USER) user.enrolledStudySlugs = [...enrolled, studySlug].slice(0, MAX_STUDY_ENROLLMENTS_PER_USER)
user.updatedAt = new Date().toISOString() user.updatedAt = new Date().toISOString()
queueStudyUsersWrite() queueStudyUsersWrite()
+14 -8
View File
@@ -806,6 +806,8 @@ export function StudyLandingPage({ content }: Props) {
>{enrollBusySlug === studyInfo.slug ? 'Working…' : 'Yes, leave'}</button> >{enrollBusySlug === studyInfo.slug ? 'Working…' : 'Yes, leave'}</button>
<button type="button" className="btn-secondary" style={{ fontSize: '0.85rem', padding: '0.3rem 0.75rem' }} onClick={() => setConfirmLeaveSlug(null)}>Cancel</button> <button type="button" className="btn-secondary" style={{ fontSize: '0.85rem', padding: '0.3rem 0.75rem' }} onClick={() => setConfirmLeaveSlug(null)}>Cancel</button>
</div> </div>
) : !studyInfo.enrolled && studyInfo.status === 'planned' ? (
<span style={{ fontSize: '0.85rem', color: '#b09e79' }}>Coming soon</span>
) : ( ) : (
<button <button
type="button" type="button"
@@ -3284,14 +3286,18 @@ export function StudyAccountPage() {
<h3 style={{ margin: '0.35rem 0 0' }}>{studyInfo.title}</h3> <h3 style={{ margin: '0.35rem 0 0' }}>{studyInfo.title}</h3>
<p style={{ margin: '0.4rem 0 0', fontSize: '0.9rem' }}>{studyInfo.completedLessons} of {studyInfo.totalLessons} lessons completed · {studyInfo.noteCount} notes</p> <p style={{ margin: '0.4rem 0 0', fontSize: '0.9rem' }}>{studyInfo.completedLessons} of {studyInfo.totalLessons} lessons completed · {studyInfo.noteCount} notes</p>
</div> </div>
<button {!studyInfo.enrolled && studyInfo.status === 'planned' ? (
type="button" <span style={{ fontSize: '0.85rem', color: '#b09e79' }}>Coming soon</span>
className={studyInfo.enrolled ? 'btn-admin-remove' : 'btn-primary'} ) : (
disabled={enrollBusySlug === studyInfo.slug} <button
onClick={() => handleEnrollmentToggle(studyInfo.slug, studyInfo.enrolled)} type="button"
> className={studyInfo.enrolled ? 'btn-admin-remove' : 'btn-primary'}
{enrollBusySlug === studyInfo.slug ? 'Working…' : studyInfo.enrolled ? 'Leave' : 'Enroll'} disabled={enrollBusySlug === studyInfo.slug}
</button> onClick={() => handleEnrollmentToggle(studyInfo.slug, studyInfo.enrolled)}
>
{enrollBusySlug === studyInfo.slug ? 'Working…' : studyInfo.enrolled ? 'Leave' : 'Enroll'}
</button>
)}
</div> </div>
</div> </div>
))} ))}