Merge branch 'main' of https://github.com/classroomio/classroomio into feat/release-v2

This commit is contained in:
Rotimi Best
2025-12-24 04:18:39 +00:00
193 changed files with 10584 additions and 6399 deletions
@@ -1,4 +1,5 @@
<script lang="ts">
import { sanitizeHtml } from '@cio/ui/tools/sanitize';
interface Props {
code?: string;
}
@@ -7,5 +8,5 @@
</script>
<div class="mb-3 rounded-md bg-gray-200 p-5 dark:bg-gray-500">
{@html code}
{@html sanitizeHtml(code)}
</div>
@@ -5,6 +5,7 @@
import { isCourseFree, getStudentInviteLink, calcCourseDiscount } from '$lib/utils/functions/course';
import { currentOrg, currentOrgDomain } from '$lib/utils/store/org';
import { goto } from '$app/navigation';
import { sanitizeHtml } from '@cio/ui/tools/sanitize';
import HtmlRender from '$lib/components/HTMLRender/HTMLRender.svelte';
import PaymentModal from './payment-modal.svelte';
import type { Course } from '$lib/utils/types';
@@ -184,7 +185,7 @@
<!-- Gift Container -->
{#if courseData?.metadata?.reward?.show}
<div class="flex flex-col items-center border-b border-t border-gray-300 p-10">
<HtmlRender>{@html get(courseData, 'metadata.reward.description', '')}</HtmlRender>
<HtmlRender>{@html sanitizeHtml(get(courseData, 'metadata.reward.description', ''))}</HtmlRender>
</div>
{/if}
</aside>
@@ -4,6 +4,7 @@
import { page } from '$app/state';
import { onMount, onDestroy } from 'svelte';
import { resolve } from '$app/paths';
import { sanitizeHtml } from '@cio/ui/tools/sanitize';
import PlayIcon from '@lucide/svelte/icons/play';
import { getLectureNo } from '$lib/components/Course/function';
@@ -216,7 +217,7 @@
</h3>
<ul class="list font-light">
<HtmlRender>{@html get(courseData, 'metadata.requirements', '')}</HtmlRender>
<HtmlRender>{@html sanitizeHtml(get(courseData, 'metadata.requirements', ''))}</HtmlRender>
</ul>
</NavSection>
{/if}
@@ -229,7 +230,7 @@
</h3>
<HtmlRender className="dark:text-white text-sm font-light">
{@html get(courseData, 'metadata.description', '')}
{@html sanitizeHtml(get(courseData, 'metadata.description', ''))}
</HtmlRender>
</NavSection>
{/if}
@@ -239,7 +240,7 @@
<NavSection id="goals">
<h3 class="mb-3 mt-0 text-2xl">{$t('course.navItem.landing_page.learn')}</h3>
<ul class="list font-light">
<HtmlRender>{@html get(courseData, 'metadata.goals', '')}</HtmlRender>
<HtmlRender>{@html sanitizeHtml(get(courseData, 'metadata.goals', ''))}</HtmlRender>
</ul>
</NavSection>
{/if}
@@ -3,6 +3,8 @@
import * as ImageCropper from '@cio/ui/custom/image-cropper';
import CameraIcon from '@lucide/svelte/icons/camera';
import PencilIcon from '@lucide/svelte/icons/pencil';
import { validateImageUpload } from '$lib/utils/functions/fileValidation';
import { snackbar } from '$features/ui/snackbar/store';
import { t } from '$lib/utils/functions/translations';
@@ -44,6 +46,16 @@
// getCroppedImg outputs PNG format, so use blob.type (which will be 'image/png') and matching filename
const file = new File([blob], 'cropped-image.png', { type: blob.type });
const validation = validateImageUpload(file);
if (!validation.isValid) {
snackbar.error(validation.error || 'Invalid file type');
errorMessage = $t('snackbar.landing_page_settings.error.try_again');
cropperSrc = '';
return;
}
// Update avatar with the cropped file
avatar = file;