Enhance audience management features with new components and API integrations

- Added `AssignCoursesModal`, `AudienceMemberRow`, `AudienceTable`, and related components for improved audience management UI.
- Implemented audience invite actions including resend and revoke functionality.
- Updated audience API to support importing members and assigning courses.
- Refactored audience data handling to include status and invite management.
- Improved overall user experience with pagination and selection features in the audience table.
This commit is contained in:
Rotimi Best
2026-03-22 18:42:23 +01:00
parent e9c4082f89
commit 3919ff6c2f
157 changed files with 13183 additions and 872 deletions
@@ -8,6 +8,8 @@ import type {
UserEnrolledCourses
} from '$features/course/types';
import { SvelteSet } from 'svelte/reactivity';
/**
* API class for course operations
*/
@@ -16,12 +18,19 @@ export class CoursesApi extends BaseApiWithErrors {
enrolledCourses = $state<UserEnrolledCourses>([]);
recommendedCourses = $state<RecommendedCourses>([]);
/** Keeps list UIs in sync after a course is deleted (server data is updated separately on navigation). */
removeCourseFromLists(courseId: string) {
this.orgCourses = this.orgCourses.filter((c) => c.id !== courseId);
this.enrolledCourses = this.enrolledCourses.filter((c) => c.id !== courseId);
this.recommendedCourses = this.recommendedCourses.filter((c) => c.id !== courseId);
}
/**
* Fetches org courses for the current organization
* Org ID is automatically added from currentOrg store
*/
async getOrgCourses(tagSlugs: string[] = []) {
const normalizedTagSlugs = Array.from(new Set(tagSlugs.map((tag) => tag.trim()).filter(Boolean)));
const normalizedTagSlugs = Array.from(new SvelteSet(tagSlugs.map((tag) => tag.trim()).filter(Boolean)));
return this.execute<GetOrgCoursesRequest>({
requestFn: () =>
@@ -32,7 +41,7 @@ export class CoursesApi extends BaseApiWithErrors {
tags: normalizedTagSlugs.join(',')
}
}
: {}
: { query: {} }
),
logContext: 'fetching org courses',
onSuccess: (response) => {