Commit 6f7cf8cf51ccd302256ddc6cc67a0bd94c973313
1 parent
fe15ee8b4c
Exists in
master
and in
3 other branches
added discussion forum,and chapter info,side bar
Showing
10 changed files
with
787 additions
and
139 deletions
Show diff stats
src/Services/AllApiCalls.js
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
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 => { | ... | ... |