@iservice365/layer-common 0.1.0 → 0.2.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 (91) hide show
  1. package/.playground/app.vue +7 -2
  2. package/.playground/pages/feedback.vue +30 -0
  3. package/CHANGELOG.md +6 -0
  4. package/components/Chat/Bubbles.vue +53 -0
  5. package/components/Chat/Information.vue +187 -0
  6. package/components/Chat/ListCard.vue +62 -0
  7. package/components/Chat/Message.vue +149 -0
  8. package/components/Chat/Navigation.vue +150 -0
  9. package/components/ConfirmDialog.vue +66 -0
  10. package/components/Container/Standard.vue +33 -0
  11. package/components/Feedback/Form.vue +136 -0
  12. package/components/FeedbackDetail.vue +465 -0
  13. package/components/FeedbackMain.vue +454 -0
  14. package/components/FormDialog.vue +65 -0
  15. package/components/Input/File.vue +203 -0
  16. package/components/Input/ListGroupSelection.vue +96 -0
  17. package/components/Input/NewDate.vue +123 -0
  18. package/components/Input/Number.vue +124 -0
  19. package/components/InvitationMain.vue +284 -0
  20. package/components/Layout/Header.vue +14 -4
  21. package/components/ListView.vue +87 -0
  22. package/components/MemberMain.vue +459 -0
  23. package/components/RolePermissionFormCreate.vue +161 -0
  24. package/components/RolePermissionFormPreviewUpdate.vue +183 -0
  25. package/components/RolePermissionMain.vue +361 -0
  26. package/components/ServiceProviderFormCreate.vue +154 -0
  27. package/components/ServiceProviderMain.vue +195 -0
  28. package/components/SignaturePad.vue +73 -0
  29. package/components/SpecificAttr.vue +53 -0
  30. package/components/SwitchContext.vue +26 -5
  31. package/components/TableList.vue +150 -0
  32. package/components/TableListSecondary.vue +164 -0
  33. package/components/WorkOrder/Create.vue +197 -0
  34. package/components/WorkOrder/ListView.vue +96 -0
  35. package/components/WorkOrder/Main.vue +308 -0
  36. package/components/Workorder.vue +1 -0
  37. package/composables/useAddress.ts +107 -0
  38. package/composables/useCommonPermission.ts +130 -0
  39. package/composables/useCustomer.ts +113 -0
  40. package/composables/useFeedback.ts +117 -0
  41. package/composables/useFile.ts +40 -0
  42. package/composables/useInvoice.ts +18 -0
  43. package/composables/useLocal.ts +24 -4
  44. package/composables/useLocalAuth.ts +58 -14
  45. package/composables/useLocalSetup.ts +52 -0
  46. package/composables/useMember.ts +104 -0
  47. package/composables/useOrg.ts +76 -92
  48. package/composables/usePaymentMethod.ts +101 -0
  49. package/composables/usePrice.ts +15 -0
  50. package/composables/usePromoCode.ts +36 -0
  51. package/composables/useRole.ts +38 -7
  52. package/composables/useServiceProvider.ts +218 -0
  53. package/composables/useSite.ts +108 -0
  54. package/composables/useSubscription.ts +149 -0
  55. package/composables/useUser.ts +38 -14
  56. package/composables/useUtils.ts +218 -6
  57. package/composables/useVerification.ts +33 -0
  58. package/composables/useWorkOrder.ts +68 -0
  59. package/middleware/01.auth.ts +11 -0
  60. package/middleware/02.org.ts +18 -0
  61. package/middleware/03.customer.ts +13 -0
  62. package/nuxt.config.ts +2 -1
  63. package/package.json +7 -3
  64. package/pages/index.vue +3 -0
  65. package/pages/payment-method-linked.vue +31 -0
  66. package/pages/require-customer.vue +56 -0
  67. package/pages/require-organization-membership.vue +47 -0
  68. package/pages/unauthorized.vue +29 -0
  69. package/plugins/API.ts +1 -3
  70. package/plugins/iconify.client.ts +5 -0
  71. package/plugins/vuetify.ts +2 -0
  72. package/public/bg-camera.jpg +0 -0
  73. package/public/bg-city.jpg +0 -0
  74. package/public/bg-condo.jpg +0 -0
  75. package/public/images/icons/delete-icon.png +0 -0
  76. package/public/sprite.svg +1 -0
  77. package/types/address.d.ts +13 -0
  78. package/types/customer.d.ts +15 -0
  79. package/types/feedback.d.ts +63 -0
  80. package/types/local.d.ts +46 -38
  81. package/types/member.d.ts +21 -0
  82. package/types/org.d.ts +13 -0
  83. package/types/permission.d.ts +1 -0
  84. package/types/price.d.ts +17 -0
  85. package/types/promo-code.d.ts +19 -0
  86. package/types/service-provider.d.ts +15 -0
  87. package/types/site.d.ts +13 -0
  88. package/types/subscription.d.ts +23 -0
  89. package/types/user.d.ts +19 -0
  90. package/types/verification.d.ts +20 -0
  91. package/types/work-order.d.ts +40 -0
