Commit 6f7cf8cf51ccd302256ddc6cc67a0bd94c973313

Authored by Amber Dev
1 parent fe15ee8b4c

added discussion forum,and chapter info,side bar

src/Services/AllApiCalls.js
... ... @@ -0,0 +1,14 @@
  1 +import GetApis from "@/Services/GetApis.js";
  2 +import PutApis from "@/Services/PutApis.js";
  3 +export default {
  4 + mixins: [GetApis, PutApis],
  5 + data() {
  6 + return {
  7 +
  8 + }
  9 + },
  10 + methods: {
  11 +
  12 +
  13 + },
  14 +}
0 15 \ No newline at end of file
... ...
src/Services/ApiCalls.js
... ... @@ -0,0 +1,195 @@
  1 +import http from "@/Services/http.js";
  2 +import Rules from "@/pages/Common/rules.js"
  3 +export default {
  4 + mixins: [Rules],
  5 + data() {
  6 + return {
  7 +
  8 + // LOADER
  9 + showLoader: false,
  10 + loading: false,
  11 + // SNACKBAR
  12 + snackbar: false,
  13 + snackbarColor: '',
  14 + text: '',
  15 + timeout: 4000,
  16 + y: "top",
  17 + x: "right",
  18 + mode: "",
  19 +
  20 + // PAGINATION
  21 + size: 10,
  22 + elements: "",
  23 + pageCount: "",
  24 + pageNumber: 0
  25 +
  26 + }
  27 + },
  28 + methods: {
  29 + // SNACKBAR
  30 + seeSnackbar(message, color) {
  31 + this.text = message;
  32 + this.showLoader = false;
  33 + this.snackbarColor = color;
  34 + this.snackbar = true;
  35 + },
  36 +
  37 + // SET PAGINATION
  38 + setPagination(response) {
  39 + this.elements = response.data.totalElements;
  40 + var l = this.elements;
  41 + var s = this.size;
  42 + var floor = (l / s);
  43 + this.pageCount = Math.floor(floor);
  44 + if (this.pageCount == floor) {
  45 + this.pageCount -= 1
  46 + }
  47 + this.showLoader = false;
  48 + this.loading = false;
  49 + },
  50 +
  51 + generateError(error) {
  52 + var customError
  53 + const errorNo = error.response.status
  54 + // console.log("satus code errorNo", errorNo)
  55 + switch (errorNo) {
  56 + case 400:
  57 + let er = error
  58 + if (er.response.data.error) {
  59 + customError = error.response.data.error
  60 + }
  61 + if (er.response.data.errorMessage) {
  62 + customError = error.response.data.errorMessage
  63 + }
  64 + if (er.response.data.message) {
  65 + customError = error.response.data.message
  66 + }
  67 + return customError
  68 + break;
  69 + case 401:
  70 + customError = "Session expired"
  71 + return customError
  72 + break;
  73 + case 404:
  74 + customError = error.response.data.errorMessage
  75 + return customError
  76 + break;
  77 + case 409:
  78 + customError = error.response.data.errorMessage
  79 + return customError
  80 + break;
  81 + case 500:
  82 + customError = error.response.data.message
  83 + return customError
  84 + break;
  85 + default:
  86 + customError = "unknown error"
  87 + return customError
  88 + }
  89 +
  90 + },
  91 +
  92 + // GET
  93 + getMethod(url, params) {
  94 + this.showLoader = true
  95 + return http()
  96 + .get(url, {
  97 + params: params,
  98 +
  99 + headers: {
  100 + // headers: { Authorization: "Bearer " + this.token }
  101 + }
  102 + })
  103 + .then(response => {
  104 + this.showLoader = false
  105 + return response
  106 + })
  107 + .catch(error => {
  108 + this.showLoader = false
  109 + // console.log("error in getMethod = ", error.response)
  110 + const message = this.generateError(error)
  111 + if (message == "Session expired") {
  112 + this.$store.dispatch("setToken", null);
  113 + this.$router.push({
  114 + name: 'Login'
  115 + });
  116 + } else {
  117 + throw new Error(message);
  118 + }
  119 +
  120 + });
  121 + },
  122 +
  123 + // POST
  124 + postMethod(url, payload) {
  125 + this.showLoader = true
  126 + return http()
  127 + .post(url, payload, {
  128 + // headers: { Authorization: "Bearer " + this.token }
  129 + })
  130 + .then(response => {
  131 + this.showLoader = false
  132 + return response
  133 + })
  134 + .catch(error => {
  135 + this.showLoader = false
  136 + console.log("error in postMethod = ", error.response)
  137 + const message = this.generateError(error)
  138 + if (message == "Session expired") {
  139 + this.$store.dispatch("setToken", null);
  140 + this.$router.push({
  141 + name: 'Login'
  142 + });
  143 + } else {
  144 + throw new Error(message);
  145 + }
  146 +
  147 + });
  148 + },
  149 +
  150 + // PUT
  151 + putMethod(url, payload) {
  152 + return http()
  153 + .put(url, payload, {
  154 + // headers: {
  155 + // // Authorization: 'Bearer ' + this.token
  156 + // }
  157 + })
  158 + .then(response => {
  159 + return response
  160 + })
  161 + .catch(error => {
  162 + console.log("error in putMethod = ", error.response)
  163 + const message = this.generateError(error)
  164 + if (message == "Session expired") {
  165 + this.$store.dispatch("setToken", null);
  166 + this.$router.push({
  167 + name: 'Login'
  168 + });
  169 + } else {
  170 + throw new Error(message);
  171 + }
  172 +
  173 + })
  174 + }
  175 +
  176 + },
  177 + computed: {
  178 + displayedPageNumber() {
  179 + return this.pageNumber + 1;
  180 + },
  181 + // managerIsADMIN_VIEW: {
  182 + // get() {
  183 + // if (this.$store.state.roleName == "ADMIN_VIEW") {
  184 + // return true;
  185 + // } else {
  186 + // return false
  187 + // }
  188 + // },
  189 + // set(newValue) {
  190 + // this.managerIsADMIN_VIEW = newValue;
  191 + // }
  192 +
  193 + // }
  194 + },
  195 +}
