feat: [frontend] Start to play around with Flashcard creation UI

This commit is contained in:
wilson 2026-05-03 13:32:26 +01:00
parent f463454e8e
commit 170f851344
3 changed files with 109 additions and 0 deletions

View file

@ -0,0 +1,45 @@
<script lang="ts">
interface Props {
promptText: string;
correctAnswers: string[];
}
let { promptText, correctAnswers }: Props = $props();
let mode: 'guess' | 'reveal' = 'reveal';
</script>
<section class="flashcard">
<div class="prompt-text">
<p class="prompt-text__text">{promptText}</p>
</div>
<div class="answer-text">
<label for="answer" class="label">Answer</label>
<input type="text" id="answer" class="input" />
</div>
{#if mode === 'reveal'}
<div class="correct-answers">
<p class="correct-answers__label">Correct Answers:</p>
<ul class="correct-answers__list">
{#each correctAnswers as answer}
<li class="correct-answers__item">{answer}</li>
{/each}
</ul>
</div>
{/if}
</section>
<style>
.flashcard {
padding: var(--space-1);
display: grid;
grid-template-columns: 1fr;
place-items: center;
max-width: 500px;
border: 1px solid var(--colour-grey-300);
}
.prompt-text {
}
</style>

View file

@ -0,0 +1,6 @@
<script>
import FlashcardForm from './FlashcardForm.svelte';
</script>
<h1>New Flashcard</h1>
<FlashcardForm />

View file

@ -0,0 +1,58 @@
<script lang="ts">
import Flashcard from '$lib/components/Flashcard.svelte';
import {
dictionarySearch,
type DictionarySearchResult
} from '../../admin/dictionary-search/dictionarySearch.remote';
let dictionarySearchDebouncer: NodeJS.Timeout | null = null;
let dictionarySearchTerm = $state('');
let promptText = $state('bonjour');
let answerText = $state('hello');
let dictionarySearchResults: DictionarySearchResult[] = $state([]);
let correctAnswers = $derived(
answerText
.split(',')
.map((t) => t.trim())
.filter((t) => t.length)
);
$effect(() => {
if (dictionarySearchDebouncer) {
clearTimeout(dictionarySearchDebouncer);
}
dictionarySearchDebouncer = setTimeout(() => {
dictionarySearch({ langCode: 'fr', text: dictionarySearchTerm }).then((results) => {
dictionarySearchResults = results;
});
}, 500);
});
</script>
<div class="form-container">
<form class="form">
<div class="field">
<label for="target_word">French Word</label>
<input type="text" id="target_word" name="target_word" bind:value={dictionarySearchTerm} />
</div>
<div class="field">
<label for="prompt_text">Prompt Text</label>
<input type="text" id="prompt_text" name="prompt_text" bind:value={promptText} />
</div>
<div class="field">
<label for="answer_text">Answers (comma separated)</label>
<input type="text" id="answer_text" name="answer_text" bind:value={answerText} />
</div>
</form>
</div>
<Flashcard {promptText} {correctAnswers} />
<style>
.form-container {
max-width: 500px;
}
</style>