OpenAI integration and Note generation from prompt
This commit is contained in:
@@ -13,3 +13,5 @@ STRIPE_CALLBACK_URL=http://localhost:3000
|
||||
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
|
||||
|
||||
DATABASE_URL="postgresql://postgres:xxxxxxxxxxxxx@db.xxxxxxxxxxxxx.supabase.co:5432/postgres"
|
||||
|
||||
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
@@ -11,6 +11,7 @@ Please don't hitch your wagon to this star just yet... I'm coding this in the op
|
||||
- Pinia (State Store. I liked vuex a lot, in particular explicit mutations but gotta go with the cool crowd)
|
||||
- Stripe (Payments including Webhook integration)
|
||||
- Tailwind + daisyUI (Tailwind because everybody is using it, daisyUI because I suck at tailwind)
|
||||
- OpenAI (text completions with AI)
|
||||
|
||||
## Features
|
||||
### User Management
|
||||
@@ -71,6 +72,7 @@ Please don't hitch your wagon to this star just yet... I'm coding this in the op
|
||||
- [x] Max Notes limit property on Plan
|
||||
- [x] Max Notes enforced
|
||||
- [x] Add, Delete notes on Dashboard
|
||||
- [x] AI Note generation with OpenAI
|
||||
|
||||
### Testing
|
||||
- [x] Manual test scenario for auth and sub workflows passing
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import prisma_client from '~~/prisma/prisma.client';
|
||||
import { openai } from './openai.client';
|
||||
|
||||
export default class NotesService {
|
||||
async getAllNotes() {
|
||||
@@ -33,4 +34,20 @@ export default class NotesService {
|
||||
async deleteNote(id: number) {
|
||||
return prisma_client.note.delete({ where: { id } });
|
||||
}
|
||||
|
||||
async generateAINoteFromPrompt(userPrompt: string) {
|
||||
const prompt = `
|
||||
Write an interesting short note about ${userPrompt}.
|
||||
Restrict the note to a single paragraph.
|
||||
`
|
||||
const completion = await openai.createCompletion({
|
||||
model: "text-davinci-003",
|
||||
prompt,
|
||||
temperature: 0.6,
|
||||
stop: "\n\n",
|
||||
max_tokens: 1000,
|
||||
n: 1,
|
||||
});
|
||||
return completion.data.choices[0].text;
|
||||
}
|
||||
}
|
||||
|
||||
9
lib/services/openai.client.ts
Normal file
9
lib/services/openai.client.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Configuration, OpenAIApi } from "openai";
|
||||
|
||||
const config = useRuntimeConfig();
|
||||
|
||||
const configuration = new Configuration({
|
||||
apiKey: config.openAIKey,
|
||||
});
|
||||
|
||||
export const openai = new OpenAIApi(configuration);
|
||||
@@ -18,6 +18,7 @@ export default defineNuxtConfig({
|
||||
subscriptionGraceDays: 3,
|
||||
initialPlanName: 'Free Trial',
|
||||
initialPlanActiveMonths: 1,
|
||||
openAIKey: process.env.OPENAI_API_KEY,
|
||||
public: {
|
||||
debugMode: true,
|
||||
siteRootUrl: 'http://localhost:3000',
|
||||
|
||||
110
package-lock.json
generated
110
package-lock.json
generated
@@ -11,6 +11,7 @@
|
||||
"@trpc/server": "^10.9.0",
|
||||
"daisyui": "^2.51.5",
|
||||
"generate-password-ts": "^1.6.3",
|
||||
"openai": "^3.2.1",
|
||||
"pinia": "^2.0.30",
|
||||
"stripe": "^11.12.0",
|
||||
"superjson": "^1.12.2",
|
||||
@@ -2914,6 +2915,11 @@
|
||||
"integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/at-least-node": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
|
||||
@@ -2955,6 +2961,14 @@
|
||||
"postcss": "^8.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "0.26.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
|
||||
"integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.14.8"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
@@ -3595,6 +3609,17 @@
|
||||
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz",
|
||||
"integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ=="
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
||||
@@ -4097,6 +4122,14 @@
|
||||
"resolved": "https://registry.npmjs.org/defu/-/defu-6.1.2.tgz",
|
||||
"integrity": "sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ=="
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
@@ -4720,7 +4753,6 @@
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
|
||||
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -4736,6 +4768,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/formdata-polyfill": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
||||
@@ -6374,7 +6419,6 @@
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -6383,7 +6427,6 @@
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
@@ -7161,6 +7204,15 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/openai": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/openai/-/openai-3.2.1.tgz",
|
||||
"integrity": "sha512-762C9BNlJPbjjlWZi4WYK9iM2tAVAv0uUp1UmI34vb0CN5T2mjB/qM6RYBmNKMh/dN9fC+bxqPwWJZUTWW052A==",
|
||||
"dependencies": {
|
||||
"axios": "^0.26.0",
|
||||
"form-data": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ora": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ora/-/ora-6.1.2.tgz",
|
||||
@@ -13417,6 +13469,11 @@
|
||||
"integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==",
|
||||
"dev": true
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"at-least-node": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
|
||||
@@ -13436,6 +13493,14 @@
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
}
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.26.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
|
||||
"integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.14.8"
|
||||
}
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
@@ -13874,6 +13939,14 @@
|
||||
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz",
|
||||
"integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ=="
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
||||
@@ -14245,6 +14318,11 @@
|
||||
"resolved": "https://registry.npmjs.org/defu/-/defu-6.1.2.tgz",
|
||||
"integrity": "sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ=="
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
@@ -14731,8 +14809,17 @@
|
||||
"follow-redirects": {
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
|
||||
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
|
||||
},
|
||||
"form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"formdata-polyfill": {
|
||||
"version": "4.0.10",
|
||||
@@ -16003,14 +16090,12 @@
|
||||
"mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mime-db": "1.52.0"
|
||||
}
|
||||
@@ -16633,6 +16718,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"openai": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/openai/-/openai-3.2.1.tgz",
|
||||
"integrity": "sha512-762C9BNlJPbjjlWZi4WYK9iM2tAVAv0uUp1UmI34vb0CN5T2mjB/qM6RYBmNKMh/dN9fC+bxqPwWJZUTWW052A==",
|
||||
"requires": {
|
||||
"axios": "^0.26.0",
|
||||
"form-data": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"ora": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ora/-/ora-6.1.2.tgz",
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"@trpc/server": "^10.9.0",
|
||||
"daisyui": "^2.51.5",
|
||||
"generate-password-ts": "^1.6.3",
|
||||
"openai": "^3.2.1",
|
||||
"pinia": "^2.0.30",
|
||||
"stripe": "^11.12.0",
|
||||
"superjson": "^1.12.2",
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
newNoteText.value = '';
|
||||
}
|
||||
|
||||
async function genNote(){
|
||||
const genNoteText = await notesStore.generateAINoteFromPrompt(newNoteText.value)
|
||||
newNoteText.value = genNoteText;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await accountStore.init();
|
||||
await notesStore.fetchNotesForCurrentUser();
|
||||
@@ -28,13 +33,18 @@
|
||||
<h2 class="text-4xl font-extrabold tracking-tight text-gray-900 sm:text-5xl md:text-6xl mb-4">Notes Dashboard</h2>
|
||||
</div>
|
||||
|
||||
<div class="w-full max-w-md mb-8">
|
||||
<div v-if="activeMembership && (activeMembership.access === ACCOUNT_ACCESS.READ_WRITE || activeMembership.access === ACCOUNT_ACCESS.ADMIN || activeMembership.access === ACCOUNT_ACCESS.OWNER)" class="flex flex-row">
|
||||
<input v-model="newNoteText" type="text" class="w-full rounded-l-md py-2 px-4 border-gray-400 border-2 focus:outline-none focus:border-blue-500" placeholder="Add a note...">
|
||||
<div v-if="activeMembership && (activeMembership.access === ACCOUNT_ACCESS.READ_WRITE || activeMembership.access === ACCOUNT_ACCESS.ADMIN || activeMembership.access === ACCOUNT_ACCESS.OWNER)" class="w-full max-w-md mx-auto mb-3">
|
||||
<textarea v-model="newNoteText" type="text" class="w-full rounded-l-md py-2 px-4 border-gray-400 border-2 focus:outline-none focus:border-blue-500" rows="5" placeholder="Add a note..."/>
|
||||
<div class="flex justify-evenly">
|
||||
<button @click.prevent="addNote()" type="button"
|
||||
class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded-r-md focus:outline-none focus:shadow-outline-blue">
|
||||
class="px-4 py-2 text-white bg-blue-500 rounded-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50">
|
||||
Add
|
||||
</button>
|
||||
<button @click.prevent="genNote()" type="button"
|
||||
class="px-4 py-2 text-white bg-orange-500 rounded-md hover:bg-orange-600 focus:outline-none focus:ring-2 focus:ring-orange-500 focus:ring-opacity-50">
|
||||
Gen
|
||||
<Icon name="mdi:magic" class="h-6 w-6"/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ const user = useSupabaseUser()
|
||||
<li>
|
||||
<Icon name="skill-icons:postgresql-dark" class="h-12 w-12 mb-2" />
|
||||
<h3 class="text-xl font-medium text-gray-900">PostgreSQL</h3>
|
||||
<p class="mt-2 text-base text-gray-500">The Progressive JavaScript Framework</p>
|
||||
<p class="mt-2 text-base text-gray-500">Relational Database</p>
|
||||
</li>
|
||||
<li>
|
||||
<Icon name="logos:prisma" class="h-12 w-12 mb-2" />
|
||||
@@ -86,6 +86,11 @@ const user = useSupabaseUser()
|
||||
<h3 class="text-xl font-medium text-gray-900">Vue.js</h3>
|
||||
<p class="mt-2 text-base text-gray-500">The Progressive JavaScript Framework</p>
|
||||
</li>
|
||||
<li>
|
||||
<Icon name="logos:openai-icon" class="h-12 w-12 mb-2" />
|
||||
<h3 class="text-xl font-medium text-gray-900">OpenAI</h3>
|
||||
<p class="mt-2 text-base text-gray-500">AI Completions including Note generation from prompt</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -38,4 +38,13 @@ export const notesRouter = router({
|
||||
note,
|
||||
}
|
||||
}),
|
||||
generateAINoteFromPrompt: readWriteProcedure
|
||||
.input(z.object({ user_prompt: z.string() }))
|
||||
.query(async ({ ctx, input }) => {
|
||||
const notesService = new NotesService();
|
||||
const noteText = (ctx.activeAccountId)?await notesService.generateAINoteFromPrompt(input.user_prompt):null;
|
||||
return {
|
||||
noteText
|
||||
}
|
||||
}),
|
||||
})
|
||||
@@ -2,10 +2,6 @@ import { Note } from ".prisma/client"
|
||||
import { defineStore, storeToRefs } from "pinia"
|
||||
import { Ref } from "vue";
|
||||
|
||||
interface State {
|
||||
notes: Note[]
|
||||
}
|
||||
|
||||
/*
|
||||
Note) the Notes Store needs to be a 'Setup Store' (https://pinia.vuejs.org/core-concepts/#setup-stores)
|
||||
because this enables the use of the watch on the Account Store
|
||||
@@ -42,10 +38,16 @@ export const useNotesStore = defineStore('notes', () => {
|
||||
}
|
||||
}
|
||||
|
||||
async function generateAINoteFromPrompt(user_prompt: string) {
|
||||
const { $client } = useNuxtApp();
|
||||
const { noteText } = await $client.notes.generateAINoteFromPrompt.query({user_prompt});
|
||||
return noteText?noteText:'';
|
||||
}
|
||||
|
||||
// if the active account changes, fetch notes again (i.e dynamic.. probabl overkill)
|
||||
watch(activeAccountId, async (val, oldVal)=> {
|
||||
await fetchNotesForCurrentUser()
|
||||
});
|
||||
|
||||
return { notes: _notes, fetchNotesForCurrentUser, createNote, deleteNote }
|
||||
return { notes: _notes, fetchNotesForCurrentUser, createNote, deleteNote, generateAINoteFromPrompt}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user