0 196 \ No newline at end of file
... ...
src/Services/GetApis.js
... ... @@ -0,0 +1,40 @@
  1 +import ApiCalls from "@/Services/ApiCalls.js";
  2 +export default {
  3 + mixins: [ApiCalls],
  4 + data() {
  5 + return {
  6 + courseData: [],
  7 +
  8 +
  9 + }
  10 + },
  11 + methods: {
  12 + /* getParticularCourseDetail */
  13 + async getParticularCourseDetail(courseId) {
  14 +
  15 + try {
  16 + let response = await this.getMethod("/getParticularCourseDetail", {
  17 + courseId: courseId
  18 + })
  19 + return response
  20 + } catch (error) {
  21 + console.log("error in getParticularCourseDetail - ", error.message)
  22 + }
  23 + },
  24 +
  25 + /* getStudentCourses - to get courseData */
  26 + async getStudentCourses(params) {
  27 + try {
  28 + let response = await this.getMethod("/getStudentCourses", {
  29 + classId: params.classId,
  30 + studentId: params.studentId
  31 + })
  32 + this.courseData = response.data.data;
  33 + console.log("coursesData - ", this.courseData)
  34 + } catch (error) {
  35 + console.log("error in getStudentCourses - ", error.message)
  36 + }
  37 + }
  38 +
  39 + },
  40 +}
0 41 \ No newline at end of file
... ...
src/Services/PutApis.js
... ... @@ -0,0 +1,14 @@
  1 +import ApiCalls from "@/Services/ApiCalls.js";
  2 +export default {
  3 + mixins: [ApiCalls],
  4 + data() {
  5 + return {
  6 +
  7 + }
  8 + },
  9 + methods: {
  10 +
  11 +
  12 +
  13 + },
  14 +}
0 15 \ No newline at end of file
... ...
src/components/pageHeader/AppToolbar.vue
1 1 <template>
2   - <v-toolbar flat class="white pt-2" fixed app>
  2 + <v-toolbar flat class="white" fixed app>
3 3 <v-toolbar-title>
4 4 <v-toolbar-side-icon @click.stop="handleDrawerToggle" class="hide darkBlue-color"></v-toolbar-side-icon>
5 5 </v-toolbar-title>
... ... @@ -15,9 +15,7 @@
15 15 type="text"
16 16 dark
17 17 ></v-text-field>-->
18   - <v-toolbar-title
19   - class="header-route-name pl-2"
20   - >{{ $route.name }}</v-toolbar-title>
  18 + <v-toolbar-title class="header-route-name pl-2">{{ $route.name }}</v-toolbar-title>
21 19 </v-flex>
22 20 <v-spacer></v-spacer>
23 21 <v-btn type="button" @click="goToSchool" v-if="adminRole && SchoolRole">Towards School!</v-btn>
... ...
src/pages/Common/rules.js
... ... @@ -0,0 +1,59 @@
  1 +export default {
  2 + data() {
  3 + return {
  4 + cantBeEmpty: [v => !!v || "Field cannot be empty"],
  5 + hasToBeNumber: [
  6 + v => !!v || "Field cannot be empty",
  7 + v => {
  8 + if (isNaN(v) || v.length < 10 || v.length > 10) {
  9 + return false || "Field can only be a 10 digit number";
  10 + } else {
  11 + return true;
  12 + }
  13 + }
  14 + ],
  15 + tenDigitNo: [
  16 + v => {
  17 + if (v.length > 0) {
  18 + if (isNaN(v) || v.length < 10 || v.length > 10) {
  19 + return false || "Field can only be a 10 digit number";
  20 + } else {
  21 + return true;
  22 + }
  23 +
  24 + } else {
  25 + return true
  26 + }
  27 +
  28 + }
  29 + ],
  30 + hasToBeNumericValue: [
  31 + v => !!v || "Field cannot be empty",
  32 + v => {
  33 + if (isNaN(v)) {
  34 + return false || "Field can only be a number";
  35 + } else {
  36 + return true;
  37 + }
  38 + }
  39 + ],
  40 + pinCodeRule: [
  41 + v => !!v || "Field cannot be empty",
  42 + v => {
  43 + if (isNaN(v) || v.length < 6 || v.length > 6) {
  44 + return false || "Field can only be a 6 digit number";
  45 + } else {
  46 + return true;
  47 + }
  48 + }
  49 + ],
  50 + emailRule: [
  51 + v =>
  52 + /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(v) ||
  53 + "E-mail must be valid"
  54 + ]
  55 +
  56 + }
  57 + },
  58 +
  59 +}
