diff --git a/src/components/TheLecturerSearchTable.vue b/src/components/TheLecturerSearchTable.vue new file mode 100644 index 0000000..726234c --- /dev/null +++ b/src/components/TheLecturerSearchTable.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/src/pages/LecturerPage.vue b/src/pages/LecturerPage.vue index ebe4f11..cbc4e47 100644 --- a/src/pages/LecturerPage.vue +++ b/src/pages/LecturerPage.vue @@ -10,7 +10,6 @@ import LecturerHeaderCard from '@/components/LecturerHeaderCard.vue'; import { adaptNumeral, getPhoto, copyUrlToClipboard } from '@/utils'; const { mobile } = useDisplay(); - const router = useRouter(); const page = ref(1); @@ -34,7 +33,7 @@ async function loadLecturer() { id: Number(lecturerId), }, query: { - info: ['comments', 'mark'], + info: ['comments'], }, }, }); diff --git a/src/pages/MainPage.vue b/src/pages/MainPage.vue index e65f3d1..f3860a4 100644 --- a/src/pages/MainPage.vue +++ b/src/pages/MainPage.vue @@ -1,139 +1,137 @@ diff --git a/src/store/lecturerStore.ts b/src/store/lecturerStore.ts new file mode 100644 index 0000000..bbc3d4c --- /dev/null +++ b/src/store/lecturerStore.ts @@ -0,0 +1,51 @@ +import { ref } from 'vue'; +import { defineStore } from 'pinia'; +import apiClient from '@/api'; +import { Lecturer, Order } from '@/models'; +import { getPhoto } from '@/utils'; +import Placeholder from '@/assets/profile_image_placeholder.webp'; + +interface FetchLecturersParams { + page: number; + itemsPerPage: number; + name?: string; + subject?: string; + orderBy?: Order; + ascending?: boolean; +} + +export const useLecturerStore = defineStore('lecturer', () => { + // State + const lecturers = ref([]); + const lecturersPhotos = ref([]); + const totalPages = ref(1); + + // Actions + async function fetchLecturers(params: FetchLecturersParams) { + const offset = (params.page - 1) * params.itemsPerPage; + const res = await apiClient.GET('/rating/lecturer', { + params: { + query: { + limit: params.itemsPerPage, + name: params.name, + offset, + info: ['comments'], + subject: params.subject, + order_by: `${params.ascending ? '+' : '-'}${params.orderBy ?? 'mark_general'}`, + }, + }, + }); + + lecturers.value = res.data?.lecturers || []; + totalPages.value = res.data?.total ? Math.ceil(res.data.total / params.itemsPerPage) : 1; + + lecturersPhotos.value = lecturers.value.map(item => getPhoto(item.avatar_link)) ?? [Placeholder]; + } + + return { + lecturers, + lecturersPhotos, + totalPages, + fetchLecturers, + }; +}); diff --git a/src/store/mainPageStateStore.ts b/src/store/mainPageStateStore.ts new file mode 100644 index 0000000..a8bd343 --- /dev/null +++ b/src/store/mainPageStateStore.ts @@ -0,0 +1,20 @@ +import { defineStore } from 'pinia'; +import { ref } from 'vue'; + +export const useMainPageStateStore = defineStore('mainPageState', () => { + const isCompactView = ref(false); + + function setCompactView(value: boolean) { + isCompactView.value = value; + } + + function toggleCompactView() { + isCompactView.value = !isCompactView.value; + } + + return { + isCompactView, + setCompactView, + toggleCompactView, + }; +}); diff --git a/src/utils/marks.ts b/src/utils/marks.ts new file mode 100644 index 0000000..c306823 --- /dev/null +++ b/src/utils/marks.ts @@ -0,0 +1,9 @@ +export function formatMark(mark: number | null | undefined): string { + if (mark === null || mark === undefined) return '—'; + return mark > 0 ? `+${mark.toFixed(1)}` : mark.toFixed(1); +} + +export function getMarkColor(mark: number | null | undefined): string { + if (mark === null || mark === undefined) return 'grey'; + return mark > 0 ? 'green' : mark === 0 ? 'grey' : 'red'; +} \ No newline at end of file