Merge styles + style task card on all exercises page
This commit is contained in:
@@ -1,17 +1,17 @@
|
||||
<script>
|
||||
import { onMount } from "svelte";
|
||||
import hotkeys from "hotkeys-js";
|
||||
import Forum24 from "carbon-icons-svelte/lib/Forum24";
|
||||
import AlignBoxTopLeft24 from "carbon-icons-svelte/lib/AlignBoxTopLeft24";
|
||||
import SendAlt24 from "carbon-icons-svelte/lib/SendAlt24";
|
||||
import ChartPie24 from "carbon-icons-svelte/lib/ChartPie24";
|
||||
import IconButton from "../IconButton/index.svelte";
|
||||
import { onMount } from 'svelte';
|
||||
import hotkeys from 'hotkeys-js';
|
||||
import Forum24 from 'carbon-icons-svelte/lib/Forum24';
|
||||
import AlignBoxTopLeft24 from 'carbon-icons-svelte/lib/AlignBoxTopLeft24';
|
||||
import SendAlt24 from 'carbon-icons-svelte/lib/SendAlt24';
|
||||
import ChartPie24 from 'carbon-icons-svelte/lib/ChartPie24';
|
||||
import IconButton from '../IconButton/index.svelte';
|
||||
|
||||
import QandA from "./components/QandA/index.svelte";
|
||||
import LiveChat from "./components/LiveChat/index.svelte";
|
||||
import Notes from "./components/Notes/index.svelte";
|
||||
import Poll from "./components/Poll/index.svelte";
|
||||
import APPS_CONSTANTS from "./constants";
|
||||
import QandA from './components/QandA/index.svelte';
|
||||
import LiveChat from './components/LiveChat/index.svelte';
|
||||
import Notes from './components/Notes/index.svelte';
|
||||
import Poll from './components/Poll/index.svelte';
|
||||
import APPS_CONSTANTS from './constants';
|
||||
|
||||
let selectedApp;
|
||||
|
||||
@@ -28,19 +28,19 @@
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
hotkeys("A+1,A+2,A+3,A+4", function (event, handler) {
|
||||
hotkeys('A+1,A+2,A+3,A+4', function (event, handler) {
|
||||
event.preventDefault();
|
||||
switch (handler.key) {
|
||||
case "A+1":
|
||||
case 'A+1':
|
||||
handleAppClick(APPS_CONSTANTS.APPS.LIVE_CHAT);
|
||||
break;
|
||||
case "A+2":
|
||||
case 'A+2':
|
||||
handleAppClick(APPS_CONSTANTS.APPS.QANDA);
|
||||
break;
|
||||
case "A+3":
|
||||
case 'A+3':
|
||||
handleAppClick(APPS_CONSTANTS.APPS.NOTES);
|
||||
break;
|
||||
case "A+4":
|
||||
case 'A+4':
|
||||
handleAppClick(APPS_CONSTANTS.APPS.POLL);
|
||||
break;
|
||||
}
|
||||
@@ -51,7 +51,7 @@
|
||||
<div class="root">
|
||||
<div class="apps">
|
||||
<IconButton
|
||||
toolTipProps={{ title: "Live Chat", hotkeys: ["A", "1"] }}
|
||||
toolTipProps={{ title: 'Live Chat', hotkeys: ['A', '1'] }}
|
||||
value={APPS_CONSTANTS.APPS.LIVE_CHAT}
|
||||
onClick={handleAppClick}
|
||||
selected={APPS_CONSTANTS.APPS.LIVE_CHAT === selectedApp}
|
||||
@@ -60,7 +60,7 @@
|
||||
</IconButton>
|
||||
|
||||
<IconButton
|
||||
toolTipProps={{ title: "QandA", hotkeys: ["A", "2"] }}
|
||||
toolTipProps={{ title: 'QandA', hotkeys: ['A', '2'] }}
|
||||
value={APPS_CONSTANTS.APPS.QANDA}
|
||||
onClick={handleAppClick}
|
||||
selected={APPS_CONSTANTS.APPS.QANDA === selectedApp}
|
||||
@@ -69,7 +69,7 @@
|
||||
</IconButton>
|
||||
|
||||
<IconButton
|
||||
toolTipProps={{ title: "Notes", hotkeys: ["A", "3"] }}
|
||||
toolTipProps={{ title: 'Notes', hotkeys: ['A', '3'] }}
|
||||
value={APPS_CONSTANTS.APPS.NOTES}
|
||||
onClick={handleAppClick}
|
||||
selected={APPS_CONSTANTS.APPS.NOTES === selectedApp}
|
||||
@@ -78,7 +78,7 @@
|
||||
</IconButton>
|
||||
|
||||
<IconButton
|
||||
toolTipProps={{ title: "Poll", hotkeys: ["A", "4"] }}
|
||||
toolTipProps={{ title: 'Poll', hotkeys: ['A', '4'] }}
|
||||
value={APPS_CONSTANTS.APPS.POLL}
|
||||
onClick={handleAppClick}
|
||||
selected={APPS_CONSTANTS.APPS.POLL === selectedApp}
|
||||
@@ -104,7 +104,7 @@
|
||||
|
||||
<style lang="scss">
|
||||
.root {
|
||||
height: 95vh;
|
||||
height: 90vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
border-left: 1px solid var(--border-color);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<script>
|
||||
import { questionnaire } from "./store/index";
|
||||
import { userQuestionniareAnswers } from "./store/answers";
|
||||
import RadioQuestion from "../../../../Question/RadioQuestion/index.svelte";
|
||||
import CheckboxQuestion from "../../../../Question/CheckboxQuestion/index.svelte";
|
||||
import TextareaQuestion from "../../../../Question/TextareaQuestion/index.svelte";
|
||||
import PrimaryButton from "../../../../PrimaryButton/index.svelte";
|
||||
import Progress from "../../../../Progress/index.svelte";
|
||||
import { removeDuplicate } from "../../../../../utils/functions/removeDuplicate";
|
||||
import { QUESTION_TYPE } from "../../../../Question/constants";
|
||||
import { STATUS } from "./constants";
|
||||
import { questionnaire } from './store/index';
|
||||
import { userQuestionniareAnswers } from './store/answers';
|
||||
import RadioQuestion from '../../../../Question/RadioQuestion/index.svelte';
|
||||
import CheckboxQuestion from '../../../../Question/CheckboxQuestion/index.svelte';
|
||||
import TextareaQuestion from '../../../../Question/TextareaQuestion/index.svelte';
|
||||
import PrimaryButton from '../../../../PrimaryButton/index.svelte';
|
||||
import Progress from '../../../../Progress/index.svelte';
|
||||
import { removeDuplicate } from '../../../../../utils/functions/removeDuplicate';
|
||||
import { QUESTION_TYPE } from '../../../../Question/constants';
|
||||
import { STATUS } from './constants';
|
||||
|
||||
export let preview;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
function onSubmit(id, value) {
|
||||
const prevAnswer = $userQuestionniareAnswers.answers[id] || [];
|
||||
const formattedAnswer =
|
||||
typeof value === "string"
|
||||
typeof value === 'string'
|
||||
? value
|
||||
: removeDuplicate([...prevAnswer, ...(value || [])]);
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
return true;
|
||||
}
|
||||
const answer = $userQuestionniareAnswers.answers[currentQuestion.id];
|
||||
const formattedAnswers = typeof answer === "string" ? [answer] : answer;
|
||||
const formattedAnswers = typeof answer === 'string' ? [answer] : answer;
|
||||
|
||||
isAnswerCorrect =
|
||||
formattedAnswers &&
|
||||
@@ -74,13 +74,13 @@
|
||||
const isOpenQuesiton = question.type === QUESTION_TYPE.TEXTAREA;
|
||||
|
||||
return {
|
||||
title: questionIndex + ". " + question.title,
|
||||
title: questionIndex + '. ' + question.title,
|
||||
name: `${question.id}`,
|
||||
options: question.options,
|
||||
answers: question.answers,
|
||||
code: question.code,
|
||||
defaultValue: isOpenQuesiton
|
||||
? answers[question.id] || ""
|
||||
? answers[question.id] || ''
|
||||
: answers[question.id] || [],
|
||||
onSubmit,
|
||||
onPrevious,
|
||||
@@ -93,22 +93,22 @@
|
||||
$userQuestionniareAnswers.isFinished,
|
||||
nextButtonProps: isLast
|
||||
? {
|
||||
label: "Finish",
|
||||
label: 'Finish',
|
||||
isActive: true,
|
||||
}
|
||||
: isOpenQuesiton
|
||||
? {
|
||||
label: "Next",
|
||||
label: 'Next',
|
||||
isActive: true,
|
||||
}
|
||||
: wasCorrectAnswerSelected(question)
|
||||
? {
|
||||
label: "Next",
|
||||
label: 'Next',
|
||||
isActive: true,
|
||||
disableOptionSelect: true,
|
||||
}
|
||||
: {
|
||||
label: "Check",
|
||||
label: 'Check',
|
||||
isActive: false,
|
||||
},
|
||||
};
|
||||
@@ -159,7 +159,7 @@
|
||||
|
||||
<!-- <svelte:window on:keydown={handleKeydown} /> -->
|
||||
|
||||
{#if !preview && !$userQuestionniareAnswers.isFinished}
|
||||
{#if !preview && questions.length && !$userQuestionniareAnswers.isFinished}
|
||||
<Progress value={$userQuestionniareAnswers.progressValue} />
|
||||
{/if}
|
||||
|
||||
@@ -191,6 +191,15 @@
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
{:else if !questions.length}
|
||||
<div
|
||||
class="w-4/5 h-40 m-auto flex items-center justify-center text-center border-2 border-gray-200 rounded-md"
|
||||
>
|
||||
<h3 class="text-2xl">
|
||||
No questions added. <br /> Click the
|
||||
<span class="text-blue-700">Edit</span> button to add.
|
||||
</h3>
|
||||
</div>
|
||||
{:else if $userQuestionniareAnswers.currentQuestionIndex === 0}
|
||||
<div>
|
||||
<h2 class="my-1">{title}</h2>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { writable } from "svelte/store";
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
import { STATUS } from "../constants";
|
||||
import { STATUS } from '../constants';
|
||||
|
||||
// export const userQuestionniareAnswers = writable({
|
||||
// answers: {},
|
||||
@@ -10,12 +10,13 @@ import { STATUS } from "../constants";
|
||||
// progressValue: 100,
|
||||
// status: STATUS.REVIEWED,
|
||||
// });
|
||||
|
||||
export const userQuestionniareAnswers = writable({
|
||||
const initAnswerState = {
|
||||
answers: {},
|
||||
scores: {},
|
||||
currentQuestionIndex: 0,
|
||||
isFinished: false,
|
||||
progressValue: 100,
|
||||
status: STATUS.IN_PROGRESS,
|
||||
});
|
||||
};
|
||||
|
||||
export const userQuestionniareAnswers = writable(initAnswerState);
|
||||
|
||||
@@ -1,98 +1,13 @@
|
||||
import { writable } from "svelte/store";
|
||||
import { writable } from 'svelte/store';
|
||||
import {
|
||||
QUESTION_TEMPLATE,
|
||||
QUESTION_TYPE,
|
||||
} from "../../../../../Question/constants";
|
||||
} from '../../../../../Question/constants';
|
||||
|
||||
export const questionnaire = writable({
|
||||
title: "Home task 1",
|
||||
description:
|
||||
"You will be to answer 10 questions, it isn't timed so you can take your time to answer. You can also continue from where you left off, you don't need to worry cause everything is automatically syncronized in the cloud.",
|
||||
questions: [
|
||||
{
|
||||
id: "react-founder",
|
||||
type: QUESTION_TYPE.CHECKBOX,
|
||||
title: "Who is the creator of React.js",
|
||||
options: [
|
||||
{
|
||||
id: "1",
|
||||
value: "Dan Abrahmov",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
value: "Google",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
value: "Facebook",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
value: "Traversy Media",
|
||||
},
|
||||
],
|
||||
answers: ['3'],
|
||||
},
|
||||
{
|
||||
id: "vue-founder",
|
||||
type: QUESTION_TYPE.CHECKBOX,
|
||||
title: "Who is the creator of Vue.js",
|
||||
code: `const name = 'Josh Perez';\nconst element = <h1>Hello, {name}</h1>;\n\nReactDOM.render(\n
|
||||
element,\,
|
||||
document.getElementById('root')
|
||||
)
|
||||
`,
|
||||
options: [
|
||||
{
|
||||
id: "1",
|
||||
value: "Evan Vue",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
value: "Mark Zukerberg",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
value: "Prince Charles",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
value: "Bill Gates",
|
||||
},
|
||||
],
|
||||
answers: ['3'],
|
||||
},
|
||||
{
|
||||
id: "svelte-founder",
|
||||
type: QUESTION_TYPE.RADIO,
|
||||
title: "Who is the creator of Svelte.js",
|
||||
options: [
|
||||
{
|
||||
id: "1",
|
||||
value: "Hillary Svelte",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
value: "Mircosoft",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
value: "Elevate",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
value: "Coding Train",
|
||||
},
|
||||
],
|
||||
answers: ["2"],
|
||||
},
|
||||
{
|
||||
id: "angular-founder",
|
||||
type: QUESTION_TYPE.TEXTAREA,
|
||||
title: "Who is the creator of Angular.js",
|
||||
value: "",
|
||||
},
|
||||
],
|
||||
title: '',
|
||||
description: '',
|
||||
questions: [],
|
||||
});
|
||||
|
||||
export function handleAddQuestion() {
|
||||
@@ -105,11 +20,11 @@ export function handleAddQuestion() {
|
||||
{
|
||||
...QUESTION_TEMPLATE,
|
||||
id: questions.length + 1,
|
||||
value: "",
|
||||
value: '',
|
||||
answers: [],
|
||||
options: [
|
||||
{
|
||||
id: "1",
|
||||
id: '1',
|
||||
value: null,
|
||||
},
|
||||
],
|
||||
@@ -133,7 +48,7 @@ export function handleAddOption(questionId) {
|
||||
...question.options,
|
||||
{
|
||||
id: question.options[question.options.length - 1].id + 1,
|
||||
value: "",
|
||||
value: '',
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -193,7 +108,7 @@ export function handleCode(questionId, shouldAdd = true) {
|
||||
if (question.id === questionId) {
|
||||
return {
|
||||
...question,
|
||||
code: shouldAdd ? (question.code || "") : undefined,
|
||||
code: shouldAdd ? question.code || '' : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -212,25 +127,26 @@ export function handleAnswerSelect(questionId, optionId) {
|
||||
...q,
|
||||
questions: questions.map((question) => {
|
||||
if (question.id === questionId) {
|
||||
const selectOption = question.options.find(option => option.id === optionId);
|
||||
const selectOption = question.options.find(
|
||||
(option) => option.id === optionId
|
||||
);
|
||||
const newAnswers = [];
|
||||
|
||||
if (question.type === QUESTION_TYPE.RADIO) {
|
||||
newAnswers.push(optionId)
|
||||
newAnswers.push(optionId);
|
||||
} else if (question.answers.includes(selectOption.id)) {
|
||||
newAnswers.push(
|
||||
...question.answers.filter(answer => answer !== selectOption.id)
|
||||
)
|
||||
...question.answers.filter(
|
||||
(answer) => answer !== selectOption.id
|
||||
)
|
||||
);
|
||||
} else {
|
||||
newAnswers.push(
|
||||
...question.answers,
|
||||
selectOption.id
|
||||
)
|
||||
newAnswers.push(...question.answers, selectOption.id);
|
||||
}
|
||||
|
||||
return {
|
||||
...question,
|
||||
answers: newAnswers
|
||||
answers: newAnswers,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -238,6 +154,5 @@ export function handleAnswerSelect(questionId, optionId) {
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
..._lesson.exercises,
|
||||
{
|
||||
...newExercise,
|
||||
link: `${path}/${_lesson.exercises.length + 1}`,
|
||||
id: _lesson.exercises.length + 1,
|
||||
},
|
||||
],
|
||||
}));
|
||||
@@ -76,7 +76,10 @@
|
||||
|
||||
<div class="flex flex-wrap">
|
||||
{#each $lesson.exercises as exercise}
|
||||
<a class="w-52 bg-gray-100 px-4 py-7 mr-4 mb-4" href={exercise.link}>
|
||||
<a
|
||||
class="w-52 bg-gray-100 px-4 py-7 mr-4 mb-4"
|
||||
href="{path}/{exercise.id}"
|
||||
>
|
||||
<h3 class="text-xl">{exercise.title}</h3>
|
||||
<p class="mt-4 text-sm">Created Jul 3, 2021</p>
|
||||
</a>
|
||||
|
||||
@@ -39,9 +39,12 @@
|
||||
display: flex;
|
||||
border-right: 1px solid var(--border-color);
|
||||
width: 100%;
|
||||
max-width: calc(100% - 100px);
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.rightBar {
|
||||
flex-grow: 1;
|
||||
width: calc(100% - 350px);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<script>
|
||||
import Forum32 from "carbon-icons-svelte/lib/Forum32";
|
||||
import SendAlt32 from "carbon-icons-svelte/lib/SendAlt32";
|
||||
import Catalog32 from "carbon-icons-svelte/lib/Catalog32";
|
||||
import UserAvatar32 from "carbon-icons-svelte/lib/UserAvatar32";
|
||||
import Forum32 from 'carbon-icons-svelte/lib/Forum32';
|
||||
import SendAlt32 from 'carbon-icons-svelte/lib/SendAlt32';
|
||||
import Catalog32 from 'carbon-icons-svelte/lib/Catalog32';
|
||||
import UserAvatar32 from 'carbon-icons-svelte/lib/UserAvatar32';
|
||||
// import Calendar32 from "carbon-icons-svelte/lib/Calendar32";
|
||||
export let segment;
|
||||
let navClass = "";
|
||||
let navClass = '';
|
||||
|
||||
$: navClass = ["discussion"].includes(segment) ? "hide" : "";
|
||||
$: navClass = ['discussion'].includes(segment) ? 'hide' : '';
|
||||
</script>
|
||||
|
||||
<nav class={navClass}>
|
||||
@@ -26,8 +26,8 @@
|
||||
<li>
|
||||
<a
|
||||
class="block"
|
||||
aria-current={segment === undefined || segment === "discussion"
|
||||
? "page"
|
||||
aria-current={segment === undefined || segment === 'discussion'
|
||||
? 'page'
|
||||
: undefined}
|
||||
href="."><Forum32 class="carbon-icon" /><span>Discussion</span></a
|
||||
>
|
||||
@@ -35,7 +35,7 @@
|
||||
<li>
|
||||
<a
|
||||
class="block"
|
||||
aria-current={segment === "courses" ? "page" : undefined}
|
||||
aria-current={segment === 'courses' ? 'page' : undefined}
|
||||
href="courses"
|
||||
><Catalog32 class="carbon-icon" />
|
||||
<span>Courses</span></a
|
||||
@@ -44,7 +44,7 @@
|
||||
<li>
|
||||
<a
|
||||
class="block"
|
||||
aria-current={segment === "profile" ? "page" : undefined}
|
||||
aria-current={segment === 'profile' ? 'page' : undefined}
|
||||
href="profile"
|
||||
><UserAvatar32 class="carbon-icon" />
|
||||
<span>Профиль</span></a
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
<style>
|
||||
nav {
|
||||
height: 95vh;
|
||||
height: 90vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100px;
|
||||
@@ -96,7 +96,7 @@
|
||||
|
||||
/* clearfix */
|
||||
ul::after {
|
||||
content: "";
|
||||
content: '';
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
@@ -76,13 +76,13 @@
|
||||
|
||||
<PageBody width="w-11/12 overflow-x-auto overflow-y-hidden h-3/4">
|
||||
<div class="flex items-center justify-between h-full w-full">
|
||||
{#each sections as { id, title, value, items }, idx (id)}
|
||||
{#each sections as { id, title, items }, idx (id)}
|
||||
<div
|
||||
class="section rounded-md bg-gray-100 border border-gray-50 p-3 h-full mr-3 overflow-hidden"
|
||||
animate:flip={{ duration: flipDurationMs }}
|
||||
>
|
||||
<div class="flex items-center mb-2">
|
||||
<Chip {value} />
|
||||
<Chip value={items.length} />
|
||||
<p class="ml-2 font-bold">{title}</p>
|
||||
</div>
|
||||
<div
|
||||
@@ -97,10 +97,27 @@
|
||||
>
|
||||
{#each items as item (item.id)}
|
||||
<div
|
||||
class="w-full h-16 my-2 mx-0 rounded-md bg-white p-2"
|
||||
class="border border-grey-700 w-full my-2 mx-0 rounded-md bg-white py-2 px-3"
|
||||
animate:flip={{ duration: flipDurationMs }}
|
||||
>
|
||||
{item.name}
|
||||
<a class="text-blue-700 text-md font-bold" href="courses/1"
|
||||
>{item.name}</a
|
||||
>
|
||||
<p class="text-grey text-sm mb-2">#2 created by sergey-semko</p>
|
||||
|
||||
<a
|
||||
class="flex items-center no-underline hover:underline text-black"
|
||||
href="/"
|
||||
>
|
||||
<img
|
||||
alt="Placeholder"
|
||||
class="block rounded-full"
|
||||
width="24"
|
||||
height="20"
|
||||
src="https://picsum.photos/32/32/?random"
|
||||
/>
|
||||
<p class="ml-2 text-sm">rotimi-best</p>
|
||||
</a>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
@@ -61,13 +61,16 @@
|
||||
]}
|
||||
>
|
||||
<svelte:fragment slot="widget">
|
||||
<div class="flex items-center">
|
||||
<PrimaryButton
|
||||
className="mr-2"
|
||||
label={mode === MODES.edit ? 'Save' : 'Edit'}
|
||||
onClick={() => (mode = mode === MODES.edit ? MODES.view : MODES.edit)}
|
||||
/>
|
||||
</div>
|
||||
{#if isMaterialsTabActive}
|
||||
<div class="flex items-center">
|
||||
<PrimaryButton
|
||||
className="mr-2"
|
||||
label={mode === MODES.edit ? 'Save' : 'Edit'}
|
||||
onClick={() =>
|
||||
(mode = mode === MODES.edit ? MODES.view : MODES.edit)}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</PageNav>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user