0 60 \ No newline at end of file
... ...
src/pages/Dashboard/ChapterInfo.vue
1 1 <template>
2 2 <div>
  3 + <!-- LOADER -->
  4 + <div class="loader" v-if="showLoader">
  5 + <v-progress-circular indeterminate color="white"></v-progress-circular>
  6 + </div>
  7 +
  8 + <!-- SNACKBAR -->
  9 + <v-snackbar
  10 + :timeout="timeout"
  11 + :top="y === 'top'"
  12 + :right="x === 'right'"
  13 + :vertical="mode === 'vertical'"
  14 + v-model="snackbar"
  15 + :color="snackbarColor"
  16 + >
  17 + {{ text }}
  18 + <v-spacer></v-spacer>
  19 + <v-btn flat text @click="snackbar = false">X</v-btn>
  20 + </v-snackbar>
  21 +
3 22 <v-container class="pt-0">
4   - <v-layout row class="mt-2">
  23 + <v-layout row class="mt-1">
5 24 <v-flex xs8>
6 25 <!-- CHAPTER INFO -->
7 26 <div class="title side-bar-color font-weight-bold">{{chapter.chapters[0].chapterName}}</div>
... ... @@ -52,26 +71,35 @@
52 71 <v-container class="pt-0">
53 72 <div class="side-bar-color font-weight-bold title">Courses</div>
54 73  
55   - <div v-for="(course,index) in courseData">
56   - <v-icon style="color: red;padding-bottom: 3px;" size="15">play_arrow</v-icon>
57   - <span class="subheading">{{course.coursrName}}</span>
  74 + <div v-for="(course,index) in courseData" :key="index">
  75 + <v-btn
  76 + flat
  77 + class="subheading text-xs-start justify-left"
  78 + style="cursor: pointer;"
  79 + block
  80 + @click="routeToCourseDetails(course._id)"
  81 + >
  82 + <div style="width: 100%;text-align: left;">
  83 + <v-icon style="color: red;padding-bottom: 3px;" size="15">play_arrow</v-icon>
  84 + {{course.coursrName}}
  85 + </div>
  86 + </v-btn>
58 87 </div>
59 88 </v-container>
60 89 </v-card>
61 90 </v-flex>
62 91 </v-layout>
63 92 </v-container>
64   - <div class="loader" v-if="showLoader">
65   - <v-progress-circular indeterminate color="white"></v-progress-circular>
66   - </div>
67 93 </div>
68 94 </template>
69 95 <script>
70 96 import http from "@/Services/http.js";
  97 +import AllApiCalls from "@/Services/AllApiCalls.js";
