tum %!s(int64=2) %!d(string=před) roky
rodič
revize
ce230f2ace

+ 23 - 0
src/composable/settings.ts

@@ -143,6 +143,17 @@ export const listCourseMats = async  (cid) => {
143 143
   console.log(data)
144 144
   return data
145 145
 }
146
+export const listCourseMatsByLevel = async  (clevels) => {
147
+  const token = await Preferences.get({ key: 'token' });
148
+  console.log("token = ", token)
149
+  const { data } = await axios.get(BASE_URL + "backend/api/mats/?course_level="+clevels.join(","), {
150
+    headers: { 
151
+    'Authorization': `Token ${token.value}`
152
+    }
153
+  })
154
+  console.log(data)
155
+  return data
156
+}
146 157
 export const getTodayProgs = async  (day=null) => {
147 158
   const token = await Preferences.get({ key: 'token' });
148 159
   console.log("token = ", token)
@@ -205,3 +216,15 @@ export const searchMat = async (s) => {
205 216
   })
206 217
   return data
207 218
 }
219
+
220
+export const callUrl = async(url) => {
221
+  
222
+  const token = await Preferences.get({ key: 'token' });
223
+  console.log("token = ", token)
224
+  const { data } = await axios.get(url, {
225
+    headers: { 
226
+    'Authorization': `Token ${token.value}`
227
+    }
228
+  })
229
+  return data
230
+}

+ 25 - 6
src/views/CourseDetailPage.vue

@@ -24,7 +24,10 @@
24 24
             <CourseMat :obj="c" :course-name="course.name" class='ion-no-margin' />
25 25
           </ion-col>
26 26
         </ion-row>
27
-      </ion-grid> 
27
+      </ion-grid>
28
+      <ion-infinite-scroll @ionInfinite="loadMore">
29
+        <ion-infinite-scroll-content></ion-infinite-scroll-content>
30
+      </ion-infinite-scroll>
28 31
     </ion-content>
29 32
   </ion-page>
30 33
 </template>
@@ -33,9 +36,10 @@
33 36
 import { IonPage, IonHeader, IonToolbar, IonTitle, IonContent,   IonNavLink,
34 37
     IonButton,
35 38
     IonButtons,
36
-    IonBackButton, onIonViewWillEnter, IonRow, IonGrid, IonCol, IonProgressBar } from '@ionic/vue';
39
+    IonBackButton, onIonViewWillEnter, IonRow, IonGrid, IonCol, IonProgressBar,  IonInfiniteScroll,
40
+    IonInfiniteScrollContent, InfiniteScrollCustomEvent  } from '@ionic/vue';
37 41
 import { useRoute } from 'vue-router';
38
-import { listCourseMats, getCourse } from '@/composable/settings';
42
+import { listCourseMats, getCourse, listCourseMatsByLevel, callUrl} from '@/composable/settings';
39 43
 import { ref } from 'vue';
40 44
 import CourseMat from '@/components/CourseMat.vue'
41 45
 
@@ -44,13 +48,28 @@ const { id } = route.params;
44 48
 
45 49
 const mats = ref([])
46 50
 const course = ref()
51
+let next_url = null
47 52
 const processing = ref(false)
