feat: home view and list per url
This commit is contained in:
@@ -16,8 +16,10 @@
|
||||
- [x] change lang
|
||||
- [x] toasts
|
||||
- [x] handle errors
|
||||
- [ ] list per URL
|
||||
- [ ] home screen
|
||||
- [x] list per URL
|
||||
- [x] home screen
|
||||
- [ ] share link
|
||||
- [ ] fill new list with "fill todo" item
|
||||
- [x] lang in cookies
|
||||
- [ ] simple view
|
||||
- [ ] Dockerfile
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"cron-parser": "^5.6.2",
|
||||
"date-fns": "^4.4.0",
|
||||
"pinia": "^3.0.4",
|
||||
"random-word-slugs": "^0.1.7",
|
||||
"vue": "^3.5.39",
|
||||
"vue-i18n": "^11.4.6",
|
||||
"vue-router": "^5.1.0",
|
||||
@@ -715,6 +716,8 @@
|
||||
|
||||
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
||||
|
||||
"random-word-slugs": ["random-word-slugs@0.1.7", "", {}, "sha512-8cyzxOIDeLFvwSPTgCItMXHGT5ZPkjhuFKUTww06Xg1dNMXuGxIKlARvS7upk6JXIm41ZKXmtlKR1iCRWklKmg=="],
|
||||
|
||||
"read-package-json-fast": ["read-package-json-fast@4.0.0", "", { "dependencies": { "json-parse-even-better-errors": "^4.0.0", "npm-normalize-package-bin": "^4.0.0" } }, "sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg=="],
|
||||
|
||||
"readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="],
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"cron-parser": "^5.6.2",
|
||||
"date-fns": "^4.4.0",
|
||||
"pinia": "^3.0.4",
|
||||
"random-word-slugs": "^0.1.7",
|
||||
"vue": "^3.5.39",
|
||||
"vue-i18n": "^11.4.6",
|
||||
"vue-router": "^5.1.0"
|
||||
|
||||
@@ -71,5 +71,7 @@
|
||||
"task_delete_error": "Could not delete task"
|
||||
},
|
||||
"not_found": "Looks like there's nothing here...",
|
||||
"not_found_button": "Go back to familiar territory"
|
||||
"not_found_button": "Go back to familiar territory",
|
||||
"home": "A shareable task list with auto resetting items.<br/>Create your list below.",
|
||||
"home_button": "Let's go !"
|
||||
}
|
||||
|
||||
@@ -71,5 +71,7 @@
|
||||
"task_delete_error": "Impossible de supprimer la tâche"
|
||||
},
|
||||
"not_found": "On dirait qu'il n'y a rien ici...",
|
||||
"not_found_button": "Retour en terrain connu"
|
||||
"not_found_button": "Retour en terrain connu",
|
||||
"home": "Une liste de tâches avec réinitialisation automatique des éléments.<br/>Créez ta liste ci-dessous.",
|
||||
"home_button": "C'est parti !"
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: [
|
||||
{ path: "/", component: HomeView },
|
||||
{ path: "/:pathMatch([\\w-]+)", component: ListView },
|
||||
{ path: "/:list", component: ListView },
|
||||
{ path: "/:pathMatch(.*)", component: NotFoundView },
|
||||
],
|
||||
});
|
||||
|
||||
@@ -1,3 +1,37 @@
|
||||
<script setup lang="ts">
|
||||
import { ArrowBigRightDashIcon, DicesIcon } from "@lucide/vue";
|
||||
import { generateSlug } from "random-word-slugs";
|
||||
import { ref } from "vue";
|
||||
|
||||
const listNameInput = ref<string>(generateSlug(4));
|
||||
|
||||
function onRandom() {
|
||||
listNameInput.value = generateSlug(4);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
TODO
|
||||
<div class="p-4">
|
||||
<div class="mb-4 italic text-xl font-extralight" v-html="$t('home')">
|
||||
</div>
|
||||
<div class="flex gap-2 mb-4">
|
||||
<input
|
||||
v-model="listNameInput"
|
||||
type="text"
|
||||
:placeholder="$t('new_task_hint')"
|
||||
class="input grow"
|
||||
/>
|
||||
<button
|
||||
class="btn btn-square"
|
||||
@click="onRandom"
|
||||
>
|
||||
<dices-icon />
|
||||
</button>
|
||||
</div>
|
||||
<div class="w-full px-4">
|
||||
<router-link class="btn btn-lg" :to="`/${listNameInput}`">
|
||||
<arrow-big-right-dash-icon class="inline" /> {{ $t('home_button') }}
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -11,10 +11,13 @@ import { SortType } from "@/enums";
|
||||
import { booleanCookieRef, enumCookieRef } from "@/lib/cookies";
|
||||
import { useAlertStore } from "@/stores/alerts";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { onBeforeRouteUpdate, useRoute } from 'vue-router'
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const list = ref<string|null>(null);
|
||||
const taskInput = ref<string>("");
|
||||
const tasks = ref<Task[]>([]);
|
||||
const list = ref<string>("test");
|
||||
|
||||
const sortType = enumCookieRef<SortType>(
|
||||
"toutDouxSortType",
|
||||
@@ -34,6 +37,7 @@ const i18n = useI18n();
|
||||
const { alertSuccess, alertError, alertWarning } = useAlertStore();
|
||||
|
||||
function fetchTasks() {
|
||||
if (list.value) {
|
||||
getTasks(list.value)
|
||||
.then((data: Task[]) => {
|
||||
tasks.value = data;
|
||||
@@ -47,6 +51,7 @@ function fetchTasks() {
|
||||
alertError(i18n.t("alerts.task_fetch_error"));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function reSortTasks() {
|
||||
@@ -54,7 +59,7 @@ function reSortTasks() {
|
||||
}
|
||||
|
||||
function onNewTask() {
|
||||
if (taskInput.value.trim()) {
|
||||
if (taskInput.value.trim() && list.value) {
|
||||
createTask(list.value, {
|
||||
name: taskInput.value.trim(),
|
||||
reset_cron: null,
|
||||
@@ -74,6 +79,7 @@ function onNewTask() {
|
||||
}
|
||||
|
||||
function onCloneTask(task: Task) {
|
||||
if (list.value) {
|
||||
createTask(list.value, {
|
||||
name: task.name,
|
||||
reset_cron: task.reset_cron,
|
||||
@@ -85,6 +91,7 @@ function onCloneTask(task: Task) {
|
||||
.catch(() => {
|
||||
alertError(i18n.t("alerts.task_create_error"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onDeleteTask(task: Task) {
|
||||
@@ -107,7 +114,15 @@ function onChangeSortReverse() {
|
||||
reSortTasks();
|
||||
}
|
||||
|
||||
onBeforeMount(fetchTasks);
|
||||
onBeforeMount(() => {
|
||||
list.value = route.params.list as string;
|
||||
fetchTasks();
|
||||
});
|
||||
|
||||
onBeforeRouteUpdate((to) => {
|
||||
list.value = to.params.list as string;
|
||||
fetchTasks();
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -3,8 +3,10 @@ import { CircleQuestionMarkIcon } from "@lucide/vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="italic text-xl font-extralight mb-2">
|
||||
<div class="italic text-xl font-extralight mb-4">
|
||||
<circle-question-mark-icon class="inline" /> {{ $t('not_found') }}
|
||||
</div>
|
||||
<div class="w-full px-4">
|
||||
<router-link to="/" class="btn mb-4">{{ $t('not_found_button') }}</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user