71 98 export default {
  99 + mixins: [AllApiCalls],
72 100 data() {
73 101 return {
74   - courseData: [],
  102 + // courseData: [],
75 103 showLoader: false,
76 104 chapter: { chapters: [{}] },
77 105 chapterNames: [],
... ... @@ -103,6 +131,20 @@ export default {
103 131 console.log("err====>", err);
104 132 this.showLoader = false;
105 133 });
  134 + },
  135 + async routeToCourseDetails(courseId) {
  136 + /* getParticularCourseDetail- To get courseDetail - defined in GetApis.js*/
  137 + let response = await this.getParticularCourseDetail(courseId);
  138 +
  139 + /* If the response is null then dont route */
  140 + if (response.data.data.length > 0) {
  141 + this.$router.push({
  142 + name: "Course Details",
  143 + query: { courseId: courseId }
  144 + });
  145 + } else {
  146 + this.seeSnackbar("No Data Available", "warning");
  147 + }
106 148 }
107 149 },
108 150 // computed:{
... ... @@ -110,7 +152,7 @@ export default {
110 152  
111 153 // }
112 154 // }
113   - created() {
  155 + async created() {
114 156 console.log("route query - ", this.$route.query);
115 157  
116 158 this.selectedChapterId = this.$route.query.chapterId;
... ... @@ -133,28 +175,13 @@ export default {
133 175 console.log(" index of selected chapter - ", this.indexSelectedChapter);
134 176  
135 177 /* get chapter clicked on using the id */
136   - this.getParticularChapterDetail(this.selectedChapterId);
  178 + await this.getParticularChapterDetail(this.selectedChapterId);
137 179  
138   - /* getStudentCourses - to get courseData */
139   - let ClassId = localStorage.getItem("parentClassId");
140   - let parentStudentsId = localStorage.getItem("parentStudentId");
141   - this.showLoader = true;
142   - http()
143   - .get("/getStudentCourses", {
144   - params: {
145   - classId: ClassId,
146   - studentId: parentStudentsId
147   - }
148   - })
149   - .then(response => {
150   - this.courseData = response.data.data;
151   - console.log(" course data - ", this.courseData);
152   - this.showLoader = false;
153   - })
154   - .catch(err => {
155   - console.log("err====>", err);
156   - this.showLoader = false;
157   - });
  180 + /* getStudentCourses - to get courseData - defined in GetApis.js*/
  181 + await this.getStudentCourses({
  182 + classId: localStorage.getItem("parentClassId"),
  183 + studentId: localStorage.getItem("parentStudentId")
  184 + });
158 185 }
159 186 };
160 187 </script>
... ...
src/pages/Dashboard/CourseDetails.vue
1 1 <template>
2 2 <div>
  3 + <!-- LOADER -->
  4 + <div class="loader" v-if="showLoader">
  5 + <v-progress-circular indeterminate color="white"></v-progress-circular>
  6 + </div>
  7 +
  8 + <!-- SNACKBAR -->
  9 + <v-snackbar
  10 + :timeout="timeout"
  11 + :top="y === 'top'"
  12 + :right="x === 'right'"
  13 + :vertical="mode === 'vertical'"
  14 + v-model="snackbar"
  15 + :color="snackbarColor"
  16 + >
  17 + {{ text }}
  18 + <v-spacer></v-spacer>
  19 + <v-btn flat text @click="snackbar = false">X</v-btn>
  20 + </v-snackbar>
  21 +
3 22 <v-container class="pt-0">
4   - <v-layout row class="mt-2">
  23 + <v-layout row class="mt-1">
5 24 <v-flex xs8>
6 25 <div
7 26 class="title side-bar-color font-weight-bold"
... ... @@ -18,7 +37,7 @@
18 37 <div>
19 38 <span
20 39 style="cursor: pointer;"
21   - @click="$router.push({name: 'Course Discussion Forum'})"
  40 + @click="$router.push({name: 'Course Discussion Forum', query:{courseId: $route.query.courseId}})"
22 41 class="grey--text lighten-1"
23 42 >
24 43 <v-icon>question_answer</v-icon>Course discussion forum
... ... @@ -56,8 +75,18 @@
56 75 <div class="side-bar-color font-weight-bold title">Courses</div>
57 76  
58 77 <div v-for="(course,index) in courseData">
59   - <v-icon style="color: red;padding-bottom: 3px;" size="15">play_arrow</v-icon>
60   - <span class="subheading">{{course.coursrName}}</span>
  78 + <v-btn
  79 + flat
  80 + class="subheading text-xs-start justify-left"
  81 + style="cursor: pointer;"
  82 + block
  83 + @click="routeToCourseDetails(course._id)"
  84 + >
  85 + <div style="width: 100%;text-align: left;">
  86 + <v-icon style="color: red;padding-bottom: 3px;" size="15">play_arrow</v-icon>
  87 + {{course.coursrName}}
  88 + </div>
  89 + </v-btn>
61 90 </div>
62 91 <!-- <v-expansion-panel focusable class="elevation-0">
63 92 <v-expansion-panel-content v-for="(item,i) in courseData" :key="i">
... ... @@ -71,21 +100,20 @@
71 100 </v-flex>
72 101 </v-layout>
73 102 </v-container>
74   - <div class="loader" v-if="showLoader">
75   - <v-progress-circular indeterminate color="white"></v-progress-circular>
76   - </div>
77 103 </div>
78 104 </template>
79 105 <script>
  106 +import AllApiCalls from "@/Services/AllApiCalls.js";
80 107 import http from "@/Services/http.js";
81 108 import moment from "moment";
82 109 export default {
  110 + mixins: [AllApiCalls],
83 111 data() {
84 112 return {
85 113 showLoader: false,
86 114 courseDetails: [{ courseId: {}, classId: {} }],
87 115 chapterIds: [],
88   - courseData: [],
  116 + // courseData: [],
89 117 courseDataTree: []
90 118 };
91 119 },
... ... @@ -104,48 +132,34 @@ export default {
104 132 name: "Chapter Info",
105 133 query: obj
106 134 });
  135 + },
  136 + async routeToCourseDetails(courseId) {
  137 + /* getParticularCourseDetail- To get courseDetail - defined in GetApis.js*/
  138 + let response = await this.getParticularCourseDetail(courseId);
  139 +
  140 + /* If the response is null then dont route */
  141 + if (response.data.data.length > 0) {
  142 + this.$router.push({
  143 + name: "Course Details",
  144 + query: { courseId: courseId }
  145 + });
  146 + } else {
  147 + this.seeSnackbar("No Data Available", "warning");
  148 + }
107 149 }
108 150 },
109   - created() {
110   - /* getParticularCourseDetail */
111   - this.showLoader = true;
112   - http()
113   - .get("/getParticularCourseDetail", {
114   - params: {
115   - courseId: this.$route.query.courseId
116   - }
117   - })
118   - .then(response => {
119   - this.courseDetails = response.data.data;
120   - console.log("courseDetails - ", this.courseDetails);
121   - this.showLoader = false;
122   - })
123   - .catch(err => {
124   - console.log("err====>", err);
125   - this.showLoader = false;
126   - });
  151 + async created() {
  152 + /* getParticularCourseDetail- To get courseDetail - defined in GetApis.js*/
  153 + let response = await this.getParticularCourseDetail(
  154 + this.$route.query.courseId
  155 + );
  156 + this.courseDetails = response.data.data;
127 157  
128   - /* getStudentCourses - to get courseData */
129   - let ClassId = localStorage.getItem("parentClassId");
130   - let parentStudentsId = localStorage.getItem("parentStudentId");
131   - this.showLoader = true;
132   - http()
133   - .get("/getStudentCourses", {
134   - params: {
135   - classId: ClassId,
136   - studentId: parentStudentsId
137   - }
138   - })
139   - .then(response => {
140   - this.courseData = response.data.data;
141   - console.log(" course data - ", this.courseData);
142   - let obj = {};
143   - this.showLoader = false;
144   - })
145   - .catch(err => {
146   - console.log("err====>", err);
147   - this.showLoader = false;
148   - });
  158 + /* getStudentCourses - to get courseData - defined in GetApis.js*/
  159 + await this.getStudentCourses({
  160 + classId: localStorage.getItem("parentClassId"),
  161 + studentId: localStorage.getItem("parentStudentId")
  162 + });
149 163 }
150 164 };
151 165 </script>
... ...
src/pages/Dashboard/CourseDiscussionForum.vue
1 1 <template>
2   - <div>
3   - <v-container class="pt-0">
4   - <v-layout row class="mt-2">
  2 + <div class="body-color">
  3 + <!-- LOADER -->
  4 + <div class="loader" v-if="showLoader">
  5 + <v-progress-circular indeterminate color="white"></v-progress-circular>
  6 + </div>
  7 +
  8 + <!-- SNACKBAR -->
  9 + <v-snackbar
  10 + :timeout="timeout"
  11 + :top="y === 'top'"
  12 + :right="x === 'right'"
  13 + :vertical="mode === 'vertical'"
  14 + v-model="snackbar"
  15 + :color="snackbarColor"
  16 + >
  17 + {{ text }}
  18 + <v-spacer></v-spacer>
  19 + <v-btn flat text @click="snackbar = false">X</v-btn>
  20 + </v-snackbar>
  21 +
  22 + <!-- DIALOG TO ADD COURSE DISCUSSION FORUM -->
  23 + <v-dialog v-model="addForumDialog" max-width="500" persistent>
  24 + <v-card flat class="card-style pa-2" dark>
  25 + <v-layout>
  26 + <v-flex xs12>
  27 + <label class="title text-xs-center">Add Forum</label>
  28 + <v-icon size="24" class="right" @click="addForumDialog = false">cancel</v-icon>
  29 + </v-flex>
  30 + </v-layout>
  31 + <v-container fluid>
  32 + <v-layout align-center>
  33 + <v-flex xs12>
  34 + <v-flex xs12 sm12>
  35 + <v-form ref="form" v-model="valid" lazy-validation>
  36 + <v-layout>
  37 + <v-flex
  38 + xs12
  39 + class="text-xs-center text-sm-center text-md-center text-lg-center"
  40 + >
  41 + <v-avatar size="100px" v-if="!imageUrl">
  42 + <img src="/static/icon/user.png" />
  43 + </v-avatar>
  44 + <input
  45 + type="file"
  46 + style="display: none"
  47 + ref="image"
  48 + accept="image/*"
  49 + @change="onFilePicked"
  50 + />
  51 + <img
  52 + :src="imageData.imageUrl"
  53 + height="150"
  54 + width="150"
  55 + v-if="imageUrl"
  56 + style="border-radius:50%; width:200px"
  57 + />
  58 + </v-flex>
  59 + </v-layout>
  60 +
  61 + <v-layout wrap>
  62 + <!-- SUBJECT -->
  63 + <v-flex xs12 sm12>
  64 + <v-layout>
  65 + <v-flex xs4 sm4 class="pt-4 subheading">
  66 + <label class="right hidden-xs-only hidden-sm-only">Subject:</label>
  67 + <label class="right hidden-lg-only hidden-md-only hidden-xl-only">Subject:</label>
  68 + </v-flex>
  69 + <v-flex xs8 sm8 class="ml-3">
  70 + <v-text-field
  71 + v-model="addForumParams.subject"
  72 + placeholder="subject"
  73 + type="text"
  74 + :rules="cantBeEmpty"
  75 + required
  76 + ></v-text-field>
  77 + </v-flex>
  78 + </v-layout>
  79 + </v-flex>
  80 + <!-- DESCRIPTION -->
  81 + <v-flex xs12 sm12>
  82 + <v-layout>
  83 + <v-flex xs4 sm4 class="pt-4 subheading">
  84 + <label class="right hidden-xs-only hidden-sm-only">Description:</label>
  85 + <label
  86 + class="right hidden-lg-only hidden-md-only hidden-xl-only"
  87 + >Description:</label>
  88 + </v-flex>
  89 + <v-flex xs8 sm8 class="ml-3">
  90 + <v-text-field
  91 + v-model="addForumParams.description"
  92 + placeholder="Description"
  93 + type="text"
  94 + :rules="cantBeEmpty"
  95 + required
  96 + ></v-text-field>
  97 + </v-flex>
  98 + </v-layout>
  99 + </v-flex>
  100 + <!-- UPLOAD IMAGE -->
  101 + <v-flex xs12 sm12>
  102 + <v-layout>
  103 + <v-flex xs4 class="pt-4 subheading">
  104 + <label class="right hidden-xs-only hidden-sm-only">Upload Image:</label>
  105 + <label class="right hidden-lg-only hidden-md-only hidden-xl-only">Upload :</label>
  106 + </v-flex>
  107 + <v-flex xs8 class="ml-3">
  108 + <v-text-field
  109 + label="Select Image"
  110 + @click="pickFile"
  111 + v-model="imageName"
  112 + append-icon="attach_file"
  113 + ></v-text-field>
  114 + </v-flex>
  115 + </v-layout>
  116 + </v-flex>
  117 + </v-layout>
  118 + <v-layout>
  119 + <v-flex xs12 sm12>
  120 + <v-layout class="right">
  121 + <v-btn @click="submit" round dark :loading="loading" class="add-button">Add</v-btn>
  122 + </v-layout>
  123 + </v-flex>
  124 + </v-layout>
  125 + </v-form>
  126 + </v-flex>
  127 + </v-flex>
  128 + </v-layout>
  129 + </v-container>
  130 + </v-card>
  131 + </v-dialog>
  132 +
  133 + <v-container grid-list-xl class="pt-0">
  134 + <v-layout row class="mt-1">
