From e32738ca5942a70f822c052aa959925d9fab334c Mon Sep 17 00:00:00 2001 From: Charvisree Koripella Date: Thu, 16 Apr 2026 00:58:57 -0500 Subject: [PATCH 01/30] Deleted the old attendence toggles --- app/components/Notes.vue | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/app/components/Notes.vue b/app/components/Notes.vue index 692886c..13de5af 100644 --- a/app/components/Notes.vue +++ b/app/components/Notes.vue @@ -547,7 +547,6 @@ method: 'POST', body: { content: savedContent, - attended: !isAbsent.value, }, })) as { id: string; createdAt: string } @@ -584,7 +583,6 @@ //Auto-save and status tracking const saveStatus = ref<'idle' | 'saving' | 'saved' | 'error'>('idle') - const isAbsent = ref(false) const lastSaved = ref(null) //Auto-save and status tracking for previous notes @@ -992,28 +990,12 @@ - - - - - + @@ -1107,9 +1089,9 @@ @click.self="showSaveModal = false" >
-

Save Note

+

Submit Note

- Are you sure you want to save this note? + Are you sure you want to submit this note?

- - + + + { content?: string reason?: string signature?: string + attendanceStatus?: string }>(event) if (!body?.content || typeof body.content !== 'string' || !body.content.trim()) { @@ -41,13 +42,18 @@ export default defineEventHandler(async (event) => { data: { sessionNoteId: note.id, originalContent: note.content, + editedContent: body.content.trim(), + oldAttendanceStatus: note.attendanceStatus, + newAttendanceStatus: body.attendanceStatus ?? note.attendanceStatus, reason: body.reason.trim(), signature: body.signature.trim(), }, }), prisma.sessionNote.update({ where: { id: note.id }, - data: { content: body.content.trim() }, + data: { content: body.content.trim(), + ...(body.attendanceStatus && { attendanceStatus: body.attendanceStatus }), + }, }), ]) From 442345807efe09f1b5d28d4da1912c0fcb040ac4 Mon Sep 17 00:00:00 2001 From: Charvisree Koripella Date: Thu, 23 Apr 2026 10:09:35 -0500 Subject: [PATCH 06/30] Fixed the attendance on notes edit and viewer --- app/components/Notes.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/components/Notes.vue b/app/components/Notes.vue index e0fcaaf..dcdf7ad 100644 --- a/app/components/Notes.vue +++ b/app/components/Notes.vue @@ -370,7 +370,7 @@ // Load current attendance status into the edit form const sn = localSessionNotes.value.find(n => n.id === sd.id) - editingAttendanceStatus.value = sn?.attendanceStatus ?? 'show' + editingAttendanceStatus.value = sn?.attendanceStatus ?? '' } else { pendingMeta.value.set(sd.id, { reason: editReason.value, @@ -586,6 +586,7 @@ id: response.id, createdAt: response.createdAt, content: savedContent, + attendanceStatus: attendanceStatus.value, }) // Clear editor → fresh current note From 2e0867aae4be45e7c3168736ddb3964b35cca1bc Mon Sep 17 00:00:00 2001 From: Charvisree Koripella Date: Sun, 26 Apr 2026 17:06:48 -0500 Subject: [PATCH 07/30] Changed to the justification modal and added a checkbox list --- app/components/Notes.vue | 98 +++++++++++---------------------- app/components/NotesToolbar.vue | 27 +-------- app/pages/notes-test.vue | 8 +++ nuxt.config.ts | 8 +++ 4 files changed, 50 insertions(+), 91 deletions(-) diff --git a/app/components/Notes.vue b/app/components/Notes.vue index dcdf7ad..66cd36a 100644 --- a/app/components/Notes.vue +++ b/app/components/Notes.vue @@ -1,6 +1,8 @@ @@ -69,24 +58,14 @@ const items: EditorToolbarItem[][] = [ v-model="localContent" :content-type="contentType || 'markdown'" placeholder="Start typing your clinical notes here..." - class="flex-1 prose prose-sm sm:prose text-left dark:prose-invert" - :class="sizeClassMap[selectedSize]" + class="flex flex-col flex-1 min-h-0 prose prose-sm sm:prose text-left dark:prose-invert" > - - diff --git a/app/pages/notes-test.vue b/app/pages/notes-test.vue index 98eade7..fc3bb7f 100644 --- a/app/pages/notes-test.vue +++ b/app/pages/notes-test.vue @@ -31,6 +31,14 @@ return clientPickerOptions.value[0]?.id ?? '' }) + type NotesEditorData = { + client: { id: string; name: string } + currentNote: { id: number; date: string; content: string } + previousNotes: { id: number; date: string; preview: string; content: string }[] + sessionNotes: { id: string; content: string; createdAt: string }[] + forms: { label?: string; status: 'complete' | 'pending' }[] + } + const { data, pending, error } = await useFetch( () => `/api/clients/${clientId.value}/notes-editor-data`, { diff --git a/nuxt.config.ts b/nuxt.config.ts index 8f578a6..051867c 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -41,5 +41,13 @@ export default defineNuxtConfig({ 'prosemirror-transform', ], }, + optimizeDeps: { + include: [ + '@vue/devtools-core', + '@vue/devtools-kit', + 'better-auth/vue', + 'better-auth/client/plugins', + ] + }, }, }) From 8f5e10f96c84469ed370fc715c4c101175b5aa5a Mon Sep 17 00:00:00 2001 From: Charvisree Koripella Date: Sun, 26 Apr 2026 17:27:29 -0500 Subject: [PATCH 08/30] checkbox list on notes toolbar --- app/assets/css/main.css | 35 +++++++++++++++++++++++++++++++++ app/components/NotesToolbar.vue | 14 ++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/app/assets/css/main.css b/app/assets/css/main.css index 16bfeb1..ca8d126 100644 --- a/app/assets/css/main.css +++ b/app/assets/css/main.css @@ -222,4 +222,39 @@ .tiptap p.is-empty:not(:first-child)::before { content: none; +} + +/* Style tiptap task list checkboxes to match Nuxt UI */ +.tiptap ul[data-type="taskList"] { + list-style: none; + padding-left: 0; +} + +.tiptap ul[data-type="taskList"] li { + display: flex; + align-items: flex-start; + gap: 0.5rem; +} + +.tiptap ul[data-type="taskList"] li > label { + margin-top: 2px; + flex-shrink: 0; +} + +.tiptap ul[data-type="taskList"] li > label input[type="checkbox"] { + width: 1rem; + height: 1rem; + border-radius: 4px; + border: 1.5px solid #d1d5db; + cursor: pointer; + accent-color: var(--color-primary-500); +} + +.tiptap ul[data-type="taskList"] li > div { + flex: 1; +} + +.tiptap ul[data-type="taskList"] li[data-checked="true"] > div { + text-decoration: line-through; + color: #9ca3af; } \ No newline at end of file diff --git a/app/components/NotesToolbar.vue b/app/components/NotesToolbar.vue index 0d6bb2a..9b7f03c 100644 --- a/app/components/NotesToolbar.vue +++ b/app/components/NotesToolbar.vue @@ -1,5 +1,6 @@ @@ -66,6 +67,17 @@ const items: EditorToolbarItem[][] = [ layout="fixed" class="w-full border-b bg-gray-50 dark:bg-gray-800 flex-shrink-0 sticky top-0 z-10" > + From 7b9b163a20eacfba458d573c3c65581aa56a2ccb Mon Sep 17 00:00:00 2001 From: Deethya Janjanam Date: Sun, 26 Apr 2026 17:57:52 -0500 Subject: [PATCH 09/30] added the labels for event creation --- app/pages/calendar.vue | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/app/pages/calendar.vue b/app/pages/calendar.vue index 2752169..8ffa216 100644 --- a/app/pages/calendar.vue +++ b/app/pages/calendar.vue @@ -692,14 +692,36 @@ Session name will be auto-generated as Firstname_Lastname_##.

