FavoriteClass.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <script setup>
  2. import { ref, reactive, watch } from "vue";
  3. import { useMainStore } from "@/stores/store";
  4. import axios from "axios";
  5. import CourseCard from "@/components/CourseCard.vue";
  6. const store = useMainStore();
  7. let favorites = reactive({
  8. list: [],
  9. });
  10. let favoritesAll = reactive({
  11. list: [],
  12. });
  13. let token = store.token;
  14. // 取得收藏課程
  15. async function getFavoriteClass() {
  16. try {
  17. const response = await axios.get(
  18. `https://cmm.ai:8088/api/get_favorite_class?access_token=${token}`
  19. );
  20. console.log(
  21. "response.data.favorite_courses",
  22. response.data.favorite_courses
  23. );
  24. favorites.list = response.data.favorite_courses;
  25. favoritesAll.list = response.data.favorite_courses;
  26. } catch (error) {
  27. console.error(error);
  28. }
  29. }
  30. getFavoriteClass();
  31. let progress = ref(false);
  32. let timeoutId = null;
  33. let searchError = ref(false);
  34. const searchText = ref("");
  35. const filtered = reactive({
  36. list: [],
  37. });
  38. watch(searchText, (val) => {
  39. if (val === "") {
  40. favorites.list = favoritesAll.list;
  41. }
  42. });
  43. // 延遲觸發
  44. const handleInput = () => {
  45. clearTimeout(timeoutId);
  46. timeoutId = setTimeout(handleSearch, 500);
  47. };
  48. // 課程搜尋
  49. const handleSearch = () => {
  50. filtered.list = favorites.list.filter((item) =>
  51. item.name.includes(searchText.value)
  52. );
  53. if (filtered.list.length) {
  54. favorites.list = filtered.list;
  55. searchError.value = false;
  56. } else {
  57. favorites.list = favoritesAll.list;
  58. searchError.value = true;
  59. setTimeout(() => {
  60. searchError.value = false;
  61. }, 2000);
  62. }
  63. console.log("filtered", filtered);
  64. };
  65. </script>
  66. <template>
  67. <v-card class="h-100">
  68. <div class="title">
  69. <h4>我的收藏</h4>
  70. </div>
  71. <v-text-field
  72. v-model.lazy="searchText"
  73. class="ms-5 mt-5"
  74. hide-details
  75. @input="handleInput"
  76. >
  77. <template v-slot:label>
  78. <span>
  79. 搜尋課程<v-icon
  80. icon="mdi-text-box-search-outline"
  81. class="pb-1 ps-1"
  82. ></v-icon>
  83. </span>
  84. </template>
  85. </v-text-field>
  86. <div class="error">
  87. <div v-if="searchError" class="d-flex align-center ms-6 pt-2">
  88. <v-icon color="primary" icon="mdi-alert" class="me-2"></v-icon>
  89. 沒有符合搜尋條件的項目
  90. </div>
  91. </div>
  92. <v-container>
  93. <v-row>
  94. <v-col cols="12" v-if="!favorites.list.length">
  95. <router-link to="/setup-courses" class="hint-item">
  96. <v-icon color="purple" icon="mdi-bookmark" class="mb-2"></v-icon>
  97. <p>
  98. 收藏是空的喔! <br />
  99. 趕快前往探索課程找尋感興趣的課程吧!
  100. </p>
  101. </router-link>
  102. </v-col>
  103. <v-col
  104. sm="4"
  105. cols="12"
  106. v-for="(item, index) in favorites.list"
  107. :key="index"
  108. class="pa-5"
  109. >
  110. <CourseCard :data="item" />
  111. </v-col>
  112. </v-row>
  113. <div class="progress-item" v-if="progress">
  114. <v-progress-circular
  115. :size="50"
  116. indeterminate
  117. color="primary"
  118. ></v-progress-circular>
  119. </div>
  120. </v-container>
  121. </v-card>
  122. </template>
  123. <style lang="scss" scoped>
  124. .error {
  125. height: 1.5625em;
  126. }
  127. </style>