Skip to content

Commit

Permalink
Merge pull request #330 from matematikk-mooc/KURSP-894-my-courses
Browse files Browse the repository at this point in the history
KURSP-894: implement my courses page, fix props in header
  • Loading branch information
manilpit authored Oct 25, 2023
2 parents e189f62 + e6bbcfc commit f06a90f
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 144 deletions.
2 changes: 1 addition & 1 deletion src/js/api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ export default (function() {
}
},
error: error,
uri: '/courses',
uri: '/courses?include[]=public_description',
params: {
include: ['syllabus_body', 'course_progress'],
per_page: '100'
Expand Down
15 changes: 15 additions & 0 deletions src/js/css/loader.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.loading-gif-wrapper {
span {
display: block;
margin: 2rem auto;
justify-content: center;
}
}

.loading-gif {
width: 2.5rem;
height: 2.5rem;
background: url('https://kompetanseudirno.azureedge.net/bitmaps/loading.gif') no-repeat center center;
background-size: 8rem;
display: inline-block;
}
1 change: 0 additions & 1 deletion src/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ jQuery(function($) {
//Multilanguage KURSP-279 Css must be present before javascript is run.
//KURSP-376-multilanguage-fix
multilanguage.initializeCss();

routes.addRouteForPath(/\/$/, function() {
var parentId = 'wrapper';

Expand Down
115 changes: 29 additions & 86 deletions src/js/modules/courselist.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import NotLoggedInPage from "../../vue/pages/NotLoggedInPage.vue";
import '../css/loader.css';

import MyCoursesPage from "../../vue/pages/MyCoursesPage.vue";
import api from "../api/api";
import courselist from "../../templates/modules/courselist.hbs";
import courselistcontainer from "../../templates/modules/courselistcontainer.hbs";
import { createApp } from "vue/dist/vue.runtime.esm-bundler.js";
import enrollprivacypolicy from "../../templates/modules/enrollprivacypolicy.hbs";
import { hrefQueryString } from "../settingsRoot";
import i18n from "../i18n";
import settings from "../settings";
import util from "./util";
Expand All @@ -13,46 +12,39 @@ export default (function () {
return {
listCourses(parentId, callback) {
if (document.getElementsByClassName("reaccept_terms").length === 0) {
let htmlLoading = `<div class='mmooc-loader-wrapper'><span class='loading-gif'></span></div>`;
$(`#${parentId}`).html(htmlLoading); //overwrite the contents in parentID and display: 'Laster kurs....'
let htmlLoading = `<div class='loading-gif-wrapper'><span class='loading-gif'></span></div>`;
document.getElementById('wrapper').innerHTML = htmlLoading; //Show loader whhil loading courses'

api.getEnrolledCourses((courses) => {
$(".mmooc-loader-wrapper").remove();

const $oldContent = $(`#${parentId}`).children(); //After an update the 'Add course button' is in #content including a popupform. So we need to move this to another place in the DOM so we don't overwrite it.
$oldContent.appendTo("#right-side-wrapper #right-side");
let html = "";
let linkToAvailableCourses = util.getLinkToAvailableCourses();
if (courses.length == 0) {
html = `<h1>Mine ${i18n.CoursePlural.toLowerCase()}</h1><p>${
i18n.NoEnrollments
}</p><a class='btn' href='${linkToAvailableCourses}'>Se tilgjengelige ${i18n.CoursePlural.toLowerCase()}</a>`;
$(`#${parentId}`).html(html);
// TODO: Insert not assigned to any courses component
} else {
html = util.renderTemplateWithData(courselistcontainer, {
courseLabel: i18n.CoursePlural.toLowerCase(),
queryString: hrefQueryString
});

const sortedCourses = util.sortCourses(courses);
const categorys = util.getCourseCategories(sortedCourses);
const coursesCategorized = util.getCoursesCategorized(
sortedCourses,
categorys
);

coursesCategorized.forEach((course) => {
html = util.renderTemplateWithData(courselist, {
title: course.title,
courses: course.courses,
courseLabel: i18n.Course.toLowerCase(),
});
$(".mmooc-course-list-container").append(html);
});
util.updateProgressForRoleBasedCourses(courses);
}
document.title = i18n.CoursePlural;
let wrapper = document.getElementById("application");
try {
if(wrapper != null){
courses.forEach(course => {
course.enrolled = true;
});
const app = createApp(MyCoursesPage, {courses: courses});

let myCourses = wrapper.appendChild(document.createElement("div"));
myCourses.setAttribute("id", "my-courses-container");
myCourses.setAttribute("style", "width: 100%; justify-content: center; display: flex;");
let footerNode = document.getElementById("wrapper");
footerNode.parentNode.insertBefore(myCourses, footerNode);
document.getElementById('wrapper').innerHTML = ''
$('#wrapper').hide();
app.mount("#my-courses-container");

}
}
catch(err) {
console.error(err);
}

}
$.isFunction(callback) && callback();
});
} else {
Expand All @@ -64,55 +56,6 @@ export default (function () {
}

},
showAddCourseButton() {
// Move canvas Start new course button, since we hide its original location
const $button = $("#start_new_course");
if ($button.length) {
$("#content").append($button);
$button.html(i18n.AddACourse);
}
},
showFilter(sortedCourses) {
// Show filter options based on first part of course code
const filterOptions = ["Alle"];
$(sortedCourses).each((index) => {
const values = sortedCourses[index].course_code.split("::");
if (values.length > 1) {
if (filterOptions.indexOf(values[0]) == -1)
filterOptions.push(values[0]);
}
});
filterOptions.push("Andre");
const options = "";
filterOptions.forEach((option) => {
options += `<option value="${option}">${option}</option>`;
});
$("#filter").append(options);
},
applyFilter(sortedCourses) {
if ($("#filter").val() == "Alle") {
$(sortedCourses).each(function () {
$(`#course_${this.id}`).show();
});
} else if ($("#filter").val() == "Andre") {
$(sortedCourses).each(() => {
if (this.course_code.indexOf("::") >= 0) {
$(`#course_${this.id}`).hide();
} else {
$(`#course_${this.id}`).show();
}
});
} else {
$(sortedCourses).each(() => {
const courseCode = this.course_code.split("::")[0];
if ($("#filter").val() == courseCode) {
$(`#course_${this.id}`).show();
} else {
$(`#course_${this.id}`).hide();
}
});
}
},
isCourseCompleted(modules) {
for (let i = 0; i < modules.length; i++) {
const module = modules[i];
Expand Down
49 changes: 7 additions & 42 deletions src/js/modules/enroll.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import '../css/loader.css';

import LoggedInLandingPage from "../../vue/pages/LoggedInLandingPage.vue";
import NotLoggedInPage from "../../vue/pages/NotLoggedInPage.vue";
import allcoursescontainer from '../../templates/modules/allcoursescontainer.hbs'
Expand Down Expand Up @@ -134,9 +136,8 @@ export default (function () {
},
printAllCourses: function () {
var self = this;
document.getElementById('content').innerHTML = "";
var html = "<div class='mmooc-loader-wrapper'><span class='loading-gif'></span></div>";
$('.mmooc-all-courses-list').append(html);
var html = "<div class='loading-gif-wrapper'><span class='loading-gif'></span></div>";
document.getElementById('content').innerHTML = html; //Show loader whhil loading courses'
api.getAllPublicCourses(function (allCourses) {
api.getEnrolledCourses(function (enrolledCourses) {
var allCoursesWithStatus = self.setCourseEnrolledStatus(
Expand All @@ -152,7 +153,7 @@ export default (function () {
var isAuthenticated = util.isAuthenticated();
if (isAuthenticated) {
document.getElementById('content').innerHTML = "";
let wrapper = document.getElementById("application");
let wrapper = document.getElementById("content");
try {
if(wrapper != null){
const customContent = document.createElement("div");
Expand All @@ -165,6 +166,7 @@ export default (function () {
customContent.setAttribute("style", "width: 100%; justify-content: center; display: flex;");
let footerNode = document.getElementById("wrapper");
footerNode.parentNode.insertBefore(customContent, footerNode)
document.getElementById('wrapper').innerHTML = '';
$('#wrapper').hide();
page.mount("#loggedInLandingPage");
}
Expand All @@ -187,6 +189,7 @@ export default (function () {
customContent.setAttribute("style", "width: 100%; justify-content: center; display: flex;");
let footerNode = document.getElementById("wrapper");
footerNode.parentNode.insertBefore(customContent, footerNode)
document.getElementById('wrapper').innerHTML = '';
$('#wrapper').hide();
page.mount("#notLoggedInPage");
}
Expand Down Expand Up @@ -373,44 +376,6 @@ export default (function () {
$('.mmooc-modal').hide();
}
});
},
populateFilter: function (categorys) {
var options =
'<option value="Alle">Alle tilgjengelige ' +
i18n.CoursePlural.toLowerCase() +
'</option>';
for (var i = 0; i < categorys.length; i++) {
options +=
'<option value="' + categorys[i] + '">' + categorys[i] + '</option>';
}
$('#filter').append(options);
},
applyFilter: function () {
var value = $('#filter').val();
if (value == 'Alle') {
$('.mmooc-all-courses-list').removeClass('filter-active');
$('.mmooc-all-courses-list h2').each(function () {
$(this).show();
$(this)
.next()
.show();
});
} else {
$('.mmooc-all-courses-list').addClass('filter-active');
$('.mmooc-all-courses-list h2').each(function () {
if ($(this).text() == value) {
$(this).show();
$(this)
.next()
.show();
} else {
$(this).hide();
$(this)
.next()
.hide();
}
});
}
}
};
})();
9 changes: 6 additions & 3 deletions src/vue/components/header/NavBar.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
<template>
<div class="header--nav-container">
<PageHeader :logged_in="$props.logged_in"></PageHeader>
<PageHeader :logged_in="logged_in"></PageHeader>
<nav class="page--nav-bar">
<NavBarLinks :logged_in="$props.logged_in"></NavBarLinks>
<NavBarLinks :logged_in="logged_in"></NavBarLinks>
</nav>
</div>
</template>
<script setup>
import PageHeader from './PageHeader.vue'
import NavBarLinks from './NavBarLinks.vue'
const loggedIn = defineProps(['logged_in'])
const {logged_in} = defineProps(['logged_in'])
</script>

<style lang="scss">
@import '../../design/colors.scss';
.header--nav-container {
width: 100%;
flex-grow: 0;
Expand Down
7 changes: 4 additions & 3 deletions src/vue/components/header/NavBarLinks.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<template>
<div class="nav-bar__link-list-container">
<ul class="nav-bar__link-list">
<li class="nav-bar__list-item">
<li class="nav-bar__list-item" v-if="logged_in">
<span>
<a class="nav-bar__link" :href="myCourses">Mine kompetansepakker</a>
</span>
</li>
<li class="nav-bar__list-item">
<li class="nav-bar__list-item" v-if="logged_in">
<span>
<a class="nav-bar__link" :href="allCourses">Alle tilgjengelige kompetansepakker</a>
</span>
Expand All @@ -15,7 +15,8 @@
</div>
</template>
<script setup>
defineProps(['logged_in'])
const {logged_in} = defineProps(['logged_in'])
console.log("LOGGED", logged_in)
const domain = window.location.origin;
const myCourses = domain + "/courses?design=udir"
Expand Down
2 changes: 1 addition & 1 deletion src/vue/components/header/PageHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
</template>

<script setup>
const props = defineProps(['logged_in'])
const {logged_in} = defineProps(['logged_in'])
const domain = window.location.origin;
const loginLink = domain + "/login/canvas"
const settingsLink = domain + "/profile/settings?design=udir"
Expand Down
7 changes: 0 additions & 7 deletions src/vue/pages/LoggedInLandingPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,6 @@
min-height: 85vh;
}
.landing-page--header {
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.landing-page--content {
width: 100%;
display: flex;
Expand Down
57 changes: 57 additions & 0 deletions src/vue/pages/MyCoursesPage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<template>
<div class="my-courses-page">
<div class="my-courses-page--content">
<h2>Mine kompetansepakker</h2>
<div class="my-courses-page--layout">
<CardList :authorized="true" :courses="courses"></CardList>
</div>
</div>
</div>
</template>


<script>
import CardList from '../components/CardList.vue';
export default{
name: 'MyCoursesPage',
components: {
CardList
},
props: {
courses: Array,
},
}
</script>

<style lang="scss">
.my-courses-page {
height: 100%;
width: 100%;
max-width: 1600px;
padding: 1.25rem;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
min-height: 85vh;
}
.my-courses-page--content {
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
margin-left: 1.5rem;
h2 {
font-size: 2rem;
margin: 1.5rem 0 1.5rem 0;
}
}
.my-courses-page--layout {
display: flex;
align-items: flex-start;
justify-content: flex-start;
}
</style>

0 comments on commit f06a90f

Please sign in to comment.