pukaad-ui-lib 1.422.0 → 1.424.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 (52) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/card/card-content/card-content-video.vue +1 -1
  3. package/dist/runtime/components/drawer/drawer-post-content.vue +8 -1
  4. package/dist/runtime/components/input/input-address.d.vue.ts +1 -1
  5. package/dist/runtime/components/input/input-address.vue.d.ts +1 -1
  6. package/dist/runtime/components/input/input-autocomplete.d.vue.ts +2 -2
  7. package/dist/runtime/components/input/input-autocomplete.vue.d.ts +2 -2
  8. package/dist/runtime/components/input/input-birth-date.d.vue.ts +1 -1
  9. package/dist/runtime/components/input/input-birth-date.vue.d.ts +1 -1
  10. package/dist/runtime/components/input/input-date-picker.d.vue.ts +1 -1
  11. package/dist/runtime/components/input/input-date-picker.vue.d.ts +1 -1
  12. package/dist/runtime/components/input/input-file.d.vue.ts +1 -1
  13. package/dist/runtime/components/input/input-file.vue.d.ts +1 -1
  14. package/dist/runtime/components/input/input-link.d.vue.ts +1 -1
  15. package/dist/runtime/components/input/input-link.vue.d.ts +1 -1
  16. package/dist/runtime/components/input/input-localized-name.d.vue.ts +1 -1
  17. package/dist/runtime/components/input/input-localized-name.vue.d.ts +1 -1
  18. package/dist/runtime/components/input/input-mention.vue +1 -1
  19. package/dist/runtime/components/input/input-password.d.vue.ts +1 -1
  20. package/dist/runtime/components/input/input-password.vue.d.ts +1 -1
  21. package/dist/runtime/components/input/input-personal-card-id.d.vue.ts +2 -2
  22. package/dist/runtime/components/input/input-personal-card-id.vue.d.ts +2 -2
  23. package/dist/runtime/components/input/input-search.d.vue.ts +1 -1
  24. package/dist/runtime/components/input/input-search.vue.d.ts +1 -1
  25. package/dist/runtime/components/input/input-select-place.d.vue.ts +4 -0
  26. package/dist/runtime/components/input/input-select-place.vue +88 -19
  27. package/dist/runtime/components/input/input-select-place.vue.d.ts +4 -0
  28. package/dist/runtime/components/input/input-suggest.d.vue.ts +2 -2
  29. package/dist/runtime/components/input/input-suggest.vue.d.ts +2 -2
  30. package/dist/runtime/components/input/input-tag-modal.d.vue.ts +1 -1
  31. package/dist/runtime/components/input/input-tag-modal.vue.d.ts +1 -1
  32. package/dist/runtime/components/input/input-tag.d.vue.ts +1 -1
  33. package/dist/runtime/components/input/input-tag.vue.d.ts +1 -1
  34. package/dist/runtime/components/input/input-text-field.d.vue.ts +1 -1
  35. package/dist/runtime/components/input/input-text-field.vue.d.ts +1 -1
  36. package/dist/runtime/components/input/input-textarea.d.vue.ts +2 -2
  37. package/dist/runtime/components/input/input-textarea.vue.d.ts +2 -2
  38. package/dist/runtime/components/input/input-typed-field.d.vue.ts +1 -1
  39. package/dist/runtime/components/input/input-typed-field.vue.d.ts +1 -1
  40. package/dist/runtime/components/modal/modal-password-confirmed.d.vue.ts +1 -1
  41. package/dist/runtime/components/modal/modal-password-confirmed.vue.d.ts +1 -1
  42. package/dist/runtime/components/modal/modal-password-verify.d.vue.ts +1 -1
  43. package/dist/runtime/components/modal/modal-password-verify.vue.d.ts +1 -1
  44. package/dist/runtime/components/ui/chart/ChartTooltipContent.d.vue.ts +1 -1
  45. package/dist/runtime/components/ui/chart/ChartTooltipContent.vue.d.ts +1 -1
  46. package/dist/runtime/components/ui/native-select/NativeSelectOptGroup.d.vue.ts +2 -2
  47. package/dist/runtime/components/ui/native-select/NativeSelectOptGroup.vue.d.ts +2 -2
  48. package/dist/runtime/components/ui/native-select/NativeSelectOption.d.vue.ts +2 -2
  49. package/dist/runtime/components/ui/native-select/NativeSelectOption.vue.d.ts +2 -2
  50. package/dist/runtime/composables/useApi.d.ts +3 -1
  51. package/dist/runtime/composables/useApi.js +2 -2
  52. package/package.json +1 -1
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pukaad-ui-lib",
3
3
  "configKey": "pukaadUI",
