Complete questionnaire builder

This commit is contained in:
rotimi-best
2021-06-26 21:32:42 +03:00
parent deb445b694
commit 445858f4bb
14 changed files with 269 additions and 254 deletions
@@ -3,38 +3,34 @@
import AddFilled24 from "carbon-icons-svelte/lib/AddFilled24";
import TextField from "../../../../Form/TextField.svelte";
import TextArea from "../../../../Form/TextArea.svelte";
import Checkbox from "../../../../Form/Checkbox.svelte";
import RadioItem from "../../../../Form/RadioItem.svelte";
import IconButton from "../../../../IconButton/index.svelte";
import Select from "../../../../Form/Select.svelte";
import PrimaryButton from "../../../../PrimaryButton/index.svelte";
import { VARIANTS } from "../../../../PrimaryButton/constants";
import QuestionContainer from "../../../../QuestionContainer/index.svelte";
import {
QUESTION_TYPE,
QUESTION_TYPES,
QUESTION_TEMPLATE,
} from "../../../../Question/constants";
// import EditContent from "../../../../EditContent/index.svelte";
// import readme from "../../readme.js";
// let value = readme;
let questions = [
{
id: 1,
title: "",
type: QUESTION_TYPE.RADIO,
options: [
{
id: 1,
value: "",
},
],
},
];
let task = {
title: "",
description: null,
};
let questions = [];
function handleAddOption(id) {
function handleAddOption(questionId) {
return () => {
questions = questions.map((question) => {
if (question.id === id) {
if (question.id === questionId) {
return {
...question,
options: [
@@ -73,78 +69,108 @@
questions = [
...questions,
{
...QUESTION_TEMPLATE,
id: questions.length + 1,
title: "",
type: QUESTION_TYPE.RADIO,
options: [
{
id: 1,
value: "",
},
],
},
];
}
function handleRemoveQuestion(questionId) {
return () => {
questions = questions.filter((q) => q.id !== questionId);
};
}
</script>
{#each questions as question}
<div
class="border-2 border-gray border-r-2 rounded-md px-4 py-2 mb-4 w-3/5 inline-block"
>
<div class="flex">
<div class="mr-2">
<TextField placeholder="Question" bind:value={question.title} />
</div>
<Select bind:value={question.type} options={QUESTION_TYPES} />
</div>
<div class="flex flex-col">
{#each question.options as option}
{#if QUESTION_TYPE.RADIO === question.type}
<RadioItem
isEditable={true}
name={question.title || "radio-name"}
bind:label={option.value}
>
<div slot="iconbutton">
<IconButton
value={option.id}
onClick={handleOptionRemove(question.id, option.id)}
>
<Delete24 class="carbon-icon" />
</IconButton>
</div>
</RadioItem>
{/if}
{#if QUESTION_TYPE.CHECKBOX === question.type}
<Checkbox
isEditable={true}
name={question || "checkbox-name"}
bind:label={option.value}
>
<div slot="iconbutton">
<IconButton
value={option.id}
onClick={handleOptionRemove(question.id)}
>
<Delete24 class="carbon-icon" />
</IconButton>
</div>
</Checkbox>
{/if}
{/each}
</div>
<div class="flex items-center">
<IconButton onClick={handleAddOption(question.id)}>
<AddFilled24 class="carbon-icon" />
</IconButton>
<p class="italic">Add option</p>
</div>
<div class="root relative">
<div class="head flex bg-white items-center justify-between sticky right-0">
<h3>Home task</h3>
<PrimaryButton
variant={VARIANTS.OUTLINED}
onClick={handleAddQuestion}
label="Add Question"
/>
</div>
{/each}
<div class="flex justify-end mt-2">
<PrimaryButton onClick={handleAddQuestion} label="Add Question" />
<QuestionContainer isTitle={true}>
<TextField placeholder="Title" bind:value={task.title} />
<TextArea
placeholder="Description and Rules"
bind:value={task.description}
/>
</QuestionContainer>
{#each questions as question}
<QuestionContainer onClose={handleRemoveQuestion(question.id)}>
<div class="flex justify-between">
<div class="mr-2 w-3/5">
<TextField placeholder="Question" bind:value={question.title} />
</div>
<Select bind:value={question.type} options={QUESTION_TYPES} />
</div>
<div class="flex flex-col">
{#each question.options as option}
{#if QUESTION_TYPE.RADIO === question.type}
<RadioItem
isEditable={true}
name={question.title || "radio-name"}
bind:label={option.value}
>
<div slot="iconbutton">
<IconButton
value={option.id}
onClick={handleOptionRemove(question.id, option.id)}
>
<Delete24 class="carbon-icon" />
</IconButton>
</div>
</RadioItem>
{/if}
{#if QUESTION_TYPE.CHECKBOX === question.type}
<Checkbox
isEditable={true}
name={question || "checkbox-name"}
bind:label={option.value}
>
<div slot="iconbutton">
<IconButton
value={option.id}
onClick={handleOptionRemove(question.id)}
>
<Delete24 class="carbon-icon" />
</IconButton>
</div>
</Checkbox>
{/if}
{#if QUESTION_TYPE.TEXTAREA === question.type}
<TextArea bind:value={option.value} />
{/if}
{/each}
</div>
{#if QUESTION_TYPE.TEXTAREA !== question.type}
<div class="flex items-center">
<IconButton onClick={handleAddOption(question.id)}>
<AddFilled24 class="carbon-icon" />
</IconButton>
<p class="italic">Add option</p>
</div>
{/if}
</QuestionContainer>
{/each}
</div>
<style>
.root {
max-width: 700px;
}
.head {
top: 63px;
z-index: 2;
}
</style>
@@ -1,94 +0,0 @@
<script>
import marked from "marked";
import PrimaryButton from "../../../PrimaryButton/index.svelte";
import readme from "../readme.js";
let isWriteMode = true;
export let value = readme;
export let placeholder = ``;
const activeClassName = "border-b-2 border-blue-700";
const handleTabClick = (tab) => (event) => {
isWriteMode = tab === 1;
};
</script>
<div class="root">
<div class="flex justify-center">
<button
on:click={handleTabClick(1)}
class="focus:outline-none p-2 {isWriteMode && `${activeClassName}`}"
>
Write
</button>
<button
on:click={handleTabClick(2)}
class="focus:outline-none p-2 {!isWriteMode && `${activeClassName}`}"
>
Preview
</button>
</div>
<div class="m-2 mb-0 p-0">
{#if isWriteMode}
<textarea
bind:value
{placeholder}
class="border border-gray rounded-md p-2"
/>
{:else}
<article class="preview prose prose-sm sm:prose p-2">
{@html marked(value)}
</article>
{/if}
</div>
{#if !isWriteMode}
<hr />
{/if}
<div class="flex justify-between items-center px-2 pb-1">
<div class="flex items-center text-sm">
<svg
class="octicon mr-2"
height="16"
viewBox="0 0 16 16"
version="1.1"
width="16"
aria-hidden="true"
>
<path
fill-rule="evenodd"
d="M14.85 3H1.15C.52 3 0 3.52 0 4.15v7.69C0 12.48.52 13 1.15 13h13.69c.64 0 1.15-.52 1.15-1.15v-7.7C16 3.52 15.48 3 14.85 3zM9 11H7V8L5.5 9.92 4 8v3H2V5h2l1.5 2L7 5h2v6zm2.99.5L9.5 8H11V5h2v3h1.5l-2.51 3.5z"
/>
</svg>
<span>Styling with Markdown is supported</span>
</div>
<PrimaryButton label="Answer" />
</div>
</div>
<!-- {@html marked(readme, {
breaks: true,
gfm: true,
})} -->
<style>
.root {
width: 100%;
min-height: 200px;
}
textarea {
width: 100%;
height: 500px;
}
.preview {
min-height: 150px;
}
.octicon {
display: inline-block;
vertical-align: text-top;
fill: currentColor;
}
</style>
@@ -49,7 +49,7 @@
</div>
</PageNav>
<div class="course">
<div class="course relative">
{#if tab === "lectures"}
<Readme {mode} />
{:else if tab === "classwork"}