@@ -2,10 +2,10 @@
2
2
  <v-app>
3
3
  <LayoutHeader />
4
4
 
5
- <LayoutNavigationDrawer :navigation-items="navigationItems"/>
5
+ <LayoutNavigationDrawer :navigation-items="navigationItems" />
6
6
 
7
7
  <v-main>
8
- <slot />
8
+ <NuxtLayout> <NuxtPage /> </NuxtLayout>
9
9
  </v-main>
10
10
  </v-app>
11
11
  </template>
@@ -28,6 +28,11 @@ const navigationItems = computed(() => {
28
28
  title: "Draft",
29
29
  route: { name: "index" },
30
30
  icon: "mdi-account-circle",
31
+ },
32
+ {
33
+ title: "Feedback",
34
+ route: { name: "feedback" },
35
+ icon: "mdi-account-circle",
31
36
  }
32
37
  );
33
38
 
@@ -0,0 +1,30 @@
1
+ <template>
2
+ <v-row class="no-gutters" align="center" justify="center">
3
+ <v-col cols="12" md="10" lg="10">
4
+ <FeedbackListView @click:create="showCreateDialog = true" />
5
+ </v-col>
6
+
7
+ <v-dialog
8
+ v-model="showCreateDialog"
9
+ fullscreen
10
+ transition="dialog-right-transition"
11
+ persistent
12
+ >
13
+ <v-card
14
+ class="ml-auto"
15
+ style="
16
+ height: 100vh;
17
+ width: 400px;
18
+ border-top-left-radius: 12px;
19
+ border-bottom-left-radius: 12px;
20
+ "
21
+ >
22
+ <FeedbackFormCreate @close="showCreateDialog = false" />
23
+ </v-card>
24
+ </v-dialog>
25
+ </v-row>
26
+ </template>
27
+
28
+ <script lang="ts" setup>
29
+ const showCreateDialog = ref(false);
30
+ </script>
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @iservice365/layer-common
2
2
 
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 7df0f0f: Add iconify
8
+
3
9
  ## 0.1.0
4
10
 
5
11
  ### Minor Changes