5 135 <v-flex xs8>
6   - <!-- HEADING -->
7   - <div class="title side-bar-color font-weight-bold">Course Discussion Forum</div>
8   - <div class="subheading grey--text lighten-1">General news and announcements</div>
9   - <div>
10   - <v-btn round class="open-dialog-button hidden-sm-only hidden-xs-only ml-0" dark>
11   - <v-icon class="white--text pr-1" size="20">add</v-icon>Add A New Discussion Topic
12   - </v-btn>
13   - </div>
  136 + <v-layout column>
  137 + <!-- HEADING -->
  138 + <v-flex>
  139 + <div class="title side-bar-color font-weight-bold">Course Discussion Forum</div>
  140 + <div class="subheading grey--text lighten-1">General news and announcements</div>
  141 + </v-flex>
14 142  
15   - <!-- ACTIVITIES -->
16   - <div class="mt-5">
17   - <v-icon>library_books</v-icon>
18   - <span class="subheading font-weight-bold">Activities</span>
19   - </div>
20   - <!-- OTHER OPTIONS -->
21   - <div class="mt-5">
22   - <ul class="subheading">
23   - <li>Live online classes solution</li>
24   - <li>Tutorial-pharmacetutical</li>
25   - <li>HSP Interactive content</li>
26   - <li>Assessment</li>
27   - </ul>
28   - </div>
  143 + <!-- ADD DISCUSSION FORUM BUTTON -->
  144 + <v-flex>
  145 + <div>
  146 + <v-btn
  147 + fab
  148 + dark
  149 + class="open-dialog-button hidden-xl-only hidden-md-only hidden-lg-only"
  150 + small
  151 + @click="addForumDialog = true"
  152 + >
  153 + <v-icon dark>add</v-icon>
  154 + </v-btn>
  155 + <v-btn
  156 + round
  157 + class="open-dialog-button hidden-sm-only hidden-xs-only"
  158 + dark
  159 + @click="addForumDialog = true"
  160 + >
  161 + <v-icon class="white--text pr-1" size="20">add</v-icon>Add A New Discussion Topic
  162 + </v-btn>
  163 + </div>
  164 + </v-flex>
  165 + </v-layout>
