All files / src/stores course.store.ts

0% Statements 0/115
0% Branches 0/1
0% Functions 0/1
0% Lines 0/115

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
      }
    },
  },
})