@nuxt-customer-portal/service-requests 0.3.0

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE +21 -0
  3. package/README.md +16 -0
  4. package/app/components/Admin/RequestDashboard.vue +64 -0
  5. package/app/components/Admin/RequestTable.vue +158 -0
  6. package/app/components/CustomerRequestDetail.vue +76 -0
  7. package/app/components/CustomerRequestForm.vue +143 -0
  8. package/app/components/ServiceRequestsDashboardAttention.vue +55 -0
  9. package/app/components/ServiceRequestsDashboardOverview.vue +55 -0
  10. package/app/components/StatusBadge.vue +16 -0
  11. package/app/composables/useAdminServiceRequests.ts +60 -0
  12. package/app/composables/usePaginatedServiceRequests.ts +21 -0
  13. package/app/composables/useServiceRequestAccess.ts +18 -0
  14. package/app/composables/useServiceRequestMenu.ts +34 -0
  15. package/app/composables/useServiceRequests.ts +134 -0
  16. package/app/composables/useServiceRequestsDashboard.ts +13 -0
  17. package/app/pages/admin/requests/[id].vue +140 -0
  18. package/app/pages/admin/requests/index.vue +55 -0
  19. package/app/pages/requests/[id].vue +161 -0
  20. package/app/pages/requests/index.vue +873 -0
  21. package/app/pages/requests/new.vue +37 -0
  22. package/app/plugins/service-requests-feature.ts +18 -0
  23. package/i18n/locales/en.json +97 -0
  24. package/i18n/locales/nl.json +97 -0
  25. package/migrations/0000_baseline.sql +30 -0
  26. package/migrations/0001_required_client.sql +6 -0
  27. package/migrations/meta/0000_snapshot.json +245 -0
  28. package/migrations/meta/_journal.json +13 -0
  29. package/nuxt.config.ts +29 -0
  30. package/package.json +53 -0
  31. package/portal.manifest.mjs +9 -0
  32. package/server/api/service-requests/[id].delete.ts +42 -0
  33. package/server/api/service-requests/[id].get.ts +39 -0
  34. package/server/api/service-requests/[id].patch.ts +44 -0
  35. package/server/api/service-requests/admin/[id].patch.ts +43 -0
  36. package/server/api/service-requests/admin/index.get.ts +19 -0
  37. package/server/api/service-requests/dashboard.get.ts +11 -0
  38. package/server/api/service-requests/index.get.ts +22 -0
  39. package/server/api/service-requests/index.post.ts +39 -0
  40. package/server/db/schema/service-requests.ts +78 -0
  41. package/server/plugins/openapi-contracts.ts +22 -0
  42. package/server/utils/service-request-repository.ts +185 -0
  43. package/server/utils/service-request-scope.ts +41 -0
  44. package/server/utils/service-request-validation.ts +54 -0
  45. package/shared/feature.ts +90 -0
  46. package/shared/types/service-request.ts +111 -0
