@mui-toolpad-extended-tuni/courses 3.0.3 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +411 -6
- package/dist/CourseTools.d.ts +1 -1
- package/dist/Forms/CourseSettings/CourseSettingsTabs.d.ts +1 -1
- package/dist/Forms/CourseSettings/tabs/EnrollmentTab.d.ts +1 -1
- package/dist/Forms/CourseSettings/tabs/StaffTab.d.ts +1 -1
- package/dist/components/ToolDisplayer/ToolCard.d.ts +1 -1
- package/dist/components/ToolDisplayer/ToolDisplayer.d.ts +1 -1
- package/dist/context/CourseMicroserviceContext.d.ts +1 -1
- package/dist/index.cjs +250 -32
- package/dist/index.d.ts +2 -0
- package/dist/index.es.js +25322 -6206
- package/dist/store/useCourseStore.d.ts +2 -2
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -5,14 +5,20 @@ Courses microservice extension for MUI Toolpad Extended TUNI. This package provi
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @mui-toolpad-extended-tuni/courses
|
|
8
|
+
npm install @mui-toolpad-extended-tuni/courses @mui-toolpad-extended-tuni/main @mui-toolpad-extended-tuni/core
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
**
|
|
11
|
+
**Important**: You must also install `@mui-toolpad-extended-tuni/main` and `@mui-toolpad-extended-tuni/core` as they are required peer dependencies.
|
|
12
12
|
|
|
13
|
-
## Peer Dependencies
|
|
13
|
+
## Required Peer Dependencies
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
This package requires the following peer dependencies to be installed:
|
|
16
|
+
|
|
17
|
+
### Required Packages
|
|
18
|
+
- **`@mui-toolpad-extended-tuni/main`**: ^3.4.0 - **MUST be installed separately**
|
|
19
|
+
- **`@mui-toolpad-extended-tuni/core`**: ^3.2.0 - **MUST be installed separately** (also required by main)
|
|
20
|
+
|
|
21
|
+
### React & UI Framework
|
|
16
22
|
- `react@^19.0.0`
|
|
17
23
|
- `react-dom@^19.0.0`
|
|
18
24
|
- `react-router-dom@^7.0.0`
|
|
@@ -24,6 +30,57 @@ npm install @mui-toolpad-extended-tuni/courses
|
|
|
24
30
|
- `axios@^1.7.0`
|
|
25
31
|
- `zustand@^4.5.0`
|
|
26
32
|
|
|
33
|
+
### Installation Example
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install @mui-toolpad-extended-tuni/courses @mui-toolpad-extended-tuni/main @mui-toolpad-extended-tuni/core \
|
|
37
|
+
react react-dom react-router-dom \
|
|
38
|
+
@mui/material @mui/icons-material @mui/x-date-pickers \
|
|
39
|
+
@emotion/react @emotion/styled \
|
|
40
|
+
axios zustand
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## API Configuration
|
|
44
|
+
|
|
45
|
+
This package uses configurable API endpoints. You can customize all endpoints via the `apiConfig` prop in `ToolpadProvider`.
|
|
46
|
+
|
|
47
|
+
### Default Endpoints
|
|
48
|
+
|
|
49
|
+
If no configuration is provided, the package uses these default endpoints:
|
|
50
|
+
|
|
51
|
+
- `get: "api/courses/"` - GET list of courses
|
|
52
|
+
- `getById: "api/courses/:id"` - GET course by ID (use `:id` placeholder)
|
|
53
|
+
- `getByUrl: "api/courses/?encoded_url=:encodedUrl"` - GET course by URL (use `:encodedUrl` placeholder)
|
|
54
|
+
- `post: "api/courses/"` - POST create new course
|
|
55
|
+
- `put: "api/courses/:id/"` - PUT update course (use `:id` placeholder)
|
|
56
|
+
- `delete: "api/chat/courses/:id"` - DELETE course (use `:id` placeholder)
|
|
57
|
+
|
|
58
|
+
### Customizing Endpoints
|
|
59
|
+
|
|
60
|
+
Configure endpoints via `ToolpadProvider`:
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
import { ToolpadProvider } from '@mui-toolpad-extended-tuni/main';
|
|
64
|
+
import type { CoursesApiEndpoints } from '@mui-toolpad-extended-tuni/courses';
|
|
65
|
+
|
|
66
|
+
const apiConfig = {
|
|
67
|
+
courses: {
|
|
68
|
+
get: "https://api.example.com/v1/courses",
|
|
69
|
+
getById: "https://api.example.com/v1/courses/:id",
|
|
70
|
+
getByUrl: "https://api.example.com/v1/courses?url=:encodedUrl",
|
|
71
|
+
post: "https://api.example.com/v1/courses",
|
|
72
|
+
put: "https://api.example.com/v1/courses/:id",
|
|
73
|
+
delete: "https://api.example.com/v1/courses/:id",
|
|
74
|
+
} as CoursesApiEndpoints,
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
<ToolpadProvider apiConfig={apiConfig}>
|
|
78
|
+
{/* Your app */}
|
|
79
|
+
</ToolpadProvider>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Note**: You can use either full URLs (`https://api.example.com/courses`) or relative paths (`api/courses/`). Placeholders like `:id` will be replaced with actual values at runtime.
|
|
83
|
+
|
|
27
84
|
## Usage
|
|
28
85
|
|
|
29
86
|
### Basic Setup
|
|
@@ -278,6 +335,338 @@ Course events are published with this structure:
|
|
|
278
335
|
}
|
|
279
336
|
```
|
|
280
337
|
|
|
338
|
+
## API Endpoints
|
|
339
|
+
|
|
340
|
+
This package makes the following API calls. All endpoints are configurable via `apiConfig`.
|
|
341
|
+
|
|
342
|
+
### GET `/api/courses/` (or configured `get` endpoint)
|
|
343
|
+
|
|
344
|
+
Retrieves a list of all courses.
|
|
345
|
+
|
|
346
|
+
**Request**: No body required
|
|
347
|
+
|
|
348
|
+
**Response**: `200 OK`
|
|
349
|
+
```json
|
|
350
|
+
[
|
|
351
|
+
{
|
|
352
|
+
"id": "course-123",
|
|
353
|
+
"title": "Introduction to Computer Science",
|
|
354
|
+
"description": "Basic CS concepts",
|
|
355
|
+
"code": "COMP.CS.100",
|
|
356
|
+
"instance": "compcs100-fall-2024",
|
|
357
|
+
"start_date": "2024-09-01T00:00:00Z",
|
|
358
|
+
"end_date": "2024-12-15T23:59:59Z",
|
|
359
|
+
"created_at": "2024-08-01T10:00:00Z",
|
|
360
|
+
"updated_at": "2024-08-15T14:30:00Z",
|
|
361
|
+
"visibility": {
|
|
362
|
+
"mode": "public",
|
|
363
|
+
"start_date": null,
|
|
364
|
+
"end_date": null
|
|
365
|
+
},
|
|
366
|
+
"events": {
|
|
367
|
+
"lecture": [],
|
|
368
|
+
"exercise": [],
|
|
369
|
+
"exam": [],
|
|
370
|
+
"deadline": [],
|
|
371
|
+
"other": []
|
|
372
|
+
},
|
|
373
|
+
"data_processing": {
|
|
374
|
+
"purposes": ["course_delivery", "assessment"],
|
|
375
|
+
"retention": 365,
|
|
376
|
+
"third_party_processors": [],
|
|
377
|
+
"special_categories": false,
|
|
378
|
+
"legal_basis": "consent"
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
]
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
**Response Type**: `Course[]` (array of Course objects)
|
|
385
|
+
|
|
386
|
+
### GET `/api/courses/:id` (or configured `getById` endpoint)
|
|
387
|
+
|
|
388
|
+
Retrieves a single course by ID.
|
|
389
|
+
|
|
390
|
+
**Request Parameters**:
|
|
391
|
+
- `:id` (path parameter) - Course ID
|
|
392
|
+
|
|
393
|
+
**Response**: `200 OK`
|
|
394
|
+
```json
|
|
395
|
+
{
|
|
396
|
+
"id": "course-123",
|
|
397
|
+
"title": "Introduction to Computer Science",
|
|
398
|
+
"description": "Basic CS concepts",
|
|
399
|
+
"code": "COMP.CS.100",
|
|
400
|
+
"instance": "compcs100-fall-2024",
|
|
401
|
+
// ... same structure as list endpoint
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
**Response Type**: `Course`
|
|
406
|
+
|
|
407
|
+
### GET `/api/courses/?encoded_url=:encodedUrl` (or configured `getByUrl` endpoint)
|
|
408
|
+
|
|
409
|
+
Retrieves a course by URL (base64-encoded).
|
|
410
|
+
|
|
411
|
+
**Request Parameters**:
|
|
412
|
+
- `encoded_url` (query parameter) - Base64-encoded course URL
|
|
413
|
+
|
|
414
|
+
**Response**: `200 OK` (array with single course)
|
|
415
|
+
```json
|
|
416
|
+
[
|
|
417
|
+
{
|
|
418
|
+
"id": "course-123",
|
|
419
|
+
// ... course object
|
|
420
|
+
}
|
|
421
|
+
]
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
**Response Type**: `Course[]` (array with one Course)
|
|
425
|
+
|
|
426
|
+
### POST `/api/courses/` (or configured `post` endpoint)
|
|
427
|
+
|
|
428
|
+
Creates a new course.
|
|
429
|
+
|
|
430
|
+
**Request Body**: `CourseRaw` (snake_case)
|
|
431
|
+
```json
|
|
432
|
+
{
|
|
433
|
+
"title": "Introduction to Computer Science",
|
|
434
|
+
"description": "Basic CS concepts",
|
|
435
|
+
"code": "COMP.CS.100",
|
|
436
|
+
"instance": "compcs100-fall-2024",
|
|
437
|
+
"start_date": "2024-09-01T00:00:00Z",
|
|
438
|
+
"end_date": "2024-12-15T23:59:59Z",
|
|
439
|
+
"visibility": {
|
|
440
|
+
"mode": "public",
|
|
441
|
+
"start_date": null,
|
|
442
|
+
"end_date": null
|
|
443
|
+
},
|
|
444
|
+
"events": {
|
|
445
|
+
"lecture": [],
|
|
446
|
+
"exercise": [],
|
|
447
|
+
"exam": [],
|
|
448
|
+
"deadline": [],
|
|
449
|
+
"other": []
|
|
450
|
+
},
|
|
451
|
+
"data_processing": {
|
|
452
|
+
"purposes": ["course_delivery", "assessment"],
|
|
453
|
+
"retention": 365,
|
|
454
|
+
"third_party_processors": [],
|
|
455
|
+
"special_categories": false,
|
|
456
|
+
"legal_basis": "consent"
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
**Response**: `201 Created`
|
|
462
|
+
```json
|
|
463
|
+
{
|
|
464
|
+
"id": "course-123",
|
|
465
|
+
"title": "Introduction to Computer Science",
|
|
466
|
+
// ... full Course object with generated ID and timestamps
|
|
467
|
+
"created_at": "2024-08-01T10:00:00Z",
|
|
468
|
+
"updated_at": "2024-08-01T10:00:00Z"
|
|
469
|
+
}
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
**Response Type**: `Course`
|
|
473
|
+
|
|
474
|
+
**Note**: The request body should be in snake_case format. The package automatically converts from camelCase.
|
|
475
|
+
|
|
476
|
+
### PUT `/api/courses/:id/` (or configured `put` endpoint)
|
|
477
|
+
|
|
478
|
+
Updates an existing course.
|
|
479
|
+
|
|
480
|
+
**Request Parameters**:
|
|
481
|
+
- `:id` (path parameter) - Course ID
|
|
482
|
+
|
|
483
|
+
**Request Body**: `Course` (snake_case, must include `id`)
|
|
484
|
+
```json
|
|
485
|
+
{
|
|
486
|
+
"id": "course-123",
|
|
487
|
+
"title": "Updated Course Title",
|
|
488
|
+
"description": "Updated description",
|
|
489
|
+
// ... all Course fields
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
**Response**: `200 OK`
|
|
494
|
+
```json
|
|
495
|
+
{
|
|
496
|
+
"id": "course-123",
|
|
497
|
+
"title": "Updated Course Title",
|
|
498
|
+
// ... updated Course object
|
|
499
|
+
"updated_at": "2024-08-15T14:30:00Z"
|
|
500
|
+
}
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
**Response Type**: `Course`
|
|
504
|
+
|
|
505
|
+
### DELETE `/api/chat/courses/:id` (or configured `delete` endpoint)
|
|
506
|
+
|
|
507
|
+
Deletes a course.
|
|
508
|
+
|
|
509
|
+
**Request Parameters**:
|
|
510
|
+
- `:id` (path parameter) - Course ID
|
|
511
|
+
|
|
512
|
+
**Response**: `200 OK`
|
|
513
|
+
```json
|
|
514
|
+
{
|
|
515
|
+
"id": "course-123",
|
|
516
|
+
// ... deleted Course object
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
**Response Type**: `Course`
|
|
521
|
+
|
|
522
|
+
## Data Types
|
|
523
|
+
|
|
524
|
+
### Course
|
|
525
|
+
|
|
526
|
+
Complete course object returned by API (includes `id`, `createdAt`, `updatedAt`).
|
|
527
|
+
|
|
528
|
+
```typescript
|
|
529
|
+
interface Course extends CourseRaw {
|
|
530
|
+
id: string; // Unique course ID
|
|
531
|
+
createdAt: string; // ISO date string - when course was created
|
|
532
|
+
updatedAt: string; // ISO date string - when course was last updated
|
|
533
|
+
}
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### CourseRaw
|
|
537
|
+
|
|
538
|
+
Course data for creating/updating courses (request body format).
|
|
539
|
+
|
|
540
|
+
```typescript
|
|
541
|
+
interface CourseRaw {
|
|
542
|
+
title: string; // Course title (required)
|
|
543
|
+
description: string; // Course description (required)
|
|
544
|
+
code: string; // Course code, e.g., "COMP.CS.300" (required)
|
|
545
|
+
instance: string; // Instance identifier, e.g., "compcs300-october-2024" (required)
|
|
546
|
+
ltiLoginUrl?: string; // LTI login URL (optional)
|
|
547
|
+
services?: string[]; // List of services used (optional)
|
|
548
|
+
image?: { // Course images (optional)
|
|
549
|
+
large: string; // 1200x800px image URL
|
|
550
|
+
medium: string; // 600x400px image URL
|
|
551
|
+
thumbnail: string; // 300x200px image URL
|
|
552
|
+
};
|
|
553
|
+
startDate: string | null; // ISO date string - course start date
|
|
554
|
+
endDate: string | null; // ISO date string - course end date
|
|
555
|
+
visibility: { // Visibility settings
|
|
556
|
+
mode: "public" | "enrolled" | "private";
|
|
557
|
+
startDate: string | null; // When course becomes visible
|
|
558
|
+
endDate: string | null; // When visibility ends
|
|
559
|
+
};
|
|
560
|
+
events: { // Course events by type
|
|
561
|
+
lecture: CourseEvent[];
|
|
562
|
+
exercise: CourseEvent[];
|
|
563
|
+
exam: CourseEvent[];
|
|
564
|
+
deadline: CourseEvent[];
|
|
565
|
+
other: CourseEvent[];
|
|
566
|
+
};
|
|
567
|
+
tags?: string[]; // Course tags for categorization
|
|
568
|
+
language?: string; // ISO 639-1 language code
|
|
569
|
+
dataProcessing: { // GDPR data processing info
|
|
570
|
+
purposes: string[]; // What data is used for
|
|
571
|
+
retention: number; // Retention period in days
|
|
572
|
+
thirdPartyProcessors: Array<{
|
|
573
|
+
name: string;
|
|
574
|
+
purpose: string;
|
|
575
|
+
dataShared: string[];
|
|
576
|
+
}>;
|
|
577
|
+
specialCategories: boolean; // Special categories of personal data
|
|
578
|
+
legalBasis: "consent" | "contract" | "legal_obligation" | "legitimate_interests";
|
|
579
|
+
};
|
|
580
|
+
enrollment?: { // Enrollment settings
|
|
581
|
+
startDate: string | null; // Enrollment opens
|
|
582
|
+
endDate: string | null; // Enrollment closes
|
|
583
|
+
status: {
|
|
584
|
+
open: boolean; // Whether new enrollments accepted
|
|
585
|
+
maxStudents?: number; // Maximum students (optional)
|
|
586
|
+
};
|
|
587
|
+
};
|
|
588
|
+
relationships?: { // Course relationships
|
|
589
|
+
prerequisites: CourseRelation[];
|
|
590
|
+
continuations: CourseRelation[];
|
|
591
|
+
alternatives: CourseRelation[];
|
|
592
|
+
related: CourseRelation[];
|
|
593
|
+
};
|
|
594
|
+
studyModule?: { // Study module info
|
|
595
|
+
name: string; // Module name
|
|
596
|
+
order?: number; // Order within module
|
|
597
|
+
credits: number; // Credit points
|
|
598
|
+
level: "basic" | "intermediate" | "advanced";
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
### CourseEvent
|
|
604
|
+
|
|
605
|
+
Individual course event (lecture, exercise, exam, etc.).
|
|
606
|
+
|
|
607
|
+
```typescript
|
|
608
|
+
interface CourseEvent {
|
|
609
|
+
id: string; // Event ID
|
|
610
|
+
type: "lecture" | "exercise" | "exam" | "deadline" | "other";
|
|
611
|
+
title: string; // Event title
|
|
612
|
+
description?: string; // Event description
|
|
613
|
+
startTime: string; // ISO date string - event start
|
|
614
|
+
endTime?: string; // ISO date string - event end
|
|
615
|
+
location?: string; // Physical or virtual location
|
|
616
|
+
teachers?: EnrollmentData[]; // Array of teachers
|
|
617
|
+
recurring?: { // Recurring event settings
|
|
618
|
+
frequency: "daily" | "weekly" | "biweekly";
|
|
619
|
+
until: string; // ISO date string - when recurrence ends
|
|
620
|
+
exceptions?: string[]; // ISO date strings - cancelled dates
|
|
621
|
+
};
|
|
622
|
+
maxParticipants?: number; // Maximum participants
|
|
623
|
+
requiresRegistration?: boolean; // Whether registration required
|
|
624
|
+
}
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
### EnrollmentData
|
|
628
|
+
|
|
629
|
+
User enrollment information for a course.
|
|
630
|
+
|
|
631
|
+
```typescript
|
|
632
|
+
interface EnrollmentData {
|
|
633
|
+
courseId: string; // Course ID
|
|
634
|
+
userId: string; // User ID
|
|
635
|
+
name: string; // User name
|
|
636
|
+
email: string; // User email
|
|
637
|
+
role: "student" | "teacher" | "guest";
|
|
638
|
+
status: "enrolled" | "pending" | "rejected";
|
|
639
|
+
}
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
### CourseRelation
|
|
643
|
+
|
|
644
|
+
Relationship between courses (prerequisites, continuations, etc.).
|
|
645
|
+
|
|
646
|
+
```typescript
|
|
647
|
+
interface CourseRelation {
|
|
648
|
+
code: string; // Related course code
|
|
649
|
+
type: "prerequisite" | "recommended" | "parallel" | "continues_from" |
|
|
650
|
+
"alternative_to" | "part_of" | "prepares_for";
|
|
651
|
+
description?: string; // Why courses are related
|
|
652
|
+
required?: boolean; // Hard requirement or suggestion
|
|
653
|
+
}
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
### Type Definitions
|
|
657
|
+
|
|
658
|
+
```typescript
|
|
659
|
+
type courseRole = "student" | "teacher" | "guest";
|
|
660
|
+
type visibilityMode = "public" | "enrolled" | "private";
|
|
661
|
+
type courseEventType = "lecture" | "exercise" | "exam" | "deadline" | "other";
|
|
662
|
+
type courseEventFrequency = "daily" | "weekly" | "biweekly";
|
|
663
|
+
type legalBasis = "consent" | "contract" | "legal_obligation" | "legitimate_interests";
|
|
664
|
+
type enrollmentStatus = "enrolled" | "pending" | "rejected";
|
|
665
|
+
type courseLevel = "basic" | "intermediate" | "advanced";
|
|
666
|
+
type courseRelationType = "prerequisite" | "recommended" | "parallel" |
|
|
667
|
+
"continues_from" | "alternative_to" | "part_of" | "prepares_for";
|
|
668
|
+
```
|
|
669
|
+
|
|
281
670
|
## Exports
|
|
282
671
|
|
|
283
672
|
### Components
|
|
@@ -297,13 +686,29 @@ Course events are published with this structure:
|
|
|
297
686
|
### Store
|
|
298
687
|
- `useCourseStore` - Zustand store for course management
|
|
299
688
|
|
|
689
|
+
### Network Functions
|
|
690
|
+
- `getCourses()` - Fetch all courses
|
|
691
|
+
- `getCourseById(courseId: string)` - Fetch course by ID
|
|
692
|
+
- `getCourseByUrl(url: string)` - Fetch course by URL
|
|
693
|
+
- `addCourse(courseData: CourseRaw)` - Create new course
|
|
694
|
+
- `updateCourse(course: Course)` - Update existing course
|
|
695
|
+
- `deleteCourse(courseId: string)` - Delete course
|
|
696
|
+
|
|
300
697
|
### Types
|
|
301
|
-
- `Course` -
|
|
302
|
-
- `CourseRaw` -
|
|
698
|
+
- `Course` - Complete course object (with id, timestamps)
|
|
699
|
+
- `CourseRaw` - Course data for create/update requests
|
|
700
|
+
- `CourseEvent` - Individual course event
|
|
701
|
+
- `EnrollmentData` - User enrollment information
|
|
702
|
+
- `CourseRelation` - Course relationship
|
|
703
|
+
- `CoursesApiEndpoints` - API endpoint configuration type
|
|
303
704
|
- `courseRole` - Course role type
|
|
304
705
|
- `courseLevel` - Course level type
|
|
305
706
|
- `courseEventType` - Course event type
|
|
306
707
|
- `enrollmentStatus` - Enrollment status type
|
|
708
|
+
- `visibilityMode` - Visibility mode type
|
|
709
|
+
- `courseEventFrequency` - Event frequency type
|
|
710
|
+
- `legalBasis` - Legal basis for data processing
|
|
711
|
+
- `courseRelationType` - Course relation type
|
|
307
712
|
|
|
308
713
|
## Features
|
|
309
714
|
|
package/dist/CourseTools.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CourseRaw } from '../../store/useCourseStore';
|
|
2
|
-
import { UserData } from 'mui-toolpad-extended-tuni';
|
|
2
|
+
import { UserData } from '@mui-toolpad-extended-tuni/main';
|
|
3
3
|
type CourseSettingsProps = {
|
|
4
4
|
formData: CourseRaw;
|
|
5
5
|
handleUpdateFormData: (newData: CourseRaw) => void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { default as React, ReactNode } from 'react';
|
|
2
|
-
import { NavigationPageStoreItem } from 'mui-toolpad-extended-tuni';
|
|
2
|
+
import { NavigationPageStoreItem } from '@mui-toolpad-extended-tuni/main';
|
|
3
3
|
/**
|
|
4
4
|
* Context for course microservices to register themselves
|
|
5
5
|
*/
|