Improve dark mode of icons + inputs improvements

This commit is contained in:
Rotimi Best
2023-08-04 12:41:12 +01:00
parent 06112a73df
commit 198c88f4ac
31 changed files with 211 additions and 370 deletions
@@ -16,7 +16,7 @@
name: 'Evgeniy', name: 'Evgeniy',
question: "I'am looking at this and it looks great", question: "I'am looking at this and it looks great",
vote: 1, vote: 1,
answered: false, answered: false
}, },
{ {
id: 2, id: 2,
@@ -24,22 +24,22 @@
question: question:
'Thanks for the feedback, what do you think about my website. https://rotimibest.com', 'Thanks for the feedback, what do you think about my website. https://rotimibest.com',
vote: 4, vote: 4,
answered: false, answered: false
}, },
{ {
id: 3, id: 3,
name: 'Vitalii Marushko', name: 'Vitalii Marushko',
question: 'Всем привет', question: 'Всем привет',
vote: 20, vote: 20,
answered: false, answered: false
}, },
{ {
id: 4, id: 4,
name: 'Natasha', name: 'Natasha',
question: 'Привет Виталий', question: 'Привет Виталий',
vote: 0, vote: 0,
answered: false, answered: false
}, }
]; ];
function handleSend() { function handleSend() {
@@ -54,15 +54,15 @@
name: 'You', name: 'You',
question, question,
vote: 0, vote: 0,
answered: false, answered: false
}, }
]; ];
question = null; question = null;
setTimeout(() => { setTimeout(() => {
bodyRef.scrollTo({ bodyRef.scrollTo({
top: bodyRef.scrollHeight, top: bodyRef.scrollHeight
}); });
}, 100); }, 100);
} }
@@ -104,22 +104,15 @@
{@html marked(question.question)} {@html marked(question.question)}
</article> </article>
</div> </div>
<button <button class={`${question.answered && 'active'}`} on:click={handleMarkAnswered(question.id)}>
class={`${question.answered && 'active'}`} <CheckmarkOutline size={20} class="carbon-icon dark:text-white" />
on:click={handleMarkAnswered(question.id)}
>
<CheckmarkOutline size={20} class="carbon-icon" />
</button> </button>
</div> </div>
{/each} {/each}
</div> </div>
<div class="footer"> <div class="footer">
<TextField <TextField placeholder="Say something" bind:value={question} onKeyDown={handleKeyDown} />
placeholder="Say something"
bind:value={question}
onKeyDown={handleKeyDown}
/>
</div> </div>
<style lang="scss"> <style lang="scss">
+4 -4
View File
@@ -56,7 +56,7 @@
onClick={handleAppClick} onClick={handleAppClick}
selected={APPS_CONSTANTS.APPS.LIVE_CHAT === selectedApp} selected={APPS_CONSTANTS.APPS.LIVE_CHAT === selectedApp}
> >
<SendAlt size={24} class="carbon-icon" /> <SendAlt size={24} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
<IconButton <IconButton
@@ -65,7 +65,7 @@
onClick={handleAppClick} onClick={handleAppClick}
selected={APPS_CONSTANTS.APPS.QANDA === selectedApp} selected={APPS_CONSTANTS.APPS.QANDA === selectedApp}
> >
<Forum size={24} class="carbon-icon" /> <Forum size={24} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
<IconButton <IconButton
@@ -74,7 +74,7 @@
onClick={handleAppClick} onClick={handleAppClick}
selected={APPS_CONSTANTS.APPS.NOTES === selectedApp} selected={APPS_CONSTANTS.APPS.NOTES === selectedApp}
> >
<AlignBoxTopLeft size={24} class="carbon-icon" /> <AlignBoxTopLeft size={24} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
<IconButton <IconButton
@@ -83,7 +83,7 @@
onClick={handleAppClick} onClick={handleAppClick}
selected={APPS_CONSTANTS.APPS.POLL === selectedApp} selected={APPS_CONSTANTS.APPS.POLL === selectedApp}
> >
<ChartPie size={24} class="carbon-icon" /> <ChartPie size={24} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
</div> </div>
@@ -10,8 +10,8 @@
<IconButton {onClick} {color} {contained} {size}> <IconButton {onClick} {color} {contained} {size}>
{#if size === 'large'} {#if size === 'large'}
<CloseIcon size={24} class="carbon-icon" title="Delete" /> <CloseIcon size={24} class="carbon-icon dark:text-white" title="Delete" />
{:else} {:else}
<CloseIcon size={24} class="carbon-icon" title="Delete" /> <CloseIcon size={24} class="carbon-icon dark:text-white" title="Delete" />
{/if} {/if}
</IconButton> </IconButton>
@@ -6,5 +6,5 @@
</script> </script>
<IconButton {onClick}> <IconButton {onClick}>
<Close size={24} class="carbon-icon" title="Close" /> <Close size={24} class="carbon-icon dark:text-white" title="Close" />
</IconButton> </IconButton>
+1 -1
View File
@@ -6,5 +6,5 @@
</script> </script>
<IconButton {onClick}> <IconButton {onClick}>
<SendFilled size={24} class="carbon-icon" /> <SendFilled size={24} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
@@ -8,7 +8,7 @@
handleRemoveQuestion, handleRemoveQuestion,
handleCode, handleCode,
handleAnswerSelect, handleAnswerSelect,
addDynamicValue, addDynamicValue
} from '../store/exercise'; } from '../store/exercise';
import TrashCanIcon from 'carbon-icons-svelte/lib/TrashCan.svelte'; import TrashCanIcon from 'carbon-icons-svelte/lib/TrashCan.svelte';
import AddFilledIcon from 'carbon-icons-svelte/lib/AddFilled.svelte'; import AddFilledIcon from 'carbon-icons-svelte/lib/AddFilled.svelte';
@@ -30,10 +30,7 @@
import QuestionContainer from '$lib/components/QuestionContainer/index.svelte'; import QuestionContainer from '$lib/components/QuestionContainer/index.svelte';
import DeleteConfirmationModal from './DeleteConfirmation.svelte'; import DeleteConfirmationModal from './DeleteConfirmation.svelte';
import OrderModal from './OrderModal.svelte'; import OrderModal from './OrderModal.svelte';
import { import { QUESTION_TYPE, QUESTION_TYPES } from '$lib/components/Question/constants';
QUESTION_TYPE,
QUESTION_TYPES,
} from '$lib/components/Question/constants';
import { filterOutDeleted } from './functions'; import { filterOutDeleted } from './functions';
import { deleteExercise } from '$lib/utils/services/courses'; import { deleteExercise } from '$lib/utils/services/courses';
import { lesson } from '../store/lessons'; import { lesson } from '../store/lessons';
@@ -98,9 +95,7 @@
lesson.update((_lesson) => ({ lesson.update((_lesson) => ({
..._lesson, ..._lesson,
exercises: _lesson.exercises.filter( exercises: _lesson.exercises.filter((exercise) => exercise.id !== exerciseId)
(exercise) => exercise.id !== exerciseId
),
})); }));
shouldDelete = false; shouldDelete = false;
@@ -193,10 +188,7 @@
<!-- {#key question.id} --> <!-- {#key question.id} -->
<QuestionContainer <QuestionContainer
onClose={onInitDeleteClicked(question.id)} onClose={onInitDeleteClicked(question.id)}
scrollToQuestion={shouldScrollToLast( scrollToQuestion={shouldScrollToLast(question.id, $questionnaire.questions)}
question.id,
$questionnaire.questions
)}
bind:points={question.points} bind:points={question.points}
hasError={!!errors[question.id]} hasError={!!errors[question.id]}
onPointsChange={() => { onPointsChange={() => {
@@ -219,7 +211,7 @@
options={extraActions} options={extraActions}
handleOptionClick={handleOptionClick(question.id)} handleOptionClick={handleOptionClick(question.id)}
> >
<AddFilledIcon class="carbon-icon" /> <AddFilledIcon class="carbon-icon dark:text-white" />
<p class="dark:text-white ml-2 text-gray-600">Add</p> <p class="dark:text-white ml-2 text-gray-600">Add</p>
</Dropdown> --> </Dropdown> -->
@@ -234,16 +226,9 @@
{#if typeof question.code === 'string'} {#if typeof question.code === 'string'}
<div class="flex justify-between items-center my-3 w-3/5"> <div class="flex justify-between items-center my-3 w-3/5">
<TextArea <TextArea bind:value={question.code} rows="2" placeholder="Write your code" />
bind:value={question.code} <IconButton value="write-code" onClick={() => handleCode(question.id, false)}>
rows="2" <TrashCanIcon size={24} class="carbon-icon dark:text-white" />
placeholder="Write your code"
/>
<IconButton
value="write-code"
onClick={() => handleCode(question.id, false)}
>
<TrashCanIcon size={24} class="carbon-icon" />
</IconButton> </IconButton>
</div> </div>
{/if} {/if}
@@ -262,7 +247,7 @@
value={option.id} value={option.id}
onClick={handleRemoveOption(question.id, option.id)} onClick={handleRemoveOption(question.id, option.id)}
> >
<TrashCanIcon size={24} class="carbon-icon" /> <TrashCanIcon size={24} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
<IconButton <IconButton
value={option.id} value={option.id}
@@ -270,9 +255,9 @@
buttonClassName={option.is_correct && 'success'} buttonClassName={option.is_correct && 'success'}
> >
{#if option.is_correct} {#if option.is_correct}
<CheckmarkFilledIcon size={24} class="carbon-icon" /> <CheckmarkFilledIcon size={24} class="carbon-icon dark:text-white" />
{:else} {:else}
<CheckmarkOutlineIcon size={24} class="carbon-icon" /> <CheckmarkOutlineIcon size={24} class="carbon-icon dark:text-white" />
{/if} {/if}
</IconButton> </IconButton>
</div> </div>
@@ -293,7 +278,7 @@
value={option.id} value={option.id}
onClick={handleRemoveOption(question.id, option.id)} onClick={handleRemoveOption(question.id, option.id)}
> >
<TrashCanIcon size={24} class="carbon-icon" /> <TrashCanIcon size={24} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
<IconButton <IconButton
value={option.id} value={option.id}
@@ -301,9 +286,9 @@
buttonClassName={option.is_correct && 'success'} buttonClassName={option.is_correct && 'success'}
> >
{#if option.is_correct} {#if option.is_correct}
<CheckmarkFilledIcon size={24} class="carbon-icon" /> <CheckmarkFilledIcon size={24} class="carbon-icon dark:text-white" />
{:else} {:else}
<CheckmarkOutlineIcon size={24} class="carbon-icon" /> <CheckmarkOutlineIcon size={24} class="carbon-icon dark:text-white" />
{/if} {/if}
</IconButton> </IconButton>
</div> </div>
@@ -316,9 +301,7 @@
{/if} {/if}
{#if getQuestionErrorMsg(errors, question, 'option')} {#if getQuestionErrorMsg(errors, question, 'option')}
<ErrorMessage <ErrorMessage message={getQuestionErrorMsg(errors, question, 'option')} />
message={getQuestionErrorMsg(errors, question, 'option')}
/>
{/if} {/if}
</div> </div>
@@ -330,7 +313,7 @@
variant={VARIANTS.OUTLINED} variant={VARIANTS.OUTLINED}
onClick={handleAddOption(question.id)} onClick={handleAddOption(question.id)}
> >
<AddFilledIcon size={24} class="carbon-icon" /> <AddFilledIcon size={24} class="carbon-icon dark:text-white" />
<p class="dark:text-white ml-2">Add option</p> <p class="dark:text-white ml-2">Add option</p>
</PrimaryButton> </PrimaryButton>
</div> </div>
@@ -10,7 +10,7 @@
questionnaire, questionnaire,
validateQuestionnaire, validateQuestionnaire,
reset, reset,
questionnaireOrder, questionnaireOrder
} from '../store/exercise'; } from '../store/exercise';
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte'; import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
import PageBody from '$lib/components/PageBody/index.svelte'; import PageBody from '$lib/components/PageBody/index.svelte';
@@ -47,7 +47,7 @@
...q, ...q,
is_title_dirty: false, is_title_dirty: false,
is_description_dirty: false, is_description_dirty: false,
questions: updatedQuestions, questions: updatedQuestions
})); }));
} else { } else {
mode = MODES.edit; mode = MODES.edit;
@@ -95,9 +95,9 @@
contained={true} contained={true}
> >
{#if preview} {#if preview}
<ViewFilledIcon size={32} class="carbon-icon" /> <ViewFilledIcon size={32} class="carbon-icon dark:text-white" />
{:else} {:else}
<ViewIcon size={32} class="carbon-icon" /> <ViewIcon size={32} class="carbon-icon dark:text-white" />
{/if} {/if}
</IconButton> </IconButton>
{/if} {/if}
@@ -109,26 +109,26 @@
onClick={handleAddQuestion} onClick={handleAddQuestion}
toolTipProps={{ title: 'Add question', direction: 'bottom' }} toolTipProps={{ title: 'Add question', direction: 'bottom' }}
> >
<AddAltIcon size={32} class="carbon-icon" /> <AddAltIcon size={32} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
<IconButton <IconButton
onClick={() => ($questionnaireOrder.open = true)} onClick={() => ($questionnaireOrder.open = true)}
toolTipProps={{ title: 'Order questionnaire', direction: 'bottom' }} toolTipProps={{ title: 'Order questionnaire', direction: 'bottom' }}
> >
<TableIcon size={32} class="carbon-icon" /> <TableIcon size={32} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
<IconButton <IconButton
onClick={() => (editDescription = true)} onClick={() => (editDescription = true)}
toolTipProps={{ title: 'Edit description', direction: 'bottom' }} toolTipProps={{ title: 'Edit description', direction: 'bottom' }}
> >
<SettingsIcon size={32} class="carbon-icon" /> <SettingsIcon size={32} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
<!-- <IconButton <!-- <IconButton
onClick={handleDeleteExercise} onClick={handleDeleteExercise}
toolTipProps={{ title: 'Delete questionnaire', direction: 'bottom' }} toolTipProps={{ title: 'Delete questionnaire', direction: 'bottom' }}
> >
<Delete32 class="carbon-icon" /> <Delete32 class="carbon-icon dark:text-white" />
</IconButton> --> </IconButton> -->
</div> </div>
{/if} {/if}
@@ -155,7 +155,7 @@
<slot:fragment slot="widget"> <slot:fragment slot="widget">
<RoleBasedSecurity allowedRoles={[1, 2]}> <RoleBasedSecurity allowedRoles={[1, 2]}>
<IconButton onClick={() => ($settingsDialog.open = !$settingsDialog.open)}> <IconButton onClick={() => ($settingsDialog.open = !$settingsDialog.open)}>
<SettingsIcon size={20} class="carbon-icon" /> <SettingsIcon size={20} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
</RoleBasedSecurity> </RoleBasedSecurity>
</slot:fragment> </slot:fragment>
@@ -198,11 +198,11 @@
<span>{item.title}</span> <span>{item.title}</span>
{#if !item.is_unlocked} {#if !item.is_unlocked}
<span class="text-md ml-2"> <span class="text-md ml-2">
<LockedIcon class="carbon-icon" /> <LockedIcon class="carbon-icon dark:text-white" />
</span> </span>
{:else if item.is_complete} {:else if item.is_complete}
<span class="ml-2"> <span class="ml-2">
<CheckmarkFilled class="carbon-icon" /> <CheckmarkFilled class="carbon-icon dark:text-white" />
</span> </span>
{/if} {/if}
</div> </div>
@@ -220,7 +220,7 @@
onClick={() => goto(`${$currentOrgPath}/courses`)} onClick={() => goto(`${$currentOrgPath}/courses`)}
buttonClassName="mx-3" buttonClassName="mx-3"
> >
<HomeIcon size={32} class="carbon-icon" /> <HomeIcon size={32} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
<a class="block mx-3" href={`/profile/${$profile.id}`}> <a class="block mx-3" href={`/profile/${$profile.id}`}>
<Avatar src={$profile.avatar_url} name={$profile.username} /> <Avatar src={$profile.avatar_url} name={$profile.username} />
@@ -80,21 +80,11 @@
</div> </div>
<div class="mt-8 flex justify-between items-center w-full"> <div class="mt-8 flex justify-between items-center w-full">
<IconButton <IconButton contained={true} value="delete" onClick={deleteReviewData} size="large">
contained={true} <TrashCanIcon size={24} class="carbon-icon dark:text-white" />
value="delete"
onClick={deleteReviewData}
size="large"
>
<TrashCanIcon size={24} class="carbon-icon" />
</IconButton> </IconButton>
<IconButton <IconButton contained={true} value="save" onClick={() => onExpand(review.id)} size="large">
contained={true} <SaveIcon size={24} class="carbon-icon dark:text-white" />
value="save"
onClick={() => onExpand(review.id)}
size="large"
>
<SaveIcon size={24} class="carbon-icon" />
</IconButton> </IconButton>
</div> </div>
</div> </div>
@@ -34,7 +34,7 @@
avatar_url: '', avatar_url: '',
rating: 1, rating: 1,
created_at: new Date().getTime(), created_at: new Date().getTime(),
description: '', description: ''
}; };
reviews = [...reviews, _review]; reviews = [...reviews, _review];
reviewToExpand = _review.id; reviewToExpand = _review.id;
@@ -45,26 +45,26 @@
const reviewSchema = z.object({ const reviewSchema = z.object({
name: z.string().min(5, { name: z.string().min(5, {
message: 'Name is too short, min of 5 character', message: 'Name is too short, min of 5 character',
invalid_type_error: 'Must not be empty', invalid_type_error: 'Must not be empty'
}), }),
avatar_url: z.string().min(6, { avatar_url: z.string().min(6, {
message: 'Upload an image', message: 'Upload an image',
invalid_type_error: 'Must not be empty', invalid_type_error: 'Must not be empty'
}), }),
rating: z rating: z
.number() .number()
.min(1, { .min(1, {
message: 'Rating must be from 1-5', message: 'Rating must be from 1-5',
invalid_type_error: 'Must not be empty', invalid_type_error: 'Must not be empty'
}) })
.max(5, { .max(5, {
message: 'Rating must be from 1-5', message: 'Rating must be from 1-5',
invalid_type_error: 'Must not be empty', invalid_type_error: 'Must not be empty'
}), }),
description: z.string().min(10, { description: z.string().min(10, {
message: 'Description is too short, min of 5 character', message: 'Description is too short, min of 5 character',
invalid_type_error: 'Must not be empty', invalid_type_error: 'Must not be empty'
}), })
}); });
const { error } = reviewSchema.safeParse(review); const { error } = reviewSchema.safeParse(review);
@@ -104,11 +104,7 @@
{#if review.id !== reviewToExpand} {#if review.id !== reviewToExpand}
<!-- the headers --> <!-- the headers -->
<div class="flex w-full justify-between items-center"> <div class="flex w-full justify-between items-center">
<Avatar <Avatar src={review.avatar_url} name={review.name} className="mt-1" />
src={review.avatar_url}
name={review.name}
className="mt-1"
/>
<p class="text-sm">{review.name}</p> <p class="text-sm">{review.name}</p>
<IconButton <IconButton
@@ -116,19 +112,13 @@
onClick={() => onExpand(review.id)} onClick={() => onExpand(review.id)}
size={$isMobile ? 'large' : 'small'} size={$isMobile ? 'large' : 'small'}
> >
<ChevronDownIcon size={16} class="carbon-icon" /> <ChevronDownIcon size={16} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
</div> </div>
{/if} {/if}
<!-- the body --> <!-- the body -->
{#if review.id === reviewToExpand} {#if review.id === reviewToExpand}
<ReviewFormEditor <ReviewFormEditor bind:reviews bind:review {errors} courseId={course.id} {onExpand} />
bind:reviews
bind:review
{errors}
courseId={course.id}
{onExpand}
/>
{/if} {/if}
</div> </div>
{/each} {/each}
@@ -28,32 +28,32 @@
const sections = [ const sections = [
{ {
key: 1, key: 1,
title: 'Header', title: 'Header'
}, },
{ {
key: 2, key: 2,
title: 'Requirement', title: 'Requirement'
}, },
{ {
key: 3, key: 3,
title: 'Description', title: 'Description'
}, },
{ {
key: 4, key: 4,
title: 'Goals', title: 'Goals'
}, },
{ {
key: 5, key: 5,
title: 'Reviews', title: 'Reviews'
}, },
{ {
key: 6, key: 6,
title: 'Instructor', title: 'Instructor'
}, },
{ {
key: 7, key: 7,
title: 'Pricing', title: 'Pricing'
}, }
]; ];
let selectedSection = null; let selectedSection = null;
@@ -75,7 +75,7 @@
if (sectionEl) { if (sectionEl) {
sectionEl.scrollIntoView({ sectionEl.scrollIntoView({
behavior: 'smooth', behavior: 'smooth',
block: 'start', block: 'start'
}); });
} }
} }
@@ -91,7 +91,7 @@
attendance: undefined, attendance: undefined,
group: undefined, group: undefined,
lessons: undefined, lessons: undefined,
slug: course.slug, slug: course.slug
}); });
loading = false; loading = false;
@@ -109,7 +109,7 @@
async function handlePublish() { async function handlePublish() {
loading = true; loading = true;
await updateCourse(courseId, undefined, { await updateCourse(courseId, undefined, {
is_published: true, is_published: true
}); });
loading = false; loading = false;
} }
@@ -129,14 +129,9 @@
onClick={handleSave} onClick={handleSave}
isLoading={loading} isLoading={loading}
/> />
<PrimaryButton <PrimaryButton label="Publish" type="button" onClick={handlePublish} isDisabled={loading} />
label="Publish"
type="button"
onClick={handlePublish}
isDisabled={loading}
/>
<IconButton onClick={handlePreview} disabled={loading || !course.slug}> <IconButton onClick={handlePreview} disabled={loading || !course.slug}>
<ArrowUpRightIcon size={24} class="carbon-icon" title="Preview" /> <ArrowUpRightIcon size={24} class="carbon-icon dark:text-white" title="Preview" />
</IconButton> </IconButton>
</div> </div>
</div> </div>
@@ -156,7 +151,7 @@
<!-- Title --> <!-- Title -->
<div class="flex items-center {borderBottomGrey} w-full"> <div class="flex items-center {borderBottomGrey} w-full">
<IconButton onClick={handleClose}> <IconButton onClick={handleClose}>
<ArrowLeftIcon size={24} class="carbon-icon" title="Go back" /> <ArrowLeftIcon size={24} class="carbon-icon dark:text-white" title="Go back" />
</IconButton> </IconButton>
<h3 class="dark:text-white">{selectedSection.title}</h3> <h3 class="dark:text-white">{selectedSection.title}</h3>
</div> </div>
@@ -33,8 +33,8 @@
$copyCourseModal.open = true; $copyCourseModal.open = true;
$copyCourseModal.title = `Copy of ${title}`; $copyCourseModal.title = `Copy of ${title}`;
})(); })();
}, }
}, }
// { // {
// label: 'Delete', // label: 'Delete',
// onClick() { // onClick() {
@@ -45,22 +45,14 @@
} }
</script> </script>
<a <a rel="prefetch" href={isOnLandingPage ? `/course/${slug}` : `/courses/${id}`} class=" text-black">
rel="prefetch"
href={isOnLandingPage ? `/course/${slug}` : `/courses/${id}`}
class=" text-black"
>
<div <div
class="root w-80 border bg-gray-100 dark:bg-gray-700 sm:mr-4 mb-4 rounded-md hover:shadow-2xl transition ease-in-out relative" class="root w-80 border bg-gray-100 dark:bg-gray-700 sm:mr-4 mb-4 rounded-md hover:shadow-2xl transition ease-in-out relative"
> >
{#if !isOnLandingPage} {#if !isOnLandingPage}
<Dropdown <Dropdown options={getOptions()} classNames="absolute top-4 right-4" isIcon={true}>
options={getOptions()}
classNames="absolute top-4 right-4"
isIcon={true}
>
<div class="p-1 rounded-full bg-white dark:bg-gray-600"> <div class="p-1 rounded-full bg-white dark:bg-gray-600">
<OverflowMenuHorizontalIcon size={20} class="carbon-icon" /> <OverflowMenuHorizontalIcon size={20} class="carbon-icon dark:text-white" />
</div> </div>
</Dropdown> </Dropdown>
{/if} {/if}
@@ -85,11 +77,7 @@
{#if isOnLandingPage} {#if isOnLandingPage}
<ArrowRight size={24} class="carbon-class" /> <ArrowRight size={24} class="carbon-class" />
{:else} {:else}
<div <div class="rounded dark:text-white bg-{isPublished ? 'green' : 'red'}-200 py-1 px-2">
class="rounded dark:text-white bg-{isPublished
? 'green'
: 'red'}-200 py-1 px-2"
>
{#if isPublished} {#if isPublished}
Published Published
{:else} {:else}
+5 -10
View File
@@ -22,8 +22,7 @@
<div {id} class="w-full bg-white dark:bg-gray-800 {rootClass}"> <div {id} class="w-full bg-white dark:bg-gray-800 {rootClass}">
<div <div
class="w-full relative flex items-center justify-between {!disableContainerPadding && class="w-full relative flex items-center justify-between {!disableContainerPadding && 'p-5'}"
'p-5'}"
role="button" role="button"
tabindex="0" tabindex="0"
on:click={handleClick} on:click={handleClick}
@@ -31,20 +30,16 @@
<p class="dark:text-white font-bold flex items-center {titleClass}"> <p class="dark:text-white font-bold flex items-center {titleClass}">
{title} {title}
{#if supportsLink} {#if supportsLink}
<a <a class="ml-2" href="{$page.url.pathname}#{id}" on:click={(e) => e.stopPropagation()}>
class="ml-2" <LinkIcon size={24} class="carbon-icon dark:text-white" />
href="{$page.url.pathname}#{id}"
on:click={(e) => e.stopPropagation()}
>
<LinkIcon size={24} class="carbon-icon" />
</a> </a>
{/if} {/if}
</p> </p>
{#if isExpanded} {#if isExpanded}
<ChevronUpIcon size={24} class="carbon-icon" /> <ChevronUpIcon size={24} class="carbon-icon dark:text-white" />
{:else} {:else}
<ChevronDownIcon size={24} class="carbon-icon" /> <ChevronDownIcon size={24} class="carbon-icon dark:text-white" />
{/if} {/if}
</div> </div>
{#if isExpanded} {#if isExpanded}
+11 -7
View File
@@ -1,4 +1,6 @@
<script> <script>
import TextField from '$lib/components/Form/TextField.svelte';
export let label; export let label;
export let value; export let value;
export let checked; export let checked;
@@ -23,13 +25,15 @@
bind:checked bind:checked
/> />
{#if isEditable} {#if isEditable}
<input <div class="w-2/4">
class="form-input p-2 mt-1 ml-1 block w-2/4 bg-gray-100 dark:bg-gray-700 border-t-0 border-l-0 border-r-0 border-b-1" <TextField
type="text" bind:value={label}
placeholder="Your option" placeholder="Your option"
bind:value={label} className="ml-1"
on:change={onChange} type="text"
/> {onChange}
/>
</div>
{:else} {:else}
<span class="dark:text-white ml-2">{label}</span> <span class="dark:text-white ml-2">{label}</span>
{/if} {/if}
+10 -7
View File
@@ -1,4 +1,5 @@
<script> <script>
import TextField from '$lib/components/Form/TextField.svelte';
export let label = ''; export let label = '';
export let value = ''; export let value = '';
export let checked = false; export let checked = false;
@@ -23,13 +24,15 @@
disabled={disabled || isEditable} disabled={disabled || isEditable}
/> />
{#if isEditable} {#if isEditable}
<input <div class="w-2/4">
class="form-input p-2 mt-1 ml-1 block w-2/4 bg-gray-100 dark:bg-gray-700 border-t-0 border-l-0 border-r-0 border-b-1" <TextField
type="text" bind:value={label}
placeholder="Your option" placeholder="Your option"
bind:value={label} className="ml-1"
on:change={onChange} type="text"
/> {onChange}
/>
</div>
{:else} {:else}
<span class="dark:text-white ml-2">{label}</span> <span class="dark:text-white ml-2">{label}</span>
{/if} {/if}
+6 -25
View File
@@ -6,7 +6,7 @@
export let maxRows = 3; export let maxRows = 3;
export let className = ''; export let className = '';
export let labelClassName = ''; export let labelClassName = '';
export let bgColor = 'bg-gray-200 dark:bg-gray-500'; export let bgColor = 'bg-gray-50 focus:bg-blue-50 dark:bg-white';
export let helperMessage = ''; export let helperMessage = '';
export let errorMessage = ''; export let errorMessage = '';
export let isRequired = false; export let isRequired = false;
@@ -18,7 +18,7 @@
<label class="block w-full relative {className}"> <label class="block w-full relative {className}">
{#if label} {#if label}
<p for="text-field" class="dark:text-white {labelClassName}"> <p for="text-field" class="dark:text-white text-left {labelClassName}">
{label} {label}
{#if isRequired} {#if isRequired}
@@ -38,10 +38,8 @@
{placeholder} {placeholder}
bind:value bind:value
required={isRequired} required={isRequired}
class="form-textarea mt-1 block w-full class="form-textarea border-l-0 border-r-0 border-t-0 border-b-2 border-gray-200 focus:border-l-0 focus:border-r-0 rounded-t-md focus:border-t-0 focus:border-b-2 focus:border-blue-600 mt-1 block w-full
{bgColor} border-t-0 border-l-0 border-r-0 border-b-1 {!!errorMessage {bgColor} {!!errorMessage ? 'border-red-500' : 'border-gray-300'}"
? 'border-red-500'
: 'border-gray-300'}"
on:change={onChange} on:change={onChange}
/> />
{#if !!errorMessage} {#if !!errorMessage}
@@ -57,24 +55,7 @@
</label> </label>
<style> <style>
/* pre, .form-textarea {
textarea { box-shadow: none !important;
font-family: inherit;
padding: 0.5em;
box-sizing: border-box;
border: 1px solid #eee;
line-height: 1.2;
overflow: hidden;
} */
/* textarea {
position: absolute;
width: 100%;
height: 100%;
top: 0;
resize: none;
} }
textarea.has-label {
top: 30px;
} */
</style> </style>
+9 -8
View File
@@ -11,7 +11,7 @@
export let className = ''; export let className = '';
export let inputClassName = ''; export let inputClassName = '';
export let labelClassName = ''; export let labelClassName = '';
export let bgColor = 'bg-gray-200'; export let bgColor = 'bg-gray-50 focus:bg-blue-50 dark:bg-white';
export let type = 'text'; export let type = 'text';
export let isPassword = false; export let isPassword = false;
export let autoFocus = false; export let autoFocus = false;
@@ -27,6 +27,7 @@
let ref; let ref;
let fieldNode; let fieldNode;
let focusClass = '';
function typeAction(node) { function typeAction(node) {
node.type = type; node.type = type;
@@ -56,21 +57,18 @@
<label class="block relative {className}"> <label class="block relative {className}">
{#if label} {#if label}
<label <p for="text-field" class="text-sm dark:text-white text-left m-0 font-light {labelClassName}">
for="text-field"
class="dark:text-white m-0 font-light {labelClassName}"
>
{label} {label}
{#if isRequired} {#if isRequired}
<span class="text-red-700">*</span> <span class="text-red-700">*</span>
{/if} {/if}
</label> </p>
{/if} {/if}
<input <input
use:typeAction use:typeAction
class="form-input {inputClassName} dark:text-black p-3 mt-1 block w-full border-none {bgColor} {errorMessage class="form-input border-l-0 border-r-0 border-t-0 border-b-2 border-gray-200 focus:border-l-0 focus:border-r-0 rounded-t-md focus:border-t-0 focus:border-b-2 focus:border-blue-600 {inputClassName} {focusClass} dark:text-black p-3 mt-1 block w-full {bgColor} {errorMessage
? 'border-red-500' ? 'border-red-600'
: ''}" : ''}"
on:keydown={onKeyDown} on:keydown={onKeyDown}
on:change={onInputChange} on:change={onInputChange}
@@ -102,6 +100,9 @@
</label> </label>
<style> <style>
.form-input {
box-shadow: none !important;
}
.password-eye { .password-eye {
position: absolute; position: absolute;
top: 23px; top: 23px;
+3 -11
View File
@@ -37,10 +37,7 @@
height="h-7" height="h-7"
/> />
{:else} {:else}
<TextChip <TextChip value={$currentOrg.shortName} className="bg-blue-200 font-bold" />
value={$currentOrg.shortName}
className="bg-blue-200 font-bold"
/>
{/if} {/if}
<OrgSelector /> <OrgSelector />
@@ -87,7 +84,7 @@
<li <li
class="flex items-center py-3 px-4 mb-2 rounded hover:bg-gray-200 dark:hover:bg-gray-500" class="flex items-center py-3 px-4 mb-2 rounded hover:bg-gray-200 dark:hover:bg-gray-500"
> >
<HelpIcon size={20} class="carbon-icon" /> <HelpIcon size={20} class="carbon-icon dark:text-white" />
<p class="dark:text-white ml-2">Help</p> <p class="dark:text-white ml-2">Help</p>
</li> </li>
</a> </a>
@@ -98,12 +95,7 @@
`/lms/settings` `/lms/settings`
) && activeClass}" ) && activeClass}"
> >
<Avatar <Avatar src={$profile.avatar_url} name={$profile.username} width="w-7" height="h-7" />
src={$profile.avatar_url}
name={$profile.username}
width="w-7"
height="h-7"
/>
<p class="dark:text-white ml-2">Settings</p> <p class="dark:text-white ml-2">Settings</p>
</li> </li>
</a> </a>
+4 -11
View File
@@ -13,9 +13,7 @@
let navClass = ''; let navClass = '';
const redirect = isCoursePage($page.url.pathname) const redirect = isCoursePage($page.url.pathname) ? `?redirect=${$page.url.pathname}` : '';
? `?redirect=${$page.url.pathname}`
: '';
$: navClass = ''; $: navClass = '';
</script> </script>
@@ -25,12 +23,7 @@
> >
<ul class="flex w-full items-center"> <ul class="flex w-full items-center">
<div class="logo"> <div class="logo">
<a <a href="/" title={`Go to ${orgName || 'ClassroomIO'} Home`} id="logo" data-hveid="8">
href="/"
title={`Go to ${orgName || 'ClassroomIO'} Home`}
id="logo"
data-hveid="8"
>
<img <img
src={logo || '/logo-192.png'} src={logo || '/logo-192.png'}
alt={`${orgName || 'ClassroomIO'} logo`} alt={`${orgName || 'ClassroomIO'} logo`}
@@ -107,8 +100,8 @@
data-file-width="25" data-file-width="25"
data-file-height="25" data-file-height="25"
/> />
<span><SendAlt32 class="carbon-icon" /> Канал</span> <span><SendAlt32 class="carbon-icon dark:text-white" /> Канал</span>
<SendAlt32 class="carbon-icon" /> <SendAlt32 class="carbon-icon dark:text-white" />
<span>Канал</span> <span>Канал</span>
</a> </a>
</li> --> </li> -->
@@ -80,11 +80,11 @@
<div class="flex justify-center items-center"> <div class="flex justify-center items-center">
<IconButton onClick={handlePrev} size="small"> <IconButton onClick={handlePrev} size="small">
<ChevronLeftIcon size={16} class="carbon-icon" /> <ChevronLeftIcon size={16} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
<p class="mx-3">{curQId + 1} / {totalQ}</p> <p class="mx-3">{curQId + 1} / {totalQ}</p>
<IconButton onClick={handleNext} size="small"> <IconButton onClick={handleNext} size="small">
<ChevronRightIcon size={16} class="carbon-icon" /> <ChevronRightIcon size={16} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
</div> </div>
{/if} {/if}
@@ -6,7 +6,7 @@
import IconButton from '$lib/components/IconButton/index.svelte'; import IconButton from '$lib/components/IconButton/index.svelte';
export let currentQuestion = { export let currentQuestion = {
label: '', label: ''
}; };
export let currentError = {}; export let currentError = {};
export let optionHasError = () => false; export let optionHasError = () => false;
@@ -41,8 +41,7 @@
bgColor="bg-white" bgColor="bg-white"
className="mt-3" className="mt-3"
isDisabled={currentQuestion.type === 'boolean'} isDisabled={currentQuestion.type === 'boolean'}
errorMessage={optionHasError(option.id, currentError.options) && errorMessage={optionHasError(option.id, currentError.options) && 'Please enter a label'}
'Please enter a label'}
/> />
<div class="flex justify-end absolute top-2 right-2"> <div class="flex justify-end absolute top-2 right-2">
<IconButton <IconButton
@@ -51,9 +50,9 @@
buttonClassName={option.isCorrect && 'success'} buttonClassName={option.isCorrect && 'success'}
> >
{#if option.isCorrect} {#if option.isCorrect}
<CheckmarkFilledIcon size={24} class="carbon-icon" /> <CheckmarkFilledIcon size={24} class="carbon-icon dark:text-white" />
{:else} {:else}
<CheckmarkOutlineIcon size={24} class="carbon-icon" /> <CheckmarkOutlineIcon size={24} class="carbon-icon dark:text-white" />
{/if} {/if}
</IconButton> </IconButton>
</div> </div>
+11 -22
View File
@@ -19,19 +19,19 @@
const menuItems = [ const menuItems = [
{ {
path: '', path: '',
label: 'Home', label: 'Home'
}, },
{ {
path: '/quiz', path: '/quiz',
label: 'Quizzes', label: 'Quizzes'
}, },
{ {
path: '/courses', path: '/courses',
label: 'Courses', label: 'Courses'
}, },
{ {
path: '/community', path: '/community',
label: 'Community', label: 'Community'
}, },
// { // {
// path: '/site', // path: '/site',
@@ -39,8 +39,8 @@
// }, // },
{ {
path: '/audience', path: '/audience',
label: 'Audience', label: 'Audience'
}, }
]; ];
function isActive(pagePath, itemPath) { function isActive(pagePath, itemPath) {
@@ -67,20 +67,14 @@
height="h-7" height="h-7"
/> />
{:else if $currentOrg.shortName} {:else if $currentOrg.shortName}
<TextChip <TextChip value={$currentOrg.shortName} className="bg-blue-200 font-bold" />
value={$currentOrg.shortName}
className="bg-blue-200 font-bold"
/>
{/if} {/if}
<OrgSelector /> <OrgSelector />
<ul class="my-5"> <ul class="my-5">
{#each menuItems as menuItem} {#each menuItems as menuItem}
<a <a href="{$currentOrgPath}{menuItem.path}" class="text-black no-underline">
href="{$currentOrgPath}{menuItem.path}"
class="text-black no-underline"
>
<li <li
class="flex items-center py-3 px-4 mb-2 rounded hover:bg-gray-200 dark:hover:bg-gray-500 {isActive( class="flex items-center py-3 px-4 mb-2 rounded hover:bg-gray-200 dark:hover:bg-gray-500 {isActive(
$page.url.pathname, $page.url.pathname,
@@ -94,7 +88,7 @@
{:else if menuItem.path === '/site'} {:else if menuItem.path === '/site'}
<SiteSettingsIcon /> <SiteSettingsIcon />
{:else if menuItem.path === '/community'} {:else if menuItem.path === '/community'}
<ForumIcon size={20} class="carbon-icon" /> <ForumIcon size={20} class="carbon-icon dark:text-white" />
{:else if menuItem.path === '/quiz'} {:else if menuItem.path === '/quiz'}
<QuizIcon /> <QuizIcon />
{:else if menuItem.path === '/audience'} {:else if menuItem.path === '/audience'}
@@ -112,7 +106,7 @@
<li <li
class="flex items-center py-3 px-4 mb-2 rounded hover:bg-gray-200 dark:hover:bg-gray-500" class="flex items-center py-3 px-4 mb-2 rounded hover:bg-gray-200 dark:hover:bg-gray-500"
> >
<HelpIcon size={20} class="carbon-icon" /> <HelpIcon size={20} class="carbon-icon dark:text-white" />
<p class="dark:text-white ml-2">Help</p> <p class="dark:text-white ml-2">Help</p>
</li> </li>
</a> </a>
@@ -123,12 +117,7 @@
`${$currentOrgPath}/settings` `${$currentOrgPath}/settings`
) && activeClass}" ) && activeClass}"
> >
<Avatar <Avatar src={$profile.avatar_url} name={$profile.username} width="w-7" height="h-7" />
src={$profile.avatar_url}
name={$profile.username}
width="w-7"
height="h-7"
/>
<p class="dark:text-white ml-2">Settings</p> <p class="dark:text-white ml-2">Settings</p>
</li> </li>
</a> </a>
+4 -4
View File
@@ -18,7 +18,7 @@
snackbarStore.update((_s) => ({ snackbarStore.update((_s) => ({
..._s, ..._s,
...snackbarStoreInitialState, ...snackbarStoreInitialState
})); }));
clearTimeout(timeoutId); clearTimeout(timeoutId);
timeoutId = null; timeoutId = null;
@@ -50,11 +50,11 @@
> >
<div class="flex items-center"> <div class="flex items-center">
{#if $snackbarStore.severity === SNACKBAR_SEVERITY.SUCCESS} {#if $snackbarStore.severity === SNACKBAR_SEVERITY.SUCCESS}
<CheckmarkOutline24 size={24} class="carbon-icon" /> <CheckmarkOutline24 size={24} class="carbon-icon dark:text-white" />
{:else if $snackbarStore.severity === SNACKBAR_SEVERITY.WARNING} {:else if $snackbarStore.severity === SNACKBAR_SEVERITY.WARNING}
<WarningIcon size={24} class="carbon-icon" /> <WarningIcon size={24} class="carbon-icon dark:text-white" />
{:else} {:else}
<InformationIcon size={24} class="carbon-icon" /> <InformationIcon size={24} class="carbon-icon dark:text-white" />
{/if} {/if}
<p class="dark:text-white ml-2 text-lg">{$snackbarStore.message}</p> <p class="dark:text-white ml-2 text-lg">{$snackbarStore.message}</p>
</div> </div>
+9 -13
View File
@@ -17,18 +17,18 @@
{ {
title: 'Access', title: 'Access',
description: description:
'Quickly find any material you need to get your job done. ClassroomIO offers the All-in-on-platform', 'Quickly find any material you need to get your job done. ClassroomIO offers the All-in-on-platform'
}, },
{ {
title: 'Analytics', title: 'Analytics',
description: description:
'Avoid assumptions, better understand the needs of your classrooms and give students a personlized experience', 'Avoid assumptions, better understand the needs of your classrooms and give students a personlized experience'
}, },
{ {
title: 'Automation', title: 'Automation',
description: description:
'Lesson reminders, deadline reminders and many other automated alerts to help everyone in the learning process be proactive', 'Lesson reminders, deadline reminders and many other automated alerts to help everyone in the learning process be proactive'
}, }
]; ];
async function handleSubmit() { async function handleSubmit() {
@@ -72,9 +72,7 @@
<form on:submit|preventDefault={handleSubmit} class="my-4"> <form on:submit|preventDefault={handleSubmit} class="my-4">
<div class="flex items-center flex-col sm:flex-row"> <div class="flex items-center flex-col sm:flex-row">
{#if success} {#if success}
<p class="dark:text-white"> <p class="dark:text-white">You have been added successfully. Thanks for joining.</p>
You have been added successfully. Thanks for joining.
</p>
{:else} {:else}
<TextField <TextField
bind:value={email} bind:value={email}
@@ -85,9 +83,7 @@
isRequired={true} isRequired={true}
isDisabled={isAdding} isDisabled={isAdding}
/> />
<PrimaryButton type="submit" isLoading={isAdding}> <PrimaryButton type="submit" isLoading={isAdding}>Join waiting list</PrimaryButton>
Join waiting list
</PrimaryButton>
{/if} {/if}
</div> </div>
</form> </form>
@@ -99,11 +95,11 @@
> >
<h3 class="dark:text-white text-3xl"> <h3 class="dark:text-white text-3xl">
{#if index === 0} {#if index === 0}
<FlowStreamReferenceIcon size={32} class="carbon-icon" /> <FlowStreamReferenceIcon size={32} class="carbon-icon dark:text-white" />
{:else if index === 1} {:else if index === 1}
<ChartClusterBarIcon size={32} class="carbon-icon" /> <ChartClusterBarIcon size={32} class="carbon-icon dark:text-white" />
{:else if index === 2} {:else if index === 2}
<MachineLearningModelIcon size={32} class="carbon-icon" /> <MachineLearningModelIcon size={32} class="carbon-icon dark:text-white" />
{/if} {/if}
{area.title} {area.title}
</h3> </h3>
+7 -7
View File
@@ -149,9 +149,9 @@
}} }}
> >
{#if lesson.is_unlocked} {#if lesson.is_unlocked}
<UnlockedIcon size={24} class="carbon-icon" /> <UnlockedIcon size={24} class="carbon-icon dark:text-white" />
{:else} {:else}
<LockedIcon size={24} class="carbon-icon" /> <LockedIcon size={24} class="carbon-icon dark:text-white" />
{/if} {/if}
</IconButton> </IconButton>
</div> </div>
@@ -166,11 +166,11 @@
handleSaveLesson(lesson, $course.id); handleSaveLesson(lesson, $course.id);
}} }}
> >
<SaveIcon size={24} class="carbon-icon" /> <SaveIcon size={24} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
{:else} {:else}
<IconButton onClick={() => (lessonEditing = lesson.id)}> <IconButton onClick={() => (lessonEditing = lesson.id)}>
<EditIcon size={24} class="carbon-icon" /> <EditIcon size={24} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
{/if} {/if}
</div> </div>
@@ -239,7 +239,7 @@
on:input={(e) => (lesson.lesson_at = e.target.value)} on:input={(e) => (lesson.lesson_at = e.target.value)}
/> />
{:else} {:else}
<TimeIcon size={24} class="carbon-icon" /> <TimeIcon size={24} class="carbon-icon dark:text-white" />
<p class="dark:text-white text-md ml-2"> <p class="dark:text-white text-md ml-2">
{new Date(lesson.lesson_at).toDateString()} {new Date(lesson.lesson_at).toDateString()}
</p> </p>
@@ -255,7 +255,7 @@
placeholder="https://meet.google.com/mga-dsjs-fmb" placeholder="https://meet.google.com/mga-dsjs-fmb"
/> />
{:else} {:else}
<PhoneIcon size={24} class="carbon-icon" /> <PhoneIcon size={24} class="carbon-icon dark:text-white" />
<a class="text-md ml-2" href={lesson.call_url || '#'} target="_blank"> <a class="text-md ml-2" href={lesson.call_url || '#'} target="_blank">
{lesson.call_url ? 'Join lesson' : 'No link'} {lesson.call_url ? 'Join lesson' : 'No link'}
</a> </a>
@@ -267,7 +267,7 @@
<RoleBasedSecurity allowedRoles={[1, 2]}> <RoleBasedSecurity allowedRoles={[1, 2]}>
<div class="absolute bottom-2 right-0"> <div class="absolute bottom-2 right-0">
<IconButton onClick={handleDelete(lesson.id)}> <IconButton onClick={handleDelete(lesson.id)}>
<TrashCanIcon size={24} class="carbon-icon" /> <TrashCanIcon size={24} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
</div> </div>
</RoleBasedSecurity> </RoleBasedSecurity>
+11 -34
View File
@@ -2,11 +2,7 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import copy from 'copy-to-clipboard'; import copy from 'copy-to-clipboard';
import CourseContainer from '$lib/components/CourseContainer/index.svelte'; import CourseContainer from '$lib/components/CourseContainer/index.svelte';
import { import { fetchCourse, deleteGroupMember, updatedGroupMember } from '$lib/utils/services/courses';
fetchCourse,
deleteGroupMember,
updatedGroupMember,
} from '$lib/utils/services/courses';
import EditIcon from 'carbon-icons-svelte/lib/Edit.svelte'; import EditIcon from 'carbon-icons-svelte/lib/Edit.svelte';
import CopyIcon from 'carbon-icons-svelte/lib/Copy.svelte'; import CopyIcon from 'carbon-icons-svelte/lib/Copy.svelte';
import TrashCanIcon from 'carbon-icons-svelte/lib/TrashCan.svelte'; import TrashCanIcon from 'carbon-icons-svelte/lib/TrashCan.svelte';
@@ -23,12 +19,9 @@
import DeleteConfirmation from '$lib/components/Course/components/People/DeleteConfirmation.svelte'; import DeleteConfirmation from '$lib/components/Course/components/People/DeleteConfirmation.svelte';
import { import {
invitationModal, invitationModal,
deleteMemberModal, deleteMemberModal
} from '$lib/components/Course/components/People/store'; } from '$lib/components/Course/components/People/store';
import type { import type { Person, ProfileRole } from '$lib/components/Course/components/People/types';
Person,
ProfileRole,
} from '$lib/components/Course/components/People/types';
import { ROLE_LABEL, ROLES } from '$lib/utils/constants/roles'; import { ROLE_LABEL, ROLES } from '$lib/utils/constants/roles';
import { profile } from '$lib/utils/store/user'; import { profile } from '$lib/utils/store/user';
import { snackbarStore } from '$lib/components/Snackbar/store'; import { snackbarStore } from '$lib/components/Snackbar/store';
@@ -51,9 +44,7 @@
// } // }
async function deletePerson() { async function deletePerson() {
$group.people = $group.people.filter( $group.people = $group.people.filter((person: { id: string }) => person.id !== member.id);
(person: { id: string }) => person.id !== member.id
);
await deleteGroupMember(member.id); await deleteGroupMember(member.id);
} }
@@ -127,9 +118,7 @@
</div> </div>
<div class="table rounded-md border border-gray-300 w-full"> <div class="table rounded-md border border-gray-300 w-full">
<div <div class="flex items-center font-bold border-t-0 {borderBottomGrey} p-3">
class="flex items-center font-bold border-t-0 {borderBottomGrey} p-3"
>
<span class="dark:text-white w-1/4 text-center">ID</span> <span class="dark:text-white w-1/4 text-center">ID</span>
<!-- <span class="flex-grow" /> --> <!-- <span class="flex-grow" /> -->
<p class="dark:text-white text-lg w-2/4">Name</p> <p class="dark:text-white text-lg w-2/4">Name</p>
@@ -156,14 +145,10 @@
</p> </p>
{#if !isStudent} {#if !isStudent}
<div class="absolute edit-btn"> <div class="absolute edit-btn">
<IconButton <IconButton onClick={() => handleEditStudentIdMode(person.id)}>
onClick={() => handleEditStudentIdMode(person.id)}
>
<EditIcon size={16} class="carbon-icon active" /> <EditIcon size={16} class="carbon-icon active" />
</IconButton> </IconButton>
<IconButton <IconButton onClick={() => copyToClipboard(person.assigned_student_id)}>
onClick={() => copyToClipboard(person.assigned_student_id)}
>
<CopyIcon size={16} class="carbon-icon active" /> <CopyIcon size={16} class="carbon-icon active" />
</IconButton> </IconButton>
</div> </div>
@@ -173,17 +158,11 @@
<!-- <span class="flex-grow" /> --> <!-- <span class="flex-grow" /> -->
{#if person.profile} {#if person.profile}
<div class="w-2/4 mx-2 flex items-center"> <div class="w-2/4 mx-2 flex items-center">
<Avatar <Avatar src={person.profile.avatar_url} name={person.profile.fullname} />
src={person.profile.avatar_url}
name={person.profile.fullname}
/>
<div class="ml-2 break-all"> <div class="ml-2 break-all">
<p class="dark:text-white text-lg">{person.profile.fullname}</p> <p class="dark:text-white text-lg">{person.profile.fullname}</p>
{#if !isStudent} {#if !isStudent}
<a <a href="mailto:{person.profile.email}" class="text-md text-blue-600">
href="mailto:{person.profile.email}"
class="text-md text-blue-600"
>
{person.profile.email} {person.profile.email}
</a> </a>
{/if} {/if}
@@ -191,9 +170,7 @@
</div> </div>
{:else} {:else}
<div class="break-all w-2/4 mx-2"> <div class="break-all w-2/4 mx-2">
<p <p class="bg-yellow-500 pending text-sm text-center rounded-xl text-white">
class="bg-yellow-500 pending text-sm text-center rounded-xl text-white"
>
Pending Invite Pending Invite
</p> </p>
<a href="mailto:{person.email}" class="text-md text-blue-600"> <a href="mailto:{person.email}" class="text-md text-blue-600">
@@ -215,7 +192,7 @@
$deleteMemberModal.open = true; $deleteMemberModal.open = true;
}} }}
> >
<TrashCanIcon size={24} class="carbon-icon" /> <TrashCanIcon size={24} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
{/if} {/if}
</div> </div>
+1 -1
View File
@@ -167,7 +167,7 @@
{lessonData.lesson_title} {lessonData.lesson_title}
{#if lessonData.is_unlocked} {#if lessonData.is_unlocked}
<span class="ml-2 success"> <span class="ml-2 success">
<CheckmarkFilledIcon size={20} class="carbon-icon" /> <CheckmarkFilledIcon size={20} class="carbon-icon dark:text-white" />
</span> </span>
{:else} {:else}
<span class="text-md ml-2">🔒</span> <span class="text-md ml-2">🔒</span>
+2 -2
View File
@@ -251,10 +251,10 @@
{lessonData.lesson_title} {lessonData.lesson_title}
{#if lessonData.is_unlocked} {#if lessonData.is_unlocked}
<span class="ml-2 success"> <span class="ml-2 success">
<LockedIcon class="carbon-icon" /> <LockedIcon class="carbon-icon dark:text-white" />
</span> </span>
{:else} {:else}
<UnlockedIcon class="carbon-icon" /> <UnlockedIcon class="carbon-icon dark:text-white" />
{/if} {/if}
</a> </a>
<p class="dark:text-white text-grey text-sm flex items-center"> <p class="dark:text-white text-grey text-sm flex items-center">
@@ -18,7 +18,7 @@
import { supabase } from '$lib/utils/functions/supabase'; import { supabase } from '$lib/utils/functions/supabase';
import { import {
askCommunityValidation, askCommunityValidation,
commentInCommunityValidation, commentInCommunityValidation
} from '$lib/utils/functions/validator'; } from '$lib/utils/functions/validator';
import { SNACKBAR_SEVERITY } from '$lib/components/Snackbar/constants'; import { SNACKBAR_SEVERITY } from '$lib/components/Snackbar/constants';
import { snackbarStore } from '$lib/components/Snackbar/store'; import { snackbarStore } from '$lib/components/Snackbar/store';
@@ -39,11 +39,11 @@
let isEditMode = false; let isEditMode = false;
let deleteComment = { let deleteComment = {
shouldDelete: false, shouldDelete: false,
commentId: null, commentId: null
}; };
let editContent = { let editContent = {
title: '', title: '',
body: '', body: ''
}; };
function mapResToQuestion(data) { function mapResToQuestion(data) {
@@ -54,7 +54,7 @@
author: { author: {
id: data?.author?.profile?.id || '', id: data?.author?.profile?.id || '',
name: data?.author?.profile?.fullname || '', name: data?.author?.profile?.fullname || '',
avatar: data?.author?.profile?.avatar_url || '', avatar: data?.author?.profile?.avatar_url || ''
}, },
body: data.body, body: data.body,
createdAt: dayjs(data.created_at).fromNow(true), createdAt: dayjs(data.created_at).fromNow(true),
@@ -65,9 +65,9 @@
avatar: c.author?.profile?.avatar_url || '', avatar: c.author?.profile?.avatar_url || '',
votes: c.votes, votes: c.votes,
comment: c.body, comment: c.body,
createdAt: dayjs(c.created_at).fromNow(true), createdAt: dayjs(c.created_at).fromNow(true)
})), })),
totalComments: 0, totalComments: 0
}; };
} }
@@ -124,7 +124,7 @@
body: comment, body: comment,
question_id: question.id, question_id: question.id,
author_id: $currentOrg.memberId, author_id: $currentOrg.memberId,
votes: 0, votes: 0
}) })
.select(); .select();
@@ -151,8 +151,8 @@
avatar: $profile?.avatar_url || '', avatar: $profile?.avatar_url || '',
votes: 0, votes: 0,
comment: _c.body, comment: _c.body,
createdAt: dayjs(_c.created_at).fromNow(true), createdAt: dayjs(_c.created_at).fromNow(true)
}, }
]; ];
// Reset input // Reset input
@@ -183,10 +183,7 @@
return c; return c;
}); });
} }
const { error } = await supabase const { error } = await supabase.from(table).update({ votes }).match({ id: matchId });
.from(table)
.update({ votes })
.match({ id: matchId });
if (error) { if (error) {
console.error('Error: upvoteQuestion', error); console.error('Error: upvoteQuestion', error);
$snackbarStore.open = true; $snackbarStore.open = true;
@@ -251,9 +248,7 @@
.match({ id: deleteComment.commentId }); .match({ id: deleteComment.commentId });
if (!error) { if (!error) {
question.comments = question.comments.filter( question.comments = question.comments.filter((c) => c.id !== deleteComment.commentId);
(c) => c.id !== deleteComment.commentId
);
deleteComment.shouldDelete = false; deleteComment.shouldDelete = false;
deleteComment.commentId = null; deleteComment.commentId = null;
@@ -288,7 +283,7 @@
class="text-gray-500 dark:text-white text-md flex items-center" class="text-gray-500 dark:text-white text-md flex items-center"
href={`${$currentOrgPath}/community`} href={`${$currentOrgPath}/community`}
> >
<ArrowLeftIcon size={24} class="carbon-icon" /> Go Back <ArrowLeftIcon size={24} class="carbon-icon dark:text-white" /> Go Back
</a> </a>
<div class="my-5 flex justify-between items-center"> <div class="my-5 flex justify-between items-center">
{#if isEditMode} {#if isEditMode}
@@ -329,9 +324,7 @@
</div> </div>
<div class="my-1 px-1 rounded-lg border border-1 border-gray"> <div class="my-1 px-1 rounded-lg border border-1 border-gray">
<header class="flex items-center justify-between leading-none p-2"> <header class="flex items-center justify-between leading-none p-2">
<div <div class="flex items-center no-underline hover:underline text-black">
class="flex items-center no-underline hover:underline text-black"
>
<Avatar <Avatar
src={question.author.avatar} src={question.author.avatar}
name={question.author.name} name={question.author.name}
@@ -375,12 +368,7 @@
<div class="w-full rounded-lg border border-1 border-gray"> <div class="w-full rounded-lg border border-1 border-gray">
<header class="flex items-center justify-between leading-none p-2"> <header class="flex items-center justify-between leading-none p-2">
<div class="flex items-center text-black"> <div class="flex items-center text-black">
<Avatar <Avatar src={comment.avatar} name={comment.name} width="w-7" height="h-7" />
src={comment.avatar}
name={comment.name}
width="w-7"
height="h-7"
/>
<p class="dark:text-white ml-2 text-sm">{comment.name}</p> <p class="dark:text-white ml-2 text-sm">{comment.name}</p>
<p class="dark:text-white ml-2 text-sm text-gray-500"> <p class="dark:text-white ml-2 text-sm text-gray-500">
{comment.createdAt} {comment.createdAt}
@@ -399,7 +387,7 @@
deleteComment.commentId = comment.id; deleteComment.commentId = comment.id;
}} }}
> >
<TrashCanIcon size={16} class="carbon-icon" /> <TrashCanIcon size={16} class="carbon-icon dark:text-white" />
</IconButton> </IconButton>
{/if} {/if}
</header> </header>
@@ -13,7 +13,7 @@
let errors = {}; let errors = {};
let fields = { let fields = {
title: '', title: '',
body: '', body: ''
}; };
async function handleSave() { async function handleSave() {
@@ -31,7 +31,7 @@
organization_id: $currentOrg.id, organization_id: $currentOrg.id,
author_id: $currentOrg.memberId, author_id: $currentOrg.memberId,
votes: 0, votes: 0,
slug: generateSlug(fields.title), slug: generateSlug(fields.title)
}) })
.select(); .select();
@@ -61,7 +61,7 @@
class="text-gray-500 dark:text-white text-md flex items-center" class="text-gray-500 dark:text-white text-md flex items-center"
href={`${$currentOrgPath}/community`} href={`${$currentOrgPath}/community`}
> >
<ArrowLeftIcon size={24} class="carbon-icon" /> Go Back <ArrowLeftIcon size={24} class="carbon-icon dark:text-white" /> Go Back
</a> </a>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<h1 class="dark:text-white text-3xl font-bold">Ask the community</h1> <h1 class="dark:text-white text-3xl font-bold">Ask the community</h1>
+13 -29
View File
@@ -11,12 +11,7 @@
import { currentOrgPath, deleteModal } from '$lib/utils/store/org'; import { currentOrgPath, deleteModal } from '$lib/utils/store/org';
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte'; import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
import { VARIANTS } from '$lib/components/PrimaryButton/constants'; import { VARIANTS } from '$lib/components/PrimaryButton/constants';
import { import { themeImages, allOptions, booleanOptions, allThemes } from '$lib/utils/constants/quiz';
themeImages,
allOptions,
booleanOptions,
allThemes,
} from '$lib/utils/constants/quiz';
import { quizStore, quizesStore } from '$lib/utils/store/org'; import { quizStore, quizesStore } from '$lib/utils/store/org';
import DeleteModal from '$lib/components/Org/Quiz/DeleteModal.svelte'; import DeleteModal from '$lib/components/Org/Quiz/DeleteModal.svelte';
import Preview from '$lib/components/Org/Quiz/Play/Preview.svelte'; import Preview from '$lib/components/Org/Quiz/Play/Preview.svelte';
@@ -30,7 +25,7 @@
// Questionnaire State // Questionnaire State
let currentQuestion = $quizStore.questions[0] || { let currentQuestion = $quizStore.questions[0] || {
options: [], options: []
}; };
// Behavioural State // Behavioural State
@@ -55,16 +50,14 @@
id: new Date().getTime(), id: new Date().getTime(),
label: '', label: '',
type: 'multichoice', type: 'multichoice',
options: [], options: []
}, }
]; ];
type = 'multichoice'; type = 'multichoice';
} }
function addOption() { function addOption() {
const cOptIds = currentQuestion.options.map((o) => o.id); const cOptIds = currentQuestion.options.map((o) => o.id);
const nextOption = cloneDeep(allOptions).find( const nextOption = cloneDeep(allOptions).find((o) => !cOptIds.includes(o.id));
(o) => !cOptIds.includes(o.id)
);
if (!nextOption) return; if (!nextOption) return;
@@ -91,9 +84,7 @@
function deleteQuestion() { function deleteQuestion() {
// Only leave one question // Only leave one question
if ($quizStore.questions.length === 1) return; if ($quizStore.questions.length === 1) return;
$quizStore.questions = $quizStore.questions.filter( $quizStore.questions = $quizStore.questions.filter((q) => q.id !== currentQuestion.id);
(q) => q.id !== currentQuestion.id
);
currentQuestion = $quizStore.questions[0]; currentQuestion = $quizStore.questions[0];
} }
@@ -115,7 +106,7 @@
if (valLabelError) { if (valLabelError) {
options.push({ options.push({
id: o.id, id: o.id,
error: true, error: true
}); });
} }
@@ -128,7 +119,7 @@
isLabelEmpty: labelError, isLabelEmpty: labelError,
hasOneAnswer, hasOneAnswer,
id: q.id, id: q.id,
options, options
}); });
}); });
@@ -149,7 +140,7 @@
.from('quiz') .from('quiz')
.update({ .update({
...$quizStore, ...$quizStore,
updated_at: new Date(), updated_at: new Date()
}) })
.match({ id: quizId }); .match({ id: quizId });
@@ -170,8 +161,7 @@
function qHasError(qId, _errs) { function qHasError(qId, _errs) {
return _errs.some((qe) => { return _errs.some((qe) => {
return ( return (
(qId ? qe.id === qId : true) && (qId ? qe.id === qId : true) && (qe.isLabelEmpty || !qe.hasOneAnswer || !!qe.options.length)
(qe.isLabelEmpty || !qe.hasOneAnswer || !!qe.options.length)
); );
}); });
} }
@@ -212,7 +202,7 @@
class="text-gray-500 dark:text-white text-md flex items-center" class="text-gray-500 dark:text-white text-md flex items-center"
href={`${$currentOrgPath}/quiz`} href={`${$currentOrgPath}/quiz`}
> >
<ArrowLeftIcon size={24} class="carbon-icon" /> Back to Quizzes <ArrowLeftIcon size={24} class="carbon-icon dark:text-white" /> Back to Quizzes
</a> </a>
<h3 class="my-3">Quiz</h3> <h3 class="my-3">Quiz</h3>
@@ -239,11 +229,7 @@
</div> </div>
<div class="w-full flex justify-end"> <div class="w-full flex justify-end">
<PrimaryButton <PrimaryButton label="Add Question" variant={VARIANTS.CONTAINED} onClick={addQuestion} />
label="Add Question"
variant={VARIANTS.CONTAINED}
onClick={addQuestion}
/>
</div> </div>
</div> </div>
</aside> </aside>
@@ -261,9 +247,7 @@
{#if isBoolean(currentError.hasOneAnswer) && !currentError.hasOneAnswer} {#if isBoolean(currentError.hasOneAnswer) && !currentError.hasOneAnswer}
<div class="mb-5"> <div class="mb-5">
<p class="text-red-500"> <p class="text-red-500">Please select at least one correct answer</p>
Please select at least one correct answer
</p>
</div> </div>
{/if} {/if}