2025-11-01 15:49:29 +01:00
|
|
|
<script lang="ts">
|
2025-12-22 02:36:48 +01:00
|
|
|
import { InputField } from '@cio/ui/custom/input-field';
|
2025-11-01 15:49:29 +01:00
|
|
|
import TrashIcon from '@lucide/svelte/icons/trash';
|
2025-12-22 02:36:48 +01:00
|
|
|
import { IconButton } from '@cio/ui/custom/icon-button';
|
2024-04-19 05:45:48 +01:00
|
|
|
import { t } from '$lib/utils/functions/translations';
|
2023-08-30 14:31:40 +00:00
|
|
|
|
2025-11-01 15:49:29 +01:00
|
|
|
interface Props {
|
|
|
|
|
isTitle?: boolean;
|
|
|
|
|
onClose?: any;
|
|
|
|
|
scrollToQuestion?: boolean;
|
|
|
|
|
points?: any;
|
|
|
|
|
hasError?: boolean;
|
2026-03-09 11:18:22 +01:00
|
|
|
errorMsg?: string | null;
|
2025-11-01 15:49:29 +01:00
|
|
|
onPointsChange?: any;
|
|
|
|
|
key?: string;
|
|
|
|
|
children?: import('svelte').Snippet;
|
|
|
|
|
}
|
2021-07-03 19:29:41 +00:00
|
|
|
|
2025-11-01 15:49:29 +01:00
|
|
|
let {
|
|
|
|
|
isTitle = false,
|
|
|
|
|
onClose = () => {},
|
|
|
|
|
scrollToQuestion = false,
|
|
|
|
|
points = $bindable(undefined),
|
|
|
|
|
hasError = false,
|
2026-03-09 11:18:22 +01:00
|
|
|
errorMsg = null,
|
2025-11-01 15:49:29 +01:00
|
|
|
onPointsChange = () => {},
|
|
|
|
|
children
|
|
|
|
|
}: Props = $props();
|
2021-07-03 19:29:41 +00:00
|
|
|
|
2025-11-01 15:49:29 +01:00
|
|
|
let ref: HTMLDivElement | undefined = $state();
|
|
|
|
|
|
|
|
|
|
$effect(() => {
|
2021-07-03 19:29:41 +00:00
|
|
|
if (ref && scrollToQuestion) {
|
2021-08-18 19:47:02 +03:00
|
|
|
ref.scrollIntoView({
|
|
|
|
|
block: 'start',
|
|
|
|
|
behavior: 'smooth',
|
2023-08-20 19:08:48 +00:00
|
|
|
inline: 'nearest'
|
2021-08-18 19:47:02 +03:00
|
|
|
});
|
2021-07-03 19:29:41 +00:00
|
|
|
}
|
2025-11-01 15:49:29 +01:00
|
|
|
});
|
2021-06-26 21:32:42 +03:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<div
|
2021-07-03 19:29:41 +00:00
|
|
|
bind:this={ref}
|
2026-03-09 11:18:22 +01:00
|
|
|
class="border-border border bg-white dark:bg-black {hasError ? 'border-red-700' : ''} root relative mb-6 rounded-md"
|
2021-06-26 21:32:42 +03:00
|
|
|
>
|
|
|
|
|
{#if isTitle}
|
2025-11-01 15:49:29 +01:00
|
|
|
<div class="title bg-primary-700 absolute"></div>
|
2021-06-26 21:32:42 +03:00
|
|
|
{/if}
|
|
|
|
|
<div class="px-4 {isTitle ? 'pt-4' : 'pt-2'} pb-3">
|
2025-11-01 15:49:29 +01:00
|
|
|
{@render children?.()}
|
2021-06-26 21:32:42 +03:00
|
|
|
</div>
|
2021-08-18 19:47:02 +03:00
|
|
|
|
|
|
|
|
{#if typeof points !== 'undefined'}
|
2026-03-09 11:18:22 +01:00
|
|
|
<div class="border-gray flex items-center justify-between border-t-2 border-r-0 border-b-0 border-l-0 p-2">
|
2025-11-01 15:49:29 +01:00
|
|
|
<div class="flex w-40 items-center">
|
|
|
|
|
<p class="mr-2 text-sm dark:text-white">
|
2024-05-13 19:35:06 +01:00
|
|
|
{$t('course.navItem.lessons.exercises.new_exercise_modal.points')}:
|
|
|
|
|
</p>
|
2025-12-22 02:36:48 +01:00
|
|
|
<InputField
|
2024-04-19 05:45:48 +01:00
|
|
|
placeholder={$t('course.navItem.lessons.exercises.new_exercise_modal.points')}
|
2021-08-18 19:47:02 +03:00
|
|
|
bind:value={points}
|
|
|
|
|
type="number"
|
2025-12-22 02:36:48 +01:00
|
|
|
onchange={onPointsChange}
|
2021-08-18 19:47:02 +03:00
|
|
|
/>
|
|
|
|
|
</div>
|
2023-08-30 14:31:40 +00:00
|
|
|
|
2026-03-09 11:18:22 +01:00
|
|
|
{#if errorMsg}
|
|
|
|
|
<p class="text-xs text-red-500">{errorMsg}</p>
|
|
|
|
|
{/if}
|
|
|
|
|
|
2023-08-30 14:31:40 +00:00
|
|
|
{#if onClose && !isTitle}
|
2025-12-22 02:36:48 +01:00
|
|
|
<IconButton onclick={onClose}>
|
2025-11-01 15:49:29 +01:00
|
|
|
<TrashIcon size={16} />
|
2023-08-30 14:31:40 +00:00
|
|
|
</IconButton>
|
|
|
|
|
{/if}
|
2021-08-18 19:47:02 +03:00
|
|
|
</div>
|
|
|
|
|
{/if}
|
2021-06-26 21:32:42 +03:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
.title {
|
|
|
|
|
color: rgba(255, 255, 255, 1);
|
|
|
|
|
border-top-left-radius: 8px;
|
|
|
|
|
border-top-right-radius: 8px;
|
|
|
|
|
height: 10px;
|
|
|
|
|
left: -1px;
|
|
|
|
|
top: -1px;
|
|
|
|
|
width: calc(100% + 2px);
|
|
|
|
|
}
|
|
|
|
|
</style>
|