geriou-bir/frontend/src/routes/ma_geriou/+page.svelte
2023-09-17 21:16:04 +02:00

211 lines
7.1 KiB
Svelte

<script lang="ts">
import { page } from "$app/stores";
import axios from "$lib/api.ts";
import WordForm from "$lib/WordForm.svelte";
import ButtonMain from "$lib/ButtonMain.svelte";
import type { Level, Word } from "../../lib/types";
import { deleteFromArray } from "$lib/arrays";
import { snakeToCamelCase } from "$lib/case";
import { onMount, tick } from "svelte";
import type { AxiosResponse } from "axios";
import { createForm } from "svelte-forms-lib";
import * as yup from "yup";
let words: Word[];
$: words;
let levels: Level[];
let promise;
let promiseLevels;
// Form
const { form, errors, state, handleChange, handleSubmit } = createForm({
initialValues: {
level: "",
word: "",
definition: "",
},
validationSchema: yup.object().shape({
level: yup.number().required(),
word: yup.string().required(),
definition: yup.string().required(),
}),
onSubmit: (values) => {
submitNewWord(values);
},
});
function fetchLevels() {
try {
promiseLevels = axios
.get("levels/")
.then((data) => {
levels = snakeToCamelCase(data.data);
})
.then(() => {
$form.level = levels[0].id.toString();
});
} catch (e) {
console.log(e);
}
}
function fetchData() {
try {
promise = axios.get("words/").then((data) => {
words = snakeToCamelCase(data.data);
});
} catch (e) {
console.log(e);
}
}
let isFormNewShown = false;
function toggleFormNew() {
isFormNewShown = !isFormNewShown;
}
function submitNewWord(values) {
const formData = {
level_id: values.level,
word: values.word,
definition: values.definition,
};
try {
axios
.post("words/", formData)
.then((data) => {
words = [snakeToCamelCase(data.data), ...words];
})
.then(() => {
$form.definition = "";
$form.word = "";
});
} catch (e) {
console.log(e);
}
}
function deleteWord(word: Word) {
if (!(word && word.id)) return;
try {
axios.delete("/words/" + word.id).then(() => {
words = deleteFromArray(words, word);
});
} catch (e) {
console.log(e);
}
}
onMount(() => {
fetchData();
fetchLevels();
window.addEventListener("keyup", (e) => {
if (e.key == "Escape") {
toggleFormNew();
}
});
});
</script>
<main>
{#await promise}
<p></p>
{:then}
<form on:submit={handleSubmit}>
<table class="w-full text-left">
<thead>
<tr
class="bg-slate-100 rounded-lg font-bold text-slate-700 border-separate border-b"
>
<th class="font-bold p-2">Live</th>
<th class="font-bold p-2">Ger</th>
<th class="font-bold p-2">Termenadur</th>
<th />
</tr>
</thead>
<tbody>
{#if !isFormNewShown}
<tr>
<td colspan="4" class="text-center p-2 border-b">
<ButtonMain onClick={toggleFormNew}>
<span
class="fa-regular fa-plus align-top"
/>
</ButtonMain>
</td>
</tr>
{:else}
<tr class="border-b">
<td class="p-2">
<select
id="level"
name="level"
on:change={handleChange}
bind:value={$form.level}
class="p-1 rounded-md border"
>
{#await promiseLevels then}
{#each levels as level}
<option value={level.levelNumber}>
{level.levelString}</option
>
{/each}
{/await}
</select>
{#if $errors.level}
<div class="text-red-500 text-sm">
{$errors.level}
</div>
{/if}
</td>
<td class="p-2">
<input
name="word"
placeholder="Ger"
on:change={handleChange}
bind:value={$form.word}
class="p-1 rounded-md border w-full"
/>
</td>
<td class="p-2">
<input
name="definition"
placeholder="Termenadur"
on:change={handleChange}
bind:value={$form.definition}
class="p-1 rounded-md border w-full"
/>
</td>
<td class="p-2">
<button
type="submit"
class="bg-violet-600 hover:bg-violet-700 rounded-md text-white p-1 w-6 h-6 justify-center"
>
<span
class="fa-regular fa-plus align-top"
/>
</button>
</td>
</tr>
{/if}
{#if words}
{#each words as word}
<WordForm
{...word}
on:deleteWord={deleteWord(word)}
/>
{/each}
{/if}
</tbody>
</table>
</form>
{:catch error}
{error}
{/await}
</main>