pukaad-ui-lib 1.369.9 → 1.371.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 (66) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/assets/svg/flags/uk.svg +14 -0
  3. package/dist/runtime/components/card/card-opening-hours.d.vue.ts +16 -0
  4. package/dist/runtime/components/card/card-opening-hours.vue +90 -0
  5. package/dist/runtime/components/card/card-opening-hours.vue.d.ts +16 -0
  6. package/dist/runtime/components/card/card-place-detail.d.vue.ts +2 -32
  7. package/dist/runtime/components/card/card-place-detail.vue +32 -69
  8. package/dist/runtime/components/card/card-place-detail.vue.d.ts +2 -32
  9. package/dist/runtime/components/drawer/drawer-suggest-place/suggest-place-map.d.vue.ts +2 -0
  10. package/dist/runtime/components/drawer/drawer-suggest-place/suggest-place-map.vue +11 -5
  11. package/dist/runtime/components/drawer/drawer-suggest-place/suggest-place-map.vue.d.ts +2 -0
  12. package/dist/runtime/components/input/input-autocomplete.d.vue.ts +1 -1
  13. package/dist/runtime/components/input/input-autocomplete.vue.d.ts +1 -1
  14. package/dist/runtime/components/input/input-file.d.vue.ts +1 -1
  15. package/dist/runtime/components/input/input-file.vue.d.ts +1 -1
  16. package/dist/runtime/components/input/input-link.d.vue.ts +5 -0
  17. package/dist/runtime/components/input/input-link.vue +14 -8
  18. package/dist/runtime/components/input/input-link.vue.d.ts +5 -0
  19. package/dist/runtime/components/input/input-typed-field.vue +3 -1
  20. package/dist/runtime/components/modal/suggest-edit-place/modal-suggest-edit-place.d.vue.ts +118 -0
  21. package/dist/runtime/components/modal/suggest-edit-place/modal-suggest-edit-place.vue +568 -0
  22. package/dist/runtime/components/modal/suggest-edit-place/modal-suggest-edit-place.vue.d.ts +118 -0
  23. package/dist/runtime/components/modal/suggest-edit-place/place-Addlink.d.vue.ts +11 -0
  24. package/dist/runtime/components/modal/suggest-edit-place/place-Addlink.vue +20 -0
  25. package/dist/runtime/components/modal/suggest-edit-place/place-Addlink.vue.d.ts +11 -0
  26. package/dist/runtime/components/modal/suggest-edit-place/place-Addphone.d.vue.ts +10 -0
  27. package/dist/runtime/components/modal/suggest-edit-place/place-Addphone.vue +18 -0
  28. package/dist/runtime/components/modal/suggest-edit-place/place-Addphone.vue.d.ts +10 -0
  29. package/dist/runtime/components/modal/suggest-edit-place/place-address.d.vue.ts +31 -0
  30. package/dist/runtime/components/modal/suggest-edit-place/place-address.vue +66 -0
  31. package/dist/runtime/components/modal/suggest-edit-place/place-address.vue.d.ts +31 -0
  32. package/dist/runtime/components/modal/suggest-edit-place/place-category.d.vue.ts +21 -0
  33. package/dist/runtime/components/modal/suggest-edit-place/place-category.vue +47 -0
  34. package/dist/runtime/components/modal/suggest-edit-place/place-category.vue.d.ts +21 -0
  35. package/dist/runtime/components/modal/suggest-edit-place/place-dateopening.d.vue.ts +25 -0
  36. package/dist/runtime/components/modal/suggest-edit-place/place-dateopening.vue +58 -0
  37. package/dist/runtime/components/modal/suggest-edit-place/place-dateopening.vue.d.ts +25 -0
  38. package/dist/runtime/components/modal/suggest-edit-place/place-description.d.vue.ts +17 -0
  39. package/dist/runtime/components/modal/suggest-edit-place/place-description.vue +48 -0
  40. package/dist/runtime/components/modal/suggest-edit-place/place-description.vue.d.ts +17 -0
  41. package/dist/runtime/components/modal/suggest-edit-place/place-link.d.vue.ts +18 -0
  42. package/dist/runtime/components/modal/suggest-edit-place/place-link.vue +64 -0
  43. package/dist/runtime/components/modal/suggest-edit-place/place-link.vue.d.ts +18 -0
  44. package/dist/runtime/components/modal/suggest-edit-place/place-name.d.vue.ts +37 -0
  45. package/dist/runtime/components/modal/suggest-edit-place/place-name.vue +110 -0
  46. package/dist/runtime/components/modal/suggest-edit-place/place-name.vue.d.ts +37 -0
  47. package/dist/runtime/components/modal/suggest-edit-place/place-phone.d.vue.ts +17 -0
  48. package/dist/runtime/components/modal/suggest-edit-place/place-phone.vue +40 -0
  49. package/dist/runtime/components/modal/suggest-edit-place/place-phone.vue.d.ts +17 -0
  50. package/dist/runtime/components/timeline.d.vue.ts +14 -0
  51. package/dist/runtime/components/timeline.vue +29 -10
  52. package/dist/runtime/components/timeline.vue.d.ts +14 -0
  53. package/dist/runtime/components/ui/chart/ChartTooltipContent.d.vue.ts +1 -1
  54. package/dist/runtime/components/ui/chart/ChartTooltipContent.vue.d.ts +1 -1
  55. package/dist/runtime/components/ui/native-select/NativeSelectOptGroup.d.vue.ts +2 -2
  56. package/dist/runtime/components/ui/native-select/NativeSelectOptGroup.vue.d.ts +2 -2
  57. package/dist/runtime/components/ui/native-select/NativeSelectOption.d.vue.ts +2 -2
  58. package/dist/runtime/components/ui/native-select/NativeSelectOption.vue.d.ts +2 -2
  59. package/dist/runtime/utils/opening-hours.d.ts +21 -0
  60. package/dist/runtime/utils/opening-hours.js +20 -0
  61. package/package.json +1 -1
  62. /package/dist/runtime/assets/svg/socials/{facebook.svg → Facebook.svg} +0 -0
  63. /package/dist/runtime/assets/svg/socials/{instagram.svg → Instagram.svg} +0 -0
  64. /package/dist/runtime/assets/svg/socials/{Tiktok.svg → TikTok.svg} +0 -0
  65. /package/dist/runtime/assets/svg/socials/{Whatsapp.svg → WhatsApp.svg} +0 -0
  66. /package/dist/runtime/assets/svg/socials/{Youtube.svg → YouTube.svg} +0 -0
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pukaad-ui-lib",
3
3
  "configKey": "pukaadUI",