48 53
 onIonViewWillEnter(async () => {
49
-  getCourse(id).then( (data) => course.value = data )
54
+  course.value = await getCourse(id)
50 55
   processing.value = true
51
-  listCourseMats(id).then( (data) => { 
52
-    mats.value = data;
56
+  listCourseMatsByLevel(course.value.clevels).then( (data) => { 
57
+    mats.value = data.results;
58
+    next_url = data.next
53 59
     processing.value = false
54 60
   })
61
+
55 62
 })
63
+  const loadMore = async (ev: InfiniteScrollCustomEvent) => {
64
+    //setTimeout(() => ev.target.complete(), 500);
65
+    console.log("next url ", next_url)
66
+    if(next_url) {
67
+      let data  = await callUrl(next_url)
68
+      mats.value.push(data.results)
69
+      next_url = data.next
70
+      ev.target.complete()
71
+    }else {
72
+      ev.target.complete()
73
+    }
74
+  };
56 75
 </script>

+ 18 - 1
src/views/CourseMatDetailPage.vue

@@ -29,7 +29,7 @@
29 29
         <ion-item-divider class='ion-margin-vertical'>
30 30
           <ion-label>Related Trainings</ion-label>
31 31
         </ion-item-divider> 
32
-      <swiper :slides-per-view="2" :loop="true" v-if="mats" class='ion-no-margin'>
32
+      <swiper :slides-per-view="1" :loop="true" v-if="mats" class='ion-no-margin'>
33 33
 
34 34
       <swiper-slide v-for="m in mats">
35 35
         <CourseMat :obj="m" :course-name="mat.course_name" />
@@ -81,3 +81,20 @@ onIonViewWillEnter(async () => {
81 81
   mats.value  = await listMats(mat.value.related_mats)
82 82
 })
83 83
 </script>
84
+
85
+<style scoped>
86
+#post_slide {
87
+   aspect-ratio:4/3 auto;
88
+}
89
+.img_16_9 {
90
+  width:480px;
91
+  height:270px;
92
+  object-fit:cover;
93
+}
94
+.swiper-slide {
95
+  width: 90% !important;
96
+	&:last-child {
97
+	  width: 100% !important;
98
+	}
99
+}
100
+</style>

+ 21 - 2
src/views/SearchPage.vue

@@ -24,17 +24,21 @@
24 24
           <h1 class='ion-text-center'>Search not found</h1>
25 25
         </template>
26 26
       </ion-list>
27
+      <ion-infinite-scroll @ionInfinite="loadMore">
28
+        <ion-infinite-scroll-content></ion-infinite-scroll-content>
29
+      </ion-infinite-scroll>
27 30
     </ion-content>
28 31
   </ion-page>
29 32
 </template>
30 33
 
31 34
 <script setup lang="ts">
32 35
 import { IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonButton, onIonViewWillEnter, IonList, IonSearchbar, IonLabel,
33
-IonItem, IonBackButton, IonProgressBar, IonButtons } from '@ionic/vue';
36
+IonItem, IonBackButton, IonProgressBar, IonButtons, IonInfiniteScroll,
37
+    IonInfiniteScrollContent, InfiniteScrollCustomEvent } from '@ionic/vue';
34 38
 import ExploreContainer from '@/components/ExploreContainer.vue';
35 39
 import { defineComponent, onMounted } from 'vue';
36 40
 import { GoogleAuth } from '@codetrix-studio/capacitor-google-auth';
37
-import { searchMat } from '@/composable/settings';
41
+import { searchMat, callUrl } from '@/composable/settings';
38 42
 
39 43
 import { ref } from 'vue';
40 44
 import SearchItem from '@/components/SearchItem.vue';
@@ -42,6 +46,7 @@ import SearchItem from '@/components/SearchItem.vue';
42 46
 const results = ref();
43 47
 const is_empty = ref(false);
44 48
 const processing = ref(false)
49
+let next_url = null
45 50
 const handleInput = async (event) => {
46 51
   console.log("handleInput")
47 52
   console.log(event)
@@ -58,6 +63,7 @@ const handleInput = async (event) => {
58 63
     processing.value = false;
59 64
 
60 65
     results.value = r.results
66
+    next_url  = r.next
61 67
     if(r.count == 0 ) {
62 68
       is_empty.value = true;
63 69
     }else {
@@ -66,4 +72,17 @@ const handleInput = async (event) => {
66 72
   }
67 73
   //test
68 74
 }
75
+  const loadMore = async (ev: InfiniteScrollCustomEvent) => {
76
+    //setTimeout(() => ev.target.complete(), 500);
77
+    console.log("next url ", next_url)
78
+    if(next_url) {
79
+      let data  = await callUrl(next_url)
80
+      console.log("data results", data.results)
81
+      results.value.push(data.results)
82
+      next_url = data.next
83
+      ev.target.complete()
84
+    }else {
85
+      ev.target.complete()
86
+    }
87
+  };
69 88
 </script>

+ 8 - 1
src/views/Tab2Page.vue

@@ -3,6 +3,11 @@
3 3
     <ion-header>
4 4
       <ion-toolbar>
5 5
         <ion-title>Courses</ion-title>
6
+       <ion-buttons slot="end">
7
+          <ion-button :router-link="'/tabs/search_page/'">
8
+            <ion-icon slot="icon-only" :icon="search"></ion-icon>
9
+          </ion-button>
10
+        </ion-buttons>
6 11
       </ion-toolbar>
7 12
     </ion-header>
8 13
     <ion-content :fullscreen="true">
@@ -26,7 +31,9 @@
26 31
 </template>
27 32
 
28 33
 <script setup lang="ts">
29
-import { IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonGrid, IonRow, IonCol, onIonViewWillEnter, IonProgressBar } from '@ionic/vue';
34
+import { IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonGrid, IonRow, IonCol, onIonViewWillEnter, IonProgressBar, IonIcon, IonButtons, IonButton} from '@ionic/vue';
35
+import { search } from 'ionicons/icons';
36
+
30 37
 import Course from '@/components/Course.vue';
31 38
 import { ref } from 'vue';
32 39