@@ -0,0 +1,90 @@
1
+ import type { PortalFeatureDefinition } from '@nuxt-customer-portal/core/shared/types/feature'
2
+
3
+ export const serviceRequestActions = ['create', 'read', 'update', 'delete', 'list', 'manage'] as const
4
+ export type ServiceRequestAction = (typeof serviceRequestActions)[number]
5
+
6
+ export const serviceRequestFeature: PortalFeatureDefinition<ServiceRequestAction> = {
7
+ id: 'service-requests',
8
+ navigation: [
9
+ {
10
+ id: 'service-requests',
11
+ labelKey: 'features.serviceRequests.navigation.myRequests',
12
+ icon: 'i-lucide-ticket',
13
+ to: '/requests',
14
+ audiences: ['authenticated'],
15
+ order: 20
16
+ },
17
+ {
18
+ id: 'service-requests-admin',
19
+ labelKey: 'features.serviceRequests.navigation.manageRequests',
20
+ icon: 'i-lucide-list-checks',
21
+ to: '/admin/requests',
22
+ audiences: ['providerAdmin'],
23
+ location: 'admin',
24
+ order: 120
25
+ }
26
+ ],
27
+ modules: [
28
+ {
29
+ id: 'service-requests',
30
+ labelKey: 'features.serviceRequests.navigation.myRequests',
31
+ icon: 'i-lucide-ticket',
32
+ to: '/requests',
33
+ routePrefixes: ['/requests', '/admin/requests'],
34
+ audiences: ['authenticated'],
35
+ order: 20,
36
+ menuItems: [
37
+ {
38
+ id: 'requests',
39
+ labelKey: 'features.serviceRequests.navigation.myRequests',
40
+ icon: 'i-lucide-inbox',
41
+ to: '/requests',
42
+ audiences: ['authenticated']
43
+ },
44
+ {
45
+ id: 'new-request',
46
+ labelKey: 'features.serviceRequests.navigation.newRequest',
47
+ icon: 'i-lucide-plus',
48
+ to: '/requests/new',
49
+ audiences: ['authenticated']
50
+ },
51
+ {
52
+ id: 'manage-requests',
53
+ labelKey: 'features.serviceRequests.navigation.manageRequests',
54
+ icon: 'i-lucide-list-checks',
55
+ to: '/admin/requests',
56
+ audiences: ['providerAdmin']
57
+ }
58
+ ]
59
+ }
60
+ ],
61
+ dashboardWidgets: [
62
+ {
63
+ id: 'service-requests-attention',
64
+ component: 'ServiceRequestsDashboardAttention',
65
+ area: 'attention',
66
+ size: 'half',
67
+ order: 30
68
+ },
69
+ {
70
+ id: 'service-requests-overview',
71
+ component: 'ServiceRequestsDashboardOverview',
72
+ area: 'aside',
73
+ size: 'full',
74
+ order: 10
75
+ }
76
+ ],
77
+ clientIntegration: { moduleId: 'service-requests', labelKey: 'features.serviceRequests.navigation.myRequests' },
78
+ policy: {
79
+ PROVIDER: {
80
+ owner: serviceRequestActions,
81
+ admin: serviceRequestActions,
82
+ member: ['create', 'read', 'update', 'list']
83
+ },
84
+ CLIENT: {
85
+ owner: ['create', 'read', 'update', 'list'],
86
+ admin: ['create', 'read', 'update', 'list'],
87
+ member: ['create', 'read', 'update', 'list']
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,111 @@
1
+ export type ServiceRequestStatus = 'OPEN' | 'IN_PROGRESS' | 'RESOLVED' | 'CLOSED'
2
+ export type ServiceRequestPriority = 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT'
3
+
4
+ export interface ServiceRequestAttachment {
5
+ id: string
6
+ url: string
7
+ filename: string
8
+ size: number
9
+ mimeType: string
10
+ uploadedAt: string
11
+ uploadedById?: string
12
+ }
13
+
14
+ export interface ServiceRequestDto {
15
+ id: string
16
+ title: string
17
+ description: string
18
+ status: ServiceRequestStatus
19
+ priority: ServiceRequestPriority
20
+ category: string | null
21
+ organizationId: string
22
+ clientOrganizationId: string
23
+ clientName?: string
24
+ createdById: string
25
+ assignedToId: string | null
26
+ attachments: readonly ServiceRequestAttachment[]
27
+ internalNotes: string | null
28
+ createdAt: string
29
+ updatedAt: string
30
+ resolvedAt: string | null
31
+ closedAt: string | null
32
+ }
33
+
34
+ export interface ServiceRequestWithRelationsDto extends ServiceRequestDto {
35
+ createdBy?: {
36
+ id: string
37
+ name: string
38
+ email: string
39
+ image: string | null
40
+ }
41
+ assignedTo?: {
42
+ id: string
43
+ name: string
44
+ email: string
45
+ image: string | null
46
+ } | null
47
+ }
48
+
49
+ export interface ServiceRequestPagination {
50
+ total: number
51
+ page: number
52
+ pageSize: number
53
+ pageCount: number
54
+ }
55
+
56
+ export interface ServiceRequestListResponse {
57
+ items: ServiceRequestDto[]
58
+ pagination: ServiceRequestPagination
59
+ }
60
+
61
+ export interface ServiceRequestDashboardDto {
62
+ overview: {
63
+ activeCount: number
64
+ resolvedCount: number
65
+ recent: ServiceRequestDto[]
66
+ }
67
+ attention?: {
68
+ urgentCount: number
69
+ unassignedCount: number
70
+ longOpenCount: number
71
+ items: ServiceRequestDto[]
72
+ }
73
+ }
74
+
75
+ export interface ServiceRequestFilters {
76
+ clientOrganizationId?: string
77
+ status?: ServiceRequestStatus
78
+ priority?: ServiceRequestPriority
79
+ category?: string
80
+ assignedToId?: string
81
+ createdById?: string
82
+ search?: string
83
+ page?: number
84
+ pageSize?: number
85
+ sortBy?: 'createdAt' | 'status' | 'priority'
86
+ sortDir?: 'asc' | 'desc'
87
+ }
88
+
89
+ export type ServiceRequest = ServiceRequestDto
90
+ export type ServiceRequestWithRelations = ServiceRequestWithRelationsDto
91
+
92
+ export interface ServiceRequestCreateInput {
93
+ clientOrganizationId?: string
94
+ title: string
95
+ description: string
96
+ priority?: ServiceRequestPriority
97
+ category?: string
98
+ }
99
+
100
+ export interface ServiceRequestUpdateInput {
101
+ title?: string
102
+ description?: string
103
+ status?: ServiceRequestStatus
104
+ priority?: ServiceRequestPriority
105
+ category?: string
106
+ }
107
+
108
+ export interface AdminServiceRequestUpdateInput extends ServiceRequestUpdateInput {
109
+ assignedToId?: string
110
+ internalNotes?: string
111
+ }