From 80709b3913c5e6e2aed04d78e024d0c461b3cac7 Mon Sep 17 00:00:00 2001 From: Norbert Maciaszek Date: Mon, 17 Nov 2025 18:24:49 +0100 Subject: [PATCH] feat: add db integration and global types --- package-lock.json | 9 +++ package.json | 3 + src/app.css | 4 ++ src/app.html | 7 ++- src/lib/integrations/db/index.ts | 92 ++++++++++++++++++++++++++++++ src/lib/integrations/db/types.d.ts | 37 ++++++++++++ src/lib/types/global.d.ts | 36 ++++++++++++ 7 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 src/lib/integrations/db/index.ts create mode 100644 src/lib/integrations/db/types.d.ts create mode 100644 src/lib/types/global.d.ts diff --git a/package-lock.json b/package-lock.json index 6c75fdd..e72ac65 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,9 @@ "": { "name": "gift-tracker-sv", "version": "0.0.1", + "dependencies": { + "pocketbase": "^0.26.3" + }, "devDependencies": { "@sveltejs/adapter-auto": "^7.0.0", "@sveltejs/kit": "^2.47.1", @@ -1821,6 +1824,12 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pocketbase": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/pocketbase/-/pocketbase-0.26.3.tgz", + "integrity": "sha512-5deUKRoEczpxxuHzwr6/DHVmgbggxylEVig8CKN+MjvtYxPUqX/C6puU0yaR2yhTi8zrh7J9s7Ty+qBGwVzWOQ==", + "license": "MIT" + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", diff --git a/package.json b/package.json index 933205e..04e3841 100644 --- a/package.json +++ b/package.json @@ -26,5 +26,8 @@ "tailwindcss": "^4.1.14", "typescript": "^5.9.3", "vite": "^7.1.10" + }, + "dependencies": { + "pocketbase": "^0.26.3" } } diff --git a/src/app.css b/src/app.css index d4b5078..75133e0 100644 --- a/src/app.css +++ b/src/app.css @@ -1 +1,5 @@ @import 'tailwindcss'; + +body { + @apply bg-gray-50 font-sans text-gray-800 antialiased; +} diff --git a/src/app.html b/src/app.html index f273cc5..c30f094 100644 --- a/src/app.html +++ b/src/app.html @@ -3,9 +3,14 @@ + Gift Tracker %sveltekit.head% -
%sveltekit.body%
+
+
+
%sveltekit.body%
+
+
diff --git a/src/lib/integrations/db/index.ts b/src/lib/integrations/db/index.ts new file mode 100644 index 0000000..484eba5 --- /dev/null +++ b/src/lib/integrations/db/index.ts @@ -0,0 +1,92 @@ +import PocketBase from 'pocketbase'; + +const pb = new PocketBase('https://db.maciaszek.ovh'); + +export const DB = { + getYear: async (year: number): Promise => { + return await pb.collection('gifts_year').getFirstListItem(`year = ${year}`, { + expand: 'gifts.person', + fields: + '*,expand.gifts.*,expand.gifts.expand.person.name,expand.gifts.expand.person.id,expand.gifts.expand.person.notes' + }); + }, + getYears: async (): Promise => { + return await pb.collection('gifts_year').getFullList(); + }, + + getPerson: async (name: string): Promise => { + return await pb.collection('gifts_person').getFirstListItem(`name = "${name}"`); + }, + createPerson: async (data: Pick): Promise => { + return await pb.collection('gifts_person').create({ ...data }); + }, + updatePerson: async (id: string, data: Pick): Promise => { + return await pb.collection('gifts_person').update(id, data); + }, + deletePerson: async (id: string): Promise => { + await pb.collection('gifts_person').delete(id); + }, + getPersons: async (yearId: string): Promise => { + return await pb.collection('gifts_person').getFullList({ + filter: `years ~ "${yearId}"`, + expand: 'gifts,years', + fields: '*,expand.gifts.*,expand.years.id,expand.years.year' + }); + }, + + getGift: async (id: string): Promise => { + return await pb.collection('gifts_items').getOne(id, { + expand: 'year,person', + fields: '*,expand.year.year,expand.person.name,expand.year.id,expand.person.id' + }); + }, + createGift: async (data: Omit): Promise => { + const gift = await pb.collection('gifts_items').create(data); + + pb.collection('gifts_person').update(data.person, { + 'gifts+': gift.id + }); + + pb.collection('gifts_year').update(data.year, { + 'gifts+': gift.id + }); + + return gift as unknown as Gift; + }, + updateGift: async ( + id: string, + data: Omit + ): Promise => { + return await pb.collection('gifts_items').update(id, data); + }, + deleteGift: async (id: string): Promise => { + const gift = await pb.collection('gifts_items').getOne(id); + await pb.collection('gifts_items').delete(id); + await pb.collection('gifts_person').update(gift.person, { + 'gifts-': id + }); + await pb.collection('gifts_year').update(gift.year, { + 'gifts-': id + }); + }, + getGifts: async (year: number): Promise => { + const yearRecord = await pb.collection('gifts_year').getFirstListItem(`year = ${year}`); + if (!yearRecord) { + return []; + } + + return await pb.collection('gifts_items').getFullList({ + filter: `year = "${yearRecord.id}"`, + expand: 'year,person', + fields: '*,expand.year.year,expand.person.name,expand.year.id,expand.person.id' + }); + }, + getRecentGifts: async (): Promise => { + return await pb.collection('gifts_items').getFullList({ + sort: 'created', + limit: 3, + expand: 'year,person', + fields: '*,expand.year.year,expand.person.name,expand.year.id,expand.person.id' + }); + } +}; diff --git a/src/lib/integrations/db/types.d.ts b/src/lib/integrations/db/types.d.ts new file mode 100644 index 0000000..c83f734 --- /dev/null +++ b/src/lib/integrations/db/types.d.ts @@ -0,0 +1,37 @@ +namespace DB { + type Year = { + id: string; + year: number; + notes: string; + budgetLimit: number; + created: Date; + updated: Date; + gifts: string[]; + }; + + type Person = { + id: string; + name: string; + notes: string; + created: Date; + updated: Date; + years: string[]; + gifts: string[]; + }; + + type Gift = { + id: string; + title: string; + description: string; + link: string; + cost: number; + imageUrl: string; + status: 'planned' | 'decided' | 'bought' | 'ready' | 'wrapped'; + created: Date; + updated: Date; + ceneo_id: string; + + year: string; + person: string; + }; +} diff --git a/src/lib/types/global.d.ts b/src/lib/types/global.d.ts new file mode 100644 index 0000000..ebce1d7 --- /dev/null +++ b/src/lib/types/global.d.ts @@ -0,0 +1,36 @@ +type Year = DB.Year & { + expand: { + gifts: Gift[] & { + expand: { + person: { + id: string; + name: string; + notes: string; + }; + }; + }; + }; +}; + +type Person = DB.Person & { + expand: { + gifts?: Gift[]; + year: { + id: string; + year: number; + }; + }; +}; + +type Gift = DB.Gift & { + expand: { + year: { + id: string; + year: number; + }; + person: { + id: string; + name: string; + }; + }; +};