Skip to content

Commit 87c6925

Browse files
author
Joshua Stübner
committed
feat: add more fields to question editor
1 parent 1689534 commit 87c6925

10 files changed

Lines changed: 294 additions & 252 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ Feel free to check them out or use them, if they're useful to you.
5151
- https://www.getpliant.com/de/ * clean
5252
- https://www.klimate.co/ * clean, techie
5353
- https://kraa.io/kraa/examples/echolibrary * clean, black/white
54+
- https://humanebydesign.com/principles/resilient/
5455

5556
### Icons
5657

apps/questionnaire/src/lib/editor/components/EditorForm.svelte

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script lang="ts">
2-
import { Input, MarkdownEditor } from '@nordcode/forms-svelte';
2+
import { Input } from '@nordcode/forms-svelte';
3+
import { MarkdownEditor } from '@nordcode/forms-svelte/markdown';
34
import { Navigation } from '../../common/config/Navigation';
45
import { currentQuestionnaire, NEW_QUESTION_ID } from '../editorStore';
56
import { createDataUrl } from '../utils/createDataUrl';
@@ -19,7 +20,7 @@ const createQuestionnaire = async (event: SubmitEvent) => {
1920
return;
2021
}
2122
22-
const cleanQuestionnaire = await finaliseQuestionnaire($currentQuestionnaire.questionnaire);
23+
const cleanQuestionnaire = await finaliseQuestionnaire({ ...$currentQuestionnaire.questionnaire });
2324
download = {
2425
dataUri: createDataUrl(cleanQuestionnaire),
2526
title: encodeURI(cleanQuestionnaire.title),
@@ -63,10 +64,27 @@ const orderedQuestions = $derived.by(() => {
6364
label="Fragebogen Beschreibung"
6465
id="description"
6566
hint="Markdown wird unterstützt."
66-
optional={true}
6767
bind:value={$currentQuestionnaire.questionnaire.description}
6868
/>
6969

70+
<MarkdownEditor
71+
errors={$currentQuestionnaire.errors.summaryText}
72+
name="summaryText"
73+
label="Fragebogen Abschlusstest"
74+
id="summaryText"
75+
hint="Markdown wird unterstützt."
76+
bind:value={$currentQuestionnaire.questionnaire.summaryText}
77+
/>
78+
79+
<Input
80+
errors={$currentQuestionnaire.errors.finalCTA}
81+
name="finalCTA"
82+
label="Fragenbogen Abschluss Call to Action"
83+
id="finalCTA"
84+
type="text"
85+
bind:value={$currentQuestionnaire.questionnaire.finalCTA}
86+
/>
87+
7088
<fieldset class="nc-fieldset" style="inline-size: 100%">
7189
<legend class="nc-legend">Fragen</legend>
7290
<div class="nc-stack">

apps/questionnaire/src/lib/editor/components/NextQuestionEditor.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ const createNewQuestion = () => {
118118
label="Gesonderte Reihenfolge festlegen?"
119119
hint="Hier kannst du pro Option eine gezielte Folgefrage festlegen"
120120
bind:checked={enableCustomOrder}
121-
optional
121+
required={false}
122122
></SwitchInput>
123123
{#if enableCustomOrder}
124124
{#each options as option}
@@ -135,7 +135,7 @@ const createNewQuestion = () => {
135135
option.value,
136136
(event?.target as HTMLInputElement).value,
137137
)}
138-
optional
138+
required={false}
139139
></Select>
140140
</div>
141141
</div>

apps/questionnaire/src/lib/editor/components/OptionsEditor.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const removeOption = (optionId: string) => {
4848
name={`option-${option.id}-description`}
4949
label="Beschreibung"
5050
id={`option-${option.id}-description`}
51-
optional
51+
required={false}
5252
bind:value={option.description}
5353
/>
5454
</div>

apps/questionnaire/src/lib/editor/components/QuestionEditor.svelte

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script lang="ts">
2-
import { Input, MarkdownEditor, Select, TextArea } from '@nordcode/forms-svelte';
2+
import { CheckboxInput, Input, Select, TextArea } from '@nordcode/forms-svelte';
3+
import { MarkdownEditor } from '@nordcode/forms-svelte/markdown';
34
import { type Question, QuestionType } from '@nordcode/questionnaire-renderer';
45
import { questionHasOptions } from '@nordcode/questionnaire-renderer';
56
import { Navigation } from '../../common/config/Navigation';
@@ -21,6 +22,11 @@ export const availableTypesRecord: Record<QuestionType, string> = {
2122
[QuestionType.multiple_choice]: 'Multiple Choice',
2223
[QuestionType.single_choice]: 'Single Choice',
2324
[QuestionType.number]: 'Zahl',
25+
[QuestionType.date_time]: 'Datum & Uhrzeit',
26+
[QuestionType.date]: 'Datum',
27+
[QuestionType.image]: 'Bild',
28+
[QuestionType.email]: 'E-Mail',
29+
[QuestionType.phone]: 'Telefon',
2430
};
2531
2632
export const availableTypes = Object.entries(availableTypesRecord).map(([key, value]) => ({
@@ -68,24 +74,41 @@ $effect(() => {
6874
bind:value={questionUpdate.type}
6975
options={availableTypes}
7076
></Select>
77+
7178
<MarkdownEditor
7279
name={`question-${questionUpdate.id}-description`}
7380
label={'Beschreibung'}
7481
hint={'Markdown wird unterstützt.'}
7582
id={`question-${questionUpdate.id}-description`}
76-
optional={true}
83+
required={false}
7784
bind:value={questionUpdate.description}
7885
></MarkdownEditor>
7986

87+
<Input
88+
name={`question-${questionUpdate.id}-label`}
89+
label="Label"
90+
id={`question-${questionUpdate.id}-label`}
91+
bind:value={questionUpdate.label}
92+
/>
93+
8094
<TextArea
8195
name={`question-${questionUpdate.id}-hint`}
8296
id={`question-${questionUpdate.id}-hint`}
8397
label={'Hinweis'}
8498
hint={'Ein Hinweis, wie die Frage gemeint oder zu beantworten ist'}
85-
optional={true}
99+
required={false}
86100
bind:value={questionUpdate.hint}
87101
splitLines={false}
88102
></TextArea>
103+
104+
<CheckboxInput
105+
label="Als Pflichtfrage markieren"
106+
name={`question-${questionUpdate.id}-required`}
107+
id={`question-${questionUpdate.id}-required`}
108+
required={false}
109+
bind:checked={questionUpdate.required}
110+
>
111+
</CheckboxInput>
89112
{#if questionHasOptions(questionUpdate)}
90113
<OptionsEditor bind:options={questionUpdate.options}></OptionsEditor>
91114
{/if}

apps/questionnaire/src/lib/editor/components/QuestionLink.svelte

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ const onDragStart = (event: DragEvent) => {
2828
document.documentElement.style.cursor = 'grabbing';
2929
event.dataTransfer.setData('application/question-id', question.id);
3030
event.dataTransfer.setDragImage(dragImage, 0, 0);
31-
// event.dataTransfer.effectAllowed = 'move';
3231
};
3332
3433
const onDragEnd = (event: DragEvent) => {
@@ -149,51 +148,69 @@ const onDrop = (event: DragEvent) => {
149148
ondragstart={onDragStart}
150149
ondragend={onDragEnd}
151150
draggable="true"
151+
role="cell"
152152
>
153-
<svg
154-
xmlns="http://www.w3.org/2000/svg"
155-
viewBox="0 0 24 24"
156-
fill="none"
157-
stroke="currentColor"
158-
stroke-width="2"
159-
stroke-linecap="round"
160-
stroke-linejoin="round"
161-
class="nc-icon"
162-
data-size="inline"
163-
aria-hidden="true"
164-
>
165-
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
166-
<path d="M9 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
167-
<path d="M9 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
168-
<path d="M9 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
169-
<path d="M15 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
170-
<path d="M15 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
171-
<path d="M15 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
153+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="nc-icon" data-size="inline">
154+
<title>Frage verschieben</title>
155+
<path
156+
stroke="currentColor"
157+
stroke-linecap="round"
158+
stroke-width="4"
159+
d="M8.025 4.75h-.05M16.025 4.75h-.05M8.025 12h-.05M16.025 12h-.05M8.025 19.25h-.05M16.025 19.25h-.05"
160+
/>
172161
</svg>
173-
<span class="sr-only">Frage verschieben</span>
174162
</div>
175163
</td>
176164
<td>
177165
<span class="nc-cluster -near -centered">
178166
<a href={questionLink}>{question.title}</a>
167+
{#if question.required}
168+
<svg
169+
xmlns="http://www.w3.org/2000/svg"
170+
fill="none"
171+
viewBox="0 0 24 24"
172+
class="nc-icon"
173+
data-size="inline"
174+
style="color: var(--color-brand-primary-base)"
175+
>
176+
<title>Required</title>
177+
<path
178+
stroke="currentColor"
179+
stroke-linecap="round"
180+
stroke-width="3"
181+
d="M12 2v20M3.34 7l17.32 10M3.34 17 20.66 7"
182+
/>
183+
</svg>
184+
{/if}
179185
{#if question.next?.length}
180186
<svg
181187
xmlns="http://www.w3.org/2000/svg"
188+
fill="none"
182189
viewBox="0 0 24 24"
183-
stroke="var(--color-brand-primary-base)"
184-
stroke-width="2"
185-
stroke-linecap="round"
186-
stroke-linejoin="round"
187190
class="nc-icon"
188191
data-size="inline"
192+
style="color: var(--color-brand-primary-base)"
189193
>
190194
<title>Geänderte Reihenfolge</title>
191-
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
192-
<path d="M16 21h3c.81 0 1.48 -.67 1.48 -1.48l.02 -.02c0 -.82 -.69 -1.5 -1.5 -1.5h-3v3z" />
193-
<path d="M16 15h2.5c.84 -.01 1.5 .66 1.5 1.5s-.66 1.5 -1.5 1.5h-2.5v-3z" />
194-
<path d="M4 9v-4c0 -1.036 .895 -2 2 -2s2 .964 2 2v4" />
195-
<path d="M2.99 11.98a9 9 0 0 0 9 9m9 -9a9 9 0 0 0 -9 -9" />
196-
<path d="M8 7h-4" />
195+
<path
196+
stroke="currentColor"
197+
stroke-linecap="round"
198+
stroke-width="3"
199+
d="m17.75 9 2.651-2.651c.297-.297.446-.446.502-.617a.75.75 0 0 0 0-.464c-.056-.171-.204-.32-.502-.617L17.75 2"
200+
/>
201+
<path
202+
stroke="currentColor"
203+
stroke-linecap="round"
204+
stroke-linejoin="bevel"
205+
stroke-width="3"
206+
d="M3.5 10.5v-.2c0-1.68 0-2.52.327-3.162a3 3 0 0 1 1.311-1.311C5.78 5.5 6.62 5.5 8.3 5.5h11.95m.25 8v.2c0 1.68 0 2.52-.327 3.162a3 3 0 0 1-1.311 1.311c-.642.327-1.482.327-3.162.327H3.75"
207+
/>
208+
<path
209+
stroke="currentColor"
210+
stroke-linecap="round"
211+
stroke-width="3"
212+
d="m6.25 15-2.651 2.651c-.297.297-.446.446-.502.617a.75.75 0 0 0 0 .464c.056.171.205.32.502.617L6.25 22"
213+
/>
197214
</svg>
198215
{/if}
199216
</span>

apps/questionnaire/src/lib/editor/utils/finaliseQuestionnaire.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ export const finaliseQuestionnaire = async (questionnaire: Questionnaire) => {
2121
return {
2222
...questionnaire,
2323
description: questionnaire.description ? convertToHtml(questionnaire.description) : '',
24-
questions: cleanupQuestions(questionnaire.questions),
24+
questions: cleanupQuestions(structuredClone(questionnaire.questions)),
2525
};
2626
};

apps/questionnaire/src/routes/+layout.svelte

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,10 @@ main {
2525
/* padding-block-start: 90px; equals <Navigation> block-size */
2626
min-block-size: 100dvh;
2727
}
28+
29+
:global {
30+
.nc-form {
31+
inline-size: min(100%, 60rem);
32+
}
33+
}
2834
</style>

apps/questionnaire/src/routes/editor/question/[id]/+page.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script lang="ts">
22
import QuestionEditor from '$lib/editor/components/QuestionEditor.svelte';
33
import { currentQuestionnaire } from '$lib/editor/editorStore';
4-
import { createNewQuestion, NEW_QUESTION_ID } from '../../../../lib/editor/editorStore';
4+
import { createNewQuestion, NEW_QUESTION_ID } from '$lib/editor/editorStore';
55
66
interface PageData {
77
data: {

0 commit comments

Comments
 (0)