@edvak99/voice-receptionist-widget 1.1.5 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -0
- package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-4UrqnTE3.mjs +306 -0
- package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-4UrqnTE3.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-ai-receptionist-api.service-srM0jC46.mjs → edvak99-voice-receptionist-widget-ai-receptionist-api.service-DokIb-9r.mjs} +2 -2
- package/fesm2022/{edvak99-voice-receptionist-widget-ai-receptionist-api.service-srM0jC46.mjs.map → edvak99-voice-receptionist-widget-ai-receptionist-api.service-DokIb-9r.mjs.map} +1 -1
- package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-DUR5f5nc.mjs +277 -0
- package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-DUR5f5nc.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-call-history-detail-page.component-0rW-PPWM.mjs → edvak99-voice-receptionist-widget-call-history-detail-page.component-A-vx_M3l.mjs} +9 -10
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-A-vx_M3l.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-gROZVIt-.mjs +193 -0
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-gROZVIt-.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-DGg_nI--.mjs → edvak99-voice-receptionist-widget-call-recording-player.component-Pla2UgeZ.mjs} +3 -3
- package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-DGg_nI--.mjs.map → edvak99-voice-receptionist-widget-call-recording-player.component-Pla2UgeZ.mjs.map} +1 -1
- package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-j_XV5a8S.mjs → edvak99-voice-receptionist-widget-call-review.service-Di7GLG9k.mjs} +2 -2
- package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-j_XV5a8S.mjs.map → edvak99-voice-receptionist-widget-call-review.service-Di7GLG9k.mjs.map} +1 -1
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-E30a8p3d.mjs +439 -0
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-E30a8p3d.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-dashboard-socket.service-CsfNZeQ4.mjs → edvak99-voice-receptionist-widget-dashboard-socket.service-D2pelzu4.mjs} +3 -3
- package/fesm2022/{edvak99-voice-receptionist-widget-dashboard-socket.service-CsfNZeQ4.mjs.map → edvak99-voice-receptionist-widget-dashboard-socket.service-D2pelzu4.mjs.map} +1 -1
- package/fesm2022/{edvak99-voice-receptionist-widget-eds-pulse-dot.component-DymAM4YH.mjs → edvak99-voice-receptionist-widget-eds-pulse-dot.component-Ig0Eoq1z.mjs} +4 -4
- package/fesm2022/{edvak99-voice-receptionist-widget-eds-pulse-dot.component-DymAM4YH.mjs.map → edvak99-voice-receptionist-widget-eds-pulse-dot.component-Ig0Eoq1z.mjs.map} +1 -1
- package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-BDtAQSyF.mjs +81 -0
- package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-BDtAQSyF.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-live-monitor-page.component-1elUtWOw.mjs → edvak99-voice-receptionist-widget-live-monitor-page.component-7e1HY6sB.mjs} +9 -9
- package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-7e1HY6sB.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-modal.component-uYApl1KF.mjs +48 -0
- package/fesm2022/edvak99-voice-receptionist-widget-modal.component-uYApl1KF.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-2GHT8NT9.mjs +267 -0
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-2GHT8NT9.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-BwCz1dlx.mjs +967 -0
- package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-BwCz1dlx.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-tasks-page.component-BGSupnFa.mjs → edvak99-voice-receptionist-widget-tasks-page.component-Mqo1UmfK.mjs} +7 -8
- package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-Mqo1UmfK.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-wizard-page.component-DskeqJwB.mjs +46 -0
- package/fesm2022/edvak99-voice-receptionist-widget-wizard-page.component-DskeqJwB.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget.mjs +228 -1
- package/fesm2022/edvak99-voice-receptionist-widget.mjs.map +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +3 -0
- package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-pQM1L7lO.mjs +0 -307
- package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-pQM1L7lO.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-B6O-PZHz.mjs +0 -278
- package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-B6O-PZHz.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-0rW-PPWM.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-Cec1ngRf.mjs +0 -194
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-Cec1ngRf.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-DD0tMAah.mjs +0 -440
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-DD0tMAah.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-eds-button.component-CAfTt7zB.mjs +0 -27
- package/fesm2022/edvak99-voice-receptionist-widget-eds-button.component-CAfTt7zB.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-JWqRMt9T.mjs +0 -203
- package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-JWqRMt9T.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-D5znr-Sx.mjs +0 -81
- package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-D5znr-Sx.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-1elUtWOw.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-modal.component-Cb-FoQ1N.mjs +0 -48
- package/fesm2022/edvak99-voice-receptionist-widget-modal.component-Cb-FoQ1N.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-CwLxW1W9.mjs +0 -268
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-CwLxW1W9.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-DAr4wuUk.mjs +0 -968
- package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-DAr4wuUk.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-BGSupnFa.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-wizard-page.component-5iG9eQRi.mjs +0 -47
- package/fesm2022/edvak99-voice-receptionist-widget-wizard-page.component-5iG9eQRi.mjs.map +0 -1
package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-DD0tMAah.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"edvak99-voice-receptionist-widget-dashboard-page.component-DD0tMAah.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/components/outbound-dial-modal/outbound-dial-modal.component.ts","../../../projects/voice-receptionist-widget/src/lib/components/outbound-dial-modal/outbound-dial-modal.component.html","../../../projects/voice-receptionist-widget/src/lib/pages/dashboard-page/dashboard-page.component.ts","../../../projects/voice-receptionist-widget/src/lib/pages/dashboard-page/dashboard-page.component.html"],"sourcesContent":["import { DatePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n EventEmitter,\n Input,\n OnChanges,\n Output,\n SimpleChanges,\n inject,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormsModule } from '@angular/forms';\nimport { Subject, debounceTime, distinctUntilChanged, switchMap, of, catchError } from 'rxjs';\n\nimport {\n OutboundAppointmentHit,\n OutboundPatientHit,\n toE164Phone,\n} from '../../models/outbound-patient.types';\nimport { OutboundPurpose } from '../../models/outbound-purpose.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport {\n formatOpeningDate,\n formatOpeningTime,\n isCustomScriptRequired,\n isPurposeFormValid,\n purposeShowsCustomScript,\n renderLiveOpeningPreview,\n requiredFieldLabel,\n} from '../../utils/outbound-purpose.util';\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\nimport { ModalComponent } from '../../shared/modal.component';\nimport { ToastService } from '../../shared/toast.service';\n\nconst E164_PATTERN = /^\\+[1-9]\\d{6,14}$/;\n\n@Component({\n selector: 'eds-outbound-dial-modal',\n imports: [FormsModule, ModalComponent, EdsButtonComponent, DatePipe],\n templateUrl: './outbound-dial-modal.component.html',\n styleUrl: './outbound-dial-modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class OutboundDialModalComponent implements OnChanges {\n private readonly api = inject(AiReceptionistApiService);\n private readonly toast = inject(ToastService);\n private readonly destroyRef = inject(DestroyRef);\n\n @Input() open = false;\n @Output() readonly closed = new EventEmitter<void>();\n @Output() readonly dialed = new EventEmitter<void>();\n\n protected readonly purposes = signal<OutboundPurpose[]>([]);\n protected readonly loading = signal(true);\n protected readonly submitting = signal(false);\n protected readonly serverError = signal<string | null>(null);\n\n protected readonly patientHits = signal<OutboundPatientHit[]>([]);\n protected readonly searchingPatients = signal(false);\n protected readonly selectedPatient = signal<OutboundPatientHit | null>(null);\n protected readonly appointments = signal<OutboundAppointmentHit[]>([]);\n protected readonly loadingAppointments = signal(false);\n protected readonly selectedAppointmentId = signal<string | null>(null);\n protected readonly showManualEntry = signal(false);\n protected readonly practiceName = signal('');\n /** Bumps OnPush re-render when plain ngModel fields change. */\n protected readonly formEpoch = signal(0);\n\n protected patientQuery = '';\n protected phone = '';\n protected name = '';\n protected purposeId = '';\n protected appointmentDate = '';\n protected appointmentTime = '';\n protected providerName = '';\n protected customScript = '';\n\n protected requiredFieldLabel = requiredFieldLabel;\n\n private readonly search$ = new Subject<string>();\n\n constructor() {\n this.search$\n .pipe(\n debounceTime(280),\n distinctUntilChanged(),\n switchMap((q) => {\n const query = q.trim();\n if (query.length < 2) {\n this.searchingPatients.set(false);\n this.patientHits.set([]);\n return of([] as OutboundPatientHit[]);\n }\n this.searchingPatients.set(true);\n return this.api.searchPatientsForOutbound(query, 10).pipe(\n catchError(() => of([] as OutboundPatientHit[])),\n );\n }),\n takeUntilDestroyed(this.destroyRef),\n )\n .subscribe((hits) => {\n this.searchingPatients.set(false);\n if (!this.selectedPatient()) {\n this.patientHits.set(hits);\n }\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['open']?.currentValue) {\n this.resetForm();\n this.loadPurposes();\n this.loadPracticeName();\n }\n }\n\n protected get selectedPurpose(): OutboundPurpose | null {\n return this.purposes().find((p) => p.purposeId === this.purposeId) ?? null;\n }\n\n protected get selectedAppointment(): OutboundAppointmentHit | null {\n const id = this.selectedAppointmentId();\n if (!id) return null;\n return this.appointments().find((a) => a.appointmentId === id) ?? null;\n }\n\n protected get previewText(): string {\n this.formEpoch(); // depend for CD when form fields change\n const p = this.selectedPurpose;\n if (!p) return '—';\n const appt = this.selectedAppointment;\n const dateSource = appt?.startTime || this.appointmentDate;\n const timeSource = appt?.startTime || this.appointmentTime;\n return renderLiveOpeningPreview(p, {\n patientName: this.name.trim() || this.selectedPatient()?.fullName || '',\n appointmentDate: formatOpeningDate(dateSource),\n appointmentTime: formatOpeningTime(this.appointmentTime || timeSource, appt?.startTime),\n providerName: this.providerName.trim() || appt?.providerName || '',\n practiceName: this.practiceName(),\n locationName: appt?.locationName || '',\n visitType: appt?.visitType || '',\n customScript: this.customScript.trim(),\n });\n }\n\n protected showsField(field: 'appointmentDate' | 'appointmentTime' | 'providerName'): boolean {\n return this.selectedPurpose?.requiredFields.includes(field) ?? false;\n }\n\n protected showsCustomScript(): boolean {\n const p = this.selectedPurpose;\n return p ? purposeShowsCustomScript(p) : false;\n }\n\n protected customScriptRequired(): boolean {\n const p = this.selectedPurpose;\n return p ? isCustomScriptRequired(p) : false;\n }\n\n protected canPlaceCall(): boolean {\n if (!E164_PATTERN.test(this.phone.trim())) return false;\n return isPurposeFormValid(this.selectedPurpose, {\n phone: this.phone,\n name: this.name,\n appointmentDate: this.appointmentDate,\n appointmentTime: this.appointmentTime,\n providerName: this.providerName,\n customScript: this.customScript,\n });\n }\n\n protected touchForm(): void {\n this.formEpoch.update((n) => n + 1);\n }\n\n protected onPatientQueryChange(value: string): void {\n this.patientQuery = value;\n if (this.selectedPatient()) return;\n this.search$.next(value);\n }\n\n protected selectPatient(patient: OutboundPatientHit): void {\n this.selectedPatient.set(patient);\n this.patientHits.set([]);\n this.patientQuery = patient.fullName;\n this.name = patient.fullName;\n this.phone = toE164Phone(patient.phone) || '';\n this.showManualEntry.set(!this.phone);\n this.selectedAppointmentId.set(null);\n this.clearApptDerivedFields();\n this.touchForm();\n this.loadAppointments(patient.patientId);\n }\n\n protected clearPatient(): void {\n this.selectedPatient.set(null);\n this.patientQuery = '';\n this.patientHits.set([]);\n this.appointments.set([]);\n this.selectedAppointmentId.set(null);\n this.name = '';\n this.phone = '';\n this.clearApptDerivedFields();\n this.touchForm();\n }\n\n protected selectAppointment(appt: OutboundAppointmentHit | null): void {\n this.selectedAppointmentId.set(appt?.appointmentId ?? null);\n if (!appt) {\n this.clearApptDerivedFields();\n this.touchForm();\n return;\n }\n this.applyAppointmentFields(appt);\n this.preferAppointmentPurpose();\n this.touchForm();\n }\n\n protected onPurposeChange(): void {\n const appt = this.selectedAppointment;\n if (appt) {\n this.applyAppointmentFields(appt);\n } else {\n this.clearApptDerivedFields();\n }\n this.customScript = '';\n this.serverError.set(null);\n this.touchForm();\n }\n\n protected close(): void {\n this.closed.emit();\n }\n\n protected submit(): void {\n this.serverError.set(null);\n if (!this.canPlaceCall() || !this.selectedPurpose) return;\n\n this.submitting.set(true);\n const patient = this.selectedPatient();\n const apptId = this.selectedAppointmentId();\n const body = {\n phone: this.phone.trim(),\n name: this.name.trim(),\n purpose: this.purposeId,\n ...(this.appointmentDate ? { appointmentDate: this.appointmentDate } : {}),\n ...(this.appointmentTime ? { appointmentTime: this.appointmentTime } : {}),\n ...(this.providerName ? { providerName: this.providerName.trim() } : {}),\n ...(this.customScript ? { customScript: this.customScript.trim() } : {}),\n ...(patient?.patientId ? { patientId: patient.patientId } : {}),\n ...(apptId ? { appointmentId: apptId } : {}),\n };\n\n this.api.placeOutboundCall(body).subscribe({\n next: (res) => {\n this.submitting.set(false);\n const msg = res.message ?? 'Outbound call started.';\n this.toast.show(msg, 'success', 5000);\n this.dialed.emit();\n this.close();\n },\n error: (err: { message?: string }) => {\n this.submitting.set(false);\n const msg = err?.message ?? 'Failed to place outbound call.';\n this.serverError.set(msg);\n this.toast.show(msg, 'error', 5000);\n },\n });\n }\n\n private preferAppointmentPurpose(): void {\n const current = this.selectedPurpose;\n const needsAppt =\n !!current &&\n (current.requiredFields.includes('appointmentDate') ||\n current.requiredFields.includes('appointmentTime'));\n if (needsAppt) return;\n\n const confirm =\n this.purposes().find(\n (p) =>\n p.isActive &&\n p.requiredFields.includes('appointmentDate') &&\n p.requiredFields.includes('appointmentTime'),\n ) ??\n this.purposes().find((p) => p.isActive && /confirm/i.test(p.label + p.purposeId));\n\n if (confirm) {\n this.purposeId = confirm.purposeId;\n }\n }\n\n private applyAppointmentFields(appt: OutboundAppointmentHit): void {\n const start = appt.startTime ? new Date(appt.startTime) : null;\n if (start && !Number.isNaN(start.getTime())) {\n const y = start.getFullYear();\n const m = String(start.getMonth() + 1).padStart(2, '0');\n const d = String(start.getDate()).padStart(2, '0');\n const hh = String(start.getHours()).padStart(2, '0');\n const mm = String(start.getMinutes()).padStart(2, '0');\n this.appointmentDate = `${y}-${m}-${d}`;\n this.appointmentTime = `${hh}:${mm}`;\n }\n if (appt.providerName) {\n this.providerName = appt.providerName;\n }\n }\n\n private clearApptDerivedFields(): void {\n this.appointmentDate = '';\n this.appointmentTime = '';\n this.providerName = '';\n }\n\n private loadAppointments(patientId: string): void {\n this.loadingAppointments.set(true);\n this.appointments.set([]);\n this.api.listPatientAppointmentsForOutbound(patientId, 20).subscribe({\n next: (rows) => {\n this.appointments.set(rows);\n this.loadingAppointments.set(false);\n if (rows.length === 1) {\n this.selectAppointment(rows[0]);\n }\n },\n error: () => {\n this.loadingAppointments.set(false);\n this.appointments.set([]);\n },\n });\n }\n\n private loadPracticeName(): void {\n this.api.getSettings().subscribe({\n next: ({ data }) => {\n const name = String(data.general?.['practiceName'] ?? '').trim();\n this.practiceName.set(name || 'our office');\n },\n error: () => this.practiceName.set('our office'),\n });\n }\n\n private resetForm(): void {\n this.patientQuery = '';\n this.phone = '';\n this.name = '';\n this.purposeId = '';\n this.appointmentDate = '';\n this.appointmentTime = '';\n this.providerName = '';\n this.customScript = '';\n this.patientHits.set([]);\n this.selectedPatient.set(null);\n this.appointments.set([]);\n this.selectedAppointmentId.set(null);\n this.searchingPatients.set(false);\n this.loadingAppointments.set(false);\n this.showManualEntry.set(false);\n this.serverError.set(null);\n this.submitting.set(false);\n this.formEpoch.set(0);\n }\n\n private loadPurposes(): void {\n this.loading.set(true);\n this.api.getOutboundPurposes(false).subscribe({\n next: ({ purposes }) => {\n this.purposes.set(purposes);\n if (purposes.length && !this.purposeId) {\n this.purposeId = purposes[0].purposeId;\n }\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.serverError.set('Failed to load outbound purposes.');\n },\n });\n }\n}\n","@if (open) {\n <app-modal\n title=\"Outbound call\"\n subtitle=\"Search a patient, pick an appointment, then dial\"\n maxWidth=\"600px\"\n (closed)=\"close()\"\n >\n @if (loading()) {\n <p class=\"eds-body-sm\">Loading purposes…</p>\n } @else {\n <form class=\"flex flex-col gap-3\" (ngSubmit)=\"submit()\" novalidate autocomplete=\"off\">\n <div class=\"dial-form__field dial-form__typeahead relative flex flex-col gap-1.5\">\n <span class=\"eds-label\">Patient <span class=\"text-[#dc2626]\">*</span></span>\n\n @if (selectedPatient(); as patient) {\n <div class=\"flex items-center justify-between gap-3 rounded-lg border border-[var(--eds-border-subtle,#e4e4e7)] bg-[var(--eds-surface-muted,#f8fafc)] px-3 py-2.5\">\n <div class=\"flex min-w-0 flex-col gap-0.5\">\n <strong>{{ patient.fullName }}</strong>\n <span class=\"dial-form__chip-meta text-xs\">\n @if (patient.phone) {\n {{ patient.phone }}\n }\n @if (patient.dob) {\n · DOB {{ patient.dob }}\n }\n </span>\n </div>\n <button type=\"button\" class=\"dial-form__chip-clear shrink-0 cursor-pointer border-none bg-transparent p-1 text-[13px] font-[inherit]\" (click)=\"clearPatient()\">\n Change\n </button>\n </div>\n } @else {\n <input\n type=\"search\"\n class=\"dial-form__input rounded-lg border px-2.5 py-2 font-[inherit]\"\n [ngModel]=\"patientQuery\"\n (ngModelChange)=\"onPatientQueryChange($event)\"\n name=\"patientQuery\"\n placeholder=\"Search by name or phone\"\n autocomplete=\"off\"\n />\n @if (searchingPatients()) {\n <span class=\"dial-form__hint text-xs\">Searching…</span>\n }\n @if (patientHits().length) {\n <ul class=\"dial-form__hits absolute left-0 right-0 top-[calc(100%+4px)] z-[5] max-h-[220px] overflow-hidden overflow-y-auto rounded-lg border\" role=\"listbox\">\n @for (hit of patientHits(); track hit.patientId) {\n <li>\n <button\n type=\"button\"\n class=\"dial-form__hit flex w-full cursor-pointer flex-col items-start gap-0.5 border-none border-b px-3 py-2.5 text-left font-[inherit] last:border-b-0\"\n role=\"option\"\n (click)=\"selectPatient(hit)\"\n >\n <span class=\"font-semibold\">{{ hit.fullName }}</span>\n <span class=\"dial-form__hit-meta text-xs\">\n {{ hit.phone || 'No phone' }}\n @if (hit.dob) {\n · {{ hit.dob }}\n }\n </span>\n </button>\n </li>\n }\n </ul>\n }\n }\n </div>\n\n @if (selectedPatient()) {\n <div class=\"flex flex-col gap-1.5\">\n <span class=\"eds-label\">Appointment</span>\n @if (loadingAppointments()) {\n <span class=\"dial-form__hint text-xs\">Loading appointments…</span>\n } @else if (!appointments().length) {\n <span class=\"dial-form__hint text-xs\">No upcoming appointments — dial without one, or enter details below.</span>\n } @else {\n <ul class=\"max-h-[220px] overflow-hidden overflow-y-auto rounded-lg border\">\n <li>\n <label class=\"dial-form__appt flex cursor-pointer items-start gap-2.5 border-b px-3 py-2.5 last:border-b-0\">\n <input\n type=\"radio\"\n name=\"appointmentId\"\n [checked]=\"!selectedAppointmentId()\"\n (change)=\"selectAppointment(null)\"\n autocomplete=\"off\"\n />\n <span>No appointment (purpose-only)</span>\n </label>\n </li>\n @for (appt of appointments(); track appt.appointmentId) {\n <li>\n <label class=\"dial-form__appt flex cursor-pointer items-start gap-2.5 border-b px-3 py-2.5 last:border-b-0\">\n <input\n type=\"radio\"\n name=\"appointmentId\"\n [checked]=\"selectedAppointmentId() === appt.appointmentId\"\n (change)=\"selectAppointment(appt)\"\n autocomplete=\"off\"\n />\n <span class=\"flex flex-col gap-0.5\">\n <strong>\n {{ appt.startTime ? (appt.startTime | date: 'medium') : 'TBD' }}\n </strong>\n <span class=\"dial-form__hit-meta text-xs\">\n {{ appt.providerName || 'Provider TBD' }}\n @if (appt.locationName) {\n · {{ appt.locationName }}\n }\n @if (appt.visitType) {\n · {{ appt.visitType }}\n }\n @if (appt.status) {\n · {{ appt.status }}\n }\n </span>\n </span>\n </label>\n </li>\n }\n </ul>\n }\n </div>\n }\n\n <button\n type=\"button\"\n class=\"dial-form__toggle self-start cursor-pointer border-none bg-transparent p-0 text-[13px] font-[inherit]\"\n (click)=\"showManualEntry.set(!showManualEntry())\"\n >\n {{ showManualEntry() ? 'Hide' : 'Show' }} phone / name\n @if (!selectedPatient()) {\n (required if no patient selected)\n }\n </button>\n\n @if (showManualEntry() || !selectedPatient()) {\n <label class=\"flex flex-col gap-1.5\">\n <span class=\"eds-label\">Phone <span class=\"text-[#dc2626]\">*</span></span>\n <input\n type=\"tel\"\n class=\"dial-form__input rounded-lg border px-2.5 py-2 font-[inherit]\"\n [(ngModel)]=\"phone\"\n (ngModelChange)=\"touchForm()\"\n name=\"phone\"\n placeholder=\"+14155550100\"\n autocomplete=\"off\"\n required\n />\n <span class=\"dial-form__hint text-xs\">E.164 format, e.g. +14155550100</span>\n </label>\n\n <label class=\"flex flex-col gap-1.5\">\n <span class=\"eds-label\">Patient name <span class=\"text-[#dc2626]\">*</span></span>\n <input\n type=\"text\"\n class=\"dial-form__input rounded-lg border px-2.5 py-2 font-[inherit]\"\n [(ngModel)]=\"name\"\n (ngModelChange)=\"touchForm()\"\n name=\"name\"\n placeholder=\"Maria Garcia\"\n required\n autocomplete=\"off\"\n />\n </label>\n }\n\n <label class=\"flex flex-col gap-1.5\">\n <span class=\"eds-label\">Purpose <span class=\"text-[#dc2626]\">*</span></span>\n <select\n class=\"dial-form__input rounded-lg border px-2.5 py-2 font-[inherit]\"\n [(ngModel)]=\"purposeId\"\n name=\"purposeId\"\n (ngModelChange)=\"onPurposeChange()\"\n required\n autocomplete=\"off\"\n >\n @for (p of purposes(); track p.purposeId) {\n <option [value]=\"p.purposeId\">{{ p.label }}</option>\n }\n </select>\n </label>\n\n @if (showsField('appointmentDate') && !selectedAppointmentId()) {\n <label class=\"flex flex-col gap-1.5\">\n <span class=\"eds-label\">{{ requiredFieldLabel('appointmentDate') }} <span class=\"text-[#dc2626]\">*</span></span>\n <input\n type=\"date\"\n class=\"dial-form__input rounded-lg border px-2.5 py-2 font-[inherit]\"\n [(ngModel)]=\"appointmentDate\"\n (ngModelChange)=\"touchForm()\"\n name=\"appointmentDate\"\n required\n autocomplete=\"off\"\n />\n </label>\n }\n\n @if (showsField('appointmentTime') && !selectedAppointmentId()) {\n <label class=\"flex flex-col gap-1.5\">\n <span class=\"eds-label\">{{ requiredFieldLabel('appointmentTime') }} <span class=\"text-[#dc2626]\">*</span></span>\n <input\n type=\"time\"\n class=\"dial-form__input rounded-lg border px-2.5 py-2 font-[inherit]\"\n [(ngModel)]=\"appointmentTime\"\n (ngModelChange)=\"touchForm()\"\n name=\"appointmentTime\"\n required\n autocomplete=\"off\"\n />\n </label>\n }\n\n @if (showsField('providerName') && !selectedAppointmentId()) {\n <label class=\"flex flex-col gap-1.5\">\n <span class=\"eds-label\">{{ requiredFieldLabel('providerName') }} <span class=\"text-[#dc2626]\">*</span></span>\n <input\n type=\"text\"\n class=\"dial-form__input rounded-lg border px-2.5 py-2 font-[inherit]\"\n [(ngModel)]=\"providerName\"\n (ngModelChange)=\"touchForm()\"\n name=\"providerName\"\n placeholder=\"Dr. Patel\"\n required\n autocomplete=\"off\"\n />\n </label>\n }\n\n @if (selectedAppointmentId() && (showsField('appointmentDate') || showsField('appointmentTime') || showsField('providerName'))) {\n <p class=\"dial-form__hint text-xs\">\n Date, time, and provider are taken from the selected appointment\n @if (appointmentDate || appointmentTime || providerName) {\n ({{ appointmentDate }}\n @if (appointmentTime) {\n {{ appointmentTime }}\n }\n @if (providerName) {\n · {{ providerName }}\n })\n }.\n </p>\n }\n\n @if (showsCustomScript()) {\n <label class=\"flex flex-col gap-1.5\">\n <span class=\"eds-label\">\n Custom script\n @if (customScriptRequired()) {\n <span class=\"text-[#dc2626]\">*</span>\n }\n </span>\n <textarea\n class=\"dial-form__textarea resize-y rounded-lg border px-2.5 py-2 font-[inherit]\"\n rows=\"4\"\n [(ngModel)]=\"customScript\"\n (ngModelChange)=\"touchForm()\"\n name=\"customScript\"\n [required]=\"customScriptRequired()\"\n placeholder=\"What should the agent say or do?\"\n autocomplete=\"off\"\n ></textarea>\n </label>\n }\n\n <section class=\"dial-form__preview eds-card rounded-lg p-3 shadow-sm\">\n <h3 class=\"eds-label\">Opening preview</h3>\n <p class=\"dial-form__preview-text mt-2 whitespace-pre-wrap text-sm leading-normal\">{{ previewText }}</p>\n @if (selectedAppointmentId()) {\n <p class=\"dial-form__hint text-xs\">\n Filled from the selected appointment and purpose template. Switch purpose to change the script.\n </p>\n } @else {\n <p class=\"dial-form__hint text-xs\">\n Select an appointment to fill date, time, and provider into this message.\n </p>\n }\n </section>\n\n @if (serverError()) {\n <p class=\"m-0 text-[13px] text-[#b91c1c]\" role=\"alert\">{{ serverError() }}</p>\n }\n\n <footer class=\"mt-1 flex justify-end gap-2\">\n <eds-button variant=\"secondary\" type=\"button\" (click)=\"close()\" [disabled]=\"submitting()\">\n Cancel\n </eds-button>\n <eds-button variant=\"primary\" type=\"submit\" [disabled]=\"submitting() || !canPlaceCall()\">\n {{ submitting() ? 'Dialing…' : 'Place call' }}\n </eds-button>\n </footer>\n </form>\n }\n </app-modal>\n}\n","import { ChangeDetectionStrategy, Component, inject, OnDestroy, OnInit, signal } from '@angular/core';\nimport { ActivatedRoute, Router, RouterLink } from '@angular/router';\nimport { DatePipe } from '@angular/common';\n\nimport { DashboardData, HistoryCall } from '../../models/ai-receptionist.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { LiveCallsListService } from '../../services/live-calls-list.service';\nimport {\n callerMetaLine,\n historyResolution,\n historyResolutionLabel,\n historyResultChips,\n resultChipIcon,\n} from '../../utils/call-history-display.util';\nimport { isNeedsReview } from '../../utils/call-review.util';\nimport { OutboundDialModalComponent } from '../../components/outbound-dial-modal/outbound-dial-modal.component';\nimport { EdsAvatarComponent } from '../../ui/eds-avatar.component';\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\nimport { EdsPulseDotComponent } from '../../ui/eds-pulse-dot.component';\nimport { EdsElapsedPipe } from '../../pipes/eds-elapsed.pipe';\n\n@Component({\n selector: 'eds-dashboard-page',\n imports: [\n RouterLink,\n DatePipe,\n EdsAvatarComponent,\n EdsButtonComponent,\n EdsIconComponent,\n EdsPulseDotComponent,\n EdsElapsedPipe,\n OutboundDialModalComponent,\n ],\n templateUrl: './dashboard-page.component.html',\n styleUrl: './dashboard-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class DashboardPageComponent implements OnInit, OnDestroy {\n private readonly api = inject(AiReceptionistApiService);\n private readonly liveCallsList = inject(LiveCallsListService);\n private readonly router = inject(Router);\n private readonly route = inject(ActivatedRoute);\n\n protected readonly data = signal<DashboardData | null>(null);\n protected readonly loading = signal(true);\n\n protected readonly liveCalls = this.liveCallsList.calls;\n protected readonly liveCallsLoading = this.liveCallsList.loading;\n protected readonly liveCallsError = this.liveCallsList.error;\n protected readonly outboundOpen = signal(false);\n\n protected readonly statTiles = [\n { key: 'activeCalls' as const, label: 'Live calls', icon: 'graphic_eq' },\n { key: 'answeredToday' as const, label: 'Calls today', icon: 'call' },\n { key: 'tasksCreated' as const, label: 'Open tasks', icon: 'task_alt' },\n {\n key: 'appointmentsBooked' as const,\n label: 'Appointments booked',\n icon: 'event_available',\n },\n { key: 'completionRate' as const, label: 'AI handled', icon: 'trending_up', suffix: '%' },\n ];\n\n protected isNeedsReview = isNeedsReview;\n protected callerMetaLine = callerMetaLine;\n protected resultChipIcon = resultChipIcon;\n protected historyResultChips = historyResultChips;\n protected historyResolutionLabel = historyResolutionLabel;\n\n ngOnInit(): void {\n this.liveCallsList.start();\n this.api.getDashboard().subscribe(({ data }) => {\n this.data.set(data);\n this.loading.set(false);\n });\n }\n\n ngOnDestroy(): void {\n this.liveCallsList.stop();\n }\n\n protected statValue(key: keyof DashboardData['stats']): number {\n if (key === 'activeCalls') {\n return this.liveCallsList.calls().length;\n }\n return this.data()?.stats[key] ?? 0;\n }\n\n protected statusTone(status: string): 'brand' | 'pos' | 'notice' | 'neg' | 'violet' | 'gray' {\n const normalized = status || 'ai';\n const map: Record<string, 'brand' | 'pos' | 'notice' | 'neg' | 'violet'> = {\n ai: 'brand',\n 'needs-help': 'notice',\n 'human-requested': 'violet',\n urgent: 'neg',\n takeover: 'violet',\n transferring: 'notice',\n };\n return map[normalized] ?? 'brand';\n }\n\n protected statusLabel(status: string): string {\n return status || 'ai';\n }\n\n protected historyAvatarTone(row: HistoryCall): 'gray' | 'brand' {\n if (!row.name?.trim() || /^unknown/i.test(row.name) || row.initials === '?') return 'gray';\n return 'brand';\n }\n\n protected resolutionOf(row: HistoryCall) {\n return historyResolution({ outcome: row.outcome, risk: row.risk });\n }\n\n protected formatDuration(sec: number): string {\n const m = Math.floor(sec / 60);\n const s = sec % 60;\n return `${m}:${s.toString().padStart(2, '0')}`;\n }\n\n protected exportCsv(): void {\n // mock export\n }\n\n protected openOutboundDial(): void {\n this.outboundOpen.set(true);\n }\n\n protected closeOutboundDial(): void {\n this.outboundOpen.set(false);\n }\n\n protected openHistoryDetail(id: string): void {\n void this.router.navigate(['../history', id], { relativeTo: this.route });\n }\n\n protected callDetailLink(callId: string): string[] {\n return ['../history', callId];\n }\n\n protected appointmentDetailLink(callId: string | null | undefined): string[] {\n return callId ? ['../history', callId] : ['../history'];\n }\n}\n","<div class=\"eds-page dashboard-page\">\n <header class=\"mb-6 flex items-start justify-between gap-4\">\n <div>\n <h1 class=\"eds-h1\">Dashboard</h1>\n <p class=\"eds-body-sm\">AI receptionist overview and live activity</p>\n </div>\n <div class=\"flex shrink-0 gap-2\">\n <eds-button variant=\"secondary\" (click)=\"exportCsv()\">\n <eds-icon name=\"download\" [size]=\"18\" /> Export\n </eds-button>\n <eds-button variant=\"primary\" (click)=\"openOutboundDial()\">\n <eds-icon name=\"call_made\" [size]=\"18\" /> New outbound call\n </eds-button>\n </div>\n </header>\n\n @if (loading()) {\n <p class=\"eds-body-sm\">Loading dashboard…</p>\n } @else if (data()) {\n <section class=\"mb-5 grid grid-cols-2 gap-3 md:grid-cols-3 lg:grid-cols-5\">\n @for (tile of statTiles; track tile.key) {\n @if (tile.key === 'appointmentsBooked') {\n <a routerLink=\"../appointments\" class=\"eds-card flex cursor-pointer flex-col gap-1.5 p-4 no-underline text-inherit transition-colors hover:border-blue-600 shadow-sm\">\n <eds-icon [name]=\"tile.icon\" [size]=\"22\" />\n <span class=\"eds-label\">{{ tile.label }}</span>\n <span class=\"text-3xl font-semibold tracking-tight text-zinc-900\">\n {{ statValue(tile.key) }}{{ tile.suffix ?? '' }}\n </span>\n </a>\n } @else if (tile.key === 'activeCalls') {\n <a routerLink=\"../live\" class=\"eds-card flex cursor-pointer flex-col gap-1.5 p-4 no-underline text-inherit transition-colors hover:border-blue-600 shadow-sm\">\n <eds-icon [name]=\"tile.icon\" [size]=\"22\" />\n <span class=\"eds-label\">{{ tile.label }}</span>\n <span class=\"text-3xl font-semibold tracking-tight text-zinc-900\">\n {{ statValue(tile.key) }}{{ tile.suffix ?? '' }}\n </span>\n </a>\n } @else {\n <article class=\"eds-card flex flex-col gap-1.5 p-4 shadow-sm\">\n <eds-icon [name]=\"tile.icon\" [size]=\"22\" />\n <span class=\"eds-label\">{{ tile.label }}</span>\n <span class=\"text-3xl font-semibold tracking-tight text-zinc-900\">\n {{ statValue(tile.key) }}{{ tile.suffix ?? '' }}\n </span>\n </article>\n }\n }\n </section>\n\n <section class=\"mb-5 grid grid-cols-1 gap-4 lg:grid-cols-3\">\n <article class=\"eds-card p-4 shadow-sm\">\n <header class=\"mb-3 flex items-center justify-between gap-2\">\n <h2 class=\"eds-h2\">Live calls</h2>\n <eds-pulse-dot />\n </header>\n <ul class=\"m-0 flex list-none flex-col gap-2 p-0\">\n @if (liveCallsError()) {\n <li class=\"eds-body-sm\" role=\"alert\">{{ liveCallsError() }}</li>\n }\n @if (liveCallsLoading() && liveCalls().length === 0) {\n <li class=\"eds-body-sm\">Loading live calls…</li>\n }\n @for (call of liveCalls(); track call.id) {\n <li>\n <a [routerLink]=\"['../live', call.id]\" class=\"grid grid-cols-[auto_1fr_auto] items-center gap-2.5 rounded-md p-2 no-underline text-inherit hover:bg-zinc-50\">\n <eds-avatar [initials]=\"call.initials\" tone=\"brand\" />\n <div class=\"flex min-w-0 flex-col\">\n <span class=\"eds-body-sm-bold\">{{ call.name }}</span>\n <span class=\"eds-body-sm\">{{ call.reason }}</span>\n </div>\n <span class=\"eds-mono-sm\">{{ call.started | edsElapsed }}</span>\n </a>\n </li>\n } @empty {\n @if (!liveCallsLoading()) {\n <li class=\"eds-body-sm\">No active calls right now.</li>\n }\n }\n </ul>\n </article>\n\n <article class=\"eds-card p-4 shadow-sm\">\n <header class=\"mb-3 flex items-center justify-between gap-2\">\n <h2 class=\"eds-h2\">Tasks created</h2>\n <a routerLink=\"../tasks\" class=\"eds-body-sm\">View all</a>\n </header>\n <ul class=\"m-0 flex list-none flex-col gap-2 p-0\">\n @for (task of data()!.latestTasks; track task.id) {\n <li class=\"border-b border-zinc-200 last:border-b-0\">\n <a\n [routerLink]=\"task.callId ? callDetailLink(task.callId) : ['../tasks']\"\n class=\"grid grid-cols-[1fr_auto] items-center gap-2.5 rounded-md p-2 no-underline text-inherit hover:bg-zinc-50\"\n [attr.aria-label]=\"'View task: ' + task.title\"\n >\n <div>\n <span class=\"eds-body-sm-bold\">{{ task.title }}</span>\n <span class=\"eds-body-sm\">\n {{ task.patient }} · {{ task.created | date: 'short' }}\n </span>\n </div>\n <eds-icon name=\"chevron_right\" [size]=\"20\" />\n </a>\n </li>\n } @empty {\n <li class=\"eds-body-sm\">No AI-created tasks yet.</li>\n }\n </ul>\n </article>\n\n <article class=\"eds-card p-4 shadow-sm\">\n <header class=\"mb-3 flex items-center justify-between gap-2\">\n <h2 class=\"eds-h2\">Appointments created</h2>\n <a routerLink=\"../appointments\" class=\"eds-body-sm\">View all</a>\n </header>\n <ul class=\"m-0 flex list-none flex-col gap-2 p-0\">\n @for (appointment of data()!.latestAppointments; track appointment.id) {\n <li class=\"border-b border-zinc-200 last:border-b-0\">\n <a\n [routerLink]=\"appointmentDetailLink(appointment.callId)\"\n class=\"grid grid-cols-[1fr_auto] items-center gap-2.5 rounded-md p-2 no-underline text-inherit hover:bg-zinc-50\"\n [attr.aria-label]=\"'View appointment for ' + appointment.patientName\"\n >\n <div>\n <span class=\"eds-body-sm-bold\">{{ appointment.patientName }}</span>\n <span class=\"eds-body-sm\">\n {{ appointment.providerName ?? 'Provider not assigned' }}\n · {{ appointment.startTime ? (appointment.startTime | date: 'short') : 'Time pending' }}\n </span>\n </div>\n <eds-icon name=\"chevron_right\" [size]=\"20\" />\n </a>\n </li>\n } @empty {\n <li class=\"eds-body-sm\">No AI-booked appointments yet.</li>\n }\n </ul>\n </article>\n\n </section>\n\n <article class=\"eds-card overflow-x-auto p-4 shadow-sm\">\n <header class=\"mb-3 flex items-center justify-between gap-2\">\n <h2 class=\"eds-h2\">Recent Call History</h2>\n <a routerLink=\"../history\" class=\"eds-body-sm\">View all</a>\n </header>\n <div class=\"overflow-x-auto\">\n <table class=\"w-full min-w-5xl border-collapse\">\n <thead>\n <tr>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-3.5 py-3 text-left text-sm font-semibold text-zinc-600\">Time</th>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-3.5 py-3 text-left text-sm font-semibold text-zinc-600\">Patient/Caller</th>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-3.5 py-3 text-left text-sm font-semibold text-zinc-600\"></th>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-3.5 py-3 text-left text-sm font-semibold text-zinc-600\">Goal Timeline</th>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-3.5 py-3 text-left text-sm font-semibold text-zinc-600\">Handled By</th>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-3.5 py-3 text-left text-sm font-semibold text-zinc-600\">Resolution</th>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-3.5 py-3 text-left text-sm font-semibold text-zinc-600\">Result</th>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-3.5 py-3 text-left text-sm font-semibold text-zinc-600\">Duration</th>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-3.5 py-3 text-left text-sm font-semibold text-zinc-600\">Reviewed</th>\n </tr>\n </thead>\n <tbody>\n @for (row of data()!.recentHistory; track row.id) {\n <tr\n class=\"cursor-pointer hover:[&>td]:bg-zinc-50 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-blue-600\"\n [class.dashboard-page__history-row--needs-review]=\"isNeedsReview(row.review)\"\n tabindex=\"0\"\n role=\"link\"\n [attr.aria-label]=\"'View call details for ' + row.name\"\n (click)=\"openHistoryDetail(row.id)\"\n (keyup.enter)=\"openHistoryDetail(row.id)\"\n >\n <td class=\"border-b border-slate-100 px-3.5 py-3.5 align-middle text-sm text-zinc-900\">\n <div class=\"flex flex-col gap-0.5 whitespace-nowrap\">\n @if (row.started) {\n <span class=\"text-sm font-semibold\">{{ row.started | date: 'shortTime' }}</span>\n <span class=\"text-xs text-zinc-500\">{{ row.started | date: 'MMM d, y' }}</span>\n } @else {\n <span class=\"text-sm font-semibold\">{{ row.whenLabel || '—' }}</span>\n }\n </div>\n </td>\n\n <td class=\"border-b border-slate-100 px-3.5 py-3.5 align-middle text-sm text-zinc-900\">\n <div class=\"flex min-w-52 items-center gap-2.5\">\n <eds-avatar\n class=\"dashboard-page__avatar\"\n [initials]=\"row.initials || '?'\"\n [tone]=\"historyAvatarTone(row)\"\n />\n <div class=\"flex min-w-0 flex-col gap-0.5\">\n <span class=\"text-sm font-semibold text-zinc-900\">{{ row.name || 'Unknown Caller' }}</span>\n <span class=\"whitespace-nowrap text-xs text-zinc-500\">\n {{\n callerMetaLine({\n dob: row.dob,\n age: row.age,\n gender: row.gender,\n phone: row.phone,\n name: row.name,\n })\n }}\n </span>\n </div>\n </div>\n </td>\n\n <td class=\"border-b border-slate-100 px-3.5 py-3.5 align-middle text-sm text-zinc-900\">\n <span\n class=\"inline-flex h-7 w-7 items-center justify-center rounded-lg\"\n [class.bg-blue-50]=\"row.direction === 'inbound'\"\n [class.text-blue-600]=\"row.direction === 'inbound'\"\n [class.bg-violet-50]=\"row.direction === 'outbound'\"\n [class.text-violet-600]=\"row.direction === 'outbound'\"\n [attr.title]=\"row.direction === 'inbound' ? 'Inbound' : 'Outbound'\"\n >\n <eds-icon\n [name]=\"row.direction === 'inbound' ? 'call_received' : 'call_made'\"\n [size]=\"16\"\n />\n </span>\n </td>\n\n <td class=\"border-b border-slate-100 px-3.5 py-3.5 align-middle text-sm text-zinc-900\">\n <span class=\"text-sm text-zinc-700\">{{ row.reason || '—' }}</span>\n </td>\n\n <td class=\"border-b border-slate-100 px-3.5 py-3.5 align-middle text-sm text-zinc-900\">\n <span\n class=\"inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium\"\n [class.bg-violet-50]=\"(row.handledBy || 'ai') === 'ai'\"\n [class.text-violet-600]=\"(row.handledBy || 'ai') === 'ai'\"\n [class.bg-blue-50]=\"row.handledBy === 'staff'\"\n [class.text-blue-600]=\"row.handledBy === 'staff'\"\n >\n {{ row.handledBy === 'staff' ? 'STAFF' : 'AI' }}\n </span>\n </td>\n\n <td class=\"border-b border-slate-100 px-3.5 py-3.5 align-middle text-sm text-zinc-900\">\n @if (resolutionOf(row); as resolution) {\n <span\n class=\"inline-flex items-center whitespace-nowrap rounded-full px-2.5 py-1 text-xs font-medium\"\n [class.bg-emerald-50]=\"resolution === 'resolved'\"\n [class.text-emerald-700]=\"resolution === 'resolved'\"\n [class.bg-orange-50]=\"resolution === 'needs_attention'\"\n [class.text-orange-700]=\"resolution === 'needs_attention'\"\n >\n {{ historyResolutionLabel(resolution) }}\n </span>\n }\n </td>\n\n <td class=\"border-b border-slate-100 px-3.5 py-3.5 align-middle text-sm text-zinc-900\">\n <div class=\"flex max-w-64 flex-wrap gap-1.5\">\n @for (chip of historyResultChips(row.results, row.outcome); track chip) {\n <span class=\"inline-flex items-center gap-1 whitespace-nowrap rounded-md bg-zinc-100 px-2 py-1 text-xs font-medium text-zinc-600\">\n <eds-icon [name]=\"resultChipIcon(chip)\" [size]=\"14\" />\n {{ chip }}\n </span>\n } @empty {\n <span class=\"text-sm text-zinc-500\">—</span>\n }\n </div>\n </td>\n\n <td class=\"whitespace-nowrap border-b border-slate-100 px-3.5 py-3.5 align-middle text-sm tabular-nums text-zinc-700\">\n {{ row.durationLabel ?? formatDuration(row.duration) }}\n </td>\n\n <td class=\"w-14 border-b border-slate-100 px-3.5 py-3.5 text-center align-middle text-sm text-zinc-900\">\n @if (row.review === 'reviewed') {\n <span class=\"inline-flex text-green-600\" title=\"Reviewed\">\n <eds-icon name=\"check_circle\" [size]=\"20\" />\n </span>\n }\n </td>\n </tr>\n } @empty {\n <tr>\n <td colspan=\"9\" class=\"px-3.5 py-3.5 text-sm text-zinc-500\">No recent calls.</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </article>\n }\n</div>\n\n<eds-outbound-dial-modal\n [open]=\"outboundOpen()\"\n (closed)=\"closeOutboundDial()\"\n (dialed)=\"closeOutboundDial()\"\n/>\n"],"names":[],"mappings":"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"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
-
|
|
4
|
-
class EdsButtonComponent {
|
|
5
|
-
constructor() {
|
|
6
|
-
this.variant = input('secondary');
|
|
7
|
-
this.type = input('button');
|
|
8
|
-
this.disabled = input(false);
|
|
9
|
-
}
|
|
10
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
11
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.17", type: EdsButtonComponent, isStandalone: true, selector: "eds-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
12
|
-
<button [type]="type()" [disabled]="disabled()" [attr.data-variant]="variant()" class="eds-btn inline-flex items-center justify-center gap-1.5 py-2 px-3.5">
|
|
13
|
-
<ng-content />
|
|
14
|
-
</button>
|
|
15
|
-
`, isInline: true, styles: [".eds-btn{border-radius:var(--eds-radius-md);border:1px solid transparent;font-family:var(--eds-font-inter);font-size:13px;font-weight:500;cursor:pointer;transition:background .12s ease,border-color .12s ease,color .12s ease}.eds-btn:disabled{opacity:.5;cursor:not-allowed}.eds-btn[data-variant=primary]{background:var(--eds-brand-600);color:#fff}.eds-btn[data-variant=primary]:hover:not(:disabled){background:var(--eds-brand-500)}.eds-btn[data-variant=secondary]{background:var(--eds-surface-l0);color:var(--eds-text-primary);border-color:var(--eds-border-default)}.eds-btn[data-variant=secondary]:hover:not(:disabled){background:var(--eds-surface-l1)}.eds-btn[data-variant=ghost]{background:transparent;color:var(--eds-text-secondary)}.eds-btn[data-variant=ghost]:hover:not(:disabled){background:var(--eds-gray-100);color:var(--eds-text-primary)}.eds-btn[data-variant=danger]{background:#f037401a;color:var(--eds-red-500);border-color:#f0374040}.eds-btn[data-variant=positive]{background:#0abf521f;color:var(--eds-green-500);border-color:#0abf5240}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
16
|
-
}
|
|
17
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsButtonComponent, decorators: [{
|
|
18
|
-
type: Component,
|
|
19
|
-
args: [{ selector: 'eds-button', standalone: true, template: `
|
|
20
|
-
<button [type]="type()" [disabled]="disabled()" [attr.data-variant]="variant()" class="eds-btn inline-flex items-center justify-center gap-1.5 py-2 px-3.5">
|
|
21
|
-
<ng-content />
|
|
22
|
-
</button>
|
|
23
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".eds-btn{border-radius:var(--eds-radius-md);border:1px solid transparent;font-family:var(--eds-font-inter);font-size:13px;font-weight:500;cursor:pointer;transition:background .12s ease,border-color .12s ease,color .12s ease}.eds-btn:disabled{opacity:.5;cursor:not-allowed}.eds-btn[data-variant=primary]{background:var(--eds-brand-600);color:#fff}.eds-btn[data-variant=primary]:hover:not(:disabled){background:var(--eds-brand-500)}.eds-btn[data-variant=secondary]{background:var(--eds-surface-l0);color:var(--eds-text-primary);border-color:var(--eds-border-default)}.eds-btn[data-variant=secondary]:hover:not(:disabled){background:var(--eds-surface-l1)}.eds-btn[data-variant=ghost]{background:transparent;color:var(--eds-text-secondary)}.eds-btn[data-variant=ghost]:hover:not(:disabled){background:var(--eds-gray-100);color:var(--eds-text-primary)}.eds-btn[data-variant=danger]{background:#f037401a;color:var(--eds-red-500);border-color:#f0374040}.eds-btn[data-variant=positive]{background:#0abf521f;color:var(--eds-green-500);border-color:#0abf5240}\n"] }]
|
|
24
|
-
}] });
|
|
25
|
-
|
|
26
|
-
export { EdsButtonComponent as E };
|
|
27
|
-
//# sourceMappingURL=edvak99-voice-receptionist-widget-eds-button.component-CAfTt7zB.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"edvak99-voice-receptionist-widget-eds-button.component-CAfTt7zB.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/ui/eds-button.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input } from '@angular/core';\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'positive';\n\n@Component({\n selector: 'eds-button',\n standalone: true,\n template: `\n <button [type]=\"type()\" [disabled]=\"disabled()\" [attr.data-variant]=\"variant()\" class=\"eds-btn inline-flex items-center justify-center gap-1.5 py-2 px-3.5\">\n <ng-content />\n </button>\n `,\n styleUrl: './eds-button.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class EdsButtonComponent {\n readonly variant = input<ButtonVariant>('secondary');\n readonly type = input<'button' | 'submit'>('button');\n readonly disabled = input(false);\n}\n"],"names":[],"mappings":";;;MAea,kBAAkB,CAAA;AAX/B,IAAA,WAAA,GAAA;AAYW,QAAA,IAAA,CAAA,OAAO,GAAG,KAAK,CAAgB,WAAW,CAAC;AAC3C,QAAA,IAAA,CAAA,IAAI,GAAG,KAAK,CAAsB,QAAQ,CAAC;AAC3C,QAAA,IAAA,CAAA,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC;AACjC,IAAA;+GAJY,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAlB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EARnB;;;;AAIT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,6hCAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAIU,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAX9B,SAAS;+BACE,YAAY,EAAA,UAAA,EACV,IAAI,EAAA,QAAA,EACN;;;;GAIT,EAAA,eAAA,EAEgB,uBAAuB,CAAC,MAAM,EAAA,MAAA,EAAA,CAAA,6hCAAA,CAAA,EAAA;;;;;"}
|
package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-JWqRMt9T.mjs
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, makeEnvironmentProviders, signal, Injectable, inject, ChangeDetectionStrategy, Component, input, computed } from '@angular/core';
|
|
3
|
-
import { RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router';
|
|
4
|
-
|
|
5
|
-
const VOICE_RECEPTIONIST_CONFIG = new InjectionToken('VOICE_RECEPTIONIST_CONFIG');
|
|
6
|
-
const VOICE_RECEPTIONIST_SESSION = new InjectionToken('VOICE_RECEPTIONIST_SESSION', { factory: () => null });
|
|
7
|
-
|
|
8
|
-
function provideVoiceReceptionist(options) {
|
|
9
|
-
const { session = null, ...config } = options;
|
|
10
|
-
return makeEnvironmentProviders([
|
|
11
|
-
{ provide: VOICE_RECEPTIONIST_CONFIG, useValue: config },
|
|
12
|
-
{ provide: VOICE_RECEPTIONIST_SESSION, useValue: session },
|
|
13
|
-
]);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
class ToastService {
|
|
17
|
-
constructor() {
|
|
18
|
-
this.nextId = 1;
|
|
19
|
-
this.timers = new Map();
|
|
20
|
-
this._toasts = signal([]);
|
|
21
|
-
this.toasts = this._toasts.asReadonly();
|
|
22
|
-
}
|
|
23
|
-
show(text, variant = 'info', durationMs = 3500) {
|
|
24
|
-
const id = this.nextId++;
|
|
25
|
-
this._toasts.update((list) => [...list, { id, text, variant }]);
|
|
26
|
-
const timer = setTimeout(() => this.dismiss(id), durationMs);
|
|
27
|
-
this.timers.set(id, timer);
|
|
28
|
-
}
|
|
29
|
-
dismiss(id) {
|
|
30
|
-
const timer = this.timers.get(id);
|
|
31
|
-
if (timer) {
|
|
32
|
-
clearTimeout(timer);
|
|
33
|
-
this.timers.delete(id);
|
|
34
|
-
}
|
|
35
|
-
this._toasts.update((list) => list.filter((t) => t.id !== id));
|
|
36
|
-
}
|
|
37
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
38
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ToastService, providedIn: 'root' }); }
|
|
39
|
-
}
|
|
40
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ToastService, decorators: [{
|
|
41
|
-
type: Injectable,
|
|
42
|
-
args: [{ providedIn: 'root' }]
|
|
43
|
-
}] });
|
|
44
|
-
|
|
45
|
-
class ToastContainerComponent {
|
|
46
|
-
constructor() {
|
|
47
|
-
this.toastService = inject(ToastService);
|
|
48
|
-
}
|
|
49
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ToastContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
50
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: ToastContainerComponent, isStandalone: true, selector: "app-toast-container", ngImport: i0, template: "<div class=\"fixed bottom-6 right-6 z-[1100] flex max-w-[380px] flex-col gap-2.5 pointer-events-none\" aria-live=\"polite\" aria-atomic=\"false\">\n @for (toast of toastService.toasts(); track toast.id) {\n <div\n class=\"toast pointer-events-auto flex items-start gap-2.5 rounded-[var(--eds-radius-md)] border border-[var(--eds-color-border)] bg-[var(--eds-color-surface)] px-3.5 py-3 text-[13px] text-[var(--eds-color-text)] shadow-[0_6px_24px_rgba(20,30,50,0.12)]\"\n role=\"status\"\n >\n <span\n class=\"inline-flex h-[22px] w-[22px] shrink-0 items-center justify-center rounded-full\"\n [class]=\"toast.variant === 'success' ? 'bg-[var(--eds-color-success-soft)] text-[var(--eds-color-success)]' : toast.variant === 'error' ? 'bg-[var(--eds-color-danger-soft)] text-[var(--eds-color-danger)]' : 'bg-[var(--eds-color-primary-soft)] text-[var(--eds-color-primary)]'\"\n aria-hidden=\"true\"\n >\n @switch (toast.variant) {\n @case ('success') {\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n }\n @case ('error') {\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" />\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\" />\n </svg>\n }\n @default {\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\" />\n </svg>\n }\n }\n </span>\n <span class=\"flex-1 leading-snug\">{{ toast.text }}</span>\n <button\n type=\"button\"\n class=\"inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border-none bg-transparent text-[var(--eds-color-text-soft)] transition-colors duration-150 hover:bg-[var(--eds-color-surface-alt)] hover:text-[var(--eds-color-text)]\"\n (click)=\"toastService.dismiss(toast.id)\"\n aria-label=\"Dismiss notification\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </div>\n }\n</div>\n", styles: [".toast{animation:slide-in .16s ease}@keyframes slide-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
51
|
-
}
|
|
52
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ToastContainerComponent, decorators: [{
|
|
53
|
-
type: Component,
|
|
54
|
-
args: [{ selector: 'app-toast-container', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fixed bottom-6 right-6 z-[1100] flex max-w-[380px] flex-col gap-2.5 pointer-events-none\" aria-live=\"polite\" aria-atomic=\"false\">\n @for (toast of toastService.toasts(); track toast.id) {\n <div\n class=\"toast pointer-events-auto flex items-start gap-2.5 rounded-[var(--eds-radius-md)] border border-[var(--eds-color-border)] bg-[var(--eds-color-surface)] px-3.5 py-3 text-[13px] text-[var(--eds-color-text)] shadow-[0_6px_24px_rgba(20,30,50,0.12)]\"\n role=\"status\"\n >\n <span\n class=\"inline-flex h-[22px] w-[22px] shrink-0 items-center justify-center rounded-full\"\n [class]=\"toast.variant === 'success' ? 'bg-[var(--eds-color-success-soft)] text-[var(--eds-color-success)]' : toast.variant === 'error' ? 'bg-[var(--eds-color-danger-soft)] text-[var(--eds-color-danger)]' : 'bg-[var(--eds-color-primary-soft)] text-[var(--eds-color-primary)]'\"\n aria-hidden=\"true\"\n >\n @switch (toast.variant) {\n @case ('success') {\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n }\n @case ('error') {\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" />\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\" />\n </svg>\n }\n @default {\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\" />\n </svg>\n }\n }\n </span>\n <span class=\"flex-1 leading-snug\">{{ toast.text }}</span>\n <button\n type=\"button\"\n class=\"inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border-none bg-transparent text-[var(--eds-color-text-soft)] transition-colors duration-150 hover:bg-[var(--eds-color-surface-alt)] hover:text-[var(--eds-color-text)]\"\n (click)=\"toastService.dismiss(toast.id)\"\n aria-label=\"Dismiss notification\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </div>\n }\n</div>\n", styles: [".toast{animation:slide-in .16s ease}@keyframes slide-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
55
|
-
}] });
|
|
56
|
-
|
|
57
|
-
class EdsIconComponent {
|
|
58
|
-
constructor() {
|
|
59
|
-
this.name = input.required();
|
|
60
|
-
this.size = input(20);
|
|
61
|
-
this.fill = input(0);
|
|
62
|
-
this.weight = input(400);
|
|
63
|
-
this.variation = computed(() => `'FILL' ${this.fill()}, 'wght' ${this.weight()}, 'GRAD' 0, 'opsz' ${this.size()}`);
|
|
64
|
-
}
|
|
65
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
66
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.17", type: EdsIconComponent, isStandalone: true, selector: "eds-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fill: { classPropertyName: "fill", publicName: "fill", isSignal: true, isRequired: false, transformFunction: null }, weight: { classPropertyName: "weight", publicName: "weight", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `<span class="eds-icon" [style.font-size.px]="size()" [style.font-variation-settings]="variation()">{{ name() }}</span>`, isInline: true, styles: [":host{display:inline-flex;line-height:0}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
67
|
-
}
|
|
68
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsIconComponent, decorators: [{
|
|
69
|
-
type: Component,
|
|
70
|
-
args: [{ selector: 'eds-icon', standalone: true, template: `<span class="eds-icon" [style.font-size.px]="size()" [style.font-variation-settings]="variation()">{{ name() }}</span>`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-flex;line-height:0}\n"] }]
|
|
71
|
-
}] });
|
|
72
|
-
|
|
73
|
-
class EdsModuleNavComponent {
|
|
74
|
-
constructor() {
|
|
75
|
-
this.config = inject(VOICE_RECEPTIONIST_CONFIG);
|
|
76
|
-
this.session = inject(VOICE_RECEPTIONIST_SESSION);
|
|
77
|
-
this.includePracticeNav = !!this.config.includePracticeNav;
|
|
78
|
-
this.receptionistNav = [
|
|
79
|
-
{ id: 'dashboard', label: 'Home', icon: 'home', route: 'dashboard' },
|
|
80
|
-
{ id: 'live', label: 'Live Calls', icon: 'phone_in_talk', route: 'live' },
|
|
81
|
-
{ id: 'history', label: 'Call History', icon: 'history', route: 'history' },
|
|
82
|
-
{ id: 'activities', label: 'Activities', icon: 'format_list_bulleted', route: 'activities' },
|
|
83
|
-
{ id: 'analytics', label: 'Analytics', icon: 'show_chart', route: 'analytics' },
|
|
84
|
-
{ id: 'settings', label: 'Agent Setting', icon: 'settings', route: 'settings' },
|
|
85
|
-
];
|
|
86
|
-
this.practiceNav = [
|
|
87
|
-
{ id: 'patients', label: 'Patients', icon: 'groups', route: 'patients' },
|
|
88
|
-
{ id: 'providers', label: 'Providers', icon: 'medical_services', route: 'providers' },
|
|
89
|
-
{ id: 'appointments', label: 'Appointments', icon: 'calendar_month', route: 'appointments' },
|
|
90
|
-
{ id: 'admin', label: 'Admin', icon: 'admin_panel_settings', route: 'admin', adminOnly: true },
|
|
91
|
-
];
|
|
92
|
-
}
|
|
93
|
-
showNavItem(item) {
|
|
94
|
-
return !item.adminOnly || !!this.session?.isAdmin();
|
|
95
|
-
}
|
|
96
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsModuleNavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
97
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: EdsModuleNavComponent, isStandalone: true, selector: "eds-module-nav", host: { classAttribute: "block shrink-0" }, ngImport: i0, template: "<nav\n class=\"flex h-screen min-h-screen w-[var(--eds-nav-width)] flex-col overflow-y-auto sticky top-0 border-r border-[var(--eds-border-default)] bg-white py-5 px-4\"\n aria-label=\"AI Receptionist\"\n>\n <div class=\"mb-4 flex items-center gap-3 border-b border-[var(--eds-border-default)] px-1 pb-4 pt-1\">\n <span class=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-[10px] bg-violet-500/15 text-[var(--eds-violet-500)]\" aria-hidden=\"true\">\n <eds-icon name=\"auto_awesome\" [size]=\"20\" [fill]=\"1\" />\n </span>\n <div class=\"flex min-w-0 flex-col gap-0.5\">\n <span class=\"text-[15px] font-semibold leading-tight tracking-tight text-[var(--eds-text-primary)]\">AI Receptionist</span>\n </div>\n </div>\n\n <div class=\"flex flex-col gap-1\">\n @for (item of receptionistNav; track item.id) {\n <a\n class=\"group/link relative flex items-center gap-3 rounded-[10px] px-3 py-2.5 text-sm font-medium leading-tight text-slate-700 no-underline transition-colors duration-150 hover:bg-slate-50 hover:text-slate-900 [&.active]:bg-slate-100 [&.active]:font-semibold [&.active]:text-slate-900\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [routerLinkActiveOptions]=\"{ exact: item.route === 'dashboard' }\"\n >\n <eds-icon class=\"shrink-0 text-slate-600 group-hover/link:text-slate-900 group-[.active]/link:text-slate-900\" [name]=\"item.icon\" [size]=\"24\" />\n <span class=\"min-w-0 flex-1\">{{ item.label }}</span>\n </a>\n }\n </div>\n\n @if (includePracticeNav) {\n <p class=\"mx-3 mb-2 mt-4.5 text-sm font-semibold text-[var(--eds-text-table-header,#4d5573)]\">Practice</p>\n <div class=\"mb-3 flex flex-col gap-1\">\n @for (item of practiceNav; track item.id) {\n @if (showNavItem(item)) {\n <a\n class=\"group/link relative flex items-center gap-3 rounded-[10px] px-3 py-2.5 text-sm font-medium leading-tight text-slate-700 no-underline transition-colors duration-150 hover:bg-slate-50 hover:text-slate-900 [&.active]:bg-slate-100 [&.active]:font-semibold [&.active]:text-slate-900\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n >\n <eds-icon class=\"shrink-0 text-slate-600 group-hover/link:text-slate-900 group-[.active]/link:text-slate-900\" [name]=\"item.icon\" [size]=\"24\" />\n <span class=\"min-w-0 flex-1\">{{ item.label }}</span>\n </a>\n }\n }\n </div>\n }\n</nav>\n", dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: EdsIconComponent, selector: "eds-icon", inputs: ["name", "size", "fill", "weight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
98
|
-
}
|
|
99
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsModuleNavComponent, decorators: [{
|
|
100
|
-
type: Component,
|
|
101
|
-
args: [{ selector: 'eds-module-nav', imports: [RouterLink, RouterLinkActive, EdsIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'block shrink-0' }, template: "<nav\n class=\"flex h-screen min-h-screen w-[var(--eds-nav-width)] flex-col overflow-y-auto sticky top-0 border-r border-[var(--eds-border-default)] bg-white py-5 px-4\"\n aria-label=\"AI Receptionist\"\n>\n <div class=\"mb-4 flex items-center gap-3 border-b border-[var(--eds-border-default)] px-1 pb-4 pt-1\">\n <span class=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-[10px] bg-violet-500/15 text-[var(--eds-violet-500)]\" aria-hidden=\"true\">\n <eds-icon name=\"auto_awesome\" [size]=\"20\" [fill]=\"1\" />\n </span>\n <div class=\"flex min-w-0 flex-col gap-0.5\">\n <span class=\"text-[15px] font-semibold leading-tight tracking-tight text-[var(--eds-text-primary)]\">AI Receptionist</span>\n </div>\n </div>\n\n <div class=\"flex flex-col gap-1\">\n @for (item of receptionistNav; track item.id) {\n <a\n class=\"group/link relative flex items-center gap-3 rounded-[10px] px-3 py-2.5 text-sm font-medium leading-tight text-slate-700 no-underline transition-colors duration-150 hover:bg-slate-50 hover:text-slate-900 [&.active]:bg-slate-100 [&.active]:font-semibold [&.active]:text-slate-900\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [routerLinkActiveOptions]=\"{ exact: item.route === 'dashboard' }\"\n >\n <eds-icon class=\"shrink-0 text-slate-600 group-hover/link:text-slate-900 group-[.active]/link:text-slate-900\" [name]=\"item.icon\" [size]=\"24\" />\n <span class=\"min-w-0 flex-1\">{{ item.label }}</span>\n </a>\n }\n </div>\n\n @if (includePracticeNav) {\n <p class=\"mx-3 mb-2 mt-4.5 text-sm font-semibold text-[var(--eds-text-table-header,#4d5573)]\">Practice</p>\n <div class=\"mb-3 flex flex-col gap-1\">\n @for (item of practiceNav; track item.id) {\n @if (showNavItem(item)) {\n <a\n class=\"group/link relative flex items-center gap-3 rounded-[10px] px-3 py-2.5 text-sm font-medium leading-tight text-slate-700 no-underline transition-colors duration-150 hover:bg-slate-50 hover:text-slate-900 [&.active]:bg-slate-100 [&.active]:font-semibold [&.active]:text-slate-900\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n >\n <eds-icon class=\"shrink-0 text-slate-600 group-hover/link:text-slate-900 group-[.active]/link:text-slate-900\" [name]=\"item.icon\" [size]=\"24\" />\n <span class=\"min-w-0 flex-1\">{{ item.label }}</span>\n </a>\n }\n }\n </div>\n }\n</nav>\n" }]
|
|
102
|
-
}] });
|
|
103
|
-
|
|
104
|
-
class EdsAppShellComponent {
|
|
105
|
-
constructor() {
|
|
106
|
-
/** EHR embed: false (default). Standalone Voice Hub: set showModuleNav: true. */
|
|
107
|
-
this.showModuleNav = !!inject(VOICE_RECEPTIONIST_CONFIG).showModuleNav;
|
|
108
|
-
}
|
|
109
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsAppShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
110
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: EdsAppShellComponent, isStandalone: true, selector: "eds-app-shell", ngImport: i0, template: "<div class=\"eds-layout flex min-h-screen\">\n @if (showModuleNav) {\n <eds-module-nav />\n }\n <div class=\"eds-main flex min-w-0 flex-1 flex-col\">\n <div class=\"eds-content flex-1 overflow-auto\">\n <router-outlet />\n </div>\n </div>\n <app-toast-container />\n</div>\n", styles: [":host{display:block}.eds-layout{background:var(--eds-surface-l1);font-family:var(--eds-font-inter, \"Inter\", sans-serif);font-size:var(--eds-font-size-base, 13px);font-weight:var(--eds-font-weight-regular, 400);color:var(--eds-text-primary, #41464c)}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: EdsModuleNavComponent, selector: "eds-module-nav" }, { kind: "component", type: ToastContainerComponent, selector: "app-toast-container" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
111
|
-
}
|
|
112
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsAppShellComponent, decorators: [{
|
|
113
|
-
type: Component,
|
|
114
|
-
args: [{ selector: 'eds-app-shell', imports: [RouterOutlet, EdsModuleNavComponent, ToastContainerComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"eds-layout flex min-h-screen\">\n @if (showModuleNav) {\n <eds-module-nav />\n }\n <div class=\"eds-main flex min-w-0 flex-1 flex-col\">\n <div class=\"eds-content flex-1 overflow-auto\">\n <router-outlet />\n </div>\n </div>\n <app-toast-container />\n</div>\n", styles: [":host{display:block}.eds-layout{background:var(--eds-surface-l1);font-family:var(--eds-font-inter, \"Inter\", sans-serif);font-size:var(--eds-font-size-base, 13px);font-weight:var(--eds-font-weight-regular, 400);color:var(--eds-text-primary, #41464c)}\n"] }]
|
|
115
|
-
}] });
|
|
116
|
-
|
|
117
|
-
/** Feature child routes (under the embed shell). */
|
|
118
|
-
const VOICE_RECEPTIONIST_FEATURE_ROUTES = [
|
|
119
|
-
{ path: '', pathMatch: 'full', redirectTo: 'dashboard' },
|
|
120
|
-
{
|
|
121
|
-
path: 'dashboard',
|
|
122
|
-
loadComponent: () => import('./edvak99-voice-receptionist-widget-dashboard-page.component-DD0tMAah.mjs').then((m) => m.DashboardPageComponent),
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
path: 'live',
|
|
126
|
-
loadComponent: () => import('./edvak99-voice-receptionist-widget-live-calls-page.component-D5znr-Sx.mjs').then((m) => m.LiveCallsPageComponent),
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
path: 'live/:id',
|
|
130
|
-
loadComponent: () => import('./edvak99-voice-receptionist-widget-live-monitor-page.component-1elUtWOw.mjs').then((m) => m.LiveMonitorPageComponent),
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
path: 'history',
|
|
134
|
-
loadComponent: () => import('./edvak99-voice-receptionist-widget-call-history-page.component-Cec1ngRf.mjs').then((m) => m.CallHistoryPageComponent),
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
path: 'history/:id',
|
|
138
|
-
loadComponent: () => import('./edvak99-voice-receptionist-widget-call-history-detail-page.component-0rW-PPWM.mjs').then((m) => m.CallHistoryDetailPageComponent),
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
path: 'activities',
|
|
142
|
-
loadComponent: () => import('./edvak99-voice-receptionist-widget-activities-page.component-pQM1L7lO.mjs').then((m) => m.ActivitiesPageComponent),
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
path: 'tasks',
|
|
146
|
-
loadComponent: () => import('./edvak99-voice-receptionist-widget-tasks-page.component-BGSupnFa.mjs').then((m) => m.TasksPageComponent),
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
path: 'analytics',
|
|
150
|
-
loadComponent: () => import('./edvak99-voice-receptionist-widget-analytics-page.component-B6O-PZHz.mjs').then((m) => m.AnalyticsPageComponent),
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
path: 'settings',
|
|
154
|
-
loadComponent: () => import('./edvak99-voice-receptionist-widget-settings-page.component-DAr4wuUk.mjs').then((m) => m.SettingsPageComponent),
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
path: 'settings/outbound-purposes',
|
|
158
|
-
loadComponent: () => import('./edvak99-voice-receptionist-widget-outbound-purposes-page.component-CwLxW1W9.mjs').then((m) => m.OutboundPurposesPageComponent),
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
path: 'knowledge',
|
|
162
|
-
loadComponent: () => import('./edvak99-voice-receptionist-widget-settings-page.component-DAr4wuUk.mjs').then((m) => m.SettingsPageComponent),
|
|
163
|
-
data: { settingsTab: 'knowledge' },
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
path: 'wizard',
|
|
167
|
-
loadComponent: () => import('./edvak99-voice-receptionist-widget-wizard-page.component-5iG9eQRi.mjs').then((m) => m.WizardPageComponent),
|
|
168
|
-
},
|
|
169
|
-
];
|
|
170
|
-
/**
|
|
171
|
-
* Lazy-loadable routes for EHR (and standalone hosts).
|
|
172
|
-
* Mount under a host path, e.g. `{ path: 'ai-receptionist', children: VOICE_RECEPTIONIST_ROUTES }`.
|
|
173
|
-
*/
|
|
174
|
-
const VOICE_RECEPTIONIST_ROUTES = [
|
|
175
|
-
{
|
|
176
|
-
path: '',
|
|
177
|
-
component: EdsAppShellComponent,
|
|
178
|
-
children: VOICE_RECEPTIONIST_FEATURE_ROUTES,
|
|
179
|
-
},
|
|
180
|
-
];
|
|
181
|
-
|
|
182
|
-
class EdsBadgeComponent {
|
|
183
|
-
constructor() {
|
|
184
|
-
this.tone = input('gray');
|
|
185
|
-
}
|
|
186
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
187
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.17", type: EdsBadgeComponent, isStandalone: true, selector: "eds-badge", inputs: { tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `<span class="eds-badge inline-flex items-center gap-1.5 py-0.5 px-2" [attr.data-tone]="tone()"><ng-content /></span>`, isInline: true, styles: [".eds-badge{border-radius:var(--eds-radius-sm);font-family:var(--eds-font-inter);font-size:12px;font-weight:500;line-height:1.4;white-space:nowrap}.eds-badge[data-tone=brand]{background:#3681f41f;color:var(--eds-brand-600)}.eds-badge[data-tone=pos]{background:#0abf521f;color:var(--eds-green-500)}.eds-badge[data-tone=notice]{background:#ffb90026;color:#b45309}.eds-badge[data-tone=neg]{background:#f037401f;color:var(--eds-red-500)}.eds-badge[data-tone=violet]{background:#8e51ff1f;color:var(--eds-violet-500)}.eds-badge[data-tone=gray]{background:var(--eds-gray-100);color:var(--eds-gray-600)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
188
|
-
}
|
|
189
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsBadgeComponent, decorators: [{
|
|
190
|
-
type: Component,
|
|
191
|
-
args: [{ selector: 'eds-badge', standalone: true, template: `<span class="eds-badge inline-flex items-center gap-1.5 py-0.5 px-2" [attr.data-tone]="tone()"><ng-content /></span>`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".eds-badge{border-radius:var(--eds-radius-sm);font-family:var(--eds-font-inter);font-size:12px;font-weight:500;line-height:1.4;white-space:nowrap}.eds-badge[data-tone=brand]{background:#3681f41f;color:var(--eds-brand-600)}.eds-badge[data-tone=pos]{background:#0abf521f;color:var(--eds-green-500)}.eds-badge[data-tone=notice]{background:#ffb90026;color:#b45309}.eds-badge[data-tone=neg]{background:#f037401f;color:var(--eds-red-500)}.eds-badge[data-tone=violet]{background:#8e51ff1f;color:var(--eds-violet-500)}.eds-badge[data-tone=gray]{background:var(--eds-gray-100);color:var(--eds-gray-600)}\n"] }]
|
|
192
|
-
}] });
|
|
193
|
-
|
|
194
|
-
/*
|
|
195
|
-
* Public API Surface of @edvak99/voice-receptionist-widget
|
|
196
|
-
*/
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Generated bundle index. Do not edit.
|
|
200
|
-
*/
|
|
201
|
-
|
|
202
|
-
export { EdsIconComponent as E, ToastService as T, VOICE_RECEPTIONIST_CONFIG as V, EdsBadgeComponent as a, EdsAppShellComponent as b, VOICE_RECEPTIONIST_FEATURE_ROUTES as c, VOICE_RECEPTIONIST_ROUTES as d, VOICE_RECEPTIONIST_SESSION as e, provideVoiceReceptionist as p };
|
|
203
|
-
//# sourceMappingURL=edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-JWqRMt9T.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-JWqRMt9T.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/config.ts","../../../projects/voice-receptionist-widget/src/lib/provide-voice-receptionist.ts","../../../projects/voice-receptionist-widget/src/lib/shared/toast.service.ts","../../../projects/voice-receptionist-widget/src/lib/shared/toast-container.component.ts","../../../projects/voice-receptionist-widget/src/lib/shared/toast-container.component.html","../../../projects/voice-receptionist-widget/src/lib/ui/eds-icon.component.ts","../../../projects/voice-receptionist-widget/src/lib/layout/eds-module-nav.component.ts","../../../projects/voice-receptionist-widget/src/lib/layout/eds-module-nav.component.html","../../../projects/voice-receptionist-widget/src/lib/layout/eds-app-shell.component.ts","../../../projects/voice-receptionist-widget/src/lib/layout/eds-app-shell.component.html","../../../projects/voice-receptionist-widget/src/lib/routes.ts","../../../projects/voice-receptionist-widget/src/lib/ui/eds-badge.component.ts","../../../projects/voice-receptionist-widget/src/public-api.ts","../../../projects/voice-receptionist-widget/src/edvak99-voice-receptionist-widget.ts"],"sourcesContent":["import { InjectionToken, Signal } from '@angular/core';\n\n/** Host-provided session for topbar / admin-only nav. */\nexport interface VoiceReceptionistSession {\n /** Current user email for display. */\n readonly email: Signal<string | null>;\n isAdmin(): boolean;\n logout(): void;\n}\n\nexport interface VoiceReceptionistConfig {\n /** Backend base URL (no trailing slash), e.g. https://api.example.com */\n apiBaseUrl: string;\n /** Use in-memory mock API (local demos). Default false. */\n useMockApi?: boolean;\n callLogsLimit?: number;\n liveCallsPollIntervalMs?: number;\n /**\n * Show Practice nav links (patients / providers / appointments / admin).\n * Enable in the standalone Voice Hub host; leave false for EHR embed.\n */\n includePracticeNav?: boolean;\n /**\n * Show the AI Receptionist side nav (Dashboard, Live Calls, …).\n * Default false for EHR embed (host owns primary nav). Standalone Voice Hub should set true.\n */\n showModuleNav?: boolean;\n}\n\nexport const VOICE_RECEPTIONIST_CONFIG = new InjectionToken<VoiceReceptionistConfig>(\n 'VOICE_RECEPTIONIST_CONFIG',\n);\n\nexport const VOICE_RECEPTIONIST_SESSION = new InjectionToken<VoiceReceptionistSession | null>(\n 'VOICE_RECEPTIONIST_SESSION',\n { factory: () => null },\n);\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\n\nimport {\n VOICE_RECEPTIONIST_CONFIG,\n VOICE_RECEPTIONIST_SESSION,\n VoiceReceptionistConfig,\n VoiceReceptionistSession,\n} from './config';\n\nexport interface ProvideVoiceReceptionistOptions extends VoiceReceptionistConfig {\n session?: VoiceReceptionistSession | null;\n}\n\nexport function provideVoiceReceptionist(\n options: ProvideVoiceReceptionistOptions,\n): EnvironmentProviders {\n const { session = null, ...config } = options;\n return makeEnvironmentProviders([\n { provide: VOICE_RECEPTIONIST_CONFIG, useValue: config },\n { provide: VOICE_RECEPTIONIST_SESSION, useValue: session },\n ]);\n}\n","import { Injectable, signal } from '@angular/core';\n\nexport interface ToastMessage {\n id: number;\n text: string;\n variant: 'info' | 'success' | 'error';\n}\n\n@Injectable({ providedIn: 'root' })\nexport class ToastService {\n private nextId = 1;\n private timers = new Map<number, ReturnType<typeof setTimeout>>();\n\n private readonly _toasts = signal<ToastMessage[]>([]);\n readonly toasts = this._toasts.asReadonly();\n\n show(text: string, variant: ToastMessage['variant'] = 'info', durationMs = 3500): void {\n const id = this.nextId++;\n this._toasts.update((list) => [...list, { id, text, variant }]);\n const timer = setTimeout(() => this.dismiss(id), durationMs);\n this.timers.set(id, timer);\n }\n\n dismiss(id: number): void {\n const timer = this.timers.get(id);\n if (timer) {\n clearTimeout(timer);\n this.timers.delete(id);\n }\n this._toasts.update((list) => list.filter((t) => t.id !== id));\n }\n}\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\n\nimport { ToastService } from './toast.service';\n\n@Component({\n selector: 'app-toast-container',\n standalone: true,\n templateUrl: './toast-container.component.html',\n styleUrl: './toast-container.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ToastContainerComponent {\n protected readonly toastService = inject(ToastService);\n}\n","<div class=\"fixed bottom-6 right-6 z-[1100] flex max-w-[380px] flex-col gap-2.5 pointer-events-none\" aria-live=\"polite\" aria-atomic=\"false\">\n @for (toast of toastService.toasts(); track toast.id) {\n <div\n class=\"toast pointer-events-auto flex items-start gap-2.5 rounded-[var(--eds-radius-md)] border border-[var(--eds-color-border)] bg-[var(--eds-color-surface)] px-3.5 py-3 text-[13px] text-[var(--eds-color-text)] shadow-[0_6px_24px_rgba(20,30,50,0.12)]\"\n role=\"status\"\n >\n <span\n class=\"inline-flex h-[22px] w-[22px] shrink-0 items-center justify-center rounded-full\"\n [class]=\"toast.variant === 'success' ? 'bg-[var(--eds-color-success-soft)] text-[var(--eds-color-success)]' : toast.variant === 'error' ? 'bg-[var(--eds-color-danger-soft)] text-[var(--eds-color-danger)]' : 'bg-[var(--eds-color-primary-soft)] text-[var(--eds-color-primary)]'\"\n aria-hidden=\"true\"\n >\n @switch (toast.variant) {\n @case ('success') {\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n }\n @case ('error') {\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" />\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\" />\n </svg>\n }\n @default {\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\" />\n </svg>\n }\n }\n </span>\n <span class=\"flex-1 leading-snug\">{{ toast.text }}</span>\n <button\n type=\"button\"\n class=\"inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border-none bg-transparent text-[var(--eds-color-text-soft)] transition-colors duration-150 hover:bg-[var(--eds-color-surface-alt)] hover:text-[var(--eds-color-text)]\"\n (click)=\"toastService.dismiss(toast.id)\"\n aria-label=\"Dismiss notification\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </div>\n }\n</div>\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\n\n@Component({\n selector: 'eds-icon',\n standalone: true,\n template: `<span class=\"eds-icon\" [style.font-size.px]=\"size()\" [style.font-variation-settings]=\"variation()\">{{ name() }}</span>`,\n styles: `:host { display: inline-flex; line-height: 0; }`,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class EdsIconComponent {\n readonly name = input.required<string>();\n readonly size = input(20);\n readonly fill = input(0);\n readonly weight = input(400);\n\n protected readonly variation = computed(\n () => `'FILL' ${this.fill()}, 'wght' ${this.weight()}, 'GRAD' 0, 'opsz' ${this.size()}`,\n );\n}\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { RouterLink, RouterLinkActive } from '@angular/router';\n\nimport {\n VOICE_RECEPTIONIST_CONFIG,\n VOICE_RECEPTIONIST_SESSION,\n} from '../config';\nimport { EdsIconComponent } from '../ui/eds-icon.component';\n\ninterface NavItem {\n id: string;\n label: string;\n icon: string;\n route: string;\n badge?: number;\n pulse?: boolean;\n adminOnly?: boolean;\n}\n\n@Component({\n selector: 'eds-module-nav',\n imports: [RouterLink, RouterLinkActive, EdsIconComponent],\n templateUrl: './eds-module-nav.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { class: 'block shrink-0' },\n})\nexport class EdsModuleNavComponent {\n private readonly config = inject(VOICE_RECEPTIONIST_CONFIG);\n private readonly session = inject(VOICE_RECEPTIONIST_SESSION);\n\n protected readonly includePracticeNav = !!this.config.includePracticeNav;\n\n protected readonly receptionistNav: NavItem[] = [\n { id: 'dashboard', label: 'Home', icon: 'home', route: 'dashboard' },\n { id: 'live', label: 'Live Calls', icon: 'phone_in_talk', route: 'live' },\n { id: 'history', label: 'Call History', icon: 'history', route: 'history' },\n { id: 'activities', label: 'Activities', icon: 'format_list_bulleted', route: 'activities' },\n { id: 'analytics', label: 'Analytics', icon: 'show_chart', route: 'analytics' },\n { id: 'settings', label: 'Agent Setting', icon: 'settings', route: 'settings' },\n ];\n\n protected readonly practiceNav: NavItem[] = [\n { id: 'patients', label: 'Patients', icon: 'groups', route: 'patients' },\n { id: 'providers', label: 'Providers', icon: 'medical_services', route: 'providers' },\n { id: 'appointments', label: 'Appointments', icon: 'calendar_month', route: 'appointments' },\n { id: 'admin', label: 'Admin', icon: 'admin_panel_settings', route: 'admin', adminOnly: true },\n ];\n\n protected showNavItem(item: NavItem): boolean {\n return !item.adminOnly || !!this.session?.isAdmin();\n }\n}\n","<nav\n class=\"flex h-screen min-h-screen w-[var(--eds-nav-width)] flex-col overflow-y-auto sticky top-0 border-r border-[var(--eds-border-default)] bg-white py-5 px-4\"\n aria-label=\"AI Receptionist\"\n>\n <div class=\"mb-4 flex items-center gap-3 border-b border-[var(--eds-border-default)] px-1 pb-4 pt-1\">\n <span class=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-[10px] bg-violet-500/15 text-[var(--eds-violet-500)]\" aria-hidden=\"true\">\n <eds-icon name=\"auto_awesome\" [size]=\"20\" [fill]=\"1\" />\n </span>\n <div class=\"flex min-w-0 flex-col gap-0.5\">\n <span class=\"text-[15px] font-semibold leading-tight tracking-tight text-[var(--eds-text-primary)]\">AI Receptionist</span>\n </div>\n </div>\n\n <div class=\"flex flex-col gap-1\">\n @for (item of receptionistNav; track item.id) {\n <a\n class=\"group/link relative flex items-center gap-3 rounded-[10px] px-3 py-2.5 text-sm font-medium leading-tight text-slate-700 no-underline transition-colors duration-150 hover:bg-slate-50 hover:text-slate-900 [&.active]:bg-slate-100 [&.active]:font-semibold [&.active]:text-slate-900\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [routerLinkActiveOptions]=\"{ exact: item.route === 'dashboard' }\"\n >\n <eds-icon class=\"shrink-0 text-slate-600 group-hover/link:text-slate-900 group-[.active]/link:text-slate-900\" [name]=\"item.icon\" [size]=\"24\" />\n <span class=\"min-w-0 flex-1\">{{ item.label }}</span>\n </a>\n }\n </div>\n\n @if (includePracticeNav) {\n <p class=\"mx-3 mb-2 mt-4.5 text-sm font-semibold text-[var(--eds-text-table-header,#4d5573)]\">Practice</p>\n <div class=\"mb-3 flex flex-col gap-1\">\n @for (item of practiceNav; track item.id) {\n @if (showNavItem(item)) {\n <a\n class=\"group/link relative flex items-center gap-3 rounded-[10px] px-3 py-2.5 text-sm font-medium leading-tight text-slate-700 no-underline transition-colors duration-150 hover:bg-slate-50 hover:text-slate-900 [&.active]:bg-slate-100 [&.active]:font-semibold [&.active]:text-slate-900\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n >\n <eds-icon class=\"shrink-0 text-slate-600 group-hover/link:text-slate-900 group-[.active]/link:text-slate-900\" [name]=\"item.icon\" [size]=\"24\" />\n <span class=\"min-w-0 flex-1\">{{ item.label }}</span>\n </a>\n }\n }\n </div>\n }\n</nav>\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\n\nimport { VOICE_RECEPTIONIST_CONFIG } from '../config';\nimport { ToastContainerComponent } from '../shared/toast-container.component';\nimport { EdsModuleNavComponent } from './eds-module-nav.component';\n\n@Component({\n selector: 'eds-app-shell',\n imports: [RouterOutlet, EdsModuleNavComponent, ToastContainerComponent],\n templateUrl: './eds-app-shell.component.html',\n styleUrl: './eds-app-shell.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class EdsAppShellComponent {\n /** EHR embed: false (default). Standalone Voice Hub: set showModuleNav: true. */\n protected readonly showModuleNav = !!inject(VOICE_RECEPTIONIST_CONFIG).showModuleNav;\n}\n","<div class=\"eds-layout flex min-h-screen\">\n @if (showModuleNav) {\n <eds-module-nav />\n }\n <div class=\"eds-main flex min-w-0 flex-1 flex-col\">\n <div class=\"eds-content flex-1 overflow-auto\">\n <router-outlet />\n </div>\n </div>\n <app-toast-container />\n</div>\n","import { Routes } from '@angular/router';\n\nimport { EdsAppShellComponent } from './layout/eds-app-shell.component';\n\n/** Feature child routes (under the embed shell). */\nexport const VOICE_RECEPTIONIST_FEATURE_ROUTES: Routes = [\n { path: '', pathMatch: 'full', redirectTo: 'dashboard' },\n {\n path: 'dashboard',\n loadComponent: () =>\n import('./pages/dashboard-page/dashboard-page.component').then(\n (m) => m.DashboardPageComponent,\n ),\n },\n {\n path: 'live',\n loadComponent: () =>\n import('./pages/live-calls-page/live-calls-page.component').then(\n (m) => m.LiveCallsPageComponent,\n ),\n },\n {\n path: 'live/:id',\n loadComponent: () =>\n import('./pages/live-monitor-page/live-monitor-page.component').then(\n (m) => m.LiveMonitorPageComponent,\n ),\n },\n {\n path: 'history',\n loadComponent: () =>\n import('./pages/call-history-page/call-history-page.component').then(\n (m) => m.CallHistoryPageComponent,\n ),\n },\n {\n path: 'history/:id',\n loadComponent: () =>\n import('./pages/call-history-detail-page/call-history-detail-page.component').then(\n (m) => m.CallHistoryDetailPageComponent,\n ),\n },\n {\n path: 'activities',\n loadComponent: () =>\n import('./pages/activities-page/activities-page.component').then(\n (m) => m.ActivitiesPageComponent,\n ),\n },\n {\n path: 'tasks',\n loadComponent: () =>\n import('./pages/tasks-page/tasks-page.component').then((m) => m.TasksPageComponent),\n },\n {\n path: 'analytics',\n loadComponent: () =>\n import('./pages/analytics-page/analytics-page.component').then(\n (m) => m.AnalyticsPageComponent,\n ),\n },\n {\n path: 'settings',\n loadComponent: () =>\n import('./pages/settings-page/settings-page.component').then(\n (m) => m.SettingsPageComponent,\n ),\n },\n {\n path: 'settings/outbound-purposes',\n loadComponent: () =>\n import('./pages/outbound-purposes-page/outbound-purposes-page.component').then(\n (m) => m.OutboundPurposesPageComponent,\n ),\n },\n {\n path: 'knowledge',\n loadComponent: () =>\n import('./pages/settings-page/settings-page.component').then(\n (m) => m.SettingsPageComponent,\n ),\n data: { settingsTab: 'knowledge' },\n },\n {\n path: 'wizard',\n loadComponent: () =>\n import('./pages/wizard-page/wizard-page.component').then((m) => m.WizardPageComponent),\n },\n];\n\n/**\n * Lazy-loadable routes for EHR (and standalone hosts).\n * Mount under a host path, e.g. `{ path: 'ai-receptionist', children: VOICE_RECEPTIONIST_ROUTES }`.\n */\nexport const VOICE_RECEPTIONIST_ROUTES: Routes = [\n {\n path: '',\n component: EdsAppShellComponent,\n children: VOICE_RECEPTIONIST_FEATURE_ROUTES,\n },\n];\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\n\nexport type BadgeTone = 'brand' | 'pos' | 'notice' | 'neg' | 'violet' | 'gray';\n\n@Component({\n selector: 'eds-badge',\n standalone: true,\n template: `<span class=\"eds-badge inline-flex items-center gap-1.5 py-0.5 px-2\" [attr.data-tone]=\"tone()\"><ng-content /></span>`,\n styleUrl: './eds-badge.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class EdsBadgeComponent {\n readonly tone = input<BadgeTone>('gray');\n}\n","/*\n * Public API Surface of @edvak99/voice-receptionist-widget\n */\n\nexport {\n VOICE_RECEPTIONIST_CONFIG,\n VOICE_RECEPTIONIST_SESSION,\n type VoiceReceptionistConfig,\n type VoiceReceptionistSession,\n} from './lib/config';\nexport {\n provideVoiceReceptionist,\n type ProvideVoiceReceptionistOptions,\n} from './lib/provide-voice-receptionist';\nexport {\n VOICE_RECEPTIONIST_ROUTES,\n VOICE_RECEPTIONIST_FEATURE_ROUTES,\n} from './lib/routes';\nexport { EdsAppShellComponent } from './lib/layout/eds-app-shell.component';\nexport { ToastService, type ToastMessage } from './lib/shared/toast.service';\nexport { EdsBadgeComponent, type BadgeTone } from './lib/ui/eds-badge.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|