@@ -0,0 +1,53 @@
1
+ <template>
2
+ <v-card class="mb-2 pa-4 rounded-lg" width="400" elevation="2">
3
+ <v-row no-gutters align="center">
4
+ <v-col cols="auto" class="mr-3">
5
+ <v-avatar color="surface-variant" size="35">
6
+ <v-img v-if="currentUser?.profile" width="15" height="15" />
7
+ <span v-else class="text-h5">{{ getNameInitials(senderName) }}</span>
8
+ </v-avatar>
9
+ </v-col>
10
+
11
+ <v-col class="d-flex flex-column">
12
+ <span class="text-body-2 font-weight-medium">{{ senderName }}</span>
13
+ <span class="text-caption text-grey">{{ role }}</span>
14
+ </v-col>
15
+ </v-row>
16
+
17
+ <v-row no-gutters class="mt-1">
18
+ <v-col>
19
+ <span class="py-2">{{ message }}</span>
20
+
21
+ <v-row no-gutters justify="space-between" align="center" class="mt-1">
22
+ <v-col cols="auto">
23
+ <span class="text-caption">{{ timestamp }}</span>
24
+ </v-col>
25
+ <v-col
26
+ v-if="isCurrentUser"
27
+ cols="auto"
28
+ class="d-flex align-center bg-grey-200"
29
+ >
30
+ <v-icon size="16" class="mr-1 text--secondary"
31
+ >mdi-eye-outline</v-icon
32
+ >
33
+ <span class="text-caption text--secondary">{{ seenLabel }}</span>
34
+ </v-col>
35
+ </v-row>
36
+ </v-col>
37
+ </v-row>
38
+ </v-card>
39
+ </template>
40
+
41
+ <script setup lang="ts">
42
+ defineProps<{
43
+ isCurrentUser: boolean;
44
+ message: string;
45
+ timestamp: string;
46
+ seenLabel?: string;
47
+ senderName: string;
48
+ role?: string;
49
+ }>();
50
+
51
+ const { currentUser } = useLocalAuth();
52
+ const { getNameInitials } = useUtils();
53
+ </script>
@@ -0,0 +1,187 @@
1
+ <template>
2
+ <v-sheet
3
+ elevation="1"
4
+ rounded="0"
5
+ class="fill-height d-flex flex-column"
6
+ style="border-right: 1px solid #e0e0e0; border-top: 1px solid #e0e0e0"
7
+ >
8
+ <v-row class="pa-4">
9
+ <v-sheet
10
+ class="overflow-y-auto flex-grow-1"
11
+ :style="{ height: 'calc(100vh - 180px)', overflowX: 'hidden' }"
12
+ >
13
+ <v-col
14
+ cols="12"
15
+ class="mb-2"
16
+ style="position: sticky; top: 0; background-color: white; z-index: 1"
17
+ >
18
+ <h3 class="text-h6">Information</h3>
19
+ </v-col>
20
+
21
+ <v-col cols="12" class="text-center mb-3" v-if="item">
22
+ <v-avatar
23
+ size="48"
24
+ class="mb-1"
25
+ v-if="!item.attachments || !item.attachments.length"
26
+ >
27
+ <v-img v-if="currentUser?.profile" width="15" height="15" />
28
+ <span v-else class="text-h5">{{
29
+ getNameInitials(senderName)
30
+ }}</span>
31
+ </v-avatar>
32
+
33
+ <v-img
34
+ v-else-if="item.attachments.length === 1"
35
+ :src="item.attachments[0]"
36
+ height="200"
37
+ cover
38
+ class="rounded mb-2"
39
+ />
40
+
41
+ <v-carousel
42
+ v-else
43
+ hide-delimiter-background
44
+ height="200"
45
+ class="rounded mb-2"
46
+ show-arrows
47
+ cycle
48
+ >
49
+ <v-carousel-item
50
+ v-for="(attachment, index) in item.attachments"
51
+ :key="index"
52
+ >
53
+ <v-img :src="attachment" cover class="w-100 h-100" />
54
+ </v-carousel-item>
55
+ </v-carousel>
56
+ </v-col>
57
+
58
+ <v-col cols="12" v-if="item">
59
+ <v-row dense class="my-1">
60
+ <v-col cols="6" class="py-1"><strong>Category:</strong></v-col>
61
+ <v-col cols="6" class="py-1 text-right text-capitalize">{{ item.category }}</v-col>
62
+ </v-row>
63
+
64
+ <v-divider />
65
+
66
+ <v-row dense class="my-1">
67
+ <v-col cols="6" class="py-1"><strong>Location:</strong></v-col>
68
+ <v-col cols="6" class="py-1 text-right">{{ item.location }}</v-col>
69
+ </v-row>
70
+ <v-divider />
71
+
72
+ <v-row dense class="my-1">
73
+ <v-col cols="12" class="py-1"
74
+ ><strong>Description Feedback:</strong></v-col
75
+ >
76
+ <v-col cols="12" class="py-1">
77
+ {{ item.description }}
78
+ </v-col>
79
+ </v-row>
80
+ <v-divider />
81
+
82
+ <v-row dense class="my-1">
83
+ <v-col cols="12" class="py-1"
84
+ ><strong>Description Work Order:</strong></v-col
85
+ >
86
+ <v-col cols="12" class="py-1">
87
+ {{
88
+ item.workOrderDescription ||
89
+ "No work order description available"
90
+ }}
91
+ </v-col>
92
+ </v-row>
93
+ <v-divider />
94
+
95
+ <v-row dense class="my-1">
96
+ <v-col cols="6" class="py-1"><strong>Workorder:</strong></v-col>
97
+ <v-col cols="6" class="py-1 text-right">{{ item.workOrder }}</v-col>
98
+ </v-row>
99
+
100
+ <v-divider />
101
+
102
+ <v-row dense class="my-1">
103
+ <v-col cols="6" class="py-1"><strong>Status:</strong></v-col>
104
+ <v-col cols="6" class="py-1 text-right">
105
+ <v-chip
106
+ :color="getColorStatus(item.status)"
107
+ size="x-small"
108
+ text-color="white"
109
+ >
110
+ {{ item.status }}
111
+ </v-chip>
112
+ </v-col>
113
+ </v-row>
114
+
115
+ <v-divider />
116
+
117
+ <v-row dense class="my-1">
118
+ <v-col cols="6" class="py-1"><strong>Created At:</strong></v-col>
119
+ <v-col cols="6" class="py-1 text-right">{{
120
+ formatDate(item.createdAt)
121
+ }}</v-col>
122
+ </v-row>
123
+ </v-col>
124
+
125
+ <v-col cols="12">
126
+ <v-btn
127
+ block
128
+ color="primary"
129
+ variant="flat"
130
+ class="mb-2 text-capitalize"
131
+ @click="$emit('edit')"
132
+ >
133
+ Edit
134
+ </v-btn>
135
+ </v-col>
136
+ </v-sheet>
137
+ </v-row>
138
+
139
+ <v-sheet class="px-4 py-2">
140
+ <v-btn
141
+ v-if="item?.status !== 'Completed'"
142
+ block
143
+ color="primary-button"
144
+ density="default"
145
+ class="mb-2 text-capitalize"
146
+ @click="$emit('mark-complete-request')"
147
+ >
148
+ Mark as Complete
149
+ </v-btn>
150
+ <v-btn
151
+ block
152
+ variant="flat"
153
+ color="red"
154
+ density="default"
155
+ class="text-white text-capitalize"
156
+ @click="$emit('delete')"
157
+ >
158
+ Delete
159
+ </v-btn>
160
+ </v-sheet>
161
+ </v-sheet>
162
+ </template>
163
+
164
+ <script setup lang="ts">
165
+ const { getColorStatus, formatDate } = useUtils();
166
+
167
+ defineProps({
168
+ item: {
169
+ type: Object,
170
+ default: () => ({}),
171
+ },
172
+ senderName: {
173
+ type: String,
174
+ default: "",
175
+ },
176
+ });
177
+
178
+ const emit = defineEmits([
179
+ "update:provider",
180
+ "mark-complete-request",
181
+ "delete",
182
+ "edit",
183
+ ]);
184
+
185
+ const { currentUser } = useLocalAuth();
186
+ const { getNameInitials } = useUtils();
187
+ </script>
@@ -0,0 +1,62 @@
1
+ <template>
2
+ <v-card class="mb-2 pa-2 rounded-lg border-sm" elevation="0">
3
+ <v-row no-gutters align="center">
4
+ <v-col cols="12" sm="4" class="d-flex justify-center align-center">
5
+ <v-img
6
+ :src="image"
7
+ alt="Photo"
8
+ max-height="100"
9
+ width="100%"
10
+ cover
11
+ class="rounded-lg"
12
+ />
13
+ </v-col>
14
+
15
+ <v-col cols="12" sm="8" class="py-2 pe-1">
16
+ <v-row dense>
17
+ <v-col cols="12" class="d-flex align-center flex-wrap">
18
+ <span class="text-caption font-weight-medium me-1">Created by</span>
19
+
20
+ <v-avatar color="surface-variant" size="20" class="me-1">
21
+ <v-img
22
+ v-if="userProfile"
23
+ :src="userProfile"
24
+ width="20"
25
+ height="20"
26
+ />
27
+ <span v-else class="text-overline">
28
+ {{ getNameInitials }}
29
+ </span>
30
+ </v-avatar>
31
+
32
+ <span class="text-caption">{{ createdByName || "Unknown" }}</span>
33
+ </v-col>
34
+
35
+ <v-col cols="12" class="text-caption">Subject: {{ subject }}</v-col>
36
+
37
+ <v-col cols="12" class="text-caption">
38
+ Status: <span class="text-orange">{{ status }}</span>
39
+ </v-col>
40
+
41
+ <v-col cols="12" class="text-caption">
42
+ Date Created: {{ createdAt }}
43
+ </v-col>
44
+ </v-row>
45
+ </v-col>
46
+ </v-row>
47
+ </v-card>
48
+ </template>
49
+
50
+ <script setup lang="ts">
51
+ const { getNameInitials } = useUtils();
52
+
53
+ defineProps({
54
+ image: String,
55
+ subject: String,
56
+ status: String,
57
+ createdAt: String,
58
+ createdByName: String,
59
+ userProfile: String,
60
+ getNameInitials: Function,
61
+ });
62
+ </script>
@@ -0,0 +1,149 @@
1
+ <template>
2
+ <v-sheet
3
+ elevation="1"
4
+ rounded="0"
5
+ class="fill-height d-flex flex-column"
6
+ style="border-right: 1px solid #e0e0e0; border-top: 1px solid #e0e0e0"
7
+ >
8
+ <div style="border-bottom: 1px solid #e0e0e0" class="px-4 pt-4 pb-2 mb-2">
9
+ <h3 class="text-h6">Chat</h3>
10
+ </div>
11
+
12
+ <v-sheet
13
+ class="overflow-y-auto flex-grow-1 pa-3"
14
+ :style="{ height: 'calc(100vh - 300px)', overflowX: 'hidden' }"
15
+ >
16
+ <v-row
17
+ v-for="(msg, i) in messages"
18
+ :key="i"
19
+ no-gutters
20
+ :justify="msg.isCurrentUser ? 'end' : 'start'"
21
+ class="mb-2"
22
+ >
23
+ <v-col cols="auto">
24
+ <ChatBubbles
25
+ :isCurrentUser="msg.isCurrentUser"
26
+ :message="msg.message"
27
+ :timestamp="msg.timestamp"
28
+ :seenLabel="msg.seenLabel"
29
+ :senderName="msg.senderName"
30
+ :role="msg.role"
31
+ />
32
+ </v-col>
33
+ </v-row>
34
+ </v-sheet>
35
+
36
+ <v-card class="mx-4 mb-4 mt-2 pa-3 rounded-lg" elevation="2">
37
+ <v-row no-gutters align="end">
38
+ <v-col cols="10">
39
+ <v-textarea
40
+ label="Message"
41
+ auto-grow
42
+ hide-details
43
+ rows="1"
44
+ variant="outlined"
45
+ />
46
+ </v-col>
47
+ <v-col cols="2" class="pl-2">
48
+ <v-btn color="primary-button" block class="pa-4 py-6 text-capitalize"
49
+ >Send</v-btn
50
+ >
51
+ </v-col>
52
+ </v-row>
53
+
54
+ <v-divider class="my-2" />
55
+
56
+ <v-row justify="start" no-gutters align="center">
57
+ <v-col cols="auto">
58
+ <v-icon size="20" class="mr-3">mdi-paperclip</v-icon>
59
+ </v-col>
60
+
61
+ <v-col cols="auto">
62
+ <v-icon size="20" class="mr-3">mdi-emoticon-happy-outline</v-icon>
63
+ </v-col>
64
+
65
+ <v-col cols="auto">
66
+ <v-menu location="top" offset="10">
67
+ <template #activator="{ props }">
68
+ <v-btn icon v-bind="props" density="compact" variant="text">
69
+ <v-icon size="20" color="gray">mdi-message-outline</v-icon>
70
+ </v-btn>
71
+ </template>
72
+
73
+ <v-card min-width="350" class="rounded-lg">
74
+ <v-card-title class="text-subtitle-1 font-weight-medium pb-1"
75
+ >Quick Chat</v-card-title
76
+ >
77
+ <v-divider class="mb-1" />
78
+
79
+ <v-list density="compact">
80
+ <v-list-item
81
+ v-for="(option, index) in quickChatOptions"
82
+ :key="index"
83
+ @click="selectQuickChat(option)"
84
+ >
85
+ <v-list-item-title>{{ option }}</v-list-item-title>
86
+ </v-list-item>
87
+ </v-list>
88
+ </v-card>
89
+ </v-menu>
90
+ </v-col>
91
+ </v-row>
92
+ </v-card>
93
+ </v-sheet>
94
+ </template>
95
+
96
+ <script setup lang="ts">
97
+ const messages = [
98
+ {
99
+ isCurrentUser: true,
100
+ message: "Hello we would like to transfer this task...",
101
+ timestamp: "06/28/2024 08:40",
102
+ seenLabel: "Seen",
103
+ senderName: "You",
104
+ role: "Site Personnel",
105
+ },
106
+ {
107
+ isCurrentUser: false,
108
+ message: "Sure. Let me take care of that.",
109
+ timestamp: "06/28/2024 08:42",
110
+ senderName: "Tan Wei",
111
+ role: "Manager",
112
+ },
113
+ {
114
+ isCurrentUser: true,
115
+ message: "Thanks!",
116
+ timestamp: "06/28/2024 08:43",
117
+ seenLabel: "Seen",
118
+ senderName: "You",
119
+ role: "Site Personnel",
120
+ },
121
+ {
122
+ isCurrentUser: false,
123
+ message: "No worries!",
124
+ timestamp: "06/28/2024 08:44",
125
+ senderName: "Tan Wei",
126
+ role: "Manager",
127
+ },
128
+ {
129
+ isCurrentUser: true,
130
+ message: "Let me know if you need anything else.",
131
+ timestamp: "06/28/2024 08:45",
132
+ seenLabel: "Seen",
133
+ senderName: "You",
134
+ role: "Site Personnel",
135
+ },
136
+ ];
137
+
138
+ const quickChatOptions = [
139
+ "This is all noted, thank you!",
140
+ "Ok, we are working on it.",
141
+ "Yes, we will do it as soon as possible.",
142
+ "Sorry, we cannot make it this time.",
143
+ "We are here to help.",
144
+ ];
145
+
146
+ const selectQuickChat = (msg: string) => {
147
+ console.log("Quick Chat Selected:", msg);
148
+ };
149
+ </script>
@@ -0,0 +1,150 @@
1
+ <template>
2
+ <v-sheet
3
+ elevation="1"
4
+ rounded="0"
5
+ class="pa-4 fill-height"
6
+ style="border-right: 1px solid #e0e0e0; border-top: 1px solid #e0e0e0"
7
+ >
8
+ <h3 class="text-h6 mb-4">{{ title }}</h3>
9
+
10
+ <v-text-field
11
+ v-model="search"
12
+ @input="_search"
13
+ label="Search"
14
+ prepend-inner-icon="mdi-magnify"
15
+ density="compact"
16
+ hide-details
17
+ variant="outlined"
18
+ class="mb-4"
19
+ />
20
+
21
+ <v-select
22
+ label="Filter by Status"
23
+ :items="['All', 'In Progress', 'To Do', 'Done']"
24
+ v-model="selectedStatus"
25
+ density="compact"
26
+ hide-details
27
+ variant="outlined"
28
+ class="mb-4"
29
+ />
30
+
31
+ <v-row dense class="mb-4" align="center">
32
+ <v-col cols="5">
33
+ <v-menu
34
+ v-model="startMenu"
35
+ :close-on-content-click="false"
36
+ transition="scale-transition"
37
+ offset-y
38
+ max-width="280px"
39
+ min-width="auto"
40
+ >
41
+ <template #activator="{ props }">
42
+ <v-text-field
43
+ v-bind="props"
44
+ v-model="startDate"
45
+ label="Start Date"
46
+ density="compact"
47
+ variant="outlined"
48
+ readonly
49
+ hide-details
50
+ prepend-inner-icon="mdi-calendar"
51
+ />
52
+ </template>
53
+
54
+ <v-date-picker
55
+ v-model="startDate"
56
+ @update:model-value="startMenu = false"
57
+ show-adjacent-months
58
+ hide-header
59
+ class="d-flex flex-column pa-2"
60
+ style="font-size: 0.85rem; max-height: 300px"
61
+ />
62
+ </v-menu>
63
+ </v-col>
64
+
65
+ <v-col cols="2" class="d-flex align-center justify-center">
66
+ <span class="text-subtitle-2">to</span>
67
+ </v-col>
68
+
69
+ <v-col cols="5">
70
+ <v-menu
71
+ v-model="endMenu"
72
+ :close-on-content-click="false"
73
+ transition="scale-transition"
74
+ offset-y
75
+ max-width="280px"
76
+ min-width="auto"
77
+ >
78
+ <template #activator="{ props }">
79
+ <v-text-field
80
+ v-bind="props"
81
+ v-model="endDate"
82
+ label="End Date"
83
+ density="compact"
84
+ variant="outlined"
85
+ readonly
86
+ hide-details
87
+ prepend-inner-icon="mdi-calendar"
88
+ />
89
+ </template>
90
+
91
+ <v-date-picker
92
+ v-model="endDate"
93
+ @update:model-value="endMenu = false"
94
+ show-adjacent-months
95
+ hide-header
96
+ class="d-flex flex-column pa-2"
97
+ style="font-size: 0.85rem; max-height: 300px"
98
+ />
99
+ </v-menu>
100
+ </v-col>
101
+ </v-row>
102
+
103
+ <v-sheet
104
+ class="overflow-y-auto flex-grow-1 pa-3"
105
+ :style="{ height: 'calc(100vh - 320px)', overflowX: 'hidden' }"
106
+ >
107
+ <v-row dense>
108
+ <v-col v-for="(item, index) in items" :key="item._id" cols="12">
109
+ <div class="cursor-pointer" @click="$emit('select', item._id)">
110
+ <ChatListCard
111
+ :image="currentUser?.profile"
112
+ :subject="item.subject"
113
+ :status="item.status"
114
+ :createdAt="
115
+ item.createdAt
116
+ ? new Date(item.createdAt).toLocaleDateString()
117
+ : ''
118
+ "
119
+ :createdByName="item.createdByName"
120
+ :userProfile="currentUser?.profile"
121
+ :getNameInitials="getNameInitials"
122
+ />
123
+ </div>
124
+ </v-col>
125
+ </v-row>
126
+ </v-sheet>
127
+ </v-sheet>
128
+ </template>
129
+
130
+ <script setup lang="ts">
131
+ defineProps<{
132
+ title: string;
133
+ items: Array<Record<string, any>>;
134
+ }>();
135
+
136
+ const emit = defineEmits(["select", "search"]);
137
+
138
+ const { currentUser } = useLocalAuth();
139
+ const { getNameInitials, search } = useUtils();
140
+
141
+ const selectedStatus = ref("All");
142
+ const startDate = ref(null);
143
+ const endDate = ref(null);
144
+ const startMenu = ref(false);
145
+ const endMenu = ref(false);
146
+
147
+ function _search() {
148
+ emit("search", search.value);
149
+ }
150
+ </script>