29 166  
30 167 <!-- NEXT CHAPTER -->
31 168 <!-- <v-flex
... ... @@ -52,20 +189,130 @@
52 189 <div class="side-bar-color font-weight-bold title">Courses</div>
53 190  
54 191 <div v-for="(course,index) in courseData">
55   - <v-icon style="color: red;padding-bottom: 3px;" size="15">play_arrow</v-icon>
56   - <span class="subheading">{{course.coursrName}}</span>
  192 + <v-btn
  193 + flat
  194 + class="subheading text-xs-start justify-left"
  195 + style="cursor: pointer;"
  196 + block
  197 + @click="routeToCourseDetails(course._id)"
  198 + >
  199 + <div style="width: 100%;text-align: left;">
  200 + <v-icon style="color: red;padding-bottom: 3px;" size="15">play_arrow</v-icon>
  201 + {{course.coursrName}}
  202 + </div>
  203 + </v-btn>
57 204 </div>
58 205 </v-container>
59 206 </v-card>
60 207 </v-flex>
61 208 </v-layout>
62 209 </v-container>
63   - <div class="loader" v-if="showLoader">
64   - <v-progress-circular indeterminate color="white"></v-progress-circular>
65   - </div>
66 210 </div>
67 211 </template>
68   -<script></script>
  212 +<script>
  213 +import AllApiCalls from "@/Services/AllApiCalls.js";
  214 +import http from "@/Services/http.js";
  215 +export default {
  216 + mixins: [AllApiCalls],
  217 + data() {
  218 + return {
  219 + valid: true,
  220 + addForumDialog: false,
  221 + addForumParams: {},
  222 + // UPLOAD IMAGE
  223 + imageName: "",
  224 + imageUrl: "",
  225 + imageFile: "",
  226 + imageData: {}
  227 + };
  228 + },
  229 + methods: {
  230 + /* UPLOAD IMAGE */
  231 + pickFile() {
  232 + this.$refs.image.click();
  233 + },
  234 +
  235 + onFilePicked(e) {
  236 + // console.log(e)
  237 + const files = e.target.files;
  238 + this.imageData.upload = e.target.files[0];
  239 + if (files[0] !== undefined) {
  240 + this.imageName = files[0].name;
  241 + if (this.imageName.lastIndexOf(".") <= 0) {
  242 + return;
  243 + }
  244 + const fr = new FileReader();
  245 + fr.readAsDataURL(files[0]);
  246 + fr.addEventListener("load", () => {
  247 + this.imageUrl = fr.result;
  248 + this.imageFile = files[0]; // this is an image file that can be sent to server...
  249 + this.imageData.imageUrl = URL.createObjectURL(this.imageFile);
  250 + });
  251 + } else {
  252 + this.imageName = "";
  253 + this.imageFile = "";
  254 + this.imageUrl = "";
  255 + }
  256 + },
  257 + submit() {
  258 + if (this.$refs.form.validate()) {
  259 + this.addForumParams.classId = localStorage.getItem("parentClassId");
  260 + this.addForumParams.courseId = this.$route.query.courseId;
  261 + this.addForumParams.studentId = localStorage.getItem("parentStudentId");
  262 +
  263 + if (this.imageUrl) {
  264 + var str = this.imageUrl;
  265 + const [baseUrl, imageUrl] = str.split(/,/);
  266 + this.addForumParams.upload = imageUrl;
  267 + }
  268 + this.loading = true;
  269 + http()
  270 + .post("/createCourseDiscussion", this.addForumParams)
  271 + .then(response => {
  272 + this.snackbar = true;
  273 + this.text = "Discussion added successfully";
  274 + this.snackbarColor = "green";
  275 + this.addForumDialog = false;
  276 + this.clear();
  277 + this.loading = false;
  278 + console.log("response of createCourseDiscussion - ", response);
  279 + })
  280 + .catch(error => {
  281 + this.snackbar = true;
  282 + this.text = error.response.data.message;
  283 + this.color = "error";
  284 + this.loading = false;
  285 + });
  286 + }
  287 + },
  288 + clear() {
  289 + this.$refs.form.reset();
  290 + this.imageUrl = "";
  291 + },
  292 + async routeToCourseDetails(courseId) {
  293 + /* getParticularCourseDetail- To get courseDetail - defined in GetApis.js*/
  294 + let response = await this.getParticularCourseDetail(courseId);
  295 +
  296 + /* If the response is null then dont route */
  297 + if (response.data.data.length > 0) {
  298 + this.$router.push({
  299 + name: "Course Details",
  300 + query: { courseId: courseId }
  301 + });
  302 + } else {
  303 + this.seeSnackbar("No Data Available", "warning");
  304 + }
  305 + }
  306 + },
  307 + async created() {
  308 + /* getStudentCourses - to get courseData - defined in GetApis.js*/
  309 + await this.getStudentCourses({
  310 + classId: localStorage.getItem("parentClassId"),
  311 + studentId: localStorage.getItem("parentStudentId")
  312 + });
  313 + }
  314 +};
  315 +</script>
