Merge pull request #9 from quirinecker/feature/ui-improvements
Feature/UI improvements
This commit is contained in:
@@ -8,6 +8,12 @@ const db = drizzle("file:local.db");
|
|||||||
const app = express();
|
const app = express();
|
||||||
const userId = "Detlef";
|
const userId = "Detlef";
|
||||||
|
|
||||||
|
type Prettify<T> = {
|
||||||
|
[K in keyof T]: T[K];
|
||||||
|
} & {};
|
||||||
|
|
||||||
|
type TaskResponse = Prettify<Omit<typeof task.$inferSelect, 'done'> & { done: boolean }>
|
||||||
|
|
||||||
app.use(cors())
|
app.use(cors())
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
@@ -15,9 +21,11 @@ app.get('/', (req, res) => {
|
|||||||
res.send('Hello World');
|
res.send('Hello World');
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/tasks', async(req, res) => {
|
app.get('/tasks', async (req, res) => {
|
||||||
const tasks = await db.select().from(task)
|
const tasks: typeof task.$inferSelect[] = await db.select().from(task)
|
||||||
res.status(200).send(tasks);
|
res.status(200).send(tasks.map<TaskResponse>(task => {
|
||||||
|
return { ...task, done: task.done === 1 }
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/events', async(req, res) => {
|
app.get('/events', async(req, res) => {
|
||||||
|
|||||||
@@ -4,24 +4,27 @@ import ListItem from './ListItem.vue';
|
|||||||
import Title1 from './Title1.vue';
|
import Title1 from './Title1.vue';
|
||||||
import type { DropdownMenuItem } from '@nuxt/ui';
|
import type { DropdownMenuItem } from '@nuxt/ui';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
|
import type { USeparator } from '#components';
|
||||||
|
|
||||||
const colorMode = useColorMode();
|
const colorMode = useColorMode();
|
||||||
|
|
||||||
const currentTheme = ref<'dark' | 'system' | 'light'>(colorMode.preference as 'dark' | 'system' | 'light');
|
const currentTheme = ref<'dark' | 'system' | 'light'>(colorMode.preference as 'dark' | 'system' | 'light');
|
||||||
|
|
||||||
const isLight = computed(() => currentTheme.value === 'light');
|
const date = defineModel<DateTime>('date', { required: true })
|
||||||
const isDark = computed(() => currentTheme.value === 'dark');
|
const tasks = defineModel<Task[]>('tasks', { required: true })
|
||||||
const isSystem = computed(() => currentTheme.value === 'system');
|
|
||||||
|
|
||||||
watch(currentTheme, () => {
|
|
||||||
console.log(currentTheme.value)
|
|
||||||
colorMode.preference = currentTheme.value;
|
|
||||||
})
|
|
||||||
|
|
||||||
const emits = defineEmits<{
|
const emits = defineEmits<{
|
||||||
(e: 'createTask', name: string): void
|
(e: 'createTask', name: string): void
|
||||||
(e: 'deleteTask', id: number): void
|
(e: 'deleteTask', id: number): void
|
||||||
|
(e: 'editTask', task: Task): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const isLight = computed(() => currentTheme.value === 'light');
|
||||||
|
const isDark = computed(() => currentTheme.value === 'dark');
|
||||||
|
const isSystem = computed(() => currentTheme.value === 'system');
|
||||||
|
const doneTasks = computed(() => tasks.value.filter(task => task.done))
|
||||||
|
const todoTasks = computed(() => tasks.value.filter(task => !task.done))
|
||||||
|
|
||||||
const dropDownItems = computed<DropdownMenuItem[][]>(() => [
|
const dropDownItems = computed<DropdownMenuItem[][]>(() => [
|
||||||
[
|
[
|
||||||
{ label: "Profile", icon: "i-lucide-user" },
|
{ label: "Profile", icon: "i-lucide-user" },
|
||||||
@@ -60,7 +63,6 @@ const dropDownItems = computed<DropdownMenuItem[][]>(() => [
|
|||||||
]
|
]
|
||||||
])
|
])
|
||||||
|
|
||||||
const date = defineModel<DateTime>('date', { required: true })
|
|
||||||
|
|
||||||
const selectedDate = computed({
|
const selectedDate = computed({
|
||||||
get() {
|
get() {
|
||||||
@@ -79,31 +81,26 @@ type Task = {
|
|||||||
userid: string
|
userid: string
|
||||||
title: string
|
title: string
|
||||||
description: string
|
description: string
|
||||||
done: number
|
done: boolean
|
||||||
estimated_time: string
|
estimated_time: string
|
||||||
due_date: string
|
due_date: string
|
||||||
created_at: string
|
created_at: string
|
||||||
updated_at: string
|
updated_at: string
|
||||||
}
|
}
|
||||||
|
|
||||||
defineProps<{
|
|
||||||
todos: Task[]
|
|
||||||
}>()
|
|
||||||
|
|
||||||
|
function addTask() {
|
||||||
function addTodo() {
|
|
||||||
const name = prompt("Todo name:")
|
const name = prompt("Todo name:")
|
||||||
console.log(name)
|
console.log(name)
|
||||||
if (name !== null) {
|
if (name !== null) {
|
||||||
emits('createTask', name)
|
emits('createTask', name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function deleteTodo(todo: Task) {
|
function deleteTask(todo: Task) {
|
||||||
console.log(todo.id)
|
|
||||||
emits('deleteTask', todo.id)
|
emits('deleteTask', todo.id)
|
||||||
}
|
}
|
||||||
function editTodo() {
|
function editTask(task: Task) {
|
||||||
|
emits('editTask', task)
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -119,42 +116,39 @@ function editTodo() {
|
|||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<Title1>Todos</Title1>
|
<Title1>Todos</Title1>
|
||||||
<div class="flex gap-2 flex-col">
|
<div class="flex gap-2 flex-col">
|
||||||
<ListItem v-for="todo in todos">
|
<ListItem v-for="task in todoTasks">
|
||||||
<div class="flex w-full gap-4 items-center">
|
<div class="flex w-full gap-4 items-center">
|
||||||
<span class="grow overflow-scroll py-3 overflow-shadow">
|
<span
|
||||||
{{ todo.title }}
|
class="grow overflow-scroll py-3 overflow-shadow flex flex-row gap-2 items-center">
|
||||||
|
<UCheckbox v-model="task.done" @change="() => editTask(task)" />{{ task.title }}
|
||||||
</span>
|
</span>
|
||||||
<div class="flex gap-1">
|
<div class="flex gap-1">
|
||||||
<UButton size="xs" color="neutral" class="flex justify-center" @click="editTodo">
|
<UButton size="xs" color="neutral" class="flex justify-center" icon="mingcute:pencil-line"
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15"
|
@click="() => editTask(task)"/>
|
||||||
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
<UButton size="xs" color="primary" class="flex justify-center" icon="octicon:trashcan-16"
|
||||||
stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-pencil">
|
@click="() => deleteTask(task)" />
|
||||||
<path
|
</div>
|
||||||
d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z">
|
</div>
|
||||||
</path>
|
</ListItem>
|
||||||
<path d="m15 5 4 4"></path>
|
<USeparator label="Done" v-if="todoTasks.length !== 0"/>
|
||||||
</svg>
|
<ListItem v-for="task in doneTasks">
|
||||||
</UButton>
|
<div class="flex w-full gap-4 items-center">
|
||||||
<UButton size="xs" class="flex justify-center" color="primary"
|
<span
|
||||||
@click="() => deleteTodo(todo)">
|
class="grow overflow-scroll py-3 overflow-shadow flex flex-row gap-2 items-center">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15"
|
<UCheckbox v-model="task.done" @change="() => editTask(task)" />{{ task.title }}
|
||||||
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
</span>
|
||||||
stroke-linecap="round" stroke-linejoin="round"
|
<div class="flex gap-1">
|
||||||
class="lucide lucide-trash-2">
|
<UButton size="xs" color="neutral" class="flex justify-center" icon="mingcute:pencil-line"
|
||||||
<path d="M3 6h18"></path>
|
@click="() => editTask(task)"/>
|
||||||
<path d="M19 6v14c0 1-2 2-2 2H7c-1 0-2-1-2-2V6"></path>
|
<UButton size="xs" color="primary" class="flex justify-center"
|
||||||
<path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
|
@click="() => deleteTask(task)" icon="octicon:trashcan-16"/>
|
||||||
<line x1="10" x2="10" y1="11" y2="17"></line>
|
|
||||||
<line x1="14" x2="14" y1="11" y2="17"></line>
|
|
||||||
</svg>
|
|
||||||
</UButton>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<UButton size="xl" class="w-full flex justify-center" @click="addTodo">
|
<UButton size="xl" class="w-full flex justify-center" @click="addTask">
|
||||||
+
|
+
|
||||||
</UButton>
|
</UButton>
|
||||||
</div>
|
</div>
|
||||||
@@ -174,6 +168,4 @@ function editTodo() {
|
|||||||
</UCard>
|
</UCard>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ type Task = {
|
|||||||
userid: string
|
userid: string
|
||||||
title: string
|
title: string
|
||||||
description: string
|
description: string
|
||||||
done: number
|
done: boolean
|
||||||
estimated_time: string
|
estimated_time: string
|
||||||
due_date: string
|
due_date: string
|
||||||
created_at: string
|
created_at: string
|
||||||
@@ -68,7 +68,7 @@ async function deleteTask(id: number) {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="h-screen w-screen p-4 flex flex-row gap-5">
|
<div class="h-screen w-screen p-4 flex flex-row gap-5">
|
||||||
<Sidebar v-if="tasks !== null" :todos="tasks" v-model:date="date" @create-task="postTask"
|
<Sidebar v-if="tasks !== null" v-model:tasks="tasks" v-model:date="date" @create-task="postTask"
|
||||||
@delete-task="deleteTask" />
|
@delete-task="deleteTask" />
|
||||||
<MainContent v-if="events !== null" v-model:events="events" v-model:date="date" @create-event="postEvent" />
|
<MainContent v-if="events !== null" v-model:events="events" v-model:date="date" @create-event="postEvent" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user