- +
+ + +
- +
+ + +
- +
+ + +
- +
+ + +

{{ createTimeRangeError }} From 842f095dc082dab1fe0c76dff178d2780560e99b Mon Sep 17 00:00:00 2001 From: Deethya Janjanam Date: Sun, 26 Apr 2026 18:04:31 -0500 Subject: [PATCH 10/30] removed the meeting link things! --- app/pages/calendar.vue | 108 ++++++++++++----------------------------- 1 file changed, 32 insertions(+), 76 deletions(-) diff --git a/app/pages/calendar.vue b/app/pages/calendar.vue index 8ffa216..a122925 100644 --- a/app/pages/calendar.vue +++ b/app/pages/calendar.vue @@ -7,12 +7,6 @@ import listPlugin from '@fullcalendar/list' import { VIDEO_PROVIDER_LABEL } from '~/utils/video-conference' - const videoMeetingTypeOptions = [ - { value: 'GOOGLE_MEET' as const, label: 'Google Meet' }, - { value: 'ZOOM' as const, label: 'Zoom' }, - { value: 'OTHER' as const, label: 'Other link' }, - ] - const isMobile = ref(process.client && window.innerWidth < 768) const calendarRef = ref() const session = authClient.useSession() @@ -380,7 +374,7 @@ ) editForm.videoJoinUrl = selectedEvent.value.videoJoinUrl || '' editForm.videoProvider = editForm.includeVideo - ? (selectedEvent.value.videoProvider as typeof editForm.videoProvider) || 'GOOGLE_MEET' + ? (selectedEvent.value.videoProvider as typeof editForm.videoProvider) || 'OTHER' : '' editTimeRangeError.value = '' } @@ -418,7 +412,7 @@ date: editForm.date, startTime: editForm.startTime, endTime: editForm.endTime, - videoProvider: editForm.includeVideo ? editForm.videoProvider || 'GOOGLE_MEET' : null, + videoProvider: editForm.includeVideo ? editForm.videoProvider || 'OTHER' : null, videoJoinUrl: editForm.includeVideo ? editForm.videoJoinUrl.trim() || null : null, }, }) @@ -493,7 +487,7 @@ form.videoProvider = '' form.videoJoinUrl = '' } else if (!form.videoProvider) { - form.videoProvider = 'GOOGLE_MEET' + form.videoProvider = 'OTHER' } } ) @@ -505,7 +499,7 @@ editForm.videoProvider = '' editForm.videoJoinUrl = '' } else if (!editForm.videoProvider) { - editForm.videoProvider = 'GOOGLE_MEET' + editForm.videoProvider = 'OTHER' } } ) @@ -570,7 +564,7 @@ date: form.date, startTime: form.startTime, endTime: form.endTime, - videoProvider: form.includeVideo ? form.videoProvider || 'GOOGLE_MEET' : undefined, + videoProvider: form.includeVideo ? form.videoProvider || 'OTHER' : undefined, videoJoinUrl: form.includeVideo ? form.videoJoinUrl.trim() : undefined, }, }) @@ -735,41 +729,22 @@