4
- "version": "1.422.0",
4
+ "version": "1.424.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -14,7 +14,7 @@
14
14
  />
15
15
 
16
16
  <div
17
- class="absolute inset-x-0 bottom-0 flex h-[84px] flex-col justify-between bg-gradient-to-t from-black/70 to-transparent p-[8px]"
17
+ class="absolute inset-x-0 bottom-0 flex h-[84px] flex-col justify-end gap-1 bg-gradient-to-t from-black/70 to-transparent p-[8px]"
18
18
  >
19
19
  <p class="line-clamp-2 break-words font-title-small-prominent text-white">
20
20
  {{ props.item.title }}
@@ -5,6 +5,7 @@
5
5
  <div class="flex flex-col gap-[2px] w-full">
6
6
  <div v-if="hasCoverFile" class="font-body-small-prominent text-gray">
7
7
  หน้าปก
8
+ <span class="text-destructive">*</span>
8
9
  </div>
9
10
  <!-- v-if ไม่ใช่ v-show — root ของ InputTextarea เป็น ShadFormField (renderless)
10
11
  style จาก v-show เลยตกไปไม่ถึง DOM จริง ซ่อนไม่ได้ -->
@@ -14,6 +15,7 @@
14
15
  name="cover-text"
15
16
  label="หน้าปก"
16
17
  class="w-full"
18
+ required
17
19
  placeholder="พิมพ์ข้อความหน้าปกหรืออัปโหลดไฟล์มีเดีย"
18
20
  disabledBorder
19
21
  resize="none"
@@ -101,6 +103,7 @@
101
103
  placeholder="อยากบอกอะไรเกี่ยวกับโพสต์นี้"
102
104
  disabledBorder
103
105
  resize="none"
106
+ required
104
107
  />
105
108
  <Divider height="1" />
106
109
  <InputTag
@@ -111,7 +114,11 @@
111
114
  />
112
115
 
113
116
  <InputMention v-model:mentions="selectedMentions" />
114
- <InputSelectPlace v-model:places="selectedPlaces" />
117
+ <InputSelectPlace
118
+ v-model:places="selectedPlaces"
119
+ :profile-scope="props.state"
120
+ required
121
+ />
115
122
  </div>
116
123
  <div class="flex flex-col gap-[8px] items-center">
117
124
  <!-- cursor-default ทับ cursor-pointer ของการ์ด — พรีวิวคลิกไม่มีผล อย่าหลอกว่าเป็นปุ่ม
@@ -50,10 +50,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
50
50
  name: string;
51
51
  required: boolean;
52
52
  placeholder: string;
53
- gap: string;
54
53
  labelDetail: string;
55
54
  placeholderDetail: string;
56
55
  requiredDetail: boolean;
56
+ gap: string;
57
57
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
58
58
  declare const _default: typeof __VLS_export;
59
59
  export default _default;
@@ -50,10 +50,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
50
50
  name: string;
51
51
  required: boolean;
52
52
  placeholder: string;
53
- gap: string;
54
53
  labelDetail: string;
55
54
  placeholderDetail: string;
56
55
  requiredDetail: boolean;
56
+ gap: string;
57
57
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
58
58
  declare const _default: typeof __VLS_export;
59
59
  export default _default;
@@ -70,12 +70,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
70
70
  required: boolean;
71
71
  description: string;
72
72
  options: AutocompleteOption[] | string[] | number[];
73
- labelKey: string;
74
73
  placeholder: string;
75
- limit: number;
74
+ labelKey: string;
76
75
  disabledErrorMessage: boolean;
77
76
  disabledBorder: boolean;
78
77
  showCounter: boolean;
78
+ limit: number;
79
79
  returnObject: boolean;
80
80
  freeText: boolean;
81
81
  valueKey: string;
@@ -70,12 +70,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
70
70
  required: boolean;
71
71
  description: string;
72
72
  options: AutocompleteOption[] | string[] | number[];
73
- labelKey: string;
74
73
  placeholder: string;
75
- limit: number;
74
+ labelKey: string;
76
75
  disabledErrorMessage: boolean;
77
76
  disabledBorder: boolean;
78
77
  showCounter: boolean;
78
+ limit: number;
79
79
  returnObject: boolean;
80
80
  freeText: boolean;
81
81
  valueKey: string;
@@ -30,8 +30,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
30
30
  id: string;
31
31
  name: string;
32
32
  required: boolean;
33
- locale: string;
34
33
  placeholder: string;
34
+ locale: string;
35
35
  disabledErrorMessage: boolean;
36
36
  layout: "month-and-year" | "month-only" | "year-only";
37
37
  dateFormat: string;
@@ -30,8 +30,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
30
30
  id: string;
31
31
  name: string;
32
32
  required: boolean;
