import { EnrollmentService } from "./chunk-AALWYTMW.js"; import { getErrorMessage } from "./chunk-QDZ3GX5R.js"; import { CourseService } from "./chunk-6K3TDILH.js"; import { NzMessageService } from "./chunk-GJYGTZ7J.js"; import { ActivatedRoute, AuthService, NzIconDirective, NzIconModule, Router } from "./chunk-2TRRHRR7.js"; import "./chunk-EDRPZB37.js"; import { Component, catchError, computed, forkJoin, inject, of, setClassMetadata, signal, ɵsetClassDebugInfo, ɵɵProvidersFeature, ɵɵadvance, ɵɵconditional, ɵɵconditionalCreate, ɵɵdefineComponent, ɵɵelement, ɵɵelementEnd, ɵɵelementStart, ɵɵgetCurrentView, ɵɵlistener, ɵɵnextContext, ɵɵproperty, ɵɵrepeater, ɵɵrepeaterCreate, ɵɵresetView, ɵɵrestoreView, ɵɵstyleProp, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate4 } from "./chunk-WI7WFVZR.js"; import "./chunk-WDMUDEB6.js"; // src/app/pages/course-viewer/course-viewer.ts var _forTrack0 = ($index, $item) => $item.id; function CourseViewerPage_Conditional_1_Template(rf, ctx) { if (rf & 1) { \u0275\u0275elementStart(0, "div", 1); \u0275\u0275element(1, "span", 2); \u0275\u0275elementEnd(); } } function CourseViewerPage_Conditional_2_Conditional_4_Template(rf, ctx) { if (rf & 1) { const _r3 = \u0275\u0275getCurrentView(); \u0275\u0275elementStart(0, "button", 20); \u0275\u0275listener("click", function CourseViewerPage_Conditional_2_Conditional_4_Template_button_click_0_listener() { \u0275\u0275restoreView(_r3); const ctx_r1 = \u0275\u0275nextContext(2); return \u0275\u0275resetView(ctx_r1.editCourse()); }); \u0275\u0275element(1, "span", 21); \u0275\u0275text(2, " Modifier "); \u0275\u0275elementEnd(); } } function CourseViewerPage_Conditional_2_Conditional_20_Conditional_8_Template(rf, ctx) { if (rf & 1) { \u0275\u0275elementStart(0, "p", 27); \u0275\u0275text(1); \u0275\u0275elementEnd(); } if (rf & 2) { const ctx_r1 = \u0275\u0275nextContext(3); \u0275\u0275advance(); \u0275\u0275textInterpolate4(" ", ctx_r1.progress().completedTopics, "/", ctx_r1.progress().totalTopics, " sujets \xB7 ", ctx_r1.progress().completedResources, "/", ctx_r1.progress().totalResources, " ressources "); } } function CourseViewerPage_Conditional_2_Conditional_20_Template(rf, ctx) { if (rf & 1) { \u0275\u0275elementStart(0, "div", 15)(1, "div", 22)(2, "span", 23); \u0275\u0275text(3, "Progression"); \u0275\u0275elementEnd(); \u0275\u0275elementStart(4, "span", 24); \u0275\u0275text(5); \u0275\u0275elementEnd()(); \u0275\u0275elementStart(6, "div", 25); \u0275\u0275element(7, "div", 26); \u0275\u0275elementEnd(); \u0275\u0275conditionalCreate(8, CourseViewerPage_Conditional_2_Conditional_20_Conditional_8_Template, 2, 4, "p", 27); \u0275\u0275elementEnd(); } if (rf & 2) { const ctx_r1 = \u0275\u0275nextContext(2); \u0275\u0275advance(5); \u0275\u0275textInterpolate1("", ctx_r1.progressPercent(), "%"); \u0275\u0275advance(2); \u0275\u0275styleProp("width", ctx_r1.progressPercent(), "%"); \u0275\u0275advance(); \u0275\u0275conditional(ctx_r1.progress() ? 8 : -1); } } function CourseViewerPage_Conditional_2_Conditional_21_Conditional_1_Template(rf, ctx) { if (rf & 1) { \u0275\u0275element(0, "span", 29); \u0275\u0275text(1, " Inscription... "); } } function CourseViewerPage_Conditional_2_Conditional_21_Conditional_2_Template(rf, ctx) { if (rf & 1) { \u0275\u0275text(0, " Commencer ce cours \u2192 "); } } function CourseViewerPage_Conditional_2_Conditional_21_Template(rf, ctx) { if (rf & 1) { const _r4 = \u0275\u0275getCurrentView(); \u0275\u0275elementStart(0, "button", 28); \u0275\u0275listener("click", function CourseViewerPage_Conditional_2_Conditional_21_Template_button_click_0_listener() { \u0275\u0275restoreView(_r4); const ctx_r1 = \u0275\u0275nextContext(2); return \u0275\u0275resetView(ctx_r1.enroll()); }); \u0275\u0275conditionalCreate(1, CourseViewerPage_Conditional_2_Conditional_21_Conditional_1_Template, 2, 0)(2, CourseViewerPage_Conditional_2_Conditional_21_Conditional_2_Template, 1, 0); \u0275\u0275elementEnd(); } if (rf & 2) { const ctx_r1 = \u0275\u0275nextContext(2); \u0275\u0275property("disabled", ctx_r1.enrolling()); \u0275\u0275advance(); \u0275\u0275conditional(ctx_r1.enrolling() ? 1 : 2); } } function CourseViewerPage_Conditional_2_Conditional_25_Template(rf, ctx) { if (rf & 1) { \u0275\u0275elementStart(0, "div", 19)(1, "p"); \u0275\u0275text(2, "Ce cours ne contient pas encore de sujets."); \u0275\u0275elementEnd()(); } } function CourseViewerPage_Conditional_2_Conditional_26_For_1_Conditional_7_Template(rf, ctx) { if (rf & 1) { \u0275\u0275elementStart(0, "p", 35); \u0275\u0275text(1); \u0275\u0275elementEnd(); } if (rf & 2) { const topic_r6 = \u0275\u0275nextContext().$implicit; \u0275\u0275advance(); \u0275\u0275textInterpolate(topic_r6.description); } } function CourseViewerPage_Conditional_2_Conditional_26_For_1_Conditional_11_Template(rf, ctx) { if (rf & 1) { const _r7 = \u0275\u0275getCurrentView(); \u0275\u0275elementStart(0, "button", 41); \u0275\u0275listener("click", function CourseViewerPage_Conditional_2_Conditional_26_For_1_Conditional_11_Template_button_click_0_listener($event) { \u0275\u0275restoreView(_r7); const topic_r6 = \u0275\u0275nextContext().$implicit; const ctx_r1 = \u0275\u0275nextContext(3); return \u0275\u0275resetView(ctx_r1.markTopicDone(topic_r6, $event)); }); \u0275\u0275element(1, "span", 42); \u0275\u0275elementEnd(); } } function CourseViewerPage_Conditional_2_Conditional_26_For_1_Conditional_13_For_2_Conditional_8_Template(rf, ctx) { if (rf & 1) { const _r8 = \u0275\u0275getCurrentView(); \u0275\u0275elementStart(0, "button", 50); \u0275\u0275listener("click", function CourseViewerPage_Conditional_2_Conditional_26_For_1_Conditional_13_For_2_Conditional_8_Template_button_click_0_listener($event) { \u0275\u0275restoreView(_r8); const resource_r9 = \u0275\u0275nextContext().$implicit; const ctx_r1 = \u0275\u0275nextContext(5); return \u0275\u0275resetView(ctx_r1.markResourceDone(resource_r9, $event)); }); \u0275\u0275element(1, "span", 51); \u0275\u0275elementEnd(); } } function CourseViewerPage_Conditional_2_Conditional_26_For_1_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) { \u0275\u0275elementStart(0, "div", 43)(1, "div", 44); \u0275\u0275element(2, "span", 45); \u0275\u0275elementEnd(); \u0275\u0275elementStart(3, "div", 46)(4, "p", 47); \u0275\u0275text(5); \u0275\u0275elementEnd(); \u0275\u0275elementStart(6, "span", 48); \u0275\u0275text(7); \u0275\u0275elementEnd()(); \u0275\u0275conditionalCreate(8, CourseViewerPage_Conditional_2_Conditional_26_For_1_Conditional_13_For_2_Conditional_8_Template, 2, 0, "button", 49); \u0275\u0275elementEnd(); } if (rf & 2) { const resource_r9 = ctx.$implicit; const ctx_r1 = \u0275\u0275nextContext(5); \u0275\u0275advance(2); \u0275\u0275property("nzType", ctx_r1.getResourceIcon(resource_r9.type)); \u0275\u0275advance(3); \u0275\u0275textInterpolate(resource_r9.title); \u0275\u0275advance(2); \u0275\u0275textInterpolate(resource_r9.type); \u0275\u0275advance(); \u0275\u0275conditional(ctx_r1.isEnrolled() ? 8 : -1); } } function CourseViewerPage_Conditional_2_Conditional_26_For_1_Conditional_13_Template(rf, ctx) { if (rf & 1) { \u0275\u0275elementStart(0, "div", 40); \u0275\u0275repeaterCreate(1, CourseViewerPage_Conditional_2_Conditional_26_For_1_Conditional_13_For_2_Template, 9, 4, "div", 43, _forTrack0); \u0275\u0275elementEnd(); } if (rf & 2) { const topic_r6 = \u0275\u0275nextContext().$implicit; \u0275\u0275advance(); \u0275\u0275repeater(topic_r6.resources); } } function CourseViewerPage_Conditional_2_Conditional_26_For_1_Template(rf, ctx) { if (rf & 1) { const _r5 = \u0275\u0275getCurrentView(); \u0275\u0275elementStart(0, "div", 30)(1, "div", 31); \u0275\u0275listener("click", function CourseViewerPage_Conditional_2_Conditional_26_For_1_Template_div_click_1_listener() { const topic_r6 = \u0275\u0275restoreView(_r5).$implicit; const ctx_r1 = \u0275\u0275nextContext(3); return \u0275\u0275resetView(ctx_r1.toggleTopic(topic_r6.id)); }); \u0275\u0275elementStart(2, "div", 32); \u0275\u0275text(3); \u0275\u0275elementEnd(); \u0275\u0275elementStart(4, "div", 33)(5, "h3", 34); \u0275\u0275text(6); \u0275\u0275elementEnd(); \u0275\u0275conditionalCreate(7, CourseViewerPage_Conditional_2_Conditional_26_For_1_Conditional_7_Template, 2, 1, "p", 35); \u0275\u0275elementStart(8, "span", 36); \u0275\u0275text(9); \u0275\u0275elementEnd()(); \u0275\u0275elementStart(10, "div", 37); \u0275\u0275conditionalCreate(11, CourseViewerPage_Conditional_2_Conditional_26_For_1_Conditional_11_Template, 2, 0, "button", 38); \u0275\u0275element(12, "span", 39); \u0275\u0275elementEnd()(); \u0275\u0275conditionalCreate(13, CourseViewerPage_Conditional_2_Conditional_26_For_1_Conditional_13_Template, 3, 0, "div", 40); \u0275\u0275elementEnd(); } if (rf & 2) { const topic_r6 = ctx.$implicit; const ctx_r1 = \u0275\u0275nextContext(3); \u0275\u0275advance(3); \u0275\u0275textInterpolate(topic_r6.position); \u0275\u0275advance(3); \u0275\u0275textInterpolate(topic_r6.title); \u0275\u0275advance(); \u0275\u0275conditional(topic_r6.description ? 7 : -1); \u0275\u0275advance(2); \u0275\u0275textInterpolate2(" ", topic_r6.resources.length, " ressource", topic_r6.resources.length !== 1 ? "s" : "", " "); \u0275\u0275advance(2); \u0275\u0275conditional(ctx_r1.isEnrolled() ? 11 : -1); \u0275\u0275advance(); \u0275\u0275property("nzType", ctx_r1.isTopicExpanded(topic_r6.id) ? "menu-fold" : "menu-unfold"); \u0275\u0275advance(); \u0275\u0275conditional(ctx_r1.isTopicExpanded(topic_r6.id) && topic_r6.resources.length > 0 ? 13 : -1); } } function CourseViewerPage_Conditional_2_Conditional_26_Template(rf, ctx) { if (rf & 1) { \u0275\u0275repeaterCreate(0, CourseViewerPage_Conditional_2_Conditional_26_For_1_Template, 14, 8, "div", 30, _forTrack0); } if (rf & 2) { const ctx_r1 = \u0275\u0275nextContext(2); \u0275\u0275repeater(ctx_r1.course().topics); } } function CourseViewerPage_Conditional_2_Template(rf, ctx) { if (rf & 1) { const _r1 = \u0275\u0275getCurrentView(); \u0275\u0275elementStart(0, "div", 3)(1, "div", 4)(2, "button", 5); \u0275\u0275listener("click", function CourseViewerPage_Conditional_2_Template_button_click_2_listener() { \u0275\u0275restoreView(_r1); const ctx_r1 = \u0275\u0275nextContext(); return \u0275\u0275resetView(ctx_r1.goBack()); }); \u0275\u0275element(3, "span", 6); \u0275\u0275elementEnd(); \u0275\u0275conditionalCreate(4, CourseViewerPage_Conditional_2_Conditional_4_Template, 3, 0, "button", 7); \u0275\u0275elementEnd(); \u0275\u0275elementStart(5, "div", 8)(6, "span", 9); \u0275\u0275text(7, "COMMUNAUT\xC9"); \u0275\u0275elementEnd(); \u0275\u0275elementStart(8, "h1", 10); \u0275\u0275text(9); \u0275\u0275elementEnd(); \u0275\u0275elementStart(10, "p", 11); \u0275\u0275text(11); \u0275\u0275elementEnd(); \u0275\u0275elementStart(12, "div", 12); \u0275\u0275element(13, "span", 13); \u0275\u0275elementStart(14, "span"); \u0275\u0275text(15); \u0275\u0275elementEnd(); \u0275\u0275elementStart(16, "span", 14); \u0275\u0275text(17, "\xB7"); \u0275\u0275elementEnd(); \u0275\u0275elementStart(18, "span"); \u0275\u0275text(19); \u0275\u0275elementEnd()()(); \u0275\u0275conditionalCreate(20, CourseViewerPage_Conditional_2_Conditional_20_Template, 9, 4, "div", 15); \u0275\u0275conditionalCreate(21, CourseViewerPage_Conditional_2_Conditional_21_Template, 3, 2, "button", 16); \u0275\u0275elementEnd(); \u0275\u0275elementStart(22, "div", 17)(23, "h2", 18); \u0275\u0275text(24, "Contenu du cours"); \u0275\u0275elementEnd(); \u0275\u0275conditionalCreate(25, CourseViewerPage_Conditional_2_Conditional_25_Template, 3, 0, "div", 19)(26, CourseViewerPage_Conditional_2_Conditional_26_Template, 2, 0); \u0275\u0275elementEnd(); } if (rf & 2) { const ctx_r1 = \u0275\u0275nextContext(); \u0275\u0275advance(4); \u0275\u0275conditional(ctx_r1.isOwnCourse() ? 4 : -1); \u0275\u0275advance(5); \u0275\u0275textInterpolate(ctx_r1.course().title); \u0275\u0275advance(2); \u0275\u0275textInterpolate(ctx_r1.course().description); \u0275\u0275advance(4); \u0275\u0275textInterpolate(ctx_r1.course().creatorName); \u0275\u0275advance(4); \u0275\u0275textInterpolate2("", ctx_r1.course().topicCount, " sujet", ctx_r1.course().topicCount !== 1 ? "s" : ""); \u0275\u0275advance(); \u0275\u0275conditional(ctx_r1.isEnrolled() ? 20 : -1); \u0275\u0275advance(); \u0275\u0275conditional(!ctx_r1.isEnrolled() && !ctx_r1.isOwnCourse() ? 21 : -1); \u0275\u0275advance(4); \u0275\u0275conditional(ctx_r1.course().topics.length === 0 ? 25 : 26); } } var CourseViewerPage = class _CourseViewerPage { route = inject(ActivatedRoute); router = inject(Router); courseService = inject(CourseService); enrollmentService = inject(EnrollmentService); authService = inject(AuthService); message = inject(NzMessageService); course = signal(null, ...ngDevMode ? [{ debugName: "course" }] : []); progress = signal(null, ...ngDevMode ? [{ debugName: "progress" }] : []); loading = signal(true, ...ngDevMode ? [{ debugName: "loading" }] : []); enrolling = signal(false, ...ngDevMode ? [{ debugName: "enrolling" }] : []); isEnrolled = signal(false, ...ngDevMode ? [{ debugName: "isEnrolled" }] : []); expandedTopicId = signal(null, ...ngDevMode ? [{ debugName: "expandedTopicId" }] : []); get currentUser() { return this.authService.currentUser(); } isOwnCourse = computed(() => { const user = this.currentUser; const course = this.course(); return user && course ? course.creatorId === user.userId : false; }, ...ngDevMode ? [{ debugName: "isOwnCourse" }] : []); progressPercent = computed(() => { const p = this.progress(); return p ? Math.round(p.progressPercentage) : 0; }, ...ngDevMode ? [{ debugName: "progressPercent" }] : []); ngOnInit() { const id = this.route.snapshot.paramMap.get("id"); this.loadCourse(id); } loadCourse(id) { this.loading.set(true); const user = this.currentUser; const course$ = this.courseService.getCourseById(id); const enrollments$ = user ? this.enrollmentService.getEnrollments(user.userId).pipe(catchError(() => of([]))) : of([]); const progress$ = user ? this.enrollmentService.getCourseProgress(id, user.userId).pipe(catchError(() => of(null))) : of(null); forkJoin([course$, enrollments$, progress$]).subscribe({ next: ([course, enrollments, progress]) => { this.course.set(course); this.progress.set(progress); if (enrollments.length > 0) { this.isEnrolled.set(enrollments.some((e) => e.courseId === id)); } if (course.topics.length > 0) { this.expandedTopicId.set(course.topics[0].id); } this.loading.set(false); }, error: () => { this.loading.set(false); this.message.error("Impossible de charger le cours"); this.router.navigate(["/catalog"]); } }); } enroll() { const user = this.currentUser; const course = this.course(); if (!user || !course) return; this.enrolling.set(true); this.enrollmentService.enroll(course.id, user.userId).subscribe({ next: () => { this.isEnrolled.set(true); this.enrolling.set(false); this.message.success("Inscription r\xE9ussie !"); this.progress.set({ courseId: course.id, userId: user.userId, totalTopics: course.topics.length, completedTopics: 0, totalResources: 0, completedResources: 0, progressPercentage: 0 }); this.loadProgress(course.id, user.userId); }, error: (err) => { this.enrolling.set(false); this.message.error(getErrorMessage(err, "Erreur lors de l'inscription")); } }); } loadProgress(courseId, userId) { this.enrollmentService.getCourseProgress(courseId, userId).subscribe({ next: (p) => this.progress.set(p), error: () => { } }); } toggleTopic(topicId) { this.expandedTopicId.set(this.expandedTopicId() === topicId ? null : topicId); } isTopicExpanded(topicId) { return this.expandedTopicId() === topicId; } markTopicDone(topic, event) { event.stopPropagation(); const user = this.currentUser; if (!user || !this.isEnrolled()) return; this.enrollmentService.markTopicProgress(topic.id, user.userId, true).subscribe({ next: () => { const course = this.course(); if (course) this.loadProgress(course.id, user.userId); }, error: () => { } }); } markResourceDone(resource, event) { event.stopPropagation(); const user = this.currentUser; if (!user || !this.isEnrolled()) return; this.enrollmentService.markResourceProgress(resource.id, user.userId, true).subscribe({ next: () => { const course = this.course(); if (course) this.loadProgress(course.id, user.userId); }, error: () => { } }); } editCourse() { const course = this.course(); if (course) this.router.navigate(["/courses", course.id, "edit"]); } goBack() { this.router.navigate(["/catalog"]); } getResourceIcon(type) { switch (type) { case "Video": return "video-camera"; case "Text": return "file-text"; case "File": return "file"; default: return "link"; } } static \u0275fac = function CourseViewerPage_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _CourseViewerPage)(); }; static \u0275cmp = /* @__PURE__ */ \u0275\u0275defineComponent({ type: _CourseViewerPage, selectors: [["app-course-viewer"]], features: [\u0275\u0275ProvidersFeature([NzMessageService])], decls: 3, vars: 1, consts: [[1, "page-container", "course-viewer-page"], [1, "loading-screen"], ["nz-icon", "", "nzType", "loading", "nzTheme", "outline", 1, "loading-spin"], [1, "viewer-header"], [1, "header-row"], [1, "back-btn", 3, "click"], ["nz-icon", "", "nzType", "arrow-left", "nzTheme", "outline"], [1, "edit-btn"], [1, "course-hero"], [1, "community-badge"], [1, "course-title"], [1, "course-description"], [1, "course-meta"], ["nz-icon", "", "nzType", "user", "nzTheme", "outline"], [1, "meta-dot"], [1, "progress-card"], [1, "enroll-btn", 3, "disabled"], [1, "topics-section"], [1, "section-title"], [1, "empty-topics"], [1, "edit-btn", 3, "click"], ["nz-icon", "", "nzType", "edit", "nzTheme", "outline"], [1, "progress-row"], [1, "progress-label"], [1, "progress-value"], [1, "mc-progress-bar"], [1, "mc-progress-fill"], [1, "progress-detail"], [1, "enroll-btn", 3, "click", "disabled"], ["nz-icon", "", "nzType", "loading", "nzTheme", "outline"], [1, "topic-card"], [1, "topic-header", 3, "click"], [1, "topic-position"], [1, "topic-info"], [1, "topic-title"], [1, "topic-desc"], [1, "resource-count"], [1, "topic-actions"], ["title", "Marquer comme termin\xE9", 1, "done-btn"], ["nz-icon", "", "nzTheme", "outline", 1, "expand-icon", 3, "nzType"], [1, "resources-list"], ["title", "Marquer comme termin\xE9", 1, "done-btn", 3, "click"], ["nz-icon", "", "nzType", "check-circle", "nzTheme", "outline"], [1, "resource-item"], [1, "resource-icon"], ["nz-icon", "", "nzTheme", "outline", 3, "nzType"], [1, "resource-info"], [1, "resource-title"], [1, "resource-type"], ["title", "Marquer comme termin\xE9", 1, "done-btn", "small"], ["title", "Marquer comme termin\xE9", 1, "done-btn", "small", 3, "click"], ["nz-icon", "", "nzType", "check", "nzTheme", "outline"]], template: function CourseViewerPage_Template(rf, ctx) { if (rf & 1) { \u0275\u0275elementStart(0, "div", 0); \u0275\u0275conditionalCreate(1, CourseViewerPage_Conditional_1_Template, 2, 0, "div", 1)(2, CourseViewerPage_Conditional_2_Template, 27, 9); \u0275\u0275elementEnd(); } if (rf & 2) { \u0275\u0275advance(); \u0275\u0275conditional(ctx.loading() ? 1 : ctx.course() ? 2 : -1); } }, dependencies: [NzIconModule, NzIconDirective], styles: ["\n\n.course-viewer-page[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n padding-bottom: 100px;\n}\n.loading-screen[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 32px;\n color: #1abc9c;\n}\n.loading-spin[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_spin 1s linear infinite;\n}\n@keyframes _ngcontent-%COMP%_spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n.viewer-header[_ngcontent-%COMP%] {\n padding: 16px 20px 20px;\n border-bottom: 1px solid var(--border);\n}\n.header-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 20px;\n}\n.back-btn[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 18px;\n color: var(--text);\n}\n.edit-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 12px;\n padding: 8px 14px;\n font-size: 14px;\n font-weight: 600;\n color: var(--text);\n cursor: pointer;\n}\n.course-hero[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n.course-icon-wrap[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 24px;\n color: var(--text);\n margin-bottom: 10px;\n}\n.community-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n font-weight: 700;\n color: var(--text-muted);\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n}\n.course-title[_ngcontent-%COMP%] {\n font-size: 22px;\n font-weight: 800;\n color: var(--text);\n margin: 0 0 8px;\n letter-spacing: -0.3px;\n line-height: 1.2;\n}\n.course-description[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--text-muted);\n margin: 0 0 12px;\n line-height: 1.5;\n}\n.course-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--text-muted);\n}\n.meta-dot[_ngcontent-%COMP%] {\n color: var(--border);\n}\n.progress-card[_ngcontent-%COMP%] {\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 14px;\n padding: 14px;\n margin-bottom: 12px;\n}\n.progress-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n margin-bottom: 8px;\n}\n.progress-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--text);\n}\n.progress-value[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 700;\n color: #1abc9c;\n}\n.progress-detail[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--text-muted);\n margin: 8px 0 0;\n}\n.enroll-btn[_ngcontent-%COMP%] {\n width: 100%;\n background-color: var(--primary);\n color: var(--primary-fg);\n border: none;\n border-radius: 14px;\n padding: 16px;\n font-size: 16px;\n font-weight: 700;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transition: opacity 0.2s;\n}\n.enroll-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n opacity: 0.85;\n}\n.enroll-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n.topics-section[_ngcontent-%COMP%] {\n padding: 20px 20px 0;\n}\n.section-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 700;\n color: var(--text);\n margin: 0 0 12px;\n}\n.empty-topics[_ngcontent-%COMP%] {\n color: var(--text-muted);\n font-size: 14px;\n text-align: center;\n padding: 32px 0;\n}\n.topic-card[_ngcontent-%COMP%] {\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 14px;\n margin-bottom: 10px;\n overflow: hidden;\n}\n.topic-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 14px;\n cursor: pointer;\n -webkit-user-select: none;\n user-select: none;\n}\n.topic-position[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n background: var(--bg);\n border: 1px solid var(--border);\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 700;\n color: var(--text-muted);\n flex-shrink: 0;\n}\n.topic-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n.topic-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 700;\n color: var(--text);\n margin: 0 0 2px;\n}\n.topic-desc[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--text-muted);\n margin: 0 0 4px;\n line-height: 1.4;\n}\n.resource-count[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--text-muted);\n}\n.topic-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n.done-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: #1abc9c;\n font-size: 18px;\n display: flex;\n align-items: center;\n padding: 0;\n}\n.done-btn.small[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.expand-icon[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--text-muted);\n}\n.resources-list[_ngcontent-%COMP%] {\n border-top: 1px solid var(--border);\n}\n.resource-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--border);\n}\n.resource-item[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n.resource-icon[_ngcontent-%COMP%] {\n width: 34px;\n height: 34px;\n background: var(--bg);\n border: 1px solid var(--border);\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n color: var(--text-muted);\n flex-shrink: 0;\n}\n.resource-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n.resource-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--text);\n margin: 0 0 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.resource-type[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--text-muted);\n}\n/*# sourceMappingURL=course-viewer.css.map */"] }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(CourseViewerPage, [{ type: Component, args: [{ selector: "app-course-viewer", imports: [NzIconModule], providers: [NzMessageService], template: `
{{ course()!.description }}
{{ progress()!.completedTopics }}/{{ progress()!.totalTopics }} sujets \xB7 {{ progress()!.completedResources }}/{{ progress()!.totalResources }} ressources
}Ce cours ne contient pas encore de sujets.
{{ topic.description }}
} {{ topic.resources.length }} ressource{{ topic.resources.length !== 1 ? 's' : '' }}{{ resource.title }}
{{ resource.type }}