Added ListPage and other UI improvements
This commit is contained in:
parent
efb01c3f75
commit
85c2feec0d
@ -55,7 +55,7 @@
|
|||||||
"stock/dashboard/item_dashboard_list.html",
|
"stock/dashboard/item_dashboard_list.html",
|
||||||
"stock/dashboard/item_dashboard.js"
|
"stock/dashboard/item_dashboard.js"
|
||||||
],
|
],
|
||||||
"js/academy.min.js": [
|
"js/lms.min.js": [
|
||||||
"public/js/education/lms/lms.js"
|
"public/js/education/lms/lms.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<Title :title="contentData.title" :author="contentData.author" :publishDate="contentData.publish_date">
|
<ContentTitle :title="contentData.title" :author="contentData.author" :publishDate="contentData.publish_date">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</Title>
|
</ContentTitle>
|
||||||
<section class="article-content-section">
|
<section class="article-content-section">
|
||||||
<div class='container'>
|
<div class='container'>
|
||||||
<div class="content" v-html="contentData.content"></div>
|
<div class="content" v-html="contentData.content"></div>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Title from './Title.vue'
|
import ContentTitle from './ContentTitle.vue'
|
||||||
export default {
|
export default {
|
||||||
props: ['content', 'type'],
|
props: ['content', 'type'],
|
||||||
name: 'Article',
|
name: 'Article',
|
||||||
@ -27,18 +27,15 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
frappe.call({
|
this.getContent().then(data => this.contentData = data);
|
||||||
method: "erpnext.www.lms.get_content",
|
},
|
||||||
args: {
|
methods: {
|
||||||
content_name: this.content,
|
getContent() {
|
||||||
content_type: this.type
|
return frappe.db.get_doc(this.type, this.content)
|
||||||
}
|
}
|
||||||
}).then(r => {
|
|
||||||
this.contentData = r.message
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Title
|
ContentTitle
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
<div class='container'>
|
<div class='container'>
|
||||||
<h3 class='text-center' v-html="title"></h3>
|
<h3 class='text-center' v-html="title"></h3>
|
||||||
<p class='lead text-center' v-html="description"></p>
|
<p class='lead text-center' v-html="description"></p>
|
||||||
<slot></slot>
|
<slot name="card-list-slot"></slot>
|
||||||
<div class='mt-4 text-center'>
|
<div class='mt-4 text-center'>
|
||||||
<a class="btn btn-primary btn-lg" href="/program">View All</a>
|
<slot name="list-bottom"></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -57,7 +57,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
programPageRoute() {
|
programPageRoute() {
|
||||||
return `Program/${this.program.name}`
|
return { name: 'program', params: { program_name: this.program.name }}
|
||||||
},
|
},
|
||||||
isEnrolled() {
|
isEnrolled() {
|
||||||
return lms.store.enrolledPrograms.has(this.program.name)
|
return lms.store.enrolledPrograms.has(this.program.name)
|
||||||
|
@ -46,15 +46,12 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
frappe.call({
|
this.getContent().then(data => this.contentData = data);
|
||||||
method: "erpnext.www.lms.get_content",
|
|
||||||
args: {
|
|
||||||
content_name: this.content,
|
|
||||||
content_type: this.type
|
|
||||||
}
|
|
||||||
}).then(r => {
|
|
||||||
this.contentData = r.message
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
getContent() {
|
||||||
|
return frappe.db.get_doc(this.type, this.content)
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<component v-bind:is="currentComponent" :content="content" :type="type">
|
<component v-bind:is="currentComponent" :content="content" :type="type">
|
||||||
<Navigation :nextContent="nextContent" :nextContentType="nextContentType"/>
|
<ContentNavigation :nextContent="nextContent" :nextContentType="nextContentType"/>
|
||||||
</component>
|
</component>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -9,7 +9,7 @@
|
|||||||
import Article from "../components/Article.vue"
|
import Article from "../components/Article.vue"
|
||||||
import Quiz from "../components/Quiz.vue"
|
import Quiz from "../components/Quiz.vue"
|
||||||
import Video from "../components/Video.vue"
|
import Video from "../components/Video.vue"
|
||||||
import Navigation from "../components/Navigation.vue"
|
import ContentNavigation from "../components/ContentNavigation.vue"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props:['program_name', 'course', 'type', 'content'],
|
props:['program_name', 'course', 'type', 'content'],
|
||||||
@ -50,7 +50,7 @@ export default {
|
|||||||
Article,
|
Article,
|
||||||
Video,
|
Video,
|
||||||
Quiz,
|
Quiz,
|
||||||
Navigation
|
ContentNavigation
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -4,11 +4,13 @@
|
|||||||
<TopSectionButton/>
|
<TopSectionButton/>
|
||||||
</TopSection>
|
</TopSection>
|
||||||
<CardList :title="'Featured Programs'" :description="'Master ERPNext'">
|
<CardList :title="'Featured Programs'" :description="'Master ERPNext'">
|
||||||
<ProgramCard v-for="item in featuredPrograms" :key="item.program.name" :program="item.program" :enrolled="item.is_enrolled"/>
|
<ProgramCard slot="card-list-slot" v-for="item in featuredPrograms" :key="item.program.name" :program="item.program" :enrolled="item.is_enrolled"/>
|
||||||
|
<AButton slot="list-bottom" :type="'primary'" :size="'lg'" :route="'List/Program'">View All</AButton>
|
||||||
</CardList>
|
</CardList>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import Button from '../components/Button.vue';
|
||||||
import TopSection from "../components/TopSection.vue"
|
import TopSection from "../components/TopSection.vue"
|
||||||
import CardList from "../components/CardList.vue"
|
import CardList from "../components/CardList.vue"
|
||||||
import ProgramCard from "../components/ProgramCard.vue"
|
import ProgramCard from "../components/ProgramCard.vue"
|
||||||
@ -19,11 +21,12 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return{
|
return{
|
||||||
portal: {},
|
portal: {},
|
||||||
featuredPrograms: [],
|
featuredPrograms: {},
|
||||||
// enrolledPrograms: new Set()
|
// enrolledPrograms: new Set()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
AButton: Button,
|
||||||
TopSection,
|
TopSection,
|
||||||
CardList,
|
CardList,
|
||||||
ProgramCard,
|
ProgramCard,
|
||||||
|
51
erpnext/public/js/education/lms/pages/ListPage.vue
Normal file
51
erpnext/public/js/education/lms/pages/ListPage.vue
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<TopSection :title="portal.title" :description="portal.description">
|
||||||
|
<AButton :type="'primary'" :size="'lg'" :route="{ name: 'signup'}">Sign Up</AButton>
|
||||||
|
</TopSection>
|
||||||
|
<CardList :title="'All Programs'" :description="''">
|
||||||
|
<ProgramCard slot="card-list-slot" v-for="item in masterData" :key="item.program.name" :program="item.program" :enrolled="item.is_enrolled"/>
|
||||||
|
</CardList>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import ProgramCard from '../components/ProgramCard.vue';
|
||||||
|
import CourseCard from "../components/CourseCard.vue"
|
||||||
|
import Button from '../components/Button.vue';
|
||||||
|
import TopSection from "../components/TopSection.vue"
|
||||||
|
import CardList from "../components/CardList.vue"
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: ['master'],
|
||||||
|
name: "ListPage",
|
||||||
|
components: {
|
||||||
|
AButton: Button,
|
||||||
|
CourseCard,
|
||||||
|
ProgramCard,
|
||||||
|
CardList,
|
||||||
|
TopSection
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
portal: {},
|
||||||
|
masterData: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getPortalDetails().then(data => this.portal = data);
|
||||||
|
this.getMaster().then(data => this.masterData = data);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// updateEnrolledPrograms(){
|
||||||
|
// return lms.call("get_program_enrollments")
|
||||||
|
// },
|
||||||
|
getPortalDetails() {
|
||||||
|
return lms.call("get_portal_details")
|
||||||
|
},
|
||||||
|
getMaster() {
|
||||||
|
return lms.call("get_all_programs")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@ -1,16 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<TopSection v-bind:title="program.program_name" v-bind:description="program.description">
|
<TopSection v-bind:title="program.program_name" v-bind:description="program.description">
|
||||||
<!-- <a-button @click="startCourse">Start Course</a-button>
|
|
||||||
<a-button @click="continueCourse">Continue Course</a-button> -->
|
|
||||||
</TopSection>
|
</TopSection>
|
||||||
<CardList :title="'Courses'" :description="''">
|
<CardList :title="'Courses'" :description="''">
|
||||||
<CourseCard v-for="course in course_data" :course="course.course" :program_name="program_name" :courseMeta="course.meta" :key="course.meta.flag"/>
|
<CourseCard slot="card-list-slot" v-for="course in course_data" :course="course.course" :program_name="program_name" :courseMeta="course.meta" :key="course.course.name + course.meta.flag"/>
|
||||||
</CardList>
|
</CardList>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Button from '../components/Button.vue';
|
|
||||||
import TopSection from "../components/TopSection.vue"
|
import TopSection from "../components/TopSection.vue"
|
||||||
import CardList from "../components/CardList.vue"
|
import CardList from "../components/CardList.vue"
|
||||||
import CourseCard from "../components/CourseCard.vue"
|
import CourseCard from "../components/CourseCard.vue"
|
||||||
@ -20,7 +17,6 @@ export default {
|
|||||||
props: ['program_name'],
|
props: ['program_name'],
|
||||||
name: "ProgramPage",
|
name: "ProgramPage",
|
||||||
components: {
|
components: {
|
||||||
AButton: Button,
|
|
||||||
TopSection,
|
TopSection,
|
||||||
CardList,
|
CardList,
|
||||||
CourseCard
|
CourseCard
|
||||||
|
@ -1,11 +1,22 @@
|
|||||||
import Home from "./pages/Home.vue";
|
import Home from "./pages/Home.vue";
|
||||||
import ProgramPage from "./pages/ProgramPage.vue";
|
import ProgramPage from "./pages/ProgramPage.vue";
|
||||||
import CoursePage from "./pages/CoursePage.vue";
|
import CoursePage from "./pages/CoursePage.vue";
|
||||||
|
import ListPage from "./pages/ListPage.vue";
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{name: 'home', path: '', component: Home},
|
{name: 'home', path: '', component: Home},
|
||||||
{name: 'program', path: '/Program/:program_name', component: ProgramPage, props: true},
|
{name: 'program', path: '/Program/:program_name', component: ProgramPage, props: true},
|
||||||
{name: 'content', path: '/Program/:program_name/:course/:type/:content', component: CoursePage, props: true},
|
{name: 'content', path: '/Program/:program_name/:course/:type/:content', component: CoursePage, props: true},
|
||||||
|
{name: 'list', path: '/List/:master', component: ListPage, props: true},
|
||||||
|
{
|
||||||
|
name: 'signup',
|
||||||
|
path: '/Signup',
|
||||||
|
beforeEnter(to, from, next) {
|
||||||
|
window.location = window.location.origin.toString() +'/login#signup'
|
||||||
|
},
|
||||||
|
component: ListPage,
|
||||||
|
props: true
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default routes;
|
export default routes;
|
@ -1,8 +1,8 @@
|
|||||||
{% extends "templates/web.html" %}
|
{% extends "templates/web.html" %}
|
||||||
|
|
||||||
{% block title %}{{ heading or "Academy"}}{% endblock %}
|
{% block title %}{{ heading or "LMS"}}{% endblock %}
|
||||||
|
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
<div id="lms-app"></div>
|
<div id="lms-app"></div>
|
||||||
<script type="text/javascript" src="/assets/js/academy.min.js"></script>
|
<script type="text/javascript" src="/assets/js/lms.min.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -28,6 +28,15 @@ def get_featured_programs():
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@frappe.whitelist(allow_guest=True)
|
||||||
|
def get_all_programs():
|
||||||
|
program_names = frappe.get_all("Program", filters={"is_published": True})
|
||||||
|
if program_names:
|
||||||
|
featured_list = [get_program(program['name']) for program in program_names]
|
||||||
|
return featured_list
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
def get_program(program_name):
|
def get_program(program_name):
|
||||||
program = frappe.get_doc('Program', program_name)
|
program = frappe.get_doc('Program', program_name)
|
||||||
is_enrolled = check_program_enrollment(program_name)
|
is_enrolled = check_program_enrollment(program_name)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user