33
- locale: string;
34
33
  placeholder: string;
34
+ locale: string;
35
35
  disabledErrorMessage: boolean;
36
36
  layout: "month-and-year" | "month-only" | "year-only";
37
37
  dateFormat: string;
@@ -44,8 +44,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
44
44
  id: string;
45
45
  name: string;
46
46
  required: boolean;
47
- locale: string;
48
47
  placeholder: string;
48
+ locale: string;
49
49
  disabledErrorMessage: boolean;
50
50
  layout: "month-and-year" | "month-only" | "year-only";
51
51
  dateFormat: string;
@@ -44,8 +44,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
44
44
  id: string;
45
45
  name: string;
46
46
  required: boolean;
47
- locale: string;
48
47
  placeholder: string;
48
+ locale: string;
49
49
  disabledErrorMessage: boolean;
50
50
  layout: "month-and-year" | "month-only" | "year-only";
51
51
  dateFormat: string;
@@ -34,9 +34,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
34
34
  name: string;
35
35
  fullHeight: boolean;
36
36
  fullWidth: boolean;
37
+ disabledErrorMessage: boolean;
37
38
  limit: number;
38
39
  accept: string;
39
- disabledErrorMessage: boolean;
40
40
  labelIcon: string;
41
41
  disabledDrop: boolean;
42
42
  column: boolean;
@@ -34,9 +34,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
34
34
  name: string;
35
35
  fullHeight: boolean;
36
36
  fullWidth: boolean;
37
+ disabledErrorMessage: boolean;
37
38
  limit: number;
38
39
  accept: string;
39
- disabledErrorMessage: boolean;
40
40
  labelIcon: string;
41
41
  disabledDrop: boolean;
42
42
  column: boolean;
@@ -17,8 +17,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
17
17
  label: string;
18
18
  name: string;
19
19
  modelValue: InputLinkItem[] | ContactChannel[];
20
- limit: number;
21
20
  showCounter: boolean;
21
+ limit: number;
22
22
  format: "legacy" | "contact_channel";
23
23
  hideType: boolean;
24
24
  hideAddButton: boolean;
@@ -17,8 +17,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
17
17
  label: string;
18
18
  name: string;
19
19
  modelValue: InputLinkItem[] | ContactChannel[];
20
- limit: number;
21
20
  showCounter: boolean;
21
+ limit: number;
22
22
  format: "legacy" | "contact_channel";
23
23
  hideType: boolean;
24
24
  hideAddButton: boolean;
@@ -13,8 +13,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
13
13
  modelValue: LocalizedNameItem[];
14
14
  options: InputSelectItem[];
15
15
  placeholder: string;
16
- limit: number;
17
16
  showCounter: boolean;
17
+ limit: number;
18
18
  addLabel: string;
19
19
  removable: boolean;
20
20
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -13,8 +13,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
13
13
  modelValue: LocalizedNameItem[];
14
14
  options: InputSelectItem[];
15
15
  placeholder: string;
16
- limit: number;
17
16
  showCounter: boolean;
17
+ limit: number;
18
18
  addLabel: string;
19
19
  removable: boolean;
20
20
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -243,7 +243,7 @@ const props = defineProps({
243
243
  label: { type: String, required: false, default: "\u0E01\u0E32\u0E23\u0E40\u0E2D\u0E48\u0E22\u0E16\u0E36\u0E07" },
244
244
  placeholder: { type: String, required: false, default: "\u0E40\u0E1E\u0E34\u0E48\u0E21\u0E01\u0E32\u0E23\u0E40\u0E2D\u0E48\u0E22\u0E16\u0E36\u0E07" }
245
245
  });
246
- const api = useApi();
246
+ const api = useApi({ includeProvince: false });
247
247
  const comboboxRef = ref();
248
248
  const selectedUsernames = ref([]);
249
249
  const isSelected = (id) => selectedUsernames.value.includes(id);