-

Meeting type

-
- -
-
- - -

- Paste a secure https link so clients can join from the dashboard and calendar. -

-
+ + +

+ Paste a secure https link so clients can join from the dashboard and calendar. +

@@ -885,38 +860,19 @@
-

Meeting type

-
- -
-
- - -
+ +
From d45eda8eb8ba0e4f71d9f52c8b44ec0c1a3262b2 Mon Sep 17 00:00:00 2001 From: Deethya Janjanam Date: Sun, 26 Apr 2026 18:11:52 -0500 Subject: [PATCH 11/30] notes can scroll --- app/components/Notes.vue | 78 ++++++++++++++++++++------------- app/components/NotesToolbar.vue | 18 ++++++-- 2 files changed, 62 insertions(+), 34 deletions(-) diff --git a/app/components/Notes.vue b/app/components/Notes.vue index c4e9916..a31fdf0 100644 --- a/app/components/Notes.vue +++ b/app/components/Notes.vue @@ -1024,9 +1024,9 @@ + + \ No newline at end of file From 310d77fd2f1ea63ce6a70329a26120a8f234154b Mon Sep 17 00:00:00 2001 From: TusharW4ni Date: Sun, 26 Apr 2026 18:21:48 -0500 Subject: [PATCH 12/30] added admin users --- prisma/seed.ts | 425 ++++++++++++------------------------------------- 1 file changed, 99 insertions(+), 326 deletions(-) diff --git a/prisma/seed.ts b/prisma/seed.ts index 174a085..d97bf6d 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -10,122 +10,6 @@ const connectionString = process.env.DATABASE_URL ?? 'file:./dev.db' const adapter = new PrismaBetterSqlite3({ url: connectionString }) const prisma = new PrismaClient({ adapter }) -async function ensureLatestGadForm(userId: string) { - const existing = await prisma.gadForm.findFirst({ - where: { userId }, - orderBy: { id: 'desc' }, - }) - - if (existing) { - return prisma.gadForm.update({ - where: { id: existing.id }, - data: { - status: 'COMPLETE', - totalScore: 12, - severity: 'Moderate', - submittedAt: new Date(), - }, - }) - } - - return prisma.gadForm.create({ - data: { - userId, - status: 'COMPLETE', - totalScore: 12, - severity: 'Moderate', - submittedAt: new Date(), - }, - }) -} - -async function ensureLatestPhqForm(userId: string) { - const existing = await prisma.phqForm.findFirst({ - where: { userId }, - orderBy: { id: 'desc' }, - }) - - if (existing) { - return prisma.phqForm.update({ - where: { id: existing.id }, - data: { - status: 'COMPLETE', - totalScore: 14, - severity: 'Moderate depression', - submittedAt: new Date(), - }, - }) - } - - return prisma.phqForm.create({ - data: { - userId, - status: 'COMPLETE', - totalScore: 14, - severity: 'Moderate depression', - submittedAt: new Date(), - }, - }) -} - -async function ensureLatestPclForm(userId: string) { - const existing = await prisma.pclForm.findFirst({ - where: { userId }, - orderBy: { id: 'desc' }, - }) - - if (existing) { - return prisma.pclForm.update({ - where: { id: existing.id }, - data: { - status: 'COMPLETE', - totalScore: 45, - severity: 'Moderate', - submittedAt: new Date(), - }, - }) - } - - return prisma.pclForm.create({ - data: { - userId, - status: 'COMPLETE', - totalScore: 45, - severity: 'Moderate', - submittedAt: new Date(), - }, - }) -} - -async function ensureLatestAceForm(userId: string) { - const existing = await prisma.aceForm.findFirst({ - where: { userId }, - orderBy: { id: 'desc' }, - }) - - if (existing) { - return prisma.aceForm.update({ - where: { id: existing.id }, - data: { - status: 'COMPLETE', - totalScore: 2, - severity: 'Low', - submittedAt: new Date(), - }, - }) - } - - return prisma.aceForm.create({ - data: { - userId, - status: 'COMPLETE', - totalScore: 2, - severity: 'Low', - submittedAt: new Date(), - }, - }) -} - async function seedForms(userId: string) { // 1. AppForm (Application) const appForm = await prisma.appForm.upsert({ @@ -151,22 +35,18 @@ async function seedForms(userId: string) { }) // 2. GAD-7 - const gadForm = await ensureLatestGadForm(userId) - - await prisma.gadQuestion.upsert({ - where: { formId: gadForm.id }, - update: { + const gadForm = await prisma.gadForm.create({ + data: { userId, - g01: 2, - g02: 1, - g03: 2, - g04: 1, - g05: 2, - g06: 2, - g07: 2, - g08: 1, + status: 'COMPLETE', + totalScore: 12, + severity: 'Moderate', + submittedAt: new Date(), }, - create: { + }) + + await prisma.gadQuestion.create({ + data: { formId: gadForm.id, userId, g01: 2, @@ -181,23 +61,21 @@ async function seedForms(userId: string) { }) // 3. PHQ-9 - const phqForm = await ensureLatestPhqForm(userId) + const phqForm = await prisma.phqForm.upsert({ + where: { userId }, + update: {}, + create: { + userId, + status: 'COMPLETE', + totalScore: 14, + severity: 'Moderate depression', + submittedAt: new Date(), + }, + }) await prisma.phqQuestion.upsert({ where: { formId: phqForm.id }, - update: { - userId, - q1: 2, - q2: 1, - q3: 2, - q4: 1, - q5: 2, - q6: 2, - q7: 2, - q8: 1, - q9: 1, - q10: 1, - }, + update: {}, create: { formId: phqForm.id, userId, @@ -215,34 +93,18 @@ async function seedForms(userId: string) { }) // 4. PCL-5 - const pclForm = await ensureLatestPclForm(userId) - - await prisma.pclQuestion.upsert({ - where: { formId: pclForm.id }, - update: { + const pclForm = await prisma.pclForm.create({ + data: { userId, - q01: 3, - q02: 2, - q03: 3, - q04: 2, - q05: 2, - q06: 3, - q07: 2, - q08: 2, - q09: 2, - q10: 2, - q11: 2, - q12: 2, - q13: 2, - q14: 2, - q15: 2, - q16: 2, - q17: 2, - q18: 2, - q19: 2, - q20: 2, + status: 'COMPLETE', + totalScore: 45, + severity: 'Moderate', + submittedAt: new Date(), }, - create: { + }) + + await prisma.pclQuestion.create({ + data: { formId: pclForm.id, userId, q01: 3, @@ -269,23 +131,21 @@ async function seedForms(userId: string) { }) // 5. ACE (Hardcoded Form) - const aceForm = await ensureLatestAceForm(userId) + const aceForm = await prisma.aceForm.upsert({ + where: { userId }, + update: {}, + create: { + userId, + status: 'COMPLETE', + totalScore: 2, + severity: 'Low', + submittedAt: new Date(), + }, + }) await prisma.aceQuestion.upsert({ where: { formId: aceForm.id }, - update: { - userId, - a01: 'Yes', - a02: 'Yes', - a03: 'No', - a04: 'No', - a05: 'No', - a06: 'No', - a07: 'No', - a08: 'No', - a09: 'No', - a10: 'No', - }, + update: {}, create: { formId: aceForm.id, userId, @@ -303,139 +163,41 @@ async function seedForms(userId: string) { }) } -async function ensureBobBuilderSessionNotes(bobUserId: string, clinicianUserId: string) { - const bobClient = await prisma.client.upsert({ +async function ensureBobBuilderSessionNotes(bobUserId: string) { + const client = await prisma.client.upsert({ where: { userId: bobUserId }, - update: { status: 'ACTIVE', clinicianUserId }, - create: { userId: bobUserId, status: 'ACTIVE', clinicianUserId }, + update: { status: 'ACTIVE' }, + create: { userId: bobUserId, status: 'ACTIVE' }, + }) + + const existingSessionNotes = await prisma.sessionNote.count({ + where: { clientId: client.id }, }) + + if (existingSessionNotes === 0) { + await prisma.sessionNote.createMany({ + data: [ + { + clientId: client.id, + content: + 'Intake / Week 1 — Rapport established. Bob reviewed clinic policies and confidentiality. Reported primary stressors related to work deadlines and sleep disruption. PHQ-9 and GAD-7 administered; safety screen negative. Plan: sleep hygiene handout, begin weekly CBT skills.', + }, + { + clientId: client.id, + content: + 'Session 2 — Focus on thought challenging around catastrophic predictions at work. Homework: thought record for 3 situations. Bob engaged well; identified one automatic thought pattern to monitor between sessions.', + }, + ], + }) + console.log('Created sample SessionNote rows for Bob Builder.') + } + // Populate form dummy data if it doesn't exist const existingApp = await prisma.appForm.count({ where: { userId: bobUserId } }) if (existingApp === 0) { await seedForms(bobUserId) console.log('Seeded clinical forms for Bob Builder.') } - return bobClient -} - -/** - * Seed a representative note in each workflow state so the multi-tier approval - * UI (draft / clinician-signed / fully-approved) has real data to exercise, - * and across both kinds (progress vs psychotherapy). - */ -async function seedApprovalWorkflowNotes( - clientId: string, - clinicianUserId: string, - adminUserId: string -) { - const existing = await prisma.sessionNote.count({ where: { clientId } }) - if (existing > 0) { - console.log('Session notes already exist; skipping approval-workflow seed.') - return - } - - const PLACEHOLDER_SIG = - 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=' - - const now = new Date() - - // 1. DRAFT progress note – still being written. - await prisma.sessionNote.create({ - data: { - clientId, - sessionName: 'Intake – initial session', - sessionNumber: 1, - kind: 'PROGRESS', - status: 'DRAFT', - content: - 'Client arrived on time. Presenting concerns include sleep disruption and work stress. Draft — still gathering history.', - attended: true, - }, - }) - - // 2. CLINICIAN_SIGNED progress note – waiting for admin sign-off. - const pendingNote = await prisma.sessionNote.create({ - data: { - clientId, - sessionName: 'Session 2 – CBT intro', - sessionNumber: 2, - kind: 'PROGRESS', - status: 'CLINICIAN_SIGNED', - content: - 'Reviewed sleep-hygiene worksheet. Client reports mild improvement. Introduced cognitive-restructuring framework.', - attended: true, - clinicianSignedAt: now, - clinicianSignedById: clinicianUserId, - clinicianSignatureData: PLACEHOLDER_SIG, - }, - }) - await prisma.notification.create({ - data: { - userId: adminUserId, - type: 'NOTE_READY_FOR_APPROVAL', - title: 'Note awaiting approval', - message: 'Carl Karl signed a progress note for Bob Builder. Please review and countersign.', - sessionNoteId: pendingNote.id, - }, - }) - - // 3. FULLY_APPROVED progress note. - await prisma.sessionNote.create({ - data: { - clientId, - sessionName: 'Session 3 – thought records', - sessionNumber: 3, - kind: 'PROGRESS', - status: 'FULLY_APPROVED', - content: - 'Completed two thought-record examples in session. Client identified core belief patterns and committed to daily practice.', - attended: true, - clinicianSignedAt: now, - clinicianSignedById: clinicianUserId, - clinicianSignatureData: PLACEHOLDER_SIG, - adminSignedAt: now, - adminSignedById: adminUserId, - adminSignatureData: PLACEHOLDER_SIG, - adminApprovalNote: 'Reviewed — documentation meets clinic standard.', - }, - }) - - // 4. PSYCHOTHERAPY draft – separately stored per HIPAA. - await prisma.sessionNote.create({ - data: { - clientId, - sessionName: 'Session 3 – clinician process notes', - sessionNumber: 3, - kind: 'PSYCHOTHERAPY', - status: 'DRAFT', - content: - 'Clinician-only process notes: countertransference observations, working hypotheses, and next-session targets.', - attended: true, - }, - }) - - // 5. PSYCHOTHERAPY fully approved – demonstrates tier-2 sign-off on process notes. - await prisma.sessionNote.create({ - data: { - clientId, - sessionName: 'Session 2 – clinician process notes', - sessionNumber: 2, - kind: 'PSYCHOTHERAPY', - status: 'FULLY_APPROVED', - content: - 'Process notes: explored defense patterns around perfectionism. Plan to revisit in session 4.', - attended: true, - clinicianSignedAt: now, - clinicianSignedById: clinicianUserId, - clinicianSignatureData: PLACEHOLDER_SIG, - adminSignedAt: now, - adminSignedById: adminUserId, - adminSignatureData: PLACEHOLDER_SIG, - adminApprovalNote: 'Approved — psychotherapy note retained separately.', - }, - }) - - console.log('Seeded 5 session notes across DRAFT / CLINICIAN_SIGNED / FULLY_APPROVED.') } async function main() { @@ -444,8 +206,8 @@ async function main() { await ensureDefaultDeclarationTemplates(prisma) await backfillSessionNotesRequestTemplates(prisma) - // Create / Upsert Alice (Admin — default approver for the note workflow) - const alice = await prisma.user.upsert({ + // Create / Upsert Alice (Admin) + await prisma.user.upsert({ where: { email: 'alice@a.com' }, update: { role: 'ADMIN', name: 'Alice Wonderland' }, create: { @@ -458,19 +220,30 @@ async function main() { }) console.log('Seeded Admin: alice@a.com') - // Create / Upsert Carl (Clinician) - const carl = await prisma.user.upsert({ - where: { email: 'carl@c.com' }, - update: { role: 'CLINICIAN', name: 'Carl Karl' }, - create: { - id: 'carl_id', - email: 'carl@c.com', - name: 'Carl Karl', - emailVerified: true, - role: 'CLINICIAN', - }, - }) - console.log('Seeded Clinician: carl@c.com') + const newAdmins = [ + { email: 'cxk230036@utdallas.edu', name: 'Charvisree Koripella ', id: 'charvisree_id' }, + { email: 'dxj230013@utdallas.edu', name: 'Deethya Janjanam', id: 'deethya_id' }, + { email: 'dxv230030@utdallas.edu', name: 'Devika Viju', id: 'devika_id' }, + { email: 'rxa230079@utdallas.edu', name: 'Ritikha Ashok', id: 'ritikha_id' }, + { email: 'sxr230101@utdallas.edu', name: 'Swaminathan Ramanathan', id: 'swaminathan_id' }, + { email: 'tmw220003@utdallas.edu', name: 'Tushar Wani', id: 'tushar_id' }, + { email: 'info@hopecopeheal.org', name: 'Adriana Lewin', id: 'adriana_id' }, + ] + + for (const admin of newAdmins) { + await prisma.user.upsert({ + where: { email: admin.email }, + update: { role: 'ADMIN', name: admin.name }, + create: { + id: admin.id, + email: admin.email, + name: admin.name, + emailVerified: true, + role: 'ADMIN', + }, + }) + console.log(`Seeded Admin: ${admin.email}`) + } // Create / Upsert Bob (Client) const bob = await prisma.user.upsert({ @@ -486,8 +259,7 @@ async function main() { }) console.log('Seeded Client: bob@b.com') - const bobClient = await ensureBobBuilderSessionNotes(bob.id, carl.id) - await seedApprovalWorkflowNotes(bobClient.id, carl.id, alice.id) + await ensureBobBuilderSessionNotes(bob.id) console.log('Seeding finished.') } @@ -501,3 +273,4 @@ main() await prisma.$disconnect() process.exit(1) }) + From 1c5b6df330312cf91be1d5cad631e2ef9a77d497 Mon Sep 17 00:00:00 2001 From: Deethya Janjanam Date: Sun, 26 Apr 2026 18:57:45 -0500 Subject: [PATCH 13/30] updated seed.ts file --- prisma/seed.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/prisma/seed.ts b/prisma/seed.ts index d97bf6d..142f27f 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -61,10 +61,8 @@ async function seedForms(userId: string) { }) // 3. PHQ-9 - const phqForm = await prisma.phqForm.upsert({ - where: { userId }, - update: {}, - create: { + const phqForm = await prisma.phqForm.create({ + data: { userId, status: 'COMPLETE', totalScore: 14, @@ -131,10 +129,8 @@ async function seedForms(userId: string) { }) // 5. ACE (Hardcoded Form) - const aceForm = await prisma.aceForm.upsert({ - where: { userId }, - update: {}, - create: { + const aceForm = await prisma.aceForm.create({ + data: { userId, status: 'COMPLETE', totalScore: 2, @@ -179,11 +175,15 @@ async function ensureBobBuilderSessionNotes(bobUserId: string) { data: [ { clientId: client.id, + sessionName: 'Intake / Week 1', + sessionNumber: 1, content: 'Intake / Week 1 — Rapport established. Bob reviewed clinic policies and confidentiality. Reported primary stressors related to work deadlines and sleep disruption. PHQ-9 and GAD-7 administered; safety screen negative. Plan: sleep hygiene handout, begin weekly CBT skills.', }, { clientId: client.id, + sessionName: 'Session 2', + sessionNumber: 2, content: 'Session 2 — Focus on thought challenging around catastrophic predictions at work. Homework: thought record for 3 situations. Bob engaged well; identified one automatic thought pattern to monitor between sessions.', }, From e25376ab7c4604f61ff0c62ac6825e444794839c Mon Sep 17 00:00:00 2001 From: Deethya Janjanam Date: Sun, 26 Apr 2026 19:08:50 -0500 Subject: [PATCH 14/30] error for video link is correctly showing up now! --- app/pages/calendar.vue | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/app/pages/calendar.vue b/app/pages/calendar.vue index a122925..6040816 100644 --- a/app/pages/calendar.vue +++ b/app/pages/calendar.vue @@ -237,6 +237,16 @@ }) const createTimeRangeError = ref('') const editTimeRangeError = ref('') + const createModalError = ref('') + const editModalError = ref('') + + function setCreateModalError(message: string) { + createModalError.value = message + } + + function setEditModalError(message: string) { + editModalError.value = message + } function getTimeRangeError( date: string, @@ -377,19 +387,19 @@ ? (selectedEvent.value.videoProvider as typeof editForm.videoProvider) || 'OTHER' : '' editTimeRangeError.value = '' + editModalError.value = '' } function cancelEdit() { isEditMode.value = false editTimeRangeError.value = '' + editModalError.value = '' } async function saveEdit() { + editModalError.value = '' if (editForm.includeVideo && !editForm.videoJoinUrl?.trim()) { - toast.add({ - title: 'Add a video link or uncheck Video', - color: 'warning', - }) + setEditModalError('Add a video link or uncheck Video.') return } editTimeRangeError.value = getTimeRangeError(editForm.date, editForm.startTime, editForm.endTime, { @@ -529,20 +539,20 @@ form.videoProvider = '' form.videoJoinUrl = '' createTimeRangeError.value = '' + createModalError.value = '' isCreateModalOpen.value = true } function closeCreateModal() { isCreateModalOpen.value = false createTimeRangeError.value = '' + createModalError.value = '' } async function createSession() { + createModalError.value = '' if (form.includeVideo && !form.videoJoinUrl?.trim()) { - toast.add({ - title: 'Add a video link or uncheck Video', - color: 'warning', - }) + setCreateModalError('Add a video link or uncheck Video.') return } createTimeRangeError.value = getTimeRangeError(form.date, form.startTime, form.endTime) @@ -669,6 +679,12 @@