From 4418e6d865c3fbce101f04c9671ba42dbd6c7110 Mon Sep 17 00:00:00 2001 From: Arthur DANJOU Date: Tue, 12 Dec 2023 16:41:10 +0100 Subject: [PATCH] Add bookmarks --- prisma/schema.prisma | 38 ++++++-- src/components/header/NavBar.vue | 4 + src/pages/bookmarks.vue | 148 +++++++++++++++++++++++++++++++ src/server/api/bookmarks.get.ts | 46 ++++++++++ src/server/api/categories.get.ts | 11 ++- src/store/bookmarks.ts | 29 ++++++ 6 files changed, 269 insertions(+), 7 deletions(-) create mode 100644 src/pages/bookmarks.vue create mode 100644 src/server/api/bookmarks.get.ts create mode 100644 src/store/bookmarks.ts diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 1c358bc..0f639e0 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -24,12 +24,19 @@ model Announcement { content String @default("") } +enum CategoryType { + TALENT + BOOKMARK +} + model Category { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - slug String @default("") - name String @default("") - talents CategoriesOnTalents[] + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + slug String @default("") + name String @default("") + type CategoryType @default(TALENT) + talents CategoriesOnTalents[] + CategoriesOnBookmarks CategoriesOnBookmarks[] } model Talent { @@ -43,6 +50,16 @@ model Talent { categories CategoriesOnTalents[] } +model Bookmark { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + name String @unique @default("") + website String @default("") + content String @default("") + favorite Boolean @default(false) + categories CategoriesOnBookmarks[] +} + model CategoriesOnTalents { talentId Int categoryId Int @@ -54,6 +71,17 @@ model CategoriesOnTalents { @@index([categoryId]) } +model CategoriesOnBookmarks { + bookmarkId Int + categoryId Int + category Category @relation(fields: [categoryId], references: [id]) + bookmark Bookmark @relation(fields: [bookmarkId], references: [id]) + + @@id([bookmarkId, categoryId]) + @@index([bookmarkId]) + @@index([categoryId]) +} + model Post { id Int @id @default(autoincrement()) slug String @unique @default("") diff --git a/src/components/header/NavBar.vue b/src/components/header/NavBar.vue index 3a72c76..c749510 100644 --- a/src/components/header/NavBar.vue +++ b/src/components/header/NavBar.vue @@ -9,6 +9,10 @@ const items = [ label: 'Guestbook', to: '/guestbook', icon: 'i-material-symbols-book-2-outline', + }, { + label: 'Bookmarks', + to: '/bookmarks', + icon: 'i-material-symbols-bookmark-add-outline-rounded', }], ] diff --git a/src/pages/bookmarks.vue b/src/pages/bookmarks.vue new file mode 100644 index 0000000..f31f2d0 --- /dev/null +++ b/src/pages/bookmarks.vue @@ -0,0 +1,148 @@ + + + diff --git a/src/server/api/bookmarks.get.ts b/src/server/api/bookmarks.get.ts new file mode 100644 index 0000000..ebe4112 --- /dev/null +++ b/src/server/api/bookmarks.get.ts @@ -0,0 +1,46 @@ +export default defineEventHandler(async (event) => { + const { favorite, category } = getQuery(event) + const prisma = usePrisma() + + let whereClause: any + + if (favorite === 'true') { + category === 'all' + ? whereClause = { + favorite: true, + categories: { every: { category: {} } }, + } + : whereClause = { + favorite: true, + categories: { some: { category: { slug: category } } }, + } + } + else { + category === 'all' + ? whereClause = { + categories: { every: { category: {} } }, + } + : whereClause = { + categories: { some: { category: { slug: category } } }, + } + } + + return await prisma.bookmark.findMany({ + where: whereClause, + orderBy: { + name: 'asc', + }, + include: { + categories: { + include: { + category: true, + }, + orderBy: { + category: { + name: 'asc', + }, + }, + }, + }, + }) +}) diff --git a/src/server/api/categories.get.ts b/src/server/api/categories.get.ts index e044b4c..0d415c0 100644 --- a/src/server/api/categories.get.ts +++ b/src/server/api/categories.get.ts @@ -1,3 +1,10 @@ -export default defineEventHandler(async () => { - return await usePrisma().category.findMany() +import type { CategoryType } from '@prisma/client' + +export default defineEventHandler(async (event) => { + const { type } = getQuery<{ type: CategoryType }>(event) + return await usePrisma().category.findMany({ + where: { + type, + }, + }) }) diff --git a/src/store/bookmarks.ts b/src/store/bookmarks.ts new file mode 100644 index 0000000..3941571 --- /dev/null +++ b/src/store/bookmarks.ts @@ -0,0 +1,29 @@ +import { defineStore } from 'pinia' + +export const useBookmarksStore = defineStore( + 'bookmarks', + () => { + const currentCategory = ref('all') + const currentFavorite = ref(false) + + const getCategory = computed(() => currentCategory) + function setCategory(newCategory: string) { + currentCategory.value = newCategory + } + + const isFavorite = computed(() => currentFavorite) + function toggleFavorite() { + currentFavorite.value = !currentFavorite.value + } + + return { + getCategory, + setCategory, + isFavorite, + toggleFavorite, + } + }, + { + persist: true, + }, +)