@@ -22,8 +22,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
22
22
  }>, {
23
23
  id: string;
24
24
  name: string;
25
- disabledForgotPassword: boolean;
26
25
  new: boolean;
26
+ disabledForgotPassword: boolean;
27
27
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
28
28
  declare const _default: typeof __VLS_export;
29
29
  export default _default;
@@ -22,8 +22,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
22
22
  }>, {
23
23
  id: string;
24
24
  name: string;
25
- disabledForgotPassword: boolean;
26
25
  new: boolean;
26
+ disabledForgotPassword: boolean;
27
27
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
28
28
  declare const _default: typeof __VLS_export;
29
29
  export default _default;
@@ -11,12 +11,12 @@ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
11
11
  declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
12
12
  "update:modelValue": (value: File | null) => any;
13
13
  } & {
14
- complete: (file: File) => any;
15
14
  remove: () => any;
15
+ complete: (file: File) => any;
16
16
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
17
17
  "onUpdate:modelValue"?: ((value: File | null) => any) | undefined;
18
- onComplete?: ((file: File) => any) | undefined;
19
18
  onRemove?: (() => any) | undefined;
19
+ onComplete?: ((file: File) => any) | undefined;
20
20
  }>, {
21
21
  name: string;
22
22
  disabledErrorMessage: boolean;
@@ -11,12 +11,12 @@ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
11
11
  declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
12
12
  "update:modelValue": (value: File | null) => any;
13
13
  } & {
14
- complete: (file: File) => any;
15
14
  remove: () => any;
15
+ complete: (file: File) => any;
16
16
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
17
17
  "onUpdate:modelValue"?: ((value: File | null) => any) | undefined;
18
- onComplete?: ((file: File) => any) | undefined;
19
18
  onRemove?: (() => any) | undefined;
19
+ onComplete?: ((file: File) => any) | undefined;
20
20
  }>, {
21
21
  name: string;
22
22
  disabledErrorMessage: boolean;
@@ -36,8 +36,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
36
36
  id: string;
37
37
  name: string;
38
38
  required: boolean;
39
- placeholder: string;
40
39
  readonly: boolean;
40
+ placeholder: string;
41
41
  disabledErrorMessage: boolean;
42
42
  iconPosition: import("#pukaad-ui/types/components/input/input-search").InputSearchIconPosition;
43
43
  disabledIcon: boolean;
@@ -36,8 +36,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
36
36
  id: string;
37
37
  name: string;
38
38
  required: boolean;
39
- placeholder: string;
40
39
  readonly: boolean;
40
+ placeholder: string;
41
41
  disabledErrorMessage: boolean;
42
42
  iconPosition: import("#pukaad-ui/types/components/input/input-search").InputSearchIconPosition;
43
43
  disabledIcon: boolean;
@@ -8,6 +8,8 @@ export interface SelectPlaceItem {
8
8
  interface InputSelectPlaceProps {
9
9
  label?: string;
10
10
  placeholder?: string;
11
+ required?: boolean;
12
+ profileScope?: "personal" | "business";
11
13
  }
12
14
  type __VLS_Props = InputSelectPlaceProps;
13
15
  type __VLS_ModelProps = {
@@ -20,7 +22,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
20
22
  "onUpdate:places"?: ((value: SelectPlaceItem[]) => any) | undefined;
21
23
  }>, {
22
24
  label: string;
25
+ required: boolean;
23
26
  placeholder: string;
27
+ profileScope: "personal" | "business";
24
28
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
25
29
  declare const _default: typeof __VLS_export;
26
30
  export default _default;
@@ -1,6 +1,9 @@
1
1
  <template>
2
2
  <div class="flex flex-col gap-[4px] w-full">
3
- <div class="font-body-large-prominent text-gray">{{ props.label }}</div>
3
+ <div class="font-body-large-prominent text-gray">
4
+ {{ props.label }}
5
+ <span v-if="props.required" class="text-destructive">*</span>
6
+ </div>
4
7
  <div v-show="selectedItems.length === 0">
5
8
  <InputCombobox
6
9
  ref="comboboxRef"
@@ -11,6 +14,12 @@
11
14
  command-list-class="max-h-[520px]"
12
15
  >
13
16
  <template #options="{ search }">
17
+ <ShadTabs v-model="currentTab" class="w-full p-2">
18
+ <ShadTabsList class="grid w-full grid-cols-2">
19
+ <ShadTabsTrigger value="popular">ยอดนิยม</ShadTabsTrigger>
20
+ <ShadTabsTrigger value="recent">ใช้งานล่าสุด</ShadTabsTrigger>
21
+ </ShadTabsList>
22
+ </ShadTabs>
14
23
  <template v-if="filterPlaces(search).length > 0">
15
24
  <div
16
25
  v-for="place in filterPlaces(search)"
@@ -56,7 +65,7 @@
56
65
  ที่กำหนดเองไม่ได้ผ่าน filter ของ cmdk เลยต้องกรอง+โชว์ empty state เองตรงนี้
57
66
  !isSearching กันโชว์ตอนกำลังยิง API อยู่ (ผลลัพธ์ยังว่างเพราะยังโหลดไม่เสร็จ ไม่ใช่ค้นไม่เจอจริง) -->
58
67
  <div
59
- v-else-if="!isSearching"
68
+ v-else-if="!isSearching && currentTab === 'popular'"
60
69
  class="flex gap-[8px] items-center hover:cursor-pointer"
61
70
  @click="drawerSuggestPlaceOpen = true"
62
71
  >
@@ -67,6 +76,22 @@
67
76
  </div>
68
77
  <div class="font-body-medium">เพิ่มสถานที่ที่ขาดไป</div>
69
78
  </div>
79
+ <div
80
+ v-else-if="!isSearching"
81
+ class="flex flex-col items-center justify-center gap-2 p-6 text-gray"
82
+ >
83
+ <Icon name="pukaad:tag-empty" class="h-[123px] w-[180px]" />
84
+ <div class="font-body-medium">
85
+ {{ search ? "\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E2A\u0E16\u0E32\u0E19\u0E17\u0E35\u0E48" : "\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E21\u0E35\u0E2A\u0E16\u0E32\u0E19\u0E17\u0E35\u0E48\u0E17\u0E35\u0E48\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19\u0E25\u0E48\u0E32\u0E2A\u0E38\u0E14" }}
86
+ </div>
87
+ </div>
88
+ <div v-if="isSearching" class="flex justify-center p-2">
89
+ <Icon
90
+ name="lucide:loader-2"
91
+ class="h-5 w-5 animate-spin text-primary"
92
+ />
93
+ </div>
94
+ <div ref="sentinelRef" class="h-1" />
70
95
  </template>
71
96
  </InputCombobox>
72
97
  </div>
@@ -127,18 +152,36 @@
127
152
 
128
153
  <script setup>
129
154
  import { computed, ref, watch } from "vue";
130
- import { useDebounceFn } from "@vueuse/core";
155
+ import { useDebounceFn, useIntersectionObserver } from "@vueuse/core";
156
+ import { useCookie } from "nuxt/app";
131
157
  import { useApi } from "../../composables/useApi";
132
158
  const props = defineProps({
133
159
  label: { type: String, required: false, default: "\u0E2A\u0E16\u0E32\u0E19\u0E17\u0E35\u0E48" },
134
- placeholder: { type: String, required: false, default: "\u0E40\u0E1E\u0E34\u0E48\u0E21\u0E2A\u0E16\u0E32\u0E19\u0E17\u0E35\u0E48" }
160
+ placeholder: { type: String, required: false, default: "\u0E40\u0E1E\u0E34\u0E48\u0E21\u0E2A\u0E16\u0E32\u0E19\u0E17\u0E35\u0E48" },
161
+ required: { type: Boolean, required: false, default: false },
162
+ profileScope: { type: String, required: false, default: "personal" }
135
163
  });
136
164
  const api = useApi();
165
+ const businessProfileId = useCookie(
166
+ "PUKAAD_BUSINESS_PROFILE_ID"
167
+ );
137
168
  const drawerSuggestPlaceOpen = ref(false);
138
169
  const comboboxRef = ref();
139
170
  const selectedIds = ref([]);
140
- const searchResults = ref([]);
141
- const isSearching = ref(false);
171
+ const currentTab = ref("popular");
172
+ const createListState = () => ({
173
+ items: [],
174
+ page: 1,
175
+ hasMore: true,
176
+ loading: false
177
+ });
178
+ const popularState = ref(createListState());
179
+ const recentState = ref(createListState());
180
+ const activeState = computed(
181
+ () => currentTab.value === "popular" ? popularState.value : recentState.value
182
+ );
183
+ const searchResults = computed(() => activeState.value.items);
184
+ const isSearching = computed(() => activeState.value.loading);
142
185
  const selectedCache = ref(/* @__PURE__ */ new Map());
143
186
  const mapPlace = (raw) => ({
144
187
  id: raw.id,
@@ -147,25 +190,42 @@ const mapPlace = (raw) => ({
147
190
  image: raw.cover_image,
148
191
  post_count: raw.post_count ?? 0
149
192
  });
150
- const performSearch = async (q) => {
151
- isSearching.value = true;
193
+ let requestGeneration = 0;
194
+ const fetchPlaces = async (type, q, reset = false) => {
195
+ const state = type === "popular" ? popularState.value : recentState.value;
196
+ if (reset) Object.assign(state, createListState());
197
+ if (state.loading || !state.hasMore) return;
198
+ state.loading = true;
199
+ const generation = requestGeneration;
152
200
  try {
153
- const res = await api(
154
- "/places/search",
155
- { query: { q, page: 1, page_size: 10 } }
156
- );
157
- searchResults.value = (res.data?.items ?? []).map(mapPlace);
201
+ const res = await api(type === "popular" ? "/places/search" : "/places/recent", {
202
+ query: {
203
+ q,
204
+ page: state.page,
205
+ page_size: 10,
206
+ scope: props.profileScope
207
+ }
208
+ });
209
+ if (generation !== requestGeneration) return;
210
+ const items = (res.data?.items ?? []).map(mapPlace);
211
+ state.items = [...state.items, ...items];
212
+ const pagination = res.data?.pagination;
213
+ state.page++;
214
+ state.hasMore = state.page <= (pagination?.total_page ?? 1);
158
215
  } catch {
159
- searchResults.value = [];
160
216
  } finally {
161
- isSearching.value = false;
217
+ if (generation === requestGeneration) state.loading = false;
162
218
  }
163
219
  };
164
- const debouncedSearch = useDebounceFn(performSearch, 300);
220
+ const debouncedSearch = useDebounceFn(
221
+ (q) => fetchPlaces(currentTab.value, q, true),
222
+ 300
223
+ );
165
224
  const searchTerm = ref("");
166
225
  watch(
167
- searchTerm,
168
- (val) => {
226
+ [searchTerm, currentTab],
227
+ ([val]) => {
228
+ requestGeneration++;
169
229
  debouncedSearch(val);
170
230
  },
171
231
  { immediate: true }
@@ -174,8 +234,17 @@ const filterPlaces = (search) => {
174
234
  if (searchTerm.value !== search) {
175
235
  searchTerm.value = search;
176
236
  }
177
- return searchResults.value;
237
+ return activeState.value.items;
178
238
  };
239
+ const sentinelRef = ref(null);
240
+ useIntersectionObserver(sentinelRef, ([entry]) => {
241
+ if (entry?.isIntersecting) fetchPlaces(currentTab.value, searchTerm.value);
242
+ });
243
+ watch([businessProfileId, () => props.profileScope], () => {
244
+ requestGeneration++;
245
+ recentState.value = createListState();
246
+ if (currentTab.value === "recent") fetchPlaces("recent", searchTerm.value);
247
+ });
179
248
  const isSelected = (id) => selectedIds.value.includes(id);
180
249
  const toggleSelect = (id) => {
181
250
  if (isSelected(id)) {
@@ -8,6 +8,8 @@ export interface SelectPlaceItem {
8
8
  interface InputSelectPlaceProps {
9
9
  label?: string;
10
10
  placeholder?: string;
11
+ required?: boolean;
12
+ profileScope?: "personal" | "business";
11
13
  }
12
14
  type __VLS_Props = InputSelectPlaceProps;
13
15
  type __VLS_ModelProps = {
@@ -20,7 +22,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
20
22
  "onUpdate:places"?: ((value: SelectPlaceItem[]) => any) | undefined;
21
23
  }>, {
22
24
  label: string;
25
+ required: boolean;
23
26
  placeholder: string;
27
+ profileScope: "personal" | "business";
24
28
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
25
29
  declare const _default: typeof __VLS_export;
26
30
  export default _default;
@@ -20,12 +20,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
20
20
  name: string;
21
21
  required: boolean;
22
22
  description: string;
23
- labelKey: string;
24
23
  placeholder: string;
25
- limit: number;
24
+ labelKey: string;
26
25
  disabledErrorMessage: boolean;
27
26
  disabledBorder: boolean;
28
27
  showCounter: boolean;
28
+ limit: number;
29
29
  descriptionKey: string;
30
30
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
31
  declare const _default: typeof __VLS_export;
@@ -20,12 +20,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
20
20
  name: string;
21
21
  required: boolean;
22
22
  description: string;
23
- labelKey: string;
24
23
  placeholder: string;
25
- limit: number;
24
+ labelKey: string;
26
25
  disabledErrorMessage: boolean;
27
26
  disabledBorder: boolean;
28
27
  showCounter: boolean;
28
+ limit: number;
29
29
  descriptionKey: string;
30
30
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
31
  declare const _default: typeof __VLS_export;
@@ -41,8 +41,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
41
41
  name: string;
42
42
  required: boolean;
43
43
  options: InputTagModalOption[];
44
- labelKey: string;
45
44
  placeholder: string;
45
+ labelKey: string;
46
46
  disabledErrorMessage: boolean;
47
47
  valueKey: string;
48
48
  searchPlaceholder: string;
@@ -41,8 +41,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
41
41
  name: string;
42
42
  required: boolean;
43
43
  options: InputTagModalOption[];
44
- labelKey: string;
45
44
  placeholder: string;
45
+ labelKey: string;
46
46
  disabledErrorMessage: boolean;
47
47
  valueKey: string;
48
48
  searchPlaceholder: string;
@@ -28,9 +28,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
28
28
  name: string;
29
29
  state: "user" | "admin";
30
30
  placeholder: string;
31
+ profileScope: "personal" | "business";
31
32
  limit: number;
32
33
  ignore: string[];
33
- profileScope: "personal" | "business";
34
34
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
35
35
  declare const _default: typeof __VLS_export;
36
36
  export default _default;
@@ -28,9 +28,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
28
28
  name: string;
29
29
  state: "user" | "admin";
30
30
  placeholder: string;
31
+ profileScope: "personal" | "business";
31
32
  limit: number;
32
33
  ignore: string[];
33
- profileScope: "personal" | "business";
34
34
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
35
35
  declare const _default: typeof __VLS_export;
36
36
  export default _default;
@@ -60,10 +60,10 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
60
60
  name: string;
61
61
  required: boolean;
62
62
  readonly: boolean;
63
- limit: number;
64
63
  disabledErrorMessage: boolean;
65
64
  disabledBorder: boolean;
66
65
  showCounter: boolean;
66
+ limit: number;
67
67
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
68
68
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
69
69
  declare const _default: typeof __VLS_export;
@@ -60,10 +60,10 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
60
60
  name: string;
61
61
  required: boolean;
62
62
  readonly: boolean;
63
- limit: number;
64
63
  disabledErrorMessage: boolean;
65
64
  disabledBorder: boolean;
66
65
  showCounter: boolean;
66
+ limit: number;
67
67
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
68
68
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
69
69
  declare const _default: typeof __VLS_export;
@@ -46,12 +46,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
46
46
  resize: "none" | "both" | "horizontal" | "vertical";
47
47
  fullHeight: boolean;
48
48
  fullWidth: boolean;
49
- rows: number;
50
49
  readonly: boolean;
51
- limit: number;
50
+ rows: number;
52
51
  disabledErrorMessage: boolean;
53
52
  disabledBorder: boolean;
54
53
  showCounter: boolean;
54
+ limit: number;
55
55
  heightScroll: boolean;
56
56
  spaceToComma: boolean;
57
57
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -46,12 +46,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
46
46
  resize: "none" | "both" | "horizontal" | "vertical";
47
47
  fullHeight: boolean;
48
48
  fullWidth: boolean;
49
- rows: number;
50
49
  readonly: boolean;
51
- limit: number;
50
+ rows: number;
52
51
  disabledErrorMessage: boolean;
53
52
  disabledBorder: boolean;
54
53
  showCounter: boolean;
54
+ limit: number;
55
55
  heightScroll: boolean;
56
56
  spaceToComma: boolean;
57
57
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -22,8 +22,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
22
22
  name: string;
23
23
  required: boolean;
24
24
  options: import("../../../types/components/input/input-select.js").InputSelectItem[];
25
- limit: number;
26
25
  showCounter: boolean;
26
+ limit: number;
27
27
  removable: boolean;
28
28
  selectClass: import("vue").HTMLAttributes["class"];
29
29
  resetOnTypeChange: boolean;
@@ -22,8 +22,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
22
22
  name: string;
23
23
  required: boolean;
24
24
  options: import("../../../types/components/input/input-select.js").InputSelectItem[];
25
- limit: number;
26
25
  showCounter: boolean;
26
+ limit: number;
27
27
  removable: boolean;
28
28
  selectClass: import("vue").HTMLAttributes["class"];
29
29
  resetOnTypeChange: boolean;
@@ -24,8 +24,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
24
24
  }) => any) | undefined;
25
25
  }>, {
26
26
  title: string;
27
- confirmText: string;
28
27
  disabledForgotPassword: boolean;
28
+ confirmText: string;
29
29
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
30
30
  declare const _default: typeof __VLS_export;
31
31
  export default _default;
@@ -24,8 +24,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
24
24
  }) => any) | undefined;
25
25
  }>, {
26
26
  title: string;
27
- confirmText: string;
28
27
  disabledForgotPassword: boolean;
28
+ confirmText: string;
29
29
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
30
30
  declare const _default: typeof __VLS_export;
31
31
  export default _default;
@@ -32,8 +32,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
32
32
  }>, {
33
33
  title: string;
34
34
  mode: "login" | "secure";
35
- confirmText: string;
36
35
  disabledForgotPassword: boolean;
36
+ confirmText: string;
37
37
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
38
38
  declare const _default: typeof __VLS_export;
39
39
  export default _default;
@@ -32,8 +32,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
32
32
  }>, {
33
33
  title: string;
34
34
  mode: "login" | "secure";
35
- confirmText: string;
36
35
  disabledForgotPassword: boolean;
36
+ confirmText: string;
37
37
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
38
38
  declare const _default: typeof __VLS_export;
39
39
  export default _default;
@@ -18,8 +18,8 @@ type __VLS_Slots = {} & {
18
18
  default?: (props: typeof __VLS_1) => any;
19
19
  };
20
20
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
21
- config: ChartConfig;
22
21
  payload: Record<string, any>;
22
+ config: ChartConfig;
23
23
  indicator: "line" | "dot" | "dashed";
24
24
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
25
25
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -18,8 +18,8 @@ type __VLS_Slots = {} & {
18
18
  default?: (props: typeof __VLS_1) => any;
19
19
  };
20
20
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
21
- config: ChartConfig;
22
21
  payload: Record<string, any>;
22
+ config: ChartConfig;
23
23
  indicator: "line" | "dot" | "dashed";
24
24
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
25
25
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -14,7 +14,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
14
14
  dir?: string | undefined | undefined;
15
15
  draggable?: (boolean | "true" | "false") | undefined;
16
16
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
17
- enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
17
+ enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
18
18
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
19
19
  id?: string | undefined | undefined;
20
20
  inert?: (boolean | "true" | "false") | undefined;
@@ -208,7 +208,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
208
208
  dir?: string | undefined | undefined;
209
209
  draggable?: (boolean | "true" | "false") | undefined;
210
210
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
211
- enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
211
+ enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
212
212
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
213
213
  id?: string | undefined | undefined;
214
214
  inert?: (boolean | "true" | "false") | undefined;
@@ -14,7 +14,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
14
14
  dir?: string | undefined | undefined;
15
15
  draggable?: (boolean | "true" | "false") | undefined;
16
16
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
17
- enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
17
+ enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
18
18
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
19
19
  id?: string | undefined | undefined;
20
20
  inert?: (boolean | "true" | "false") | undefined;
@@ -208,7 +208,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
208
208
  dir?: string | undefined | undefined;
209
209
  draggable?: (boolean | "true" | "false") | undefined;
210
210
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
211
- enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
211
+ enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
212
212
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
213
213
  id?: string | undefined | undefined;
214
214
  inert?: (boolean | "true" | "false") | undefined;
@@ -16,7 +16,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
16
16
  dir?: string | undefined | undefined;
17
17
  draggable?: (boolean | "true" | "false") | undefined;
18
18
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
19
- enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
19
+ enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
20
20
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
21
21
  id?: string | undefined | undefined;
22
22
  inert?: (boolean | "true" | "false") | undefined;
@@ -212,7 +212,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
212
212
  dir?: string | undefined | undefined;
213
213
  draggable?: (boolean | "true" | "false") | undefined;
214
214
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
215
- enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
215
+ enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
216
216
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
217
217
  id?: string | undefined | undefined;
218
218
  inert?: (boolean | "true" | "false") | undefined;
@@ -16,7 +16,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
16
16
  dir?: string | undefined | undefined;
17
17
  draggable?: (boolean | "true" | "false") | undefined;
18
18
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
19
- enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
19
+ enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
20
20
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
21
21
  id?: string | undefined | undefined;
22
22
  inert?: (boolean | "true" | "false") | undefined;
@@ -212,7 +212,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
212
212
  dir?: string | undefined | undefined;
213
213
  draggable?: (boolean | "true" | "false") | undefined;
214
214
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
215
- enterKeyHint?: "search" | "done" | "next" | "send" | "enter" | "go" | "previous" | undefined;
215
+ enterKeyHint?: "search" | "done" | "send" | "next" | "enter" | "go" | "previous" | undefined;
216
216
  hidden?: "" | (boolean | "true" | "false") | "hidden" | "until-found" | undefined;
217
217
  id?: string | undefined | undefined;
218
218
  inert?: (boolean | "true" | "false") | undefined;
@@ -1 +1,3 @@
1
- export declare const useApi: () => import("nitropack").$Fetch<unknown, import("nitropack").NitroFetchRequest>;
1
+ export declare const useApi: (apiOptions?: {
2
+ includeProvince?: boolean;
3
+ }) => import("nitropack").$Fetch<unknown, import("nitropack").NitroFetchRequest>;
@@ -1,5 +1,5 @@
1
1
  import { useRuntimeConfig, useCookie, useState } from "nuxt/app";
2
- export const useApi = () => {
2
+ export const useApi = (apiOptions = {}) => {
3
3
  const config = useRuntimeConfig();
4
4
  const baseURL = config.public.BASE_URL_API;
5
5
  const provinceIdState = useState("pukaad:province-id", () => null);
@@ -20,7 +20,7 @@ export const useApi = () => {
20
20
  headers.set("Authorization", `Bearer ${secId.value}`);
21
21
  }
22
22
  const pid = provinceIdState.value ?? configProvinceId;
23
- if (pid) {
23
+ if (apiOptions.includeProvince !== false && pid) {
24
24
  headers.set("X-Province-ID", String(pid));
25
25
  }
26
26
  if (businessProfileId.value) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pukaad-ui-lib",
3
- "version": "1.422.0",
3
+ "version": "1.424.0",
4
4
  "description": "pukaad-ui for MeMSG",
5
5
  "repository": {
6
6
  "type": "git",