feat: home view and list per url
This commit is contained in:
@@ -16,8 +16,10 @@
|
|||||||
- [x] change lang
|
- [x] change lang
|
||||||
- [x] toasts
|
- [x] toasts
|
||||||
- [x] handle errors
|
- [x] handle errors
|
||||||
- [ ] list per URL
|
- [x] list per URL
|
||||||
- [ ] home screen
|
- [x] home screen
|
||||||
|
- [ ] share link
|
||||||
|
- [ ] fill new list with "fill todo" item
|
||||||
- [x] lang in cookies
|
- [x] lang in cookies
|
||||||
- [ ] simple view
|
- [ ] simple view
|
||||||
- [ ] Dockerfile
|
- [ ] Dockerfile
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"cron-parser": "^5.6.2",
|
"cron-parser": "^5.6.2",
|
||||||
"date-fns": "^4.4.0",
|
"date-fns": "^4.4.0",
|
||||||
"pinia": "^3.0.4",
|
"pinia": "^3.0.4",
|
||||||
|
"random-word-slugs": "^0.1.7",
|
||||||
"vue": "^3.5.39",
|
"vue": "^3.5.39",
|
||||||
"vue-i18n": "^11.4.6",
|
"vue-i18n": "^11.4.6",
|
||||||
"vue-router": "^5.1.0",
|
"vue-router": "^5.1.0",
|
||||||
@@ -715,6 +716,8 @@
|
|||||||
|
|
||||||
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
"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=="],
|
"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=="],
|
"readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="],
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
"cron-parser": "^5.6.2",
|
"cron-parser": "^5.6.2",
|
||||||
"date-fns": "^4.4.0",
|
"date-fns": "^4.4.0",
|
||||||
"pinia": "^3.0.4",
|
"pinia": "^3.0.4",
|
||||||
|
"random-word-slugs": "^0.1.7",
|
||||||
"vue": "^3.5.39",
|
"vue": "^3.5.39",
|
||||||
"vue-i18n": "^11.4.6",
|
"vue-i18n": "^11.4.6",
|
||||||
"vue-router": "^5.1.0"
|
"vue-router": "^5.1.0"
|
||||||
|
|||||||
@@ -71,5 +71,7 @@
|
|||||||
"task_delete_error": "Could not delete task"
|
"task_delete_error": "Could not delete task"
|
||||||
},
|
},
|
||||||
"not_found": "Looks like there's nothing here...",
|
"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"
|
"task_delete_error": "Impossible de supprimer la tâche"
|
||||||
},
|
},
|
||||||
"not_found": "On dirait qu'il n'y a rien ici...",
|
"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(),
|
history: createWebHistory(),
|
||||||
routes: [
|
routes: [
|
||||||
{ path: "/", component: HomeView },
|
{ path: "/", component: HomeView },
|
||||||
{ path: "/:pathMatch([\\w-]+)", component: ListView },
|
{ path: "/:list", component: ListView },
|
||||||
{ path: "/:pathMatch(.*)", component: NotFoundView },
|
{ 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>
|
<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>
|
</template>
|
||||||
|
|||||||
@@ -11,10 +11,13 @@ import { SortType } from "@/enums";
|
|||||||
import { booleanCookieRef, enumCookieRef } from "@/lib/cookies";
|
import { booleanCookieRef, enumCookieRef } from "@/lib/cookies";
|
||||||
import { useAlertStore } from "@/stores/alerts";
|
import { useAlertStore } from "@/stores/alerts";
|
||||||
import { useI18n } from "vue-i18n";
|
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 taskInput = ref<string>("");
|
||||||
const tasks = ref<Task[]>([]);
|
const tasks = ref<Task[]>([]);
|
||||||
const list = ref<string>("test");
|
|
||||||
|
|
||||||
const sortType = enumCookieRef<SortType>(
|
const sortType = enumCookieRef<SortType>(
|
||||||
"toutDouxSortType",
|
"toutDouxSortType",
|
||||||
@@ -34,6 +37,7 @@ const i18n = useI18n();
|
|||||||
const { alertSuccess, alertError, alertWarning } = useAlertStore();
|
const { alertSuccess, alertError, alertWarning } = useAlertStore();
|
||||||
|
|
||||||
function fetchTasks() {
|
function fetchTasks() {
|
||||||
|
if (list.value) {
|
||||||
getTasks(list.value)
|
getTasks(list.value)
|
||||||
.then((data: Task[]) => {
|
.then((data: Task[]) => {
|
||||||
tasks.value = data;
|
tasks.value = data;
|
||||||
@@ -48,13 +52,14 @@ function fetchTasks() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function reSortTasks() {
|
function reSortTasks() {
|
||||||
tasks.value = sortTasks(tasks.value, sortType.value, sortReverse.value);
|
tasks.value = sortTasks(tasks.value, sortType.value, sortReverse.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onNewTask() {
|
function onNewTask() {
|
||||||
if (taskInput.value.trim()) {
|
if (taskInput.value.trim() && list.value) {
|
||||||
createTask(list.value, {
|
createTask(list.value, {
|
||||||
name: taskInput.value.trim(),
|
name: taskInput.value.trim(),
|
||||||
reset_cron: null,
|
reset_cron: null,
|
||||||
@@ -74,6 +79,7 @@ function onNewTask() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onCloneTask(task: Task) {
|
function onCloneTask(task: Task) {
|
||||||
|
if (list.value) {
|
||||||
createTask(list.value, {
|
createTask(list.value, {
|
||||||
name: task.name,
|
name: task.name,
|
||||||
reset_cron: task.reset_cron,
|
reset_cron: task.reset_cron,
|
||||||
@@ -86,6 +92,7 @@ function onCloneTask(task: Task) {
|
|||||||
alertError(i18n.t("alerts.task_create_error"));
|
alertError(i18n.t("alerts.task_create_error"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onDeleteTask(task: Task) {
|
function onDeleteTask(task: Task) {
|
||||||
deleteTask(task.id)
|
deleteTask(task.id)
|
||||||
@@ -107,7 +114,15 @@ function onChangeSortReverse() {
|
|||||||
reSortTasks();
|
reSortTasks();
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeMount(fetchTasks);
|
onBeforeMount(() => {
|
||||||
|
list.value = route.params.list as string;
|
||||||
|
fetchTasks();
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeRouteUpdate((to) => {
|
||||||
|
list.value = to.params.list as string;
|
||||||
|
fetchTasks();
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ import { CircleQuestionMarkIcon } from "@lucide/vue";
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<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') }}
|
<circle-question-mark-icon class="inline" /> {{ $t('not_found') }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="w-full px-4">
|
||||||
<router-link to="/" class="btn mb-4">{{ $t('not_found_button') }}</router-link>
|
<router-link to="/" class="btn mb-4">{{ $t('not_found_button') }}</router-link>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user