4
- "version": "1.369.9",
4
+ "version": "1.371.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -0,0 +1,14 @@
1
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g clip-path="url(#clip0_8829_2067)">
3
+ <path d="M0 0H20V20H0V0Z" fill="#012169"/>
4
+ <path d="M20 0V2.5L12.5781 10L20 17.3047V20H17.3828L9.92188 12.6562L2.65625 20H0V17.3438L7.26562 10.0391L0 2.89062V0H2.42188L9.92188 7.34375L17.1875 0H20Z" fill="white"/>
5
+ <path d="M7.1875 12.6562L7.61719 13.9844L1.64062 20H0V19.8828L7.1875 12.6562ZM12.0312 12.1875L14.1406 12.5L20 18.2422V20L12.0312 12.1875ZM20 0L12.5 7.65625L12.3438 5.9375L18.2031 0H20ZM0 0.0390625L7.53906 7.42188L5.23438 7.10938L0 1.91406V0.0390625Z" fill="#C8102E"/>
6
+ <path d="M6.875 0V20H13.125V0H6.875ZM0 6.875V13.125H20V6.875H0Z" fill="white"/>
7
+ <path d="M0 8.125V11.875H20V8.125H0ZM8.125 0V20H11.875V0H8.125Z" fill="#C8102E"/>
8
+ </g>
9
+ <defs>
10
+ <clipPath id="clip0_8829_2067">
11
+ <rect width="20" height="20" rx="10" fill="white"/>
12
+ </clipPath>
13
+ </defs>
14
+ </svg>
@@ -0,0 +1,16 @@
1
+ import type { OpeningHour, SpecialDay } from "#pukaad-ui/runtime/utils/opening-hours";
2
+ export type { OpeningHour, SpecialDay, TimeSlot, } from "#pukaad-ui/runtime/utils/opening-hours";
3
+ type __VLS_Props = {
4
+ items?: OpeningHour[];
5
+ specialDays?: SpecialDay[];
6
+ openStatus?: string;
7
+ filterUpcomingSpecialDays?: boolean;
8
+ };
9
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
10
+ items: OpeningHour[];
11
+ specialDays: SpecialDay[];
12
+ openStatus: string;
13
+ filterUpcomingSpecialDays: boolean;
14
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
@@ -0,0 +1,90 @@
1
+ <template>
2
+ <div class="font-body-large flex flex-col gap-[4px] w-full">
3
+ <!-- สถานะปิดชั่วคราว -->
4
+ <div
5
+ v-if="props.openStatus === 'temporarily_closed'"
6
+ class="font-body-large-prominent text-error"
7
+ >
8
+ ปิดชั่วคราว
9
+ </div>
10
+
11
+ <!-- เวลาทำการปกติ -->
12
+ <div
13
+ v-for="(line, index) in lines"
14
+ :key="index"
15
+ class="flex items-start justify-between"
16
+ >
17
+ <span>{{ line.day }}</span>
18
+ <div class="flex flex-col items-end">
19
+ <span v-for="(time, timeIndex) in line.time_lines" :key="timeIndex">
20
+ {{ time }}
21
+ </span>
22
+ </div>
23
+ </div>
24
+
25
+ <!-- วันทำการพิเศษ -->
26
+ <template v-if="formattedSpecialDays.length">
27
+ <div class="font-body-large-prominent text-warning">วันทำการพิเศษ</div>
28
+ <div
29
+ v-for="(special, index) in formattedSpecialDays"
30
+ :key="index"
31
+ class="flex items-start justify-between text-warning"
32
+ >
33
+ <span>{{ special.date_label }}</span>
34
+ <div class="flex flex-col items-end">
35
+ <span
36
+ v-for="(time, timeIndex) in special.time_lines"
37
+ :key="timeIndex"
38
+ >
39
+ {{ time }}
40
+ </span>
41
+ </div>
42
+ </div>
43
+ </template>
44
+
45
+ <div
46
+ v-if="
47
+ !lines.length && !formattedSpecialDays.length && props.openStatus !== 'temporarily_closed'
48
+ "
49
+ class="text-cloud"
50
+ >
51
+ ไม่มีข้อมูลเวลาทำการ
52
+ </div>
53
+ </div>
54
+ </template>
55
+
56
+ <script setup>
57
+ import { computed } from "vue";
58
+ import dayjs from "#pukaad-ui/runtime/utils/dayjs";
59
+ import { useConvert } from "#pukaad-ui/runtime/composables/useConvert";
60
+ import {
61
+ toDayLines,
62
+ getTimeLines
63
+ } from "#pukaad-ui/runtime/utils/opening-hours";
64
+ const props = defineProps({
65
+ items: { type: Array, required: false, default: () => [] },
66
+ specialDays: { type: Array, required: false, default: () => [] },
67
+ openStatus: { type: String, required: false, default: void 0 },
68
+ filterUpcomingSpecialDays: { type: Boolean, required: false, default: true }
69
+ });
70
+ const { convertDate } = useConvert();
71
+ const toArray = (value) => Array.isArray(value) ? value : [];
72
+ const lines = computed(() => toDayLines(props.items));
73
+ const sortedSpecialDays = computed(() => {
74
+ const allSpecial = toArray(props.specialDays).filter(
75
+ (s) => !!s?.date
76
+ );
77
+ if (!props.filterUpcomingSpecialDays) return allSpecial;
78
+ const today = dayjs().startOf("day");
79
+ const maxDate = today.add(30, "day").endOf("day");
80
+ return allSpecial.map((s) => ({ ...s, parsedDate: dayjs(s.date) })).filter((s) => s.parsedDate.isValid()).filter(
81
+ (s) => !s.parsedDate.isBefore(today) && !s.parsedDate.isAfter(maxDate)
82
+ ).sort((a, b) => a.parsedDate.valueOf() - b.parsedDate.valueOf());
83
+ });
84
+ const formattedSpecialDays = computed(
85
+ () => sortedSpecialDays.value.map((s) => ({
86
+ date_label: convertDate(s.date),
87
+ time_lines: getTimeLines(s.isOpen, s.timeSlots)
88
+ }))
89
+ );
90
+ </script>
@@ -0,0 +1,16 @@
1
+ import type { OpeningHour, SpecialDay } from "#pukaad-ui/runtime/utils/opening-hours";
2
+ export type { OpeningHour, SpecialDay, TimeSlot, } from "#pukaad-ui/runtime/utils/opening-hours";
3
+ type __VLS_Props = {
4
+ items?: OpeningHour[];
5
+ specialDays?: SpecialDay[];
6
+ openStatus?: string;
7
+ filterUpcomingSpecialDays?: boolean;
8
+ };
9
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
10
+ items: OpeningHour[];
11
+ specialDays: SpecialDay[];
12
+ openStatus: string;
13
+ filterUpcomingSpecialDays: boolean;
14
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
@@ -1,35 +1,5 @@
1
- export interface Category {
2
- id: string;
3
- category_name: string;
4
- }
5
- export interface TimeSlot {
6
- start: string;
7
- end: string;
8
- }
9
- export interface OpeningHour {
10
- day: number;
11
- isOpen: boolean;
12
- isAllDay?: boolean;
13
- timeSlots?: TimeSlot[];
14
- }
15
- export interface ContactChannel {
16
- channel_type: string;
17
- value: string;
18
- }
19
- export interface SpecialDay {
20
- date: string | Date;
21
- isOpen: boolean;
22
- timeSlots?: TimeSlot[];
23
- }
24
- export interface PlaceDetailItem {
25
- description?: string;
26
- categories?: Category[];
27
- open_status?: string;
28
- opening_hours?: OpeningHour[];
29
- special_days?: SpecialDay[];
30
- phone?: string;
31
- contact_channels?: ContactChannel[];
32
- }
1
+ import type { PlaceDetailItem } from "#pukaad-ui/types/models/place";
2
+ export type { PlaceDetailItem } from "#pukaad-ui/types/models/place";
33
3
  type __VLS_Props = {
34
4
  item?: PlaceDetailItem;
35
5
  };
