@7365admin1/layer-common 1.8.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 (198) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.editorconfig +12 -0
  4. package/.github/workflows/main.yml +17 -0
  5. package/.github/workflows/publish.yml +39 -0
  6. package/.nuxtrc +1 -0
  7. package/.playground/app.vue +41 -0
  8. package/.playground/eslint.config.mjs +6 -0
  9. package/.playground/nuxt.config.ts +22 -0
  10. package/.playground/pages/feedback.vue +30 -0
  11. package/CHANGELOG.md +263 -0
  12. package/README.md +73 -0
  13. package/app.vue +3 -0
  14. package/components/AccessCardAddForm.vue +363 -0
  15. package/components/AccessManagement.vue +420 -0
  16. package/components/Avatar/Main.vue +68 -0
  17. package/components/BillingMain.vue +66 -0
  18. package/components/BtnUploadFile.vue +139 -0
  19. package/components/BuildingForm.vue +303 -0
  20. package/components/BuildingManagement/buildings.vue +335 -0
  21. package/components/BuildingManagement/units.vue +350 -0
  22. package/components/BuildingUnitFormAdd.vue +441 -0
  23. package/components/BuildingUnitFormEdit.vue +429 -0
  24. package/components/CameraForm.vue +264 -0
  25. package/components/CameraMain.vue +352 -0
  26. package/components/Card/DeleteConfirmation.vue +51 -0
  27. package/components/Card/MemberInfoSummary.vue +44 -0
  28. package/components/Card/Toggle.vue +25 -0
  29. package/components/Chat/Bubbles.vue +53 -0
  30. package/components/Chat/Information.vue +416 -0
  31. package/components/Chat/ListCard.vue +62 -0
  32. package/components/Chat/Message.vue +158 -0
  33. package/components/Chat/Navigation.vue +150 -0
  34. package/components/ConfirmDialog.vue +66 -0
  35. package/components/Container/Standard.vue +33 -0
  36. package/components/DashboardPlaceholder.vue +1524 -0
  37. package/components/Dialog/DeleteConfirmation.vue +51 -0
  38. package/components/Dialog/ReplaceAutofillPrompt.vue +49 -0
  39. package/components/Dialog/UpdateMoreAction.vue +103 -0
  40. package/components/DocumentForm.vue +187 -0
  41. package/components/DocumentManagement.vue +376 -0
  42. package/components/Editor.vue +95 -0
  43. package/components/EntryPassMain.vue +518 -0
  44. package/components/Feedback/Form.vue +173 -0
  45. package/components/FeedbackDetail.vue +599 -0
  46. package/components/FeedbackMain.vue +588 -0
  47. package/components/FormDialog.vue +65 -0
  48. package/components/ImageCarousel.vue +138 -0
  49. package/components/Input/Date.vue +177 -0
  50. package/components/Input/DateTimePicker.vue +131 -0
  51. package/components/Input/File.vue +236 -0
  52. package/components/Input/FileV2.vue +234 -0
  53. package/components/Input/InputPhoneNumberV2.vue +164 -0
  54. package/components/Input/ListGroupSelection.vue +96 -0
  55. package/components/Input/NRICNumber.vue +53 -0
  56. package/components/Input/NewDate.vue +123 -0
  57. package/components/Input/Number.vue +124 -0
  58. package/components/Input/Password.vue +22 -0
  59. package/components/Input/PhoneNumber.vue +188 -0
  60. package/components/Input/VehicleNumber.vue +49 -0
  61. package/components/InputLabel.vue +22 -0
  62. package/components/InvitationForm.vue +359 -0
  63. package/components/InvitationMain.vue +310 -0
  64. package/components/Layout/Header.vue +129 -0
  65. package/components/Layout/NavigationDrawer.vue +44 -0
  66. package/components/ListItem.vue +35 -0
  67. package/components/ListView.vue +87 -0
  68. package/components/LocalPagination.vue +31 -0
  69. package/components/MemberMain.vue +459 -0
  70. package/components/NFC/NFCPatrolReportMain.vue +591 -0
  71. package/components/NFC/NFCPatrolRouteForm.vue +596 -0
  72. package/components/NFC/NFCPatrolRouteMain.vue +539 -0
  73. package/components/NFC/NFCTagForm.vue +236 -0
  74. package/components/NFC/NFCTagMain.vue +337 -0
  75. package/components/NFC/PatrolSettings.vue +130 -0
  76. package/components/NavigationItem.vue +83 -0
  77. package/components/NumberSettingField.vue +107 -0
  78. package/components/OnlineFormConfigurationForm.vue +290 -0
  79. package/components/OnlineFormsConfiguration.vue +429 -0
  80. package/components/PeopleForm.vue +452 -0
  81. package/components/PlaceholderComponent.vue +34 -0
  82. package/components/RolePermissionFormCreate.vue +161 -0
  83. package/components/RolePermissionFormPreviewUpdate.vue +183 -0
  84. package/components/RolePermissionMain.vue +361 -0
  85. package/components/SearchVehicleNumberUser.vue +91 -0
  86. package/components/ServiceProviderFormCreate.vue +154 -0
  87. package/components/ServiceProviderMain.vue +547 -0
  88. package/components/SignaturePad.vue +73 -0
  89. package/components/Snackbar.vue +23 -0
  90. package/components/SpecificAttr.vue +53 -0
  91. package/components/SupplyManagement.vue +292 -0
  92. package/components/SwitchContext.vue +108 -0
  93. package/components/TableList.vue +150 -0
  94. package/components/TableListSecondary.vue +164 -0
  95. package/components/TableMain.vue +142 -0
  96. package/components/TableWithButton.vue +94 -0
  97. package/components/VehicleUpdateMoreAction.vue +84 -0
  98. package/components/VideoPlayer.vue +125 -0
  99. package/components/VisitorForm.vue +659 -0
  100. package/components/VisitorFormSelection.vue +53 -0
  101. package/components/VisitorManagement.vue +490 -0
  102. package/components/WorkOrder/Create.vue +284 -0
  103. package/components/WorkOrder/Detail.vue +71 -0
  104. package/components/WorkOrder/ListView.vue +96 -0
  105. package/components/WorkOrder/Main.vue +489 -0
  106. package/components/Workorder.vue +1 -0
  107. package/composables/useAddress.ts +107 -0
  108. package/composables/useBuilding.ts +250 -0
  109. package/composables/useBuildingUnit.ts +116 -0
  110. package/composables/useCard.ts +46 -0
  111. package/composables/useCommonPermission.ts +207 -0
  112. package/composables/useCustomer.ts +113 -0
  113. package/composables/useCustomerSite.ts +56 -0
  114. package/composables/useDashboard.ts +31 -0
  115. package/composables/useDashboardData.ts +425 -0
  116. package/composables/useDocument.ts +57 -0
  117. package/composables/useFacility.ts +246 -0
  118. package/composables/useFeedback.ts +119 -0
  119. package/composables/useFile.ts +55 -0
  120. package/composables/useInvoice.ts +18 -0
  121. package/composables/useLocal.ts +131 -0
  122. package/composables/useLocalAuth.ts +137 -0
  123. package/composables/useLocalSetup.ts +13 -0
  124. package/composables/useMember.ts +111 -0
  125. package/composables/useNFCPatrolRoute.ts +77 -0
  126. package/composables/useNFCPatrolSettings.ts +19 -0
  127. package/composables/useNFCPatrolTag.ts +53 -0
  128. package/composables/useOnlineForm.ts +67 -0
  129. package/composables/useOrg.ts +129 -0
  130. package/composables/usePDFDownload.ts +25 -0
  131. package/composables/usePaymentMethod.ts +101 -0
  132. package/composables/usePeople.ts +81 -0
  133. package/composables/usePermission.ts +54 -0
  134. package/composables/usePhoneCountries.ts +561 -0
  135. package/composables/usePrice.ts +15 -0
  136. package/composables/usePromoCode.ts +36 -0
  137. package/composables/useRecapPermission.ts +26 -0
  138. package/composables/useRole.ts +104 -0
  139. package/composables/useSecurityUtils.ts +18 -0
  140. package/composables/useServiceProvider.ts +224 -0
  141. package/composables/useSite.ts +109 -0
  142. package/composables/useSiteEntryPassSettings.ts +46 -0
  143. package/composables/useSiteSettings.ts +123 -0
  144. package/composables/useSubscription.ts +150 -0
  145. package/composables/useUser.ts +132 -0
  146. package/composables/useUtils.ts +445 -0
  147. package/composables/useVerification.ts +34 -0
  148. package/composables/useVisitor.ts +120 -0
  149. package/composables/useWorkOrder.ts +85 -0
  150. package/error.vue +41 -0
  151. package/layouts/plain.vue +7 -0
  152. package/middleware/01.auth.ts +20 -0
  153. package/middleware/02.org.ts +21 -0
  154. package/middleware/03.customer.ts +13 -0
  155. package/middleware/member.ts +4 -0
  156. package/nuxt.config.ts +54 -0
  157. package/package.json +39 -0
  158. package/pages/index.vue +3 -0
  159. package/pages/payment-method-linked.vue +31 -0
  160. package/pages/require-customer.vue +56 -0
  161. package/pages/require-organization-membership.vue +47 -0
  162. package/pages/unauthorized.vue +29 -0
  163. package/plugins/API.ts +21 -0
  164. package/plugins/iconify.client.ts +5 -0
  165. package/plugins/secure-member.client.ts +86 -0
  166. package/plugins/vuetify.ts +62 -0
  167. package/public/bg-camera.jpg +0 -0
  168. package/public/bg-city.jpg +0 -0
  169. package/public/bg-condo.jpg +0 -0
  170. package/public/images/icons/delete-icon.png +0 -0
  171. package/public/sprite.svg +1 -0
  172. package/tsconfig.json +3 -0
  173. package/types/address.d.ts +13 -0
  174. package/types/building.d.ts +27 -0
  175. package/types/camera.d.ts +31 -0
  176. package/types/card.d.ts +22 -0
  177. package/types/customer.d.ts +27 -0
  178. package/types/document.d.ts +6 -0
  179. package/types/feedback.d.ts +68 -0
  180. package/types/local.d.ts +74 -0
  181. package/types/member.d.ts +21 -0
  182. package/types/online-form.d.ts +15 -0
  183. package/types/org.d.ts +13 -0
  184. package/types/people.d.ts +24 -0
  185. package/types/permission.d.ts +25 -0
  186. package/types/phone-number.d.ts +10 -0
  187. package/types/price.d.ts +17 -0
  188. package/types/promo-code.d.ts +19 -0
  189. package/types/role.d.ts +11 -0
  190. package/types/select.d.ts +4 -0
  191. package/types/service-provider.d.ts +15 -0
  192. package/types/site.d.ts +20 -0
  193. package/types/subscription.d.ts +23 -0
  194. package/types/user.d.ts +19 -0
  195. package/types/verification.d.ts +20 -0
  196. package/types/visitor.d.ts +42 -0
  197. package/types/work-order.d.ts +42 -0
  198. package/utils/phoneMasks.ts +1703 -0
