Complete questionnaire builder
This commit is contained in:
@@ -45,7 +45,6 @@
|
|||||||
hasUserVoted = poll.options.some((option) =>
|
hasUserVoted = poll.options.some((option) =>
|
||||||
option.selectedBy.find((u) => u.value === currentUserId)
|
option.selectedBy.find((u) => u.value === currentUserId)
|
||||||
);
|
);
|
||||||
console.log("hasUserVoted", hasUserVoted, currentUserId);
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,6 @@
|
|||||||
|
|
||||||
function handleMarkAnswered(id) {
|
function handleMarkAnswered(id) {
|
||||||
return () => {
|
return () => {
|
||||||
console.log(`id`, id);
|
|
||||||
questions = questions
|
questions = questions
|
||||||
.map((question) => {
|
.map((question) => {
|
||||||
if (question.id === id) {
|
if (question.id === id) {
|
||||||
|
|||||||
@@ -28,19 +28,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
hotkeys("ctrl+1,ctrl+2,ctrl+3,ctrl+4", function (event, handler) {
|
hotkeys("A+1,A+2,A+3,A+4", function (event, handler) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
switch (handler.key) {
|
switch (handler.key) {
|
||||||
case "ctrl+1":
|
case "A+1":
|
||||||
handleAppClick(APPS_CONSTANTS.APPS.LIVE_CHAT);
|
handleAppClick(APPS_CONSTANTS.APPS.LIVE_CHAT);
|
||||||
break;
|
break;
|
||||||
case "ctrl+2":
|
case "A+2":
|
||||||
handleAppClick(APPS_CONSTANTS.APPS.QANDA);
|
handleAppClick(APPS_CONSTANTS.APPS.QANDA);
|
||||||
break;
|
break;
|
||||||
case "ctrl+3":
|
case "A+3":
|
||||||
handleAppClick(APPS_CONSTANTS.APPS.NOTES);
|
handleAppClick(APPS_CONSTANTS.APPS.NOTES);
|
||||||
break;
|
break;
|
||||||
case "ctrl+4":
|
case "A+4":
|
||||||
handleAppClick(APPS_CONSTANTS.APPS.POLL);
|
handleAppClick(APPS_CONSTANTS.APPS.POLL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
<div class="root">
|
<div class="root">
|
||||||
<div class="apps">
|
<div class="apps">
|
||||||
<IconButton
|
<IconButton
|
||||||
toolTipProps={{ title: "Live Chat", hotkeys: ["Ctrl", "1"] }}
|
toolTipProps={{ title: "Live Chat", hotkeys: ["A", "1"] }}
|
||||||
value={APPS_CONSTANTS.APPS.LIVE_CHAT}
|
value={APPS_CONSTANTS.APPS.LIVE_CHAT}
|
||||||
onClick={handleAppClick}
|
onClick={handleAppClick}
|
||||||
selected={APPS_CONSTANTS.APPS.LIVE_CHAT === selectedApp}
|
selected={APPS_CONSTANTS.APPS.LIVE_CHAT === selectedApp}
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
||||||
<IconButton
|
<IconButton
|
||||||
toolTipProps={{ title: "QandA", hotkeys: ["Ctrl", "2"] }}
|
toolTipProps={{ title: "QandA", hotkeys: ["A", "2"] }}
|
||||||
value={APPS_CONSTANTS.APPS.QANDA}
|
value={APPS_CONSTANTS.APPS.QANDA}
|
||||||
onClick={handleAppClick}
|
onClick={handleAppClick}
|
||||||
selected={APPS_CONSTANTS.APPS.QANDA === selectedApp}
|
selected={APPS_CONSTANTS.APPS.QANDA === selectedApp}
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
||||||
<IconButton
|
<IconButton
|
||||||
toolTipProps={{ title: "Notes", hotkeys: ["Ctrl", "3"] }}
|
toolTipProps={{ title: "Notes", hotkeys: ["A", "3"] }}
|
||||||
value={APPS_CONSTANTS.APPS.NOTES}
|
value={APPS_CONSTANTS.APPS.NOTES}
|
||||||
onClick={handleAppClick}
|
onClick={handleAppClick}
|
||||||
selected={APPS_CONSTANTS.APPS.NOTES === selectedApp}
|
selected={APPS_CONSTANTS.APPS.NOTES === selectedApp}
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
||||||
<IconButton
|
<IconButton
|
||||||
toolTipProps={{ title: "Poll", hotkeys: ["Ctrl", "4"] }}
|
toolTipProps={{ title: "Poll", hotkeys: ["A", "4"] }}
|
||||||
value={APPS_CONSTANTS.APPS.POLL}
|
value={APPS_CONSTANTS.APPS.POLL}
|
||||||
onClick={handleAppClick}
|
onClick={handleAppClick}
|
||||||
selected={APPS_CONSTANTS.APPS.POLL === selectedApp}
|
selected={APPS_CONSTANTS.APPS.POLL === selectedApp}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
function handleFacultyFilters() {
|
function handleFacultyFilters() {
|
||||||
console.log("clicking");
|
|
||||||
facultyFilterOpened = facultyFilterOpened ? false : true;
|
facultyFilterOpened = facultyFilterOpened ? false : true;
|
||||||
}
|
}
|
||||||
let things = [
|
let things = [
|
||||||
@@ -34,7 +33,6 @@
|
|||||||
|
|
||||||
function handleClick() {
|
function handleClick() {
|
||||||
things = things.slice(1);
|
things = things.slice(1);
|
||||||
console.log("things", things);
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -83,10 +83,10 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
hotkeys("ctrl+b", function (event, handler) {
|
hotkeys("b", function (event, handler) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
switch (handler.key) {
|
switch (handler.key) {
|
||||||
case "ctrl+b":
|
case "b":
|
||||||
show = !show;
|
show = !show;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,7 @@
|
|||||||
onClick={() => (show = !show)}
|
onClick={() => (show = !show)}
|
||||||
toolTipProps={{
|
toolTipProps={{
|
||||||
title: "Toggle sidebar",
|
title: "Toggle sidebar",
|
||||||
hotkeys: ["Ctrl", "B"],
|
hotkeys: ["B"],
|
||||||
direction: "right",
|
direction: "right",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import TextareaQuestion from "../../../../Question/TextareaQuestion/index.svelte";
|
import TextareaQuestion from "../../../../Question/TextareaQuestion/index.svelte";
|
||||||
import PrimaryButton from "../../../../PrimaryButton/index.svelte";
|
import PrimaryButton from "../../../../PrimaryButton/index.svelte";
|
||||||
import Progress from "../../../../Progress/index.svelte";
|
import Progress from "../../../../Progress/index.svelte";
|
||||||
|
import { removeDuplicate } from "../../../../../utils/functions/removeDuplicate";
|
||||||
import { QUESTION_TYPE } from "../../../../Question/constants";
|
import { QUESTION_TYPE } from "../../../../Question/constants";
|
||||||
|
|
||||||
export let preview;
|
export let preview;
|
||||||
@@ -15,6 +15,8 @@
|
|||||||
let currentQuestion = {};
|
let currentQuestion = {};
|
||||||
let renderProps = {};
|
let renderProps = {};
|
||||||
let progressValue = 0;
|
let progressValue = 0;
|
||||||
|
let isAnswerCorrect;
|
||||||
|
let isFinished;
|
||||||
|
|
||||||
const { questions, title, description } = $questionnaire;
|
const { questions, title, description } = $questionnaire;
|
||||||
|
|
||||||
@@ -22,39 +24,98 @@
|
|||||||
currentQuestionIndex += 1;
|
currentQuestionIndex += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSubmit(name, value) {
|
function onSubmit(id, value) {
|
||||||
// if (!value) return;
|
const prevAnswer = answers[id] || [];
|
||||||
|
const formattedAnswer =
|
||||||
|
typeof value === "string"
|
||||||
|
? value
|
||||||
|
: removeDuplicate([...prevAnswer, ...(value || [])]);
|
||||||
|
|
||||||
answers = {
|
answers = {
|
||||||
...answers,
|
...answers,
|
||||||
[name]: value,
|
[id]: formattedAnswer,
|
||||||
};
|
};
|
||||||
currentQuestionIndex += 1;
|
|
||||||
|
if (isAnswerCorrect) {
|
||||||
|
currentQuestionIndex += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onPrevious() {
|
function onPrevious() {
|
||||||
currentQuestionIndex -= 1;
|
currentQuestionIndex -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRenderProps(question, questionIndex) {
|
function wasCorrectAnswerSelected(currentQuestion) {
|
||||||
|
const isOpenQuesiton = currentQuestion.type === QUESTION_TYPE.TEXTAREA;
|
||||||
|
|
||||||
|
if (isOpenQuesiton) {
|
||||||
|
isAnswerCorrect = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const answer = answers[currentQuestion.id];
|
||||||
|
const formattedAnswers = typeof answer === "string" ? [answer] : answer;
|
||||||
|
const options = currentQuestion.options;
|
||||||
|
|
||||||
|
isAnswerCorrect =
|
||||||
|
formattedAnswers &&
|
||||||
|
formattedAnswers.some((answer) => {
|
||||||
|
if (
|
||||||
|
!currentQuestion.answers?.length ||
|
||||||
|
currentQuestion.answers.includes(answer)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return isAnswerCorrect;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRenderProps(question, questionIndex, answers) {
|
||||||
|
const isLast = questionIndex === questions.length;
|
||||||
|
const isOpenQuesiton = question.type === QUESTION_TYPE.TEXTAREA;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: questionIndex + ". " + question.title,
|
title: questionIndex + ". " + question.title,
|
||||||
name: `${question.id}`,
|
name: `${question.id}`,
|
||||||
options: question.options,
|
options: question.options,
|
||||||
|
answers: question.answers,
|
||||||
code: question.code,
|
code: question.code,
|
||||||
defaultValue:
|
defaultValue: isOpenQuesiton
|
||||||
question.type === QUESTION_TYPE.TEXTAREA
|
? answers[question.id] || ""
|
||||||
? question.value || ""
|
: answers[question.id] || [],
|
||||||
: answers[question.id] || [],
|
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onPrevious,
|
onPrevious,
|
||||||
disablePreviousButton: questionIndex === 1,
|
disablePreviousButton: questionIndex === 1,
|
||||||
isLast: questionIndex === questions.length,
|
isLast,
|
||||||
isPreview: preview,
|
isPreview: preview || isFinished,
|
||||||
|
disabled: wasCorrectAnswerSelected(question) && isFinished,
|
||||||
|
nextButtonProps: isLast
|
||||||
|
? {
|
||||||
|
label: "Finish",
|
||||||
|
isActive: true,
|
||||||
|
}
|
||||||
|
: isOpenQuesiton
|
||||||
|
? {
|
||||||
|
label: "Next",
|
||||||
|
isActive: true,
|
||||||
|
}
|
||||||
|
: wasCorrectAnswerSelected(question)
|
||||||
|
? {
|
||||||
|
label: "Next",
|
||||||
|
isActive: true,
|
||||||
|
disableOptionSelect: true,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
label: "Check",
|
||||||
|
isActive: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProgressValue(currentQuestionIndex) {
|
function getProgressValue(currentQuestionIndex) {
|
||||||
if (!currentQuestion) {
|
if (isFinished) {
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,9 +126,16 @@
|
|||||||
|
|
||||||
$: {
|
$: {
|
||||||
currentQuestion = questions[currentQuestionIndex - 1];
|
currentQuestion = questions[currentQuestionIndex - 1];
|
||||||
|
if (currentQuestionIndex > 0 && !currentQuestion) {
|
||||||
|
isFinished = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (currentQuestion) {
|
if (currentQuestion) {
|
||||||
renderProps = getRenderProps(currentQuestion, currentQuestionIndex);
|
renderProps = getRenderProps(
|
||||||
|
currentQuestion,
|
||||||
|
currentQuestionIndex,
|
||||||
|
answers
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,26 +150,17 @@
|
|||||||
|
|
||||||
{#if preview}
|
{#if preview}
|
||||||
{#each questions as currentQuestion, currentQuestionIndex}
|
{#each questions as currentQuestion, currentQuestionIndex}
|
||||||
{#if currentQuestionIndex === 0}
|
{#if QUESTION_TYPE.RADIO === currentQuestion.type}
|
||||||
<div class="mb-2">
|
|
||||||
<h2 class="my-1">{title}</h2>
|
|
||||||
<p>{description}</p>
|
|
||||||
</div>
|
|
||||||
{:else if !currentQuestion}
|
|
||||||
<pre>
|
|
||||||
<code>{JSON.stringify(answers)}</code>
|
|
||||||
</pre>
|
|
||||||
{:else if QUESTION_TYPE.RADIO === currentQuestion.type}
|
|
||||||
<RadioQuestion
|
<RadioQuestion
|
||||||
{...getRenderProps(currentQuestion, currentQuestionIndex)}
|
{...getRenderProps(currentQuestion, currentQuestionIndex + 1, answers)}
|
||||||
/>
|
/>
|
||||||
{:else if QUESTION_TYPE.CHECKBOX === currentQuestion.type}
|
{:else if QUESTION_TYPE.CHECKBOX === currentQuestion.type}
|
||||||
<CheckboxQuestion
|
<CheckboxQuestion
|
||||||
{...getRenderProps(currentQuestion, currentQuestionIndex)}
|
{...getRenderProps(currentQuestion, currentQuestionIndex + 1, answers)}
|
||||||
/>
|
/>
|
||||||
{:else if QUESTION_TYPE.TEXTAREA === currentQuestion.type}
|
{:else if QUESTION_TYPE.TEXTAREA === currentQuestion.type}
|
||||||
<TextareaQuestion
|
<TextareaQuestion
|
||||||
{...getRenderProps(currentQuestion, currentQuestionIndex)}
|
{...getRenderProps(currentQuestion, currentQuestionIndex + 1, answers)}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
@@ -117,10 +176,23 @@
|
|||||||
type="button"
|
type="button"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{:else if !currentQuestion}
|
{:else if isFinished}
|
||||||
<pre>
|
<h2 class="text-lg">Congratulations you have completed your task</h2>
|
||||||
<code>{JSON.stringify(answers)}</code>
|
{#each questions as currentQuestion, currentQuestionIndex}
|
||||||
</pre>
|
{#if QUESTION_TYPE.RADIO === currentQuestion.type}
|
||||||
|
<RadioQuestion
|
||||||
|
{...getRenderProps(currentQuestion, currentQuestionIndex + 1, answers)}
|
||||||
|
/>
|
||||||
|
{:else if QUESTION_TYPE.CHECKBOX === currentQuestion.type}
|
||||||
|
<CheckboxQuestion
|
||||||
|
{...getRenderProps(currentQuestion, currentQuestionIndex + 1, answers)}
|
||||||
|
/>
|
||||||
|
{:else if QUESTION_TYPE.TEXTAREA === currentQuestion.type}
|
||||||
|
<TextareaQuestion
|
||||||
|
{...getRenderProps(currentQuestion, currentQuestionIndex + 1, answers)}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
{:else if QUESTION_TYPE.RADIO === currentQuestion.type}
|
{:else if QUESTION_TYPE.RADIO === currentQuestion.type}
|
||||||
<RadioQuestion {...renderProps} />
|
<RadioQuestion {...renderProps} />
|
||||||
{:else if QUESTION_TYPE.CHECKBOX === currentQuestion.type}
|
{:else if QUESTION_TYPE.CHECKBOX === currentQuestion.type}
|
||||||
|
|||||||
@@ -11,27 +11,27 @@ export const questionnaire = writable({
|
|||||||
questions: [
|
questions: [
|
||||||
{
|
{
|
||||||
id: "react-founder",
|
id: "react-founder",
|
||||||
type: QUESTION_TYPE.RADIO,
|
type: QUESTION_TYPE.CHECKBOX,
|
||||||
title: "Who is the creator of React.js",
|
title: "Who is the creator of React.js",
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: "1",
|
||||||
value: "Dan Abrahmov",
|
value: "Dan Abrahmov",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: "2",
|
||||||
value: "Google",
|
value: "Google",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: "3",
|
||||||
value: "Facebook",
|
value: "Facebook",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 4,
|
id: "4",
|
||||||
value: "Traversy Media",
|
value: "Traversy Media",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
answers: [],
|
answers: ['3'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "vue-founder",
|
id: "vue-founder",
|
||||||
@@ -44,47 +44,47 @@ export const questionnaire = writable({
|
|||||||
`,
|
`,
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: "1",
|
||||||
value: "Evan Vue",
|
value: "Evan Vue",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: "2",
|
||||||
value: "Mark Zukerberg",
|
value: "Mark Zukerberg",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: "3",
|
||||||
value: "Prince Charles",
|
value: "Prince Charles",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 4,
|
id: "4",
|
||||||
value: "Bill Gates",
|
value: "Bill Gates",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
answers: [],
|
answers: ['3'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "svelte-founder",
|
id: "svelte-founder",
|
||||||
type: QUESTION_TYPE.CHECKBOX,
|
type: QUESTION_TYPE.RADIO,
|
||||||
title: "Who is the creator of Svelte.js",
|
title: "Who is the creator of Svelte.js",
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: "1",
|
||||||
value: "Hillary Svelte",
|
value: "Hillary Svelte",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: "2",
|
||||||
value: "Mircosoft",
|
value: "Mircosoft",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: "3",
|
||||||
value: "Elevate",
|
value: "Elevate",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 4,
|
id: "4",
|
||||||
value: "Coding Train",
|
value: "Coding Train",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
answers: [2],
|
answers: ["2"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "angular-founder",
|
id: "angular-founder",
|
||||||
@@ -109,7 +109,7 @@ export function handleAddQuestion() {
|
|||||||
answers: [],
|
answers: [],
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: "1",
|
||||||
value: null,
|
value: null,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -215,7 +215,9 @@ export function handleAnswerSelect(questionId, optionId) {
|
|||||||
const selectOption = question.options.find(option => option.id === optionId);
|
const selectOption = question.options.find(option => option.id === optionId);
|
||||||
const newAnswers = [];
|
const newAnswers = [];
|
||||||
|
|
||||||
if (question.answers.includes(selectOption.id)) {
|
if (question.type === QUESTION_TYPE.RADIO) {
|
||||||
|
newAnswers.push(optionId)
|
||||||
|
} else if (question.answers.includes(selectOption.id)) {
|
||||||
newAnswers.push(
|
newAnswers.push(
|
||||||
...question.answers.filter(answer => answer !== selectOption.id)
|
...question.answers.filter(answer => answer !== selectOption.id)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte";
|
|
||||||
import PageNav from "../../../PageNav/index.svelte";
|
import PageNav from "../../../PageNav/index.svelte";
|
||||||
import Classwork from "./Classwork.svelte";
|
import Classwork from "./Classwork.svelte";
|
||||||
import Homework from "./Homework/index.svelte";
|
import Homework from "./Homework/index.svelte";
|
||||||
@@ -9,10 +8,6 @@
|
|||||||
export let path;
|
export let path;
|
||||||
export let tab;
|
export let tab;
|
||||||
export let showLectureHome;
|
export let showLectureHome;
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
console.log("mounted");
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if showLectureHome}
|
{#if showLectureHome}
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
import { writable } from "svelte/store";
|
|
||||||
|
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
function onClick(optionIndex) {
|
function onClick(optionIndex) {
|
||||||
return () => {
|
return () => {
|
||||||
open = !open;
|
open = !open;
|
||||||
console.log("onClick", optionIndex);
|
|
||||||
handleOptionClick(optionIndex);
|
handleOptionClick(optionIndex);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,15 +4,20 @@
|
|||||||
export let checked;
|
export let checked;
|
||||||
export let name;
|
export let name;
|
||||||
export let isEditable = false;
|
export let isEditable = false;
|
||||||
|
export let disabled = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label class="inline-flex items-center w-full">
|
<label
|
||||||
|
class="inline-flex items-center w-full {disabled
|
||||||
|
? 'cursor-not-allowed'
|
||||||
|
: 'cursor-pointer'}"
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="rounded border-gray-300 text-indigo-600 shadow-sm focus:border-indigo-300 focus:ring focus:ring-offset-0 focus:ring-indigo-200 focus:ring-opacity-50"
|
class="rounded border-gray-300 text-indigo-600 shadow-sm focus:border-indigo-300 focus:ring focus:ring-offset-0 focus:ring-indigo-200 focus:ring-opacity-50"
|
||||||
{name}
|
{name}
|
||||||
{value}
|
{value}
|
||||||
disabled={isEditable}
|
disabled={disabled || isEditable}
|
||||||
bind:checked
|
bind:checked
|
||||||
/>
|
/>
|
||||||
{#if isEditable}
|
{#if isEditable}
|
||||||
|
|||||||
@@ -4,16 +4,21 @@
|
|||||||
export let checked;
|
export let checked;
|
||||||
export let name;
|
export let name;
|
||||||
export let isEditable = false;
|
export let isEditable = false;
|
||||||
|
export let disabled = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label class="inline-flex items-center w-full">
|
<label
|
||||||
|
class="inline-flex items-center w-full {disabled
|
||||||
|
? 'cursor-not-allowed'
|
||||||
|
: 'cursor-pointer'}"
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="form-radio"
|
class="form-radio"
|
||||||
type="radio"
|
type="radio"
|
||||||
{checked}
|
{checked}
|
||||||
{name}
|
{name}
|
||||||
{value}
|
{value}
|
||||||
disabled={isEditable}
|
disabled={disabled || isEditable}
|
||||||
/>
|
/>
|
||||||
{#if isEditable}
|
{#if isEditable}
|
||||||
<input
|
<input
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
export let variant = VARIANTS.CONTAINED;
|
export let variant = VARIANTS.CONTAINED;
|
||||||
export let disablePadding = false;
|
export let disablePadding = false;
|
||||||
export let isDisabled = false;
|
export let isDisabled = false;
|
||||||
|
|
||||||
const variantClass = VARIANTS_CLASS[variant];
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="{isDisabled &&
|
class="{isDisabled &&
|
||||||
'bg-opacity-25 hover:bg-opacity-25 cursor-not-allowed'} flex items-center h-auto {variantClass} {!disablePadding &&
|
'bg-opacity-25 hover:bg-opacity-25 cursor-not-allowed'} flex items-center h-auto {VARIANTS_CLASS[
|
||||||
|
variant
|
||||||
|
]} {!disablePadding &&
|
||||||
'py-1 px-5'} rounded {className} transition delay-150 duration-300 ease-in-out "
|
'py-1 px-5'} rounded {className} transition delay-150 duration-300 ease-in-out "
|
||||||
on:click={onClick}
|
on:click={onClick}
|
||||||
{name}
|
{name}
|
||||||
|
|||||||
@@ -8,20 +8,21 @@
|
|||||||
export let code;
|
export let code;
|
||||||
export let name = "";
|
export let name = "";
|
||||||
export let options = [];
|
export let options = [];
|
||||||
|
export let answers = [];
|
||||||
export let onSubmit = () => {};
|
export let onSubmit = () => {};
|
||||||
export let onPrevious = () => {};
|
export let onPrevious = () => {};
|
||||||
export let defaultValue = [];
|
export let defaultValue = [];
|
||||||
export let disablePreviousButton = false;
|
export let disablePreviousButton = false;
|
||||||
export let isLast = false;
|
|
||||||
export let isPreview = false;
|
export let isPreview = false;
|
||||||
|
export let nextButtonProps = {};
|
||||||
|
|
||||||
function getRadioVal(form, name) {
|
function getVal(form, name) {
|
||||||
let values = [];
|
let values = [];
|
||||||
const radios = form.elements[name];
|
const checkboxEl = form.elements[name];
|
||||||
|
|
||||||
for (let i = 0, len = radios.length; i < len; i++) {
|
for (let i = 0, len = checkboxEl.length; i < len; i++) {
|
||||||
if (radios[i].checked) {
|
if (checkboxEl[i].checked) {
|
||||||
values.push(radios[i].value);
|
values.push(checkboxEl[i].value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,15 +31,27 @@
|
|||||||
|
|
||||||
function handleFormSubmit(event) {
|
function handleFormSubmit(event) {
|
||||||
if (isPreview) return;
|
if (isPreview) return;
|
||||||
const values = getRadioVal(event.target, name);
|
const values = getVal(event.target, name);
|
||||||
onSubmit(name, values);
|
onSubmit(name, values);
|
||||||
event.target.reset();
|
// event.target.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePrevious(event) {
|
function handlePrevious(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
onPrevious();
|
onPrevious();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getValidationClassName(option) {
|
||||||
|
if (defaultValue.includes(option.id)) {
|
||||||
|
if (answers.includes(option.id)) {
|
||||||
|
return "border-green-700";
|
||||||
|
} else {
|
||||||
|
return "border-red-700";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form on:submit|preventDefault={handleFormSubmit}>
|
<form on:submit|preventDefault={handleFormSubmit}>
|
||||||
@@ -51,14 +64,17 @@
|
|||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
{#each options as option}
|
{#each options as option}
|
||||||
<button
|
<button
|
||||||
class="cursor-pointer text-left my-2 border border-gray-300 p-2 rounded-md cursor-pointer hover:bg-gray-200 w-full"
|
class="cursor-pointer text-left my-2 border-2 border-gray-300 p-2 rounded-md cursor-pointer hover:bg-gray-200 w-full {getValidationClassName(
|
||||||
|
option
|
||||||
|
)}"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
{name}
|
{name}
|
||||||
value={option.value}
|
value={option.id}
|
||||||
checked={defaultValue.includes(option.value)}
|
checked={defaultValue.includes(option.id)}
|
||||||
label={option.label || option.value}
|
label={option.label || option.value}
|
||||||
|
disabled={nextButtonProps.disableOptionSelect}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
{/each}
|
{/each}
|
||||||
@@ -72,9 +88,11 @@
|
|||||||
variant={VARIANTS.OUTLINED}
|
variant={VARIANTS.OUTLINED}
|
||||||
/>
|
/>
|
||||||
<PrimaryButton
|
<PrimaryButton
|
||||||
variant={VARIANTS.OUTLINED}
|
variant={nextButtonProps.isActive
|
||||||
|
? VARIANTS.CONTAINED
|
||||||
|
: VARIANTS.OUTLINED}
|
||||||
type="submit"
|
type="submit"
|
||||||
label={isLast ? "Finish" : "Next"}
|
label={nextButtonProps.label}
|
||||||
{name}
|
{name}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,12 +8,13 @@
|
|||||||
export let code;
|
export let code;
|
||||||
export let name = "";
|
export let name = "";
|
||||||
export let options = [];
|
export let options = [];
|
||||||
|
export let answers = [];
|
||||||
export let onSubmit = () => {};
|
export let onSubmit = () => {};
|
||||||
export let onPrevious = () => {};
|
export let onPrevious = () => {};
|
||||||
export let defaultValue = "";
|
export let defaultValue = "";
|
||||||
export let disablePreviousButton = false;
|
export let disablePreviousButton = false;
|
||||||
export let isLast = false;
|
|
||||||
export let isPreview = false;
|
export let isPreview = false;
|
||||||
|
export let nextButtonProps = {};
|
||||||
|
|
||||||
function getRadioVal(form, name) {
|
function getRadioVal(form, name) {
|
||||||
let val;
|
let val;
|
||||||
@@ -31,14 +32,26 @@
|
|||||||
function handleFormSubmit(event) {
|
function handleFormSubmit(event) {
|
||||||
if (isPreview) return;
|
if (isPreview) return;
|
||||||
const value = getRadioVal(event.target, name);
|
const value = getRadioVal(event.target, name);
|
||||||
onSubmit(name, value);
|
onSubmit(name, [value]);
|
||||||
event.target.reset();
|
// event.target.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePrevious(event) {
|
function handlePrevious(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
onPrevious();
|
onPrevious();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getValidationClassName(option) {
|
||||||
|
if (defaultValue.includes(option.id)) {
|
||||||
|
if (answers.includes(option.id)) {
|
||||||
|
return "border-green-700";
|
||||||
|
} else {
|
||||||
|
return "border-red-700";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form on:submit|preventDefault={handleFormSubmit}>
|
<form on:submit|preventDefault={handleFormSubmit}>
|
||||||
@@ -51,14 +64,18 @@
|
|||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
{#each options as option}
|
{#each options as option}
|
||||||
<button
|
<button
|
||||||
class="cursor-pointer text-left my-2 border border-gray-300 p-2 rounded-md cursor-pointer hover:bg-gray-200 w-full"
|
class="cursor-pointer text-left my-2 border-2 border-gray-300 p-2 rounded-md cursor-pointer hover:bg-gray-200 w-full {getValidationClassName(
|
||||||
|
option
|
||||||
|
)}"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<RadioItem
|
<RadioItem
|
||||||
{name}
|
{name}
|
||||||
value={option.value}
|
value={option.id}
|
||||||
checked={option.value === defaultValue}
|
checked={defaultValue.includes(option.id) &&
|
||||||
|
answers.includes(option.id)}
|
||||||
label={option.label || option.value}
|
label={option.label || option.value}
|
||||||
|
disabled={nextButtonProps.disableOptionSelect}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
{/each}
|
{/each}
|
||||||
@@ -73,9 +90,11 @@
|
|||||||
variant={VARIANTS.OUTLINED}
|
variant={VARIANTS.OUTLINED}
|
||||||
/>
|
/>
|
||||||
<PrimaryButton
|
<PrimaryButton
|
||||||
variant={VARIANTS.OUTLINED}
|
variant={nextButtonProps.isActive
|
||||||
|
? VARIANTS.CONTAINED
|
||||||
|
: VARIANTS.OUTLINED}
|
||||||
type="submit"
|
type="submit"
|
||||||
label={isLast ? "Finish" : "Next"}
|
label={nextButtonProps.label}
|
||||||
{name}
|
{name}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,12 +13,13 @@
|
|||||||
export let disablePreviousButton = false;
|
export let disablePreviousButton = false;
|
||||||
export let isLast = false;
|
export let isLast = false;
|
||||||
export let isPreview = false;
|
export let isPreview = false;
|
||||||
|
export let disabled = false;
|
||||||
|
|
||||||
function handleFormSubmit(event) {
|
function handleFormSubmit(event) {
|
||||||
if (isPreview) return;
|
if (isPreview) return;
|
||||||
|
|
||||||
onSubmit(name, defaultValue);
|
onSubmit(name, defaultValue);
|
||||||
event.target.reset();
|
// event.target.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePrevious(event) {
|
function handlePrevious(event) {
|
||||||
@@ -35,11 +36,15 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<TextArea
|
{#if disabled}
|
||||||
bind:value={defaultValue}
|
<CodeSnippet code={defaultValue} />
|
||||||
rows="5"
|
{:else}
|
||||||
placeholder="Write your answer here"
|
<TextArea
|
||||||
/>
|
bind:value={defaultValue}
|
||||||
|
rows="5"
|
||||||
|
placeholder="Write your answer here"
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if !isPreview}
|
{#if !isPreview}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export function removeDuplicate(arr) {
|
||||||
|
let s = new Set(arr);
|
||||||
|
let it = s.values();
|
||||||
|
return Array.from(it);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user