2026-06-25 22:39:30 +01:00
|
|
|
<script lang="ts">
|
2026-08-19 11:47:43 +01:00
|
|
|
import { tick } from 'svelte';
|
2026-06-25 22:39:30 +01:00
|
|
|
import { Button } from '@cio/ui/base/button';
|
|
|
|
|
import * as Dialog from '@cio/ui/base/dialog';
|
|
|
|
|
import { courseApi } from '$features/course/api';
|
|
|
|
|
import { publishCourse } from '$features/course/utils/publish-course';
|
|
|
|
|
import { openCoursePreview } from '$features/course/utils/course-preview';
|
2026-08-19 11:47:43 +01:00
|
|
|
import { goToCourseCompletionDeadline } from '$features/course/utils/compliance-deadline';
|
2026-06-25 22:39:30 +01:00
|
|
|
import { t } from '$lib/utils/functions/translations';
|
2026-08-19 11:47:43 +01:00
|
|
|
import CertificateDeadlineRequiredDialog from './certificate-deadline-required-dialog.svelte';
|
2026-06-25 22:39:30 +01:00
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
|
open?: boolean;
|
|
|
|
|
currentOrgDomain?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let { open = $bindable(false), currentOrgDomain = '' }: Props = $props();
|
|
|
|
|
|
|
|
|
|
let isPublishing = $state(false);
|
2026-08-19 11:47:43 +01:00
|
|
|
let openDeadlineDialog = $state(false);
|
2026-06-25 22:39:30 +01:00
|
|
|
|
|
|
|
|
async function handlePublishCourse() {
|
|
|
|
|
const course = courseApi.course;
|
|
|
|
|
if (!course?.id) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isPublishing = true;
|
|
|
|
|
|
2026-08-19 11:47:43 +01:00
|
|
|
const result = await publishCourse(course);
|
2026-06-25 22:39:30 +01:00
|
|
|
isPublishing = false;
|
|
|
|
|
|
2026-08-19 11:47:43 +01:00
|
|
|
if (!result.ok && result.reason === 'missing_deadline') {
|
|
|
|
|
open = false;
|
|
|
|
|
await tick();
|
|
|
|
|
openDeadlineDialog = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!result.ok) {
|
2026-06-25 22:39:30 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
open = false;
|
|
|
|
|
|
|
|
|
|
openCoursePreview({
|
|
|
|
|
courseId: course.id,
|
|
|
|
|
courseSlug: courseApi.course?.slug,
|
|
|
|
|
currentOrgDomain
|
|
|
|
|
});
|
|
|
|
|
}
|
2026-08-19 11:47:43 +01:00
|
|
|
|
|
|
|
|
async function goToCompletionDeadline() {
|
|
|
|
|
const courseId = courseApi.course?.id;
|
|
|
|
|
openDeadlineDialog = false;
|
|
|
|
|
|
|
|
|
|
if (!courseId) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await tick();
|
|
|
|
|
goToCourseCompletionDeadline(courseId);
|
|
|
|
|
}
|
2026-06-25 22:39:30 +01:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<Dialog.Root
|
|
|
|
|
bind:open
|
|
|
|
|
onOpenChange={(isOpen) => {
|
|
|
|
|
if (!isOpen && !isPublishing) {
|
|
|
|
|
open = false;
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
>
|
2026-08-19 11:47:43 +01:00
|
|
|
<Dialog.Content class="w-[calc(100%-2rem)] max-w-md! p-4" onCloseAutoFocus={(e) => e.preventDefault()}>
|
2026-06-25 22:39:30 +01:00
|
|
|
<Dialog.Header>
|
|
|
|
|
<Dialog.Title>{$t('course.view_course_site.unpublished_title')}</Dialog.Title>
|
|
|
|
|
<Dialog.Description>{$t('course.view_course_site.unpublished_description')}</Dialog.Description>
|
|
|
|
|
</Dialog.Header>
|
|
|
|
|
|
|
|
|
|
<Dialog.Footer>
|
|
|
|
|
<Button variant="outline" onclick={() => (open = false)} disabled={isPublishing}>
|
|
|
|
|
{$t('course.view_course_site.cancel')}
|
|
|
|
|
</Button>
|
|
|
|
|
<Button variant="default" onclick={handlePublishCourse} loading={isPublishing} disabled={!courseApi.course?.id}>
|
|
|
|
|
{$t('course.view_course_site.publish_course')}
|
|
|
|
|
</Button>
|
|
|
|
|
</Dialog.Footer>
|
|
|
|
|
</Dialog.Content>
|
|
|
|
|
</Dialog.Root>
|
2026-08-19 11:47:43 +01:00
|
|
|
|
|
|
|
|
<CertificateDeadlineRequiredDialog bind:open={openDeadlineDialog} onGoToDeadline={goToCompletionDeadline} />
|