diff --git a/app/app.config.ts b/app/app.config.ts index 7864699..8e62ab4 100644 --- a/app/app.config.ts +++ b/app/app.config.ts @@ -1,6 +1,23 @@ export default defineAppConfig({ ui: { - gray: 'neutral', + gray: 'zinc', primary: 'gray', + notifications: { + position: 'bottom-0 right-0', + }, + input: { + color: { + white: { + outline: 'shadow-sm bg-white dark:bg-gray-900 text-gray-900 dark:text-white ring-1 ring-inset ring-gray-300 dark:ring-gray-700 focus:ring-2 focus:ring-zinc-500 dark:focus:ring-zinc-500', + }, + }, + }, + select: { + color: { + white: { + outline: 'shadow-sm bg-white dark:bg-gray-900 text-gray-900 dark:text-white ring-1 ring-inset ring-gray-300 dark:ring-gray-700 focus:ring-2 focus:ring-zinc-500 dark:focus:ring-zinc-500', + }, + }, + }, }, }) diff --git a/app/app.vue b/app/app.vue index 0b922ae..ea33268 100644 --- a/app/app.vue +++ b/app/app.vue @@ -4,58 +4,22 @@ useHead({ title: 'ArtHome by Arthur Danjou', }) -const { loggedIn, clear, user } = useUserSession() -const colorMode = useColorMode() +const { loggedIn } = useUserSession() watch(loggedIn, async () => { if (!loggedIn.value) { navigateTo('/login') } }) - -function toggleColorMode() { - colorMode.preference = colorMode.preference === 'dark' ? 'light' : 'dark' -} - -async function logout() { - await clear() - navigateTo('/login') - window.location.reload() -} - -defineShortcuts({ - t: () => toggleColorMode(), - c: () => toggleColorMode(), -}) diff --git a/app/components/App/Header.vue b/app/components/App/Header.vue new file mode 100644 index 0000000..f310995 --- /dev/null +++ b/app/components/App/Header.vue @@ -0,0 +1,123 @@ + + + diff --git a/app/components/App/Tab.vue b/app/components/App/Tab.vue new file mode 100644 index 0000000..ac64770 --- /dev/null +++ b/app/components/App/Tab.vue @@ -0,0 +1,109 @@ + + + diff --git a/app/components/Category.vue b/app/components/Category.vue deleted file mode 100644 index 2b36b5f..0000000 --- a/app/components/Category.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - - - diff --git a/app/components/CategoryHeader.vue b/app/components/CategoryHeader.vue new file mode 100644 index 0000000..2db3b99 --- /dev/null +++ b/app/components/CategoryHeader.vue @@ -0,0 +1,56 @@ + + + diff --git a/app/components/Modal/CreateCategory.vue b/app/components/Modal/CreateCategory.vue new file mode 100644 index 0000000..a2278e8 --- /dev/null +++ b/app/components/Modal/CreateCategory.vue @@ -0,0 +1,70 @@ + + + diff --git a/app/components/Modal/CreateTab.vue b/app/components/Modal/CreateTab.vue new file mode 100644 index 0000000..c8d41f6 --- /dev/null +++ b/app/components/Modal/CreateTab.vue @@ -0,0 +1,91 @@ + + + diff --git a/app/components/Modal/DeleteCategory.vue b/app/components/Modal/DeleteCategory.vue new file mode 100644 index 0000000..fbeb764 --- /dev/null +++ b/app/components/Modal/DeleteCategory.vue @@ -0,0 +1,58 @@ + + + diff --git a/app/components/Modal/DeleteTab.vue b/app/components/Modal/DeleteTab.vue new file mode 100644 index 0000000..d085a9d --- /dev/null +++ b/app/components/Modal/DeleteTab.vue @@ -0,0 +1,58 @@ + + + diff --git a/app/components/Modal/UpdateCategory.vue b/app/components/Modal/UpdateCategory.vue new file mode 100644 index 0000000..745aec3 --- /dev/null +++ b/app/components/Modal/UpdateCategory.vue @@ -0,0 +1,80 @@ + + + diff --git a/app/components/Modal/UpdateTab.vue b/app/components/Modal/UpdateTab.vue new file mode 100644 index 0000000..a109dd2 --- /dev/null +++ b/app/components/Modal/UpdateTab.vue @@ -0,0 +1,89 @@ + + + diff --git a/app/components/Tab.vue b/app/components/Tab.vue deleted file mode 100644 index a2b8b82..0000000 --- a/app/components/Tab.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - - - diff --git a/app/composables/categories.ts b/app/composables/categories.ts index 3c9fec2..1a7561f 100644 --- a/app/composables/categories.ts +++ b/app/composables/categories.ts @@ -1,13 +1,47 @@ -export function useCategories() { - async function getCategories() { - return useAsyncData(async () => { - const res = await $fetch('/api/categories') - console.log('res', res) - return res +import type { type CategoryType, CreateCategorySchema, UpdateCategorySchema } from '~~/types/types' + +export async function useCategories() { + const { data: categories, refresh } + = await useAsyncData(async () => await useRequestFetch()('/api/categories')) + + async function getCategory(id: number) { + return categories.data.value.find(category => category.id === id) + } + + async function createCategory(category: CreateCategorySchema) { + await $fetch('/api/categories', { + method: 'POST', + body: JSON.stringify(category), }) + .catch(error => useErrorToast('Category creation failed!', `Error: ${error}`)) + await refresh() + await useSuccessToast('Category successfully created!') + } + + async function updateCategory(category: UpdateCategorySchema & { id: number }) { + await $fetch(`/api/categories/${category.id}`, { + method: 'PUT', + body: JSON.stringify(category), + }) + .catch(error => useErrorToast('Category update failed!', `Error: ${error}`)) + await refresh() + await useSuccessToast('Category successfully updated!') + } + + async function deleteCategory(id: number) { + await $fetch(`/api/categories/${id}`, { + method: 'DELETE', + }) + .catch(error => useErrorToast('Category deletion failed!', `Error: ${error}`)) + await refresh() + await useSuccessToast('Category successfully deleted!') } return { - getCategories, + categories, + getCategory, + createCategory, + updateCategory, + deleteCategory, } } diff --git a/app/composables/tabs.ts b/app/composables/tabs.ts index f077756..19f0013 100644 --- a/app/composables/tabs.ts +++ b/app/composables/tabs.ts @@ -1,21 +1,52 @@ -export function useTabs() { - async function createTab(tab: TabType) { - console.log('createTab', tab) - return tab +import type { CreateTabSchema, TabType, UpdateTabSchema } from '~~/types/types' + +export async function useTabs() { + const { data: tabs, refresh } + = await useAsyncData(async () => await useRequestFetch()('/api/tabs')) + + function getTabsForCategory(categoryId: number): TabType[] { + return tabs.value.filter(tab => tab.categoryId === categoryId) } - async function deleteTab(tab: TabType) { - console.log('deleteTab', tab) - return tab + async function createTab(tab: CreateTabSchema) { + await $fetch('/api/tabs', { + method: 'POST', + body: JSON.stringify(tab), + }) + .then(async () => { + await refresh() + useSuccessToast('Tab successfully created!') + }) + .catch(error => useErrorToast('Tab creation failed!', `Error: ${error}`)) } - async function updateTab(tab: TabType) { - console.log('updateTab', tab) - return tab + async function updateTab(tab: UpdateTabSchema) { + console.log(tab) + await $fetch(`/api/tabs/${tab.id}`, { + method: 'PUT', + body: JSON.stringify(tab), + }) + .then(async () => { + await refresh() + useSuccessToast('Tab successfully updated!') + }) + .catch(error => useErrorToast('Tab update failed!', `Error: ${error}`)) + } + + async function deleteTab(id: number) { + await $fetch(`/api/tabs/${id}`, { + method: 'DELETE', + }) + .catch(error => useErrorToast('Tab deletion failed!', `Error: ${error}`)) + await refresh() + useSuccessToast('Tab successfully deleted!') } return { + tabs, createTab, deleteTab, + getTabsForCategory, + updateTab, } } diff --git a/app/layouts/default.vue b/app/layouts/default.vue new file mode 100644 index 0000000..43f2ca2 --- /dev/null +++ b/app/layouts/default.vue @@ -0,0 +1,8 @@ + diff --git a/app/layouts/login.vue b/app/layouts/login.vue new file mode 100644 index 0000000..b02b6d6 --- /dev/null +++ b/app/layouts/login.vue @@ -0,0 +1,7 @@ + diff --git a/app/pages/index.vue b/app/pages/index.vue index bee0ebe..c969aa1 100644 --- a/app/pages/index.vue +++ b/app/pages/index.vue @@ -1,4 +1,7 @@ diff --git a/app/pages/login.vue b/app/pages/login.vue index 6217619..1729238 100644 --- a/app/pages/login.vue +++ b/app/pages/login.vue @@ -7,13 +7,13 @@ const { loggedIn } = useUserSession() definePageMeta({ middleware: 'ghost', + layout: 'login', }) const schema = z.object({ email: z.string().email('Invalid email'), }) -const form = ref() type Schema = z.output const state = reactive({ email: undefined }) @@ -62,7 +62,7 @@ if (import.meta.server) {