@@ -30,50 +30,13 @@
30
30
  props.item.open_status === 'temporarily_closed' ? 'text-destructive' : 'text-primary '
31
31
  ]"
32
32
  />
33
- <div v-if="businessHours.length" class="flex flex-col gap-[4px] flex-1">
34
- <div
35
- v-if="props.item.open_status === 'temporarily_closed'"
36
- class="font-body-large-prominent text-error"
37
- >
38
- ปิดชั่วคราว
39
- </div>
40
- <div
41
- v-for="(hour, index) in businessHours"
42
- :key="index"
43
- class="flex items-start justify-between"
44
- >
45
- <span>{{ hour.day }}</span>
46
- <div class="flex flex-col items-end">
47
- <span v-for="(line, li) in hour.time_lines" :key="li">{{
48
- line
49
- }}</span>
50
- </div>
51
- </div>
52
-
53
- <template v-if="upcomingSpecialDays.length">
54
- <div class="font-body-large-prominent text-warning">
55
- วันทำการพิเศษ
56
- </div>
57
- <div
58
- v-for="(special, index) in upcomingSpecialDays"
59
- :key="index"
60
- class="flex items-start justify-between text-warning"
61
- >
62
- <span>{{ special.date_label }}</span>
63
- <div class="flex flex-col items-end">
64
- <span v-for="(line, li) in special.time_lines" :key="li">{{
65
- line
66
- }}</span>
67
- </div>
68
- </div>
69
- </template>
70
- </div>
71
- <div v-else-if="props.item.open_status === 'temporarily_closed'">
72
- <div class="font-body-large-prominent text-destructive">
73
- ปิดชั่วคราว
74
- </div>
33
+ <div class="flex-1 min-w-0">
34
+ <CardOpeningHours
35
+ :items="props.item.opening_hours"
36
+ :special-days="props.item.special_days"
37
+ :open-status="props.item.open_status"
38
+ />
75
39
  </div>
