feat: [frontend] Start to play around with Flashcard creation UI
This commit is contained in:
parent
f463454e8e
commit
170f851344
3 changed files with 109 additions and 0 deletions
45
frontend/src/lib/components/Flashcard.svelte
Normal file
45
frontend/src/lib/components/Flashcard.svelte
Normal 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>
|
||||
6
frontend/src/routes/app/flashcards/new/+page.svelte
Normal file
6
frontend/src/routes/app/flashcards/new/+page.svelte
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<script>
|
||||
import FlashcardForm from './FlashcardForm.svelte';
|
||||
</script>
|
||||
|
||||
<h1>New Flashcard</h1>
|
||||
<FlashcardForm />
|
||||
58
frontend/src/routes/app/flashcards/new/FlashcardForm.svelte
Normal file
58
frontend/src/routes/app/flashcards/new/FlashcardForm.svelte
Normal 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>
|
||||
Loading…
Reference in a new issue