@@ -0,0 +1,246 @@
1
+ export default function(){
2
+
3
+ const facilityIcons = [
4
+ "001-coffee-4.svg",
5
+ "001-football.svg",
6
+ "001-ice-cream-3.svg",
7
+ "001-skin oil.svg",
8
+ "002-basketball.svg",
9
+ "002-cezve.svg",
10
+ "002-lollipop.svg",
11
+ "002-manicure.svg",
12
+ "003-aromatherapy.svg",
13
+ "003-latte.svg",
14
+ "003-sweet.svg",
15
+ "003-volleyball.svg",
16
+ "004-boxing.svg",
17
+ "004-chocolate.svg",
18
+ "004-honey.svg",
19
+ "004-hot tub.svg",
20
+ "005-candle.svg",
21
+ "005-coffee-grinder.svg",
22
+ "005-flour.svg",
23
+ "005-shuttlecock.svg",
24
+ "006-cake-3.svg",
25
+ "006-chess.svg",
26
+ "006-tea-bag-1.svg",
27
+ "006-teapot.svg",
28
+ "007-baseball.svg",
29
+ "007-cake-2.svg",
30
+ "007-juice.svg",
31
+ "007-wash feet.svg",
32
+ "008-baseball.svg",
33
+ "008-break.svg",
34
+ "008-cucumber slice.svg",
35
+ "008-tea-bag.svg",
36
+ "009-american football.svg",
37
+ "009-coffee-3.svg",
38
+ "009-gingerbread-man.svg",
39
+ "009-room heater.svg",
40
+ "010-coffee-2.svg",
41
+ "010-helmet.svg",
42
+ "010-sauna.svg",
43
+ "010-shrimp-1.svg",
44
+ "011-artichoke.svg",
45
+ "011-bowling.svg",
46
+ "011-can.svg",
47
+ "011-hot stone.svg",
48
+ "012-avocado.svg",
49
+ "012-soak.svg",
50
+ "012-Surfboard.svg",
51
+ "012-syrup.svg",
52
+ "013-beef.svg",
53
+ "013-kettle-1.svg",
54
+ "013-ping pong.svg",
55
+ "013-yoga mat.svg",
56
+ "014-carrot.svg",
57
+ "014-comb.svg",
58
+ "014-expresso.svg",
59
+ "014-football.svg",
60
+ "015-bucket.svg",
61
+ "015-coffee-machine-2.svg",
62
+ "015-ice-cream.svg",
63
+ "015-whistle.svg",
64
+ "016-coffee-machine-1.svg",
65
+ "016-coffee-shop.svg",
66
+ "016-football.svg",
67
+ "016-lotion.svg",
68
+ "017-basketball.svg",
69
+ "017-chinese-food.svg",
70
+ "017-coffee-machine.svg",
71
+ "017-humidifier.svg",
72
+ "018-chocolate.svg",
73
+ "018-medal.svg",
74
+ "018-olive branch.svg",
75
+ "018-orange-1.svg",
76
+ "019-brush.svg",
77
+ "019-kiwi.svg",
78
+ "019-mocha.svg",
79
+ "019-trophy.svg",
80
+ "020-lemon.svg",
81
+ "020-podium.svg",
82
+ "020-tea-1.svg",
83
+ "020-towel.svg",
84
+ "021-badminton.svg",
85
+ "021-bottle.svg",
86
+ "021-firewood.svg",
87
+ "021-pomegranate.svg",
88
+ "022-bullseye.svg",
89
+ "022-map.svg",
90
+ "022-noodles-1.svg",
91
+ "022-sponge.svg",
92
+ "023-mortar.svg",
93
+ "023-onigiri.svg",
94
+ "023-rafting.svg",
95
+ "023-spoons.svg",
96
+ "024-bamboo.svg",
97
+ "024-cocktail.svg",
98
+ "024-dart.svg",
99
+ "024-pie.svg",
100
+ "025-blender.svg",
101
+ "025-ice hockey.svg",
102
+ "025-potato.svg",
103
+ "025-sleeping mask.svg",
104
+ "026-chips.svg",
105
+ "026-football.svg",
106
+ "026-hair dryer.svg",
107
+ "026-sugar.svg",
108
+ "027-bathrobe.svg",
109
+ "027-croissant.svg",
110
+ "027-goal box.svg",
111
+ "027-spoon.svg",
112
+ "028-basketball.svg",
113
+ "028-sandals.svg",
114
+ "028-sandwich.svg",
115
+ "028-toast.svg",
116
+ "029-donut.svg",
117
+ "029-massage.svg",
118
+ "029-pretzel.svg",
119
+ "029-ski.svg",
120
+ "030-frappe.svg",
121
+ "030-rice-cooker-1.svg",
122
+ "030-sauna.svg",
123
+ "030-ski goggles.svg",
124
+ "031-beauty treatment.svg",
125
+ "031-flippers.svg",
126
+ "031-tea-pot.svg",
127
+ "031-watermelon.svg",
128
+ "032-apple.svg",
129
+ "032-cookies.svg",
130
+ "032-snorkeling.svg",
131
+ "032-wax.svg",
132
+ "033-archery.svg",
133
+ "033-skewer.svg",
134
+ "033-tea-bag.svg",
135
+ "034-cake-1.svg",
136
+ "034-milkshake.svg",
137
+ "034-tennis.svg",
138
+ "035-coffee-1.svg",
139
+ "035-pastry.svg",
140
+ "035-running shoe.svg",
141
+ "036-bowling.svg",
142
+ "036-french-press.svg",
143
+ "036-ham.svg",
144
+ "037-dumbbell.svg",
145
+ "037-milk.svg",
146
+ "037-pasta.svg",
147
+ "038-biscuit.svg",
148
+ "038-caviar.svg",
149
+ "038-kayak.svg",
150
+ "039-coffee-beans.svg",
151
+ "039-cricket.svg",
152
+ "039-shrimp.svg",
153
+ "040-golf.svg",
154
+ "040-pepper.svg",
155
+ "040-tea.svg",
156
+ "041-billiard.svg",
157
+ "041-coffee.svg",
158
+ "041-sauces.svg",
159
+ "042-bowling.svg",
160
+ "042-piece-of-cake.svg",
161
+ "042-pot.svg",
162
+ "043-coffee-maker.svg",
163
+ "043-golf.svg",
164
+ "043-popcorn.svg",
165
+ "044-bicycle.svg",
166
+ "044-rice-cooker.svg",
167
+ "044-water.svg",
168
+ "045-basketball.svg",
169
+ "045-kettle.svg",
170
+ "045-vegetables-1.svg",
171
+ "046-cake.svg",
172
+ "046-coffee-machine.svg",
173
+ "046-water bottle.svg",
174
+ "047-coffee-bag.svg",
175
+ "047-muffin.svg",
176
+ "047-tennis.svg",
177
+ "048-ice-cream-2.svg",
178
+ "048-muffin.svg",
179
+ "048-stopwatch.svg",
180
+ "049-croissant.svg",
181
+ "049-karate.svg",
182
+ "049-olives.svg",
183
+ "050-doughnut.svg",
184
+ "050-skipping rope.svg",
185
+ "050-take-away.svg",
186
+ "051-lobster.svg",
187
+ "052-breakfast.svg",
188
+ "053-fish-2.svg",
189
+ "054-burger.svg",
190
+ "055-steak.svg",
191
+ "056-ice-cream-1.svg",
192
+ "057-star-fruit.svg",
193
+ "058-salt.svg",
194
+ "059-cheese.svg",
195
+ "060-cracker.svg",
196
+ "061-turnip.svg",
197
+ "062-ribs-1.svg",
198
+ "063-tuna-1.svg",
199
+ "064-fried-egg-1.svg",
200
+ "065-tuna.svg",
201
+ "066-ribs.svg",
202
+ "067-feeder.svg",
203
+ "068-milk.svg",
204
+ "069-fish-1.svg",
205
+ "070-turkey.svg",
206
+ "071-vegetables.svg",
207
+ "072-fried-egg.svg",
208
+ "073-roast-chicken.svg",
209
+ "074-spaghetti.svg",
210
+ "075-french-fries.svg",
211
+ "076-fruit.svg",
212
+ "077-cake.svg",
213
+ "078-cinnamon-roll.svg",
214
+ "079-fish.svg",
215
+ "080-soup-1.svg",
216
+ "081-jelly.svg",
217
+ "082-dishes.svg",
218
+ "083-oil-bottle.svg",
219
+ "084-napkin.svg",
220
+ "085-meat-grinder-1.svg",
221
+ "086-meat-grinder.svg",
222
+ "087-soup.svg",
223
+ "088-ice-cream.svg",
224
+ "089-taco-1.svg",
225
+ "090-taco.svg",
226
+ "091-toaster.svg",
227
+ "092-sushi-2.svg",
228
+ "093-sushi-1.svg",
229
+ "094-sushi.svg",
230
+ "095-noodles.svg",
231
+ "096-rice.svg",
232
+ "097-corkscrew.svg",
233
+ "098-pear.svg",
234
+ "099-orange.svg",
235
+ "100-tomato.svg",
236
+ ];
237
+
238
+
239
+
240
+
241
+ return {
242
+
243
+ facilityIcons,
244
+
245
+ }
246
+ }
@@ -0,0 +1,119 @@
1
+ export default function useFeedback() {
2
+ const feedbacks = useState<Array<TFeedback>>("feedbacks", () => []);
3
+ const page = useState("page", () => 1);
4
+ const pages = useState("pages", () => 0);
5
+ const pageRange = useState("pageRange", () => "-- - -- of --");
6
+
7
+ const feedback = useState(
8
+ "feedback",
9
+ (): TFeedback => ({
10
+ _id: "",
11
+ attachments: [],
12
+ category: "",
13
+ categoryInfo: "",
14
+ subject: "",
15
+ location: "",
16
+ description: "",
17
+ createdBy: "",
18
+ createdAt: "",
19
+ updatedAt: "",
20
+ status: "pending",
21
+ metadata: {
22
+ serviceProvider: "",
23
+ assignee: "",
24
+ organization: "",
25
+ site: "",
26
+ name: "",
27
+ signature: "",
28
+ attachments: "",
29
+ completedAt: "",
30
+ },
31
+ workOrderNo: "",
32
+ })
33
+ );
34
+
35
+ async function getFeedbacks({
36
+ page = 1,
37
+ site = "",
38
+ status = "to-do",
39
+ search = "",
40
+ limit = 10,
41
+ from = "",
42
+ category = "",
43
+ } = {}) {
44
+ try {
45
+ return useNuxtApp().$api<Record<string, any>>(
46
+ `/api/feedbacks/site/${site}/status/${status}`,
47
+ {
48
+ method: "GET",
49
+ query: { page, search, limit, from, category },
50
+ }
51
+ );
52
+ } catch (err) {
53
+ console.error("Error fetching feedbacks:", err);
54
+ }
55
+ }
56
+
57
+ function getFeedbackById(id: string) {
58
+ return useNuxtApp().$api<TFeedback>(`/api/feedbacks/${id}`, {
59
+ method: "GET",
60
+ });
61
+ }
62
+
63
+ function createFeedback(payload: TFeedbackCreate) {
64
+ return useNuxtApp().$api<Record<string, any>>("/api/feedbacks", {
65
+ method: "POST",
66
+ body: payload,
67
+ });
68
+ }
69
+
70
+ function updateFeedback(id: string, payload: TFeedbackUpdate) {
71
+ return useNuxtApp().$api<Record<string, any>>(`/api/feedbacks/${id}`, {
72
+ method: "PUT",
73
+ body: payload,
74
+ });
75
+ }
76
+
77
+ function deleteFeedback(id: string) {
78
+ return useNuxtApp().$api<Record<string, any>>(`/api/feedbacks/${id}`, {
79
+ method: "DELETE",
80
+ });
81
+ }
82
+
83
+ function updateFeedbackServiceProvider(id: string, serviceProvider: string) {
84
+ return useNuxtApp().$api<Record<string, any>>(
85
+ `/api/feedbacks/${id}/service-provider`,
86
+ {
87
+ method: "PATCH",
88
+ body: {
89
+ serviceProvider,
90
+ },
91
+ }
92
+ );
93
+ }
94
+
95
+ function updateStatusComplete(id: string, payload: TFeedbackStatusComplete) {
96
+ return useNuxtApp().$api<Record<string, any>>(
97
+ `/api/feedbacks/${id}/status-complete`,
98
+ {
99
+ method: "PUT",
100
+ body: payload,
101
+ }
102
+ );
103
+ }
104
+
105
+ return {
106
+ feedbacks,
107
+ feedback,
108
+ page,
109
+ pages,
110
+ pageRange,
111
+ getFeedbacks,
112
+ getFeedbackById,
113
+ createFeedback,
114
+ updateFeedback,
115
+ deleteFeedback,
116
+ updateFeedbackServiceProvider,
117
+ updateStatusComplete,
118
+ };
119
+ }
@@ -0,0 +1,55 @@
1
+ export default function useFile() {
2
+ const baseUrl = useRuntimeConfig().public.API_DO_STORAGE_ENDPOINT;
3
+
4
+ function addFile(file: File | null) {
5
+ if (!file) {
6
+ throw new Error("File not found.");
7
+ }
8
+
9
+ const formData = new FormData();
10
+ formData.append("file", file);
11
+
12
+ return $fetch<Record<string, any>>("/api/files", {
13
+ method: "POST",
14
+ body: formData,
15
+ });
16
+ }
17
+
18
+ function getFileUrl(id: string) {
19
+ return `${baseUrl}/${id}`;
20
+ }
21
+
22
+ async function urlToFile(url: string, filename: string): Promise<File> {
23
+ const response = await fetch(url);
24
+ const blob = await response.blob();
25
+
26
+ // Try to extract MIME type if possible (e.g. image/png)
27
+ const mimeType = blob.type || "image/jpeg";
28
+
29
+ return new File([blob], filename, { type: mimeType });
30
+ }
31
+
32
+ function deleteFile(attachmentId: string) {
33
+ return useNuxtApp().$api<Record<string, any>>(
34
+ `/api/files/${attachmentId}`,
35
+ {
36
+ method: "DELETE",
37
+ }
38
+ );
39
+ }
40
+
41
+ function getFileById(id: string) {
42
+ return useNuxtApp().$api<Record<string, any>>(`/api/files/id/${id}`, {
43
+ method: "GET",
44
+ });
45
+ }
46
+
47
+ return {
48
+ baseUrl,
49
+ addFile,
50
+ deleteFile,
51
+ urlToFile,
52
+ getFileUrl,
53
+ getFileById,
54
+ };
55
+ }
@@ -0,0 +1,18 @@
1
+ export default function useInvoice() {
2
+ function getBySubscriptionId({ search = "", id = "", page = 1 } = {}) {
3
+ return useNuxtApp().$api<Record<string, any>>(
4
+ `/api/invoices/subscription/${id}`,
5
+ {
6
+ method: "GET",
7
+ params: {
8
+ search,
9
+ page,
10
+ },
11
+ }
12
+ );
13
+ }
14
+
15
+ return {
16
+ getBySubscriptionId,
17
+ };
18
+ }
@@ -0,0 +1,131 @@
1
+ export default function useLocal() {
2
+ const appConfig = useRuntimeConfig().public;
3
+
4
+ const { cookieConfig } = appConfig;
5
+
6
+ function getUserFromCookie() {
7
+ return useCookie("user", cookieConfig).value;
8
+ }
9
+
10
+ const drawer = useState("drawer", () => true);
11
+
12
+ const { APP_ACCOUNT, APP_ORG } = appConfig;
13
+
14
+ const apps = computed(() => {
15
+ return [
16
+ {
17
+ title: "Account",
18
+ icon: "mdi-account-group",
19
+ link: APP_ACCOUNT as string,
20
+ landingPage: "home",
21
+ },
22
+ {
23
+ title: "Organization",
24
+ icon: "mdi-account-group",
25
+ link: APP_ORG as string,
26
+ landingPage: "/",
27
+ },
28
+ ];
29
+ });
30
+
31
+ const headerSearch = useState("headerSearch", () => "");
32
+
33
+ const natureOfBusiness = [
34
+ {
35
+ title: "Real Estate Developer",
36
+ value: "real_estate_developer",
37
+ },
38
+ {
39
+ title: "Property Management Agency",
40
+ value: "property_management_agency",
41
+ },
42
+ { title: "Security Agency", value: "security_agency" },
43
+ {
44
+ title: "Mechanical and Electrical Services",
45
+ value: "mechanical_electrical_services",
46
+ },
47
+ { title: "Cleaning Services", value: "cleaning_services" },
48
+ { title: "Pest Control Services", value: "pest_control_services" },
49
+ { title: "Landscaping Services", value: "landscaping_services" },
50
+ { title: "Pool Maintenance Services", value: "pool_maintenance_services" },
51
+ ];
52
+
53
+ const landingPage = useCookie("landing-page", cookieConfig);
54
+
55
+ const subjects = [
56
+ {
57
+ title: "Facilities",
58
+ value: "Facilities",
59
+ subtitle:
60
+ "Shared amenities like gym, pool, BBQ pits, and function rooms.",
61
+ },
62
+ {
63
+ title: "Building Facade",
64
+ value: "Building Facade",
65
+ subtitle:
66
+ "Exterior walls, paint, cladding, signage, and overall appearance.",
67
+ },
68
+ {
69
+ title: "Security",
70
+ value: "Security",
71
+ subtitle:
72
+ "Guard services, access control, patrols, and visitor management.",
73
+ },
74
+ {
75
+ title: "Cleaning",
76
+ value: "Cleaning",
77
+ subtitle:
78
+ "Cleanliness of lobbies, corridors, lifts, bins, and common areas.",
79
+ },
80
+ {
81
+ title: "Landscape",
82
+ value: "Landscape",
83
+ subtitle: "Condition of plants, lawns, trees, and garden maintenance.",
84
+ },
85
+ {
86
+ title: "Pest Control",
87
+ value: "Pest Control",
88
+ subtitle:
89
+ "Effectiveness of measures against insects, rodents, and pests.",
90
+ },
91
+ {
92
+ title: "Water Features",
93
+ value: "Water Features",
94
+ subtitle:
95
+ "Operation and cleanliness of fountains, ponds, and pools (non-swimming).",
96
+ },
97
+ {
98
+ title: "Car Park",
99
+ value: "Car Park",
100
+ subtitle:
101
+ "Parking availability, markings, lighting, and barrier systems.",
102
+ },
103
+ {
104
+ title: "Lift",
105
+ value: "Lift",
106
+ subtitle:
107
+ "Lift reliability, speed, cleanliness, ventilation, and downtime.",
108
+ },
109
+ {
110
+ title: "Security Systems",
111
+ value: "Security Systems",
112
+ subtitle: "CCTV, intercoms, access cards, and gate/door sensors.",
113
+ },
114
+ {
115
+ title: "Others",
116
+ value: "Others",
117
+ subtitle: "Any issues or feedback not covered by the categories above.",
118
+ },
119
+ ];
120
+
121
+ return {
122
+ cookieConfig,
123
+ getUserFromCookie,
124
+ drawer,
125
+ apps,
126
+ headerSearch,
127
+ natureOfBusiness,
128
+ landingPage,
129
+ subjects,
130
+ };
131
+ }
@@ -0,0 +1,137 @@
1
+ export default function useLocalAuth() {
2
+ const { cookieConfig } = useRuntimeConfig().public;
3
+
4
+ const currentUser = useState<TUser | null>("currentUser", () => null);
5
+
6
+ async function authenticate() {
7
+ const user = useCookie("user", cookieConfig).value;
8
+
9
+ const { data: getCurrentUserReq, error: getCurrentUserErr } =
10
+ await useLazyAsyncData("getCurrentUser", () =>
11
+ useNuxtApp().$api<TUser>(`/api/users/id/${user}`)
12
+ );
13
+
14
+ watchEffect(() => {
15
+ if (getCurrentUserReq.value) {
16
+ currentUser.value = getCurrentUserReq.value;
17
+ }
18
+ });
19
+
20
+ watchEffect(() => {
21
+ if (getCurrentUserErr.value) {
22
+ // Redirect to login page if user authentication fails
23
+ navigateTo({ name: "index" });
24
+ }
25
+ });
26
+ }
27
+
28
+ async function login({ email = "", password = "" }) {
29
+ return useNuxtApp().$api<Record<string, any>>("/api/auth", {
30
+ method: "POST",
31
+ body: JSON.stringify({ email, password }),
32
+ });
33
+ }
34
+
35
+ function setSession({ sid = "", user = "" }) {
36
+ useCookie("sid", cookieConfig).value = sid;
37
+ useCookie("user", cookieConfig).value = user;
38
+ }
39
+
40
+ function clearCookies() {
41
+ useCookie("sid", cookieConfig).value = null;
42
+ useCookie("user", cookieConfig).value = null;
43
+ useCookie("organization", cookieConfig).value = null;
44
+ }
45
+
46
+ async function logout() {
47
+ const sid = useCookie("sid", cookieConfig).value;
48
+ if (sid) {
49
+ try {
50
+ await useNuxtApp().$api(`/api/auth/${sid}`, {
51
+ method: "DELETE",
52
+ });
53
+
54
+ clearCookies();
55
+ } catch (error) {
56
+ console.error("Logout failed:", error);
57
+ }
58
+ }
59
+ }
60
+
61
+ async function getCurrentUser() {
62
+ const user = useCookie("user", cookieConfig).value;
63
+ if (!user) return null;
64
+ const _user = await useNuxtApp().$api<TUser>(`/api/users/id/${user}`, {
65
+ method: "GET",
66
+ });
67
+ currentUser.value = _user;
68
+ return _user;
69
+ }
70
+
71
+ async function forgotPassword(email: string) {
72
+ if (!email) {
73
+ throw new Error("Email is required for password reset request.");
74
+ }
75
+
76
+ try {
77
+ return await useNuxtApp().$api<Record<string, any>>(
78
+ "/api/auth/forget-password",
79
+ {
80
+ method: "POST",
81
+ body: JSON.stringify({ email }),
82
+ headers: { "Content-Type": "application/json" },
83
+ }
84
+ );
85
+ } catch (error) {
86
+ console.error("Error in password reset request:", error);
87
+ throw error;
88
+ }
89
+ }
90
+
91
+ async function resetPassword(
92
+ otp: string,
93
+ newPassword: string,
94
+ passwordConfirmation: string
95
+ ) {
96
+ try {
97
+ return await useNuxtApp().$api<Record<string, any>>(
98
+ "/api/auth/reset-password",
99
+ {
100
+ method: "POST",
101
+ body: JSON.stringify({ otp, newPassword, passwordConfirmation }),
102
+ headers: { "Content-Type": "application/json" },
103
+ }
104
+ );
105
+ } catch (error) {
106
+ console.error("Error resetting password:", error);
107
+ throw error;
108
+ }
109
+ }
110
+
111
+ function verify(id: string) {
112
+ return useNuxtApp().$api<Record<string, any>>(`/api/auth/verify/${id}`, {
113
+ method: "GET",
114
+ });
115
+ }
116
+
117
+ function signUp(email: string, referral: string) {
118
+ return useNuxtApp().$api<Record<string, any>>("/api/auth/sign-up", {
119
+ method: "POST",
120
+ body: { email, referral },
121
+ });
122
+ }
123
+
124
+ return {
125
+ authenticate,
126
+ login,
127
+ setSession,
128
+ logout,
129
+ clearCookies,
130
+ getCurrentUser,
131
+ forgotPassword,
132
+ resetPassword,
133
+ currentUser,
134
+ verify,
135
+ signUp,
136
+ };
137
+ }