76
- <div v-else class="text-cloud">ไม่มีข้อมูลเวลาทำการ</div>
77
40
  </div>
78
41
 
79
42
  <div class="flex gap-[12px]">
@@ -85,7 +48,25 @@
85
48
  <div v-if="props.item.phone">{{ props.item.phone }}</div>
86
49
  <div v-else class="text-cloud">ไม่มีข้อมูลเบอร์โทรศัพท์</div>
87
50
  </div>
88
-
51
+ <div class="flex gap-[12px]">
52
+ <Icon
53
+ name="lucide:shield-check"
54
+ :size="20"
55
+ class="text-primary shrink-0 mt-[2px]"
56
+ />
57
+ <div class="font-body-large">หากคุณเป็นเจ้าของธุรกิจนี้</div>
58
+ </div>
59
+ <div
60
+ class="flex gap-[12px] hover:cursor-pointer"
61
+ @click="isOpenModalSuggestEdit = true"
62
+ >
63
+ <Icon
64
+ name="lucide:square-pen"
65
+ :size="20"
66
+ class="text-primary shrink-0 mt-[2px]"
67
+ />
68
+ <div class="font-body-large">แนะนำให้แก้ไข</div>
69
+ </div>
89
70
  <Divider />
90
71
 
91
72
  <div v-if="socialLinks.length" class="flex flex-col gap-[8px]">
