Files
classroomio/apps/dashboard/src/lib/features/course/components/new-course-modal.svelte
T

146 lines
4.4 KiB
Svelte
Raw Normal View History

<script lang="ts">
2025-11-01 15:49:29 +01:00
import { preventDefault } from '$lib/utils/functions/svelte';
import { goto } from '$app/navigation';
2025-11-01 15:49:29 +01:00
import { page } from '$app/state';
2026-03-09 11:18:22 +01:00
import { createCourseModal } from '../utils/store';
import { TextareaField } from '@cio/ui/custom/textarea-field';
import { InputField } from '@cio/ui/custom/input-field';
import * as Dialog from '@cio/ui/base/dialog';
import { Button } from '@cio/ui/base/button';
import * as Field from '@cio/ui/base/field';
2026-03-09 11:18:22 +01:00
import { RadioOptionCardGroup } from '@cio/ui/custom/radio-option-card';
import { t } from '$lib/utils/functions/translations';
2026-03-09 11:18:22 +01:00
import type { TCourseType } from '@cio/db/types';
import { courseApi } from '../api';
2021-12-30 22:30:30 +02:00
2025-11-01 15:49:29 +01:00
let step = $state(0);
2021-12-30 22:30:30 +02:00
const options = [
{
id: 'self-paced',
title: $t('new_course_modal.self_paced_label'),
subtitle: $t('new_course_modal.self_paced_subtitle'),
2026-03-09 11:18:22 +01:00
type: 'SELF_PACED' as TCourseType,
isDisabled: false
2026-04-27 11:40:38 +01:00
},
{
id: 'live-class',
title: $t('new_course_modal.live_class_label'),
subtitle: $t('new_course_modal.live_class_subtitle'),
type: 'LIVE_CLASS' as TCourseType,
isDisabled: false
},
2026-04-27 11:40:38 +01:00
{
id: 'compliance',
title: $t('new_course_modal.compliance_label'),
subtitle: $t('new_course_modal.compliance_subtitle'),
type: 'COMPLIANCE' as TCourseType,
isDisabled: false
},
{
id: 'public',
title: $t('new_course_modal.public_label'),
subtitle: $t('new_course_modal.public_subtitle'),
type: 'PUBLIC' as TCourseType,
isDisabled: false
}
];
2026-03-09 11:18:22 +01:00
const courseTypeOptionsForGroup = options.map((o) => ({
id: o.id,
title: o.title,
description: o.subtitle,
value: o.type
}));
2025-11-01 15:49:29 +01:00
let type = $state(options[0].type);
2024-07-11 09:03:35 +01:00
function onClose(redirectTo) {
2024-06-21 10:39:50 +01:00
goto(redirectTo);
createCourseModal.update(() => ({
title: '',
description: '',
type: '',
emails: '',
tutors: '',
students: ''
}));
}
2023-10-30 06:04:53 +00:00
async function createCourse() {
2026-03-09 11:18:22 +01:00
await courseApi.create({
title: $createCourseModal.title,
description: $createCourseModal.description,
type: type
2023-10-30 06:04:53 +00:00
});
2021-12-30 22:30:30 +02:00
}
2025-11-01 15:49:29 +01:00
let open = $derived(new URLSearchParams(page.url.search).get('create') === 'true');
2021-12-30 22:30:30 +02:00
</script>
{#snippet course_type_selector()}
<Field.Description>{$t('courses.new_course_modal.type_selector_title')}</Field.Description>
<RadioOptionCardGroup options={courseTypeOptionsForGroup} bind:value={type} class="grid-cols-1 md:grid-cols-2" />
{/snippet}
<Dialog.Root
bind:open
onOpenChange={(isOpen) => {
if (!isOpen) onClose(page.url.pathname);
}}
2021-12-30 22:30:30 +02:00
>
<Dialog.Content class="mx-auto w-4/5 max-w-2xl md:w-2/5 md:min-w-[600px]">
<Dialog.Header>
<Dialog.Title>{$t('courses.new_course_modal.heading')}</Dialog.Title>
</Dialog.Header>
{#if step === 0}
<div class="my-4 space-y-4">
{@render course_type_selector()}
<Dialog.Footer>
<Button onclick={() => (step = 1)} disabled={!type}>
{$t('courses.new_course_modal.next')}
</Button>
</Dialog.Footer>
</div>
{:else}
<form onsubmit={preventDefault(createCourse)}>
<div class="mb-4 flex items-end space-x-2">
<InputField
label={$t('courses.new_course_modal.course_name')}
bind:value={$createCourseModal.title}
placeholder={$t('courses.new_course_modal.course_name_placeholder')}
className="w-full"
isRequired={true}
2026-03-09 11:18:22 +01:00
errorMessage={courseApi.errors.title}
autoComplete={false}
/>
</div>
<TextareaField
label={$t('courses.new_course_modal.short_description')}
bind:value={$createCourseModal.description}
rows={4}
placeholder={$t('courses.new_course_modal.short_description_placeholder')}
className="mb-4"
isRequired={true}
2026-03-09 11:18:22 +01:00
errorMessage={courseApi.errors.description}
isAIEnabled={true}
initAIPrompt="Write a 30 word description for a course titled: {$createCourseModal.title}"
/>
<Dialog.Footer>
<Button variant="outline" onclick={() => (step = 0)}>
{$t('courses.new_course_modal.back')}
</Button>
2026-03-09 11:18:22 +01:00
<Button type="submit" disabled={courseApi.isLoading} loading={courseApi.isLoading}>
{$t('courses.new_course_modal.button')}
</Button>
</Dialog.Footer>
</form>
{/if}
</Dialog.Content>
</Dialog.Root>