69 316 <style scoped>
70 317 .side-bar-color {
71 318 color: #827bfa !important;
... ...
src/pages/Dashboard/dashboard.vue
... ... @@ -48,6 +48,26 @@
48 48 </v-card>
49 49 </v-dialog>-->
50 50 <!-- <v-container fluid grid-list-xl> -->
  51 +
  52 + <!-- LOADER -->
  53 + <div class="loader" v-if="showLoader">
  54 + <v-progress-circular indeterminate color="white"></v-progress-circular>
  55 + </div>
  56 +
  57 + <!-- SNACKBAR -->
  58 + <v-snackbar
  59 + :timeout="timeout"
  60 + :top="y === 'top'"
  61 + :right="x === 'right'"
  62 + :vertical="mode === 'vertical'"
  63 + v-model="snackbar"
  64 + :color="snackbarColor"
  65 + >
  66 + {{ text }}
  67 + <v-spacer></v-spacer>
  68 + <v-btn flat text @click="snackbar = false">X</v-btn>
  69 + </v-snackbar>
  70 +
51 71 <v-layout wrap>
52 72 <v-flex xs12>
53 73 <v-layout wrap row>
... ... @@ -239,7 +259,7 @@
239 259 <v-list-tile-content>
240 260 <v-list-tile-title
241 261 style="cursor: pointer;"
242   - @click="$router.push( { name:'Course Details', query:{courseId: course._id} } )"
  262 + @click="routeToCourseDetails(course._id)"
243 263 >{{ course.coursrName }}</v-list-tile-title>
244 264 </v-list-tile-content>
245 265 </v-list-tile>
... ... @@ -414,21 +434,20 @@
414 434 </v-flex>
415 435 </v-card>
416 436 </v-dialog>
417   - <div class="loader" v-if="showLoader">
418   - <v-progress-circular indeterminate color="white"></v-progress-circular>
419   - </div>
420 437 </v-app>
421 438 </template>
422 439  
423 440 <script>
424 441 import http from "@/Services/http.js";
425 442 import moment from "moment";
  443 +import AllApiCalls from "@/Services/AllApiCalls.js";
426 444 // import { FunctionalCalendar } from "vue-functional-calendar";
427 445  
428 446 export default {
429 447 components: {
430 448 // FunctionalCalendar
431 449 },
  450 + mixins: [AllApiCalls],
432 451 data() {
433 452 return {
434 453 // data: {
... ... @@ -437,6 +456,7 @@ export default {
437 456 // markedDates: ["16/4/2019", "18/4/2019", "20/4/2019", "21/4/2019"],
438 457 // calendarData: {},
439 458 // calendar: {},
  459 +
440 460 colorsArray: ["#ff8a89", "#71d9ea", "#7852cc", "#F9A825"],
441 461 demoEvents: [
442 462 {
... ... @@ -623,6 +643,20 @@ export default {
623 643 // this.getUsersList();
624 644 },
625 645 methods: {
  646 + async routeToCourseDetails(courseId) {
  647 + /* getParticularCourseDetail- To get courseDetail - defined in GetApis.js*/
  648 + let response = await this.getParticularCourseDetail(courseId);
  649 +
  650 + /* If the response is null then dont route */
  651 + if (response.data.data.length > 0) {
  652 + this.$router.push({
  653 + name: "Course Details",
  654 + query: { courseId: courseId }
  655 + });
  656 + } else {
  657 + this.seeSnackbar("No Data Available", "warning");
  658 + }
  659 + },
626 660 studentMeetingEvents() {
627 661 http()
628 662 .get("/studentMeetingEvents", {
... ... @@ -831,14 +865,14 @@ export default {
831 865  
832 866 if (localStorage.getItem("parentStudentId") == null) {
833 867 var parentStudentsId = response.data.data.students[0].classId;
834   - var ClassId = response.data.data.students[0]._id;
  868 + var classId = response.data.data.students[0]._id;
835 869 }
836 870 if (localStorage.getItem("parentStudentId")) {
837 871 var parentStudentsId = localStorage.getItem("parentStudentId");
838   - var ClassId = localStorage.getItem("parentClassId");
  872 + var classId = localStorage.getItem("parentClassId");
839 873 }
840   - this.getCourses(parentStudentsId, ClassId);
841   - this.getAnnoucementes(ClassId);
  874 + this.getCourses(parentStudentsId, classId);
  875 + this.getAnnoucementes(classId);
842 876 this.showLoader = false;
843 877 })
844 878 .catch(err => {
... ... @@ -846,30 +880,36 @@ export default {
846 880 this.showLoader = false;
847 881 });
848 882 },
849   - getCourses(parentStudentsId, ClassId) {
850   - this.showLoader = true;
851   - http()
852   - .get("/getStudentCourses", {
853   - params: {
854   - classId: ClassId,
855   - studentId: parentStudentsId
856   - }
857   - })
858   - .then(response => {
859   - this.courseData = response.data.data;
860   - this.showLoader = false;
861   - })
862   - .catch(err => {
863   - console.log("err====>", err);
864   - this.showLoader = false;
865   - });
  883 + async getCourses(parentStudentsId, classId) {
  884 + /* getStudentCourses - to get courseData - defined in GetApis.js*/
  885 + await this.getStudentCourses({
  886 + classId: classId,
  887 + studentId: parentStudentsId
  888 + });
  889 + // this.showLoader = true;
  890 + // http()
  891 + // .get("/getStudentCourses", {
  892 + // params: {
  893 + // classId: classId,
  894 + // studentId: parentStudentsId
  895 + // }
  896 + // })
  897 + // .then(response => {
  898 + // this.courseData = response.data.data;
  899 + // console.log("course data - ",this.courseData)
  900 + // this.showLoader = false;
  901 + // })
  902 + // .catch(err => {
  903 + // console.log("err====>", err);
  904 + // this.showLoader = false;
  905 + // });
866 906 },
867   - getAnnoucementes(ClassId) {
  907 + getAnnoucementes(classId) {
868 908 this.showLoader = true;
869 909 http()
870 910 .get("/getAnnoucementesList", {
871 911 params: {
872   - classId: ClassId
  912 + classId: classId
873 913 }
874 914 })
875 915 .then(response => {
... ...