Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | import { defineStore } from 'pinia' import { courseApi } from '@/api/course.api' import type { Course, CourseWithUsers, CourseCreate, CourseUpdate, User } from '@/types' export const useCourseStore = defineStore('course', { state: () => ({ courses: [] as Course[], currentCourse: null as CourseWithUsers | null, // Sole source of truth for the detail page's roster — kept // separate from ``currentCourse.users`` so member mutations don't // need to refetch the whole course just to update the list. currentMembers: [] as User[], isLoading: false, error: null as string | null, }), actions: { async fetchCourses() { this.isLoading = true this.error = null try { const { data } = await courseApi.list() this.courses = data } catch (err: any) { this.error = err.response?.data?.detail || 'Failed to fetch courses' } finally { this.isLoading = false } }, async fetchCourseById(courseId: string) { this.isLoading = true this.error = null try { const { data } = await courseApi.getById(courseId) this.currentCourse = data this.currentMembers = data.users ?? [] } catch (err: any) { this.error = err.response?.data?.detail || 'Failed to fetch course' throw err } finally { this.isLoading = false } }, async createCourse(data: CourseCreate) { this.isLoading = true this.error = null try { const { data: course } = await courseApi.create(data) this.courses.push(course) return course } catch (err: any) { this.error = err.response?.data?.detail || 'Failed to create course' throw err } finally { this.isLoading = false } }, async updateCourse(courseId: string, data: CourseUpdate) { this.isLoading = true this.error = null try { const { data: course } = await courseApi.update(courseId, data) const index = this.courses.findIndex((c) => c.courseId === courseId) if (index !== -1) { this.courses[index] = course } if (this.currentCourse && this.currentCourse.courseId === courseId) { this.currentCourse = { ...this.currentCourse, ...course } } return course } catch (err: any) { this.error = err.response?.data?.detail || 'Failed to update course' throw err } finally { this.isLoading = false } }, async deleteCourse(courseId: string) { this.isLoading = true this.error = null try { await courseApi.delete(courseId) this.courses = this.courses.filter((c) => c.courseId !== courseId) } catch (err: any) { this.error = err.response?.data?.detail || 'Failed to delete course' throw err } finally { this.isLoading = false } }, // -------------------------------------------------------------- // MEMBERS // -------------------------------------------------------------- async fetchMembers(courseId: string) { try { const { data } = await courseApi.listMembers(courseId) this.currentMembers = data return data } catch (err: any) { this.error = err.response?.data?.detail || 'Failed to fetch members' throw err } }, async addMembers(courseId: string, userIds: string[]) { try { const { data } = await courseApi.addMembers(courseId, userIds) this.currentMembers = data return data } catch (err: any) { this.error = err.response?.data?.detail || 'Failed to add members' throw err } }, async removeMember(courseId: string, userId: string) { try { await courseApi.removeMember(courseId, userId) this.currentMembers = this.currentMembers.filter((u) => u.userId !== userId) } catch (err: any) { this.error = err.response?.data?.detail || 'Failed to remove member' throw err } }, }, }) |