@@ -108,11 +89,15 @@
108
89
  <span class="text-cloud">ไม่มีข้อมูลช่องทางติดต่อ</span>
109
90
  </div>
110
91
  </div>
92
+ <ModalSuggestEditPlace
93
+ v-model="isOpenModalSuggestEdit"
94
+ :item="props.item"
95
+ />
111
96
  </Card>
112
97
  </template>
113
98
 
114
99
  <script setup>
115
- import { computed } from "vue";
100
+ import { computed, ref } from "vue";
116
101
  import dayjs from "#pukaad-ui/runtime/utils/dayjs";
117
102
  const DAY_NAMES = [
118
103
  "\u0E27\u0E31\u0E19\u0E2D\u0E32\u0E17\u0E34\u0E15\u0E22\u0E4C",
@@ -126,21 +111,10 @@ const DAY_NAMES = [
126
111
  const props = defineProps({
127
112
  item: { type: Object, required: false, default: () => ({}) }
128
113
  });
114
+ const isOpenModalSuggestEdit = ref(false);
129
115
  const toArray = (value) => Array.isArray(value) ? value : [];
130
116
  const categoryText = computed(
131
- () => toArray(props.item.categories).filter((c) => c?.category_name).map((c) => c.category_name).join(", ")
132
- );
133
- const getTimeLines = (isOpen, timeSlots, isAllDay) => {
134
- if (!isOpen) return ["\u0E2B\u0E22\u0E38\u0E14\u0E17\u0E33\u0E01\u0E32\u0E23"];
135
- const slots = toArray(timeSlots);
136
- if (isAllDay || slots.length === 0) return ["\u0E40\u0E1B\u0E34\u0E14\u0E15\u0E25\u0E2D\u0E14 24 \u0E0A\u0E21."];
137
- return slots.map((t) => `${t.start} - ${t.end} \u0E19.`);
138
- };
139
- const businessHours = computed(
140
- () => toArray(props.item.opening_hours).filter((h) => !!h).map((h) => ({
141
- day: DAY_NAMES[h.day] ?? "",
142
- time_lines: getTimeLines(h.isOpen, h.timeSlots, h.isAllDay)
143
- }))
117
+ () => props.item.categories?.map((c) => c.category_name).join(", ") ?? ""
144
118
  );
145
119
  const socialLinks = computed(
146
120
  () => toArray(props.item.contact_channels).filter((ch) => ch?.value).map((ch) => ({
@@ -148,17 +122,6 @@ const socialLinks = computed(
148
122
  link: ch.value
149
123
  }))
150
124
  );
151
- const sortedSpecialDays = computed(() => {
152
- const today = dayjs().startOf("day");
153
- const maxDate = today.add(30, "day").endOf("day");
154
- return toArray(props.item.special_days).filter((s) => !!s?.date).map((s) => ({ ...s, date: dayjs(s.date) })).filter((s) => s.date.isValid()).filter((s) => !s.date.isBefore(today) && !s.date.isAfter(maxDate)).sort((a, b) => a.date.valueOf() - b.date.valueOf());
155
- });
156
- const upcomingSpecialDays = computed(
157
- () => sortedSpecialDays.value.map((s) => ({
158
- date_label: s.date.locale("th").format("D MMMM BBBB"),
159
- time_lines: getTimeLines(s.isOpen, s.timeSlots)
160
- }))
161
- );
162
125
  const onClickLink = (link) => {
163
126
  window.open(link, "_blank");
164
127
  };
@@ -1,35 +1,5 @@
1
- export interface Category {
2
- id: string;
3
- category_name: string;
4
- }
5
- export interface TimeSlot {
6
- start: string;
7
- end: string;
8
- }
9
- export interface OpeningHour {
10
- day: number;
11
- isOpen: boolean;
12
- isAllDay?: boolean;
13
- timeSlots?: TimeSlot[];
14
- }
15
- export interface ContactChannel {
16
- channel_type: string;
17
- value: string;
18
- }
19
- export interface SpecialDay {
20
- date: string | Date;
21
- isOpen: boolean;
22
- timeSlots?: TimeSlot[];
23
- }
24
- export interface PlaceDetailItem {
25
- description?: string;
26
- categories?: Category[];
27
- open_status?: string;
28
- opening_hours?: OpeningHour[];
29
- special_days?: SpecialDay[];
30
- phone?: string;
31
- contact_channels?: ContactChannel[];
32
- }
1
+ import type { PlaceDetailItem } from "#pukaad-ui/types/models/place";
2
+ export type { PlaceDetailItem } from "#pukaad-ui/types/models/place";
33
3
  type __VLS_Props = {
34
4
  item?: PlaceDetailItem;
35
5
  };
@@ -1,7 +1,9 @@
1
+ import type { HTMLAttributes } from "vue";
1
2
  type __VLS_Props = {
2
3
  provinceId?: number;
3
4
  amphurId?: number;
4
5
  tambonId?: number;
6
+ class?: HTMLAttributes["class"];
5
7
  };
6
8
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
7
9
  "update:latLng": (val: {
@@ -1,19 +1,25 @@
1
1
  <template>
2
- <div
3
- class="relative w-[334px] h-[434px] rounded-[12px] overflow-hidden bg-gray-300 z-0"
4
- >
2
+ <div :class="rootClass">
5
3
  <div ref="mapContainer" class="w-full h-full z-0"></div>
6
4
  </div>
7
5
  </template>
8
6
 
9
7
  <script setup>
10
- import { ref, onMounted, watch } from "vue";
8
+ import { computed, ref, onMounted, watch } from "vue";
11
9
  import mapPinSvg from "#pukaad-ui/runtime/assets/svg/map-pin.svg?raw";
10
+ import { cn } from "#pukaad-ui/runtime/plugins/shadcn";
12
11
  const props = defineProps({
13
12
  provinceId: { type: Number, required: false },
14
13
  amphurId: { type: Number, required: false },
15
- tambonId: { type: Number, required: false }
14
+ tambonId: { type: Number, required: false },
15
+ class: { type: null, required: false }
16
16
  });
17
+ const rootClass = computed(
18
+ () => cn(
19
+ "relative w-[334px] h-[434px] rounded-[12px] overflow-hidden bg-gray-300 z-0",
20
+ props.class
21
+ )
22
+ );
17
23
  const emits = defineEmits(["update:latLng"]);
18
24
  const mapContainer = ref(null);
19
25
  let map = null;
@@ -1,7 +1,9 @@
1
+ import type { HTMLAttributes } from "vue";
1
2
  type __VLS_Props = {
2
3
  provinceId?: number;
3
4
  amphurId?: number;
4
5
  tambonId?: number;
6
+ class?: HTMLAttributes["class"];
5
7
  };
6
8
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
7
9
  "update:latLng": (val: {
@@ -48,8 +48,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
48
48
  id: string;
49
49
  name: string;
50
50
  required: boolean;
51
- options: AutocompleteOption[] | string[] | number[];
52
51
  description: string;
52
+ options: AutocompleteOption[] | string[] | number[];
53
53
  labelKey: string;
54
54
  placeholder: string;
55
55
  limit: number;
@@ -48,8 +48,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
48
48
  id: string;
49
49
  name: string;
50
50
  required: boolean;
51
- options: AutocompleteOption[] | string[] | number[];
52
51
  description: string;
52
+ options: AutocompleteOption[] | string[] | number[];
53
53
  labelKey: string;
54
54
  placeholder: string;
55
55
  limit: number;
@@ -35,8 +35,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
35
35
  fullHeight: boolean;
36
36
  fullWidth: boolean;
37
37
  limit: number;
38
- accept: string;
39
38
  disabledErrorMessage: boolean;
39
+ accept: string;
40
40
  labelIcon: string;
41
41
  disabledDrop: boolean;
42
42
  column: boolean;
@@ -35,8 +35,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
35
35
  fullHeight: boolean;
36
36
  fullWidth: boolean;
37
37
  limit: number;
38
- accept: string;
39
38
  disabledErrorMessage: boolean;
39
+ accept: string;
40
40
  labelIcon: string;
41
41
  disabledDrop: boolean;
42
42
  column: boolean;
@@ -2,8 +2,10 @@ import type { InputLinkItem, ContactChannel, InputLinkProps } from "#pukaad-ui/t
2
2
  type __VLS_Props = InputLinkProps & {
3
3
  modelValue?: InputLinkItem[] | ContactChannel[];
4
4
  defaultFirst?: boolean;
5
+ defaultType?: string;
5
6
  showCounter?: boolean;
6
7
  limit?: number;
8
+ label?: string;
7
9
  };
8
10
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
9
11
  hasError: () => boolean;
@@ -12,11 +14,14 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
12
14
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
13
15
  "onUpdate:modelValue"?: ((value: InputLinkItem[] | ContactChannel[]) => any) | undefined;
14
16
  }>, {
17
+ label: string;
15
18
  name: string;
16
19
  modelValue: InputLinkItem[] | ContactChannel[];
17
20
  limit: number;
18
21
  showCounter: boolean;
19
22
  format: "legacy" | "contact_channel";
23
+ hideType: boolean;
24
+ hideAddButton: boolean;
20
25
  defaultFirst: boolean;
21
26
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
22
27
  declare const _default: typeof __VLS_export;
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="relative">
3
- <div class="font-body-large-prominent text-gray">ช่องทางการติดต่อ</div>
3
+ <div class="font-body-large-prominent text-gray">{{ props.label }}</div>
4
4
  <ul class="flex flex-col gap-[16px]">
5
5
  <li v-for="(link, i) in linkValue" :key="i">
6
6
  <InputTypedField
@@ -10,12 +10,13 @@
10
10
  :rules="(v) => rules(v, link.name)"
11
11
  :show-counter="props.showCounter"
12
12
  :limit="props.limit"
13
+ :hide-type="props.hideType"
13
14
  v-model:type="link.name"
14
15
  v-model:value="link.link"
15
16
  @change="onChangeLink(link, i)"
16
17
  />
17
18
  </li>
18
- <li>
19
+ <li v-if="!props.hideAddButton">
19
20
  <Button variant="text" color="primary" @click="addLink">
20
21
  <Icon name="lucide:plus" />
21
22
  เพิ่มช่องทาง
@@ -30,10 +31,14 @@ import { computed, ref, watch, onMounted } from "vue";
30
31
  const props = defineProps({
31
32
  name: { type: String, required: false, default: "link" },
32
33
  format: { type: String, required: false, default: "legacy" },
34
+ hideType: { type: Boolean, required: false, default: false },
35
+ hideAddButton: { type: Boolean, required: false, default: false },
33
36
  modelValue: { type: Array, required: false, default: () => [] },
34
37
  defaultFirst: { type: Boolean, required: false, default: false },
38
+ defaultType: { type: String, required: false },
35
39
  showCounter: { type: Boolean, required: false, default: false },
36
- limit: { type: Number, required: false, default: 0 }
40
+ limit: { type: Number, required: false, default: 0 },
41
+ label: { type: String, required: false, default: "\u0E0A\u0E48\u0E2D\u0E07\u0E17\u0E32\u0E07\u0E01\u0E32\u0E23\u0E15\u0E34\u0E14\u0E15\u0E48\u0E2D\u0E2D\u0E37\u0E48\u0E19" }
37
42
  });
38
43
  const emit = defineEmits(["update:modelValue"]);
39
44
  const listSocial = [
@@ -167,13 +172,14 @@ watch(
167
172
  },
168
173
  { deep: true }
169
174
  );
175
+ const findSocial = (name) => listSocial.find((item) => item.name.toLowerCase() === name?.toLowerCase());
170
176
  const rules = (v, linkName) => {
171
177
  if (!v) return true;
172
- const socialItem = listSocial.find((item) => item.name === linkName);
178
+ const socialItem = findSocial(linkName);
173
179
  if (socialItem && socialItem.regex) {
174
180
  if (!socialItem.regex.test(v)) {
175
- if (linkName === "Email") return "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01\u0E2D\u0E35\u0E40\u0E21\u0E25\u0E17\u0E35\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07";
176
- return `\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A\u0E25\u0E34\u0E07\u0E04\u0E4C ${linkName} \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07`;
181
+ if (socialItem.name === "Email") return "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01\u0E2D\u0E35\u0E40\u0E21\u0E25\u0E17\u0E35\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07";
182
+ return `\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A\u0E25\u0E34\u0E07\u0E04\u0E4C ${socialItem.name} \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07`;
177
183
  }
178
184
  return true;
179
185
  }
@@ -181,7 +187,7 @@ const rules = (v, linkName) => {
181
187
  return regex.test(v) || "\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A\u0E25\u0E34\u0E07\u0E04\u0E4C\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07";
182
188
  };
183
189
  const getPlaceholder = (name) => {
184
- return listSocial.find((f) => f.name === name)?.example || "";
190
+ return findSocial(name)?.example || "";
185
191
  };
186
192
  const listOption = computed(() => {
187
193
  const arr = listSocial.map((item) => {
@@ -200,7 +206,7 @@ onMounted(() => {
200
206
  });
201
207
  const addLink = () => {
202
208
  const link = {
203
- name: "Email",
209
+ name: props.defaultType || "Email",
204
210
  link: ""
205
211
  };
206
212
  if (!Array.isArray(linkValue.value)) {
@@ -2,8 +2,10 @@ import type { InputLinkItem, ContactChannel, InputLinkProps } from "#pukaad-ui/t
2
2
  type __VLS_Props = InputLinkProps & {
3
3
  modelValue?: InputLinkItem[] | ContactChannel[];
4
4
  defaultFirst?: boolean;
5
+ defaultType?: string;
5
6
  showCounter?: boolean;
6
7
  limit?: number;
8
+ label?: string;
7
9
  };
8
10
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
9
11
  hasError: () => boolean;
@@ -12,11 +14,14 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
12
14
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
13
15
  "onUpdate:modelValue"?: ((value: InputLinkItem[] | ContactChannel[]) => any) | undefined;
14
16
  }>, {
17
+ label: string;
15
18
  name: string;
16
19
  modelValue: InputLinkItem[] | ContactChannel[];
17
20
  limit: number;
18
21
  showCounter: boolean;
19
22
  format: "legacy" | "contact_channel";
23
+ hideType: boolean;
24
+ hideAddButton: boolean;
20
25
  defaultFirst: boolean;
21
26
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
22
27
  declare const _default: typeof __VLS_export;
@@ -21,6 +21,7 @@
21
21
 
22
22
  <div class="flex items-start gap-[8px] font-body-large">
23
23
  <InputSelect
24
+ v-if="!props.hideType"
24
25
  :name="`${props.name}-type`"
25
26
  :class="props.selectClass"
26
27
  :options="props.options"
@@ -55,7 +56,8 @@ const props = defineProps({
55
56
  limit: { type: Number, required: false, default: 0 },
56
57
  selectClass: { type: null, required: false, default: "w-[172px]" },
57
58
  fieldClass: { type: null, required: false },
58
- resetOnTypeChange: { type: Boolean, required: false, default: true }
59
+ resetOnTypeChange: { type: Boolean, required: false, default: true },
60
+ hideType: { type: Boolean, required: false }
59
61
  });
60
62
  const emit = defineEmits(["typeChange", "change"]);
61
63
  const type = defineModel("type", { type: String, ...{ default: "" } });