feat: add course catalog, enrollment, progress tracking, quizzes, and reviews
Backend changes: - Add Enrollment and LessonProgress models to track user progress - Add UserRole enum (USER, MODERATOR, ADMIN) - Add course verification and moderation fields - New CatalogModule: public course browsing, publishing, verification - New EnrollmentModule: enroll, progress tracking, quiz submission, reviews - Add quiz generation endpoint to LessonsController Frontend changes: - Redesign course viewer: proper course UI with lesson navigation, progress bar - Add beautiful typography styles for course content (prose-course) - Fix first-login bug with token exchange retry logic - New pages: /catalog (public courses), /catalog/[id] (course details), /learning (enrollments) - Add LessonQuiz component with scoring and results - Update sidebar navigation: add Catalog and My Learning links - Add publish/verify buttons in course editor - Integrate enrollment progress tracking with backend All courses now support: sequential progression, quiz tests, reviews, ratings, author verification badges, and full marketplace publishing workflow. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -57,16 +57,30 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
setApiToken(null);
|
||||
return;
|
||||
}
|
||||
api
|
||||
.exchangeToken(session.access_token)
|
||||
.then(({ accessToken }) => {
|
||||
setApiToken(accessToken);
|
||||
setLoading(false);
|
||||
})
|
||||
.catch(() => {
|
||||
setApiToken(null);
|
||||
setLoading(false);
|
||||
});
|
||||
|
||||
let attempt = 0;
|
||||
const maxRetries = 3;
|
||||
|
||||
const tryExchange = () => {
|
||||
api
|
||||
.exchangeToken(session.access_token)
|
||||
.then(({ accessToken }) => {
|
||||
setApiToken(accessToken);
|
||||
setLoading(false);
|
||||
})
|
||||
.catch(() => {
|
||||
attempt++;
|
||||
if (attempt < maxRetries) {
|
||||
// Retry with exponential backoff (500ms, 1500ms, 3500ms)
|
||||
setTimeout(tryExchange, 500 * Math.pow(2, attempt));
|
||||
} else {
|
||||
setApiToken(null);
|
||||
setLoading(false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
tryExchange();
|
||||
}, [session?.access_token]);
|
||||
|
||||
// Exchange Supabase token for backend JWT; keep loading true until done so API calls wait for JWT
|
||||
|
||||
Reference in New Issue
Block a user