import * as _ from 'lodash' import type { CircleCompletion, LearningContent, LearningPathChild, CourseWagtailPage, Topic } from '@/types' import { Circle } from '@/services/circle' function getLastCompleted(learningPathKey: string, completionData: CircleCompletion[]) { return _.orderBy(completionData, ['updated_at'], 'desc').find((c: CircleCompletion) => { return c.completed && c.learning_path_key === learningPathKey && c.page_type === 'learnpath.LearningContent' }) } export class LearningPath implements CourseWagtailPage { readonly type = 'learnpath.LearningPath' public topics: Topic[] public circles: Circle[] public nextLearningContent?: LearningContent public static fromJson(json: any, completionData: CircleCompletion[]): LearningPath { return new LearningPath(json.id, json.slug, json.title, json.translation_key, json.children, completionData) } constructor( public readonly id: number, public readonly slug: string, public readonly title: string, public readonly translation_key: string, public children: LearningPathChild[], completionData?: any ) { // parse children this.topics = [] this.circles = [] let topic: Topic | undefined this.children.forEach((page) => { if (page.type === 'learnpath.Topic') { if (topic) { this.topics.push(topic) } topic = Object.assign(page, { circles: [] }) } if (page.type === 'learnpath.Circle') { const circle = Circle.fromJson(page, this) circle.parseCompletionData(completionData) if (topic) { topic.circles.push(circle) } circle.previousCircle = this.circles[this.circles.length - 1] if (circle.previousCircle) { circle.previousCircle.nextCircle = circle } this.circles.push(circle) } }) if (topic) { this.topics.push(topic) } this.calcNextLearningContent(completionData) } public calcNextLearningContent(completionData: CircleCompletion[]): void { this.nextLearningContent = undefined const lastCompletedLearningContent = getLastCompleted(this.translation_key, completionData) if (lastCompletedLearningContent) { const lastCircle = this.circles.find( (circle) => circle.translation_key === lastCompletedLearningContent.circle_key ) if (lastCircle) { const lastLearningContent = lastCircle.flatLearningContents.find( (learningContent) => learningContent.translation_key === lastCompletedLearningContent.page_key ) if (lastLearningContent && lastLearningContent.nextLearningContent) { this.nextLearningContent = lastLearningContent.nextLearningContent } else { if (lastCircle.nextCircle) { this.nextLearningContent = lastCircle.nextCircle.flatLearningContents[0] } } } } else { if (this.circles[0]) { this.nextLearningContent = this.circles[0].flatLearningContents[0] } } } }