pukaad-ui-lib 1.355.0 → 1.357.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 (32) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +1 -0
  3. package/dist/runtime/components/drawer/drawer-notification.vue +146 -146
  4. package/dist/runtime/components/google-translate.client.d.vue.ts +3 -0
  5. package/dist/runtime/components/google-translate.client.vue +41 -0
  6. package/dist/runtime/components/google-translate.client.vue.d.ts +3 -0
  7. package/dist/runtime/components/image/image-cropper.d.vue.ts +2 -2
  8. package/dist/runtime/components/image/image-cropper.vue.d.ts +2 -2
  9. package/dist/runtime/components/input/input-autocomplete.d.vue.ts +2 -2
  10. package/dist/runtime/components/input/input-autocomplete.vue.d.ts +2 -2
  11. package/dist/runtime/components/input/input-combobox.d.vue.ts +1 -1
  12. package/dist/runtime/components/input/input-combobox.vue.d.ts +1 -1
  13. package/dist/runtime/components/input/input-localized-name.d.vue.ts +1 -1
  14. package/dist/runtime/components/input/input-localized-name.vue.d.ts +1 -1
  15. package/dist/runtime/components/input/input-suggest.d.vue.ts +2 -2
  16. package/dist/runtime/components/input/input-suggest.vue.d.ts +2 -2
  17. package/dist/runtime/components/input/input-tag.d.vue.ts +1 -1
  18. package/dist/runtime/components/input/input-tag.vue.d.ts +1 -1
  19. package/dist/runtime/components/input/input-textarea.d.vue.ts +1 -1
  20. package/dist/runtime/components/input/input-textarea.vue.d.ts +1 -1
  21. package/dist/runtime/components/label/label-card-content.d.vue.ts +0 -2
  22. package/dist/runtime/components/label/label-card-content.vue +1 -7
  23. package/dist/runtime/components/label/label-card-content.vue.d.ts +0 -2
  24. package/dist/runtime/components/modal/modal-report.d.vue.ts +3 -9
  25. package/dist/runtime/components/modal/modal-report.vue +106 -45
  26. package/dist/runtime/components/modal/modal-report.vue.d.ts +3 -9
  27. package/dist/runtime/components/picker/picker-option-menu/picker-option-menu-user.d.vue.ts +2 -2
  28. package/dist/runtime/components/picker/picker-option-menu/picker-option-menu-user.vue.d.ts +2 -2
  29. package/dist/runtime/composables/useGoogleTranslate.d.ts +4 -0
  30. package/dist/runtime/composables/useGoogleTranslate.js +42 -0
  31. package/package.json +1 -1
  32. /package/dist/runtime/assets/svg/socials/{WhatsApp.svg → Whatsapp.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.355.0",
4
+ "version": "1.357.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -247,6 +247,7 @@ const module$1 = defineNuxtModule({
247
247
  _nuxt.options.runtimeConfig.public.RECAPTCHA_KEY ??= process.env.RECAPTCHA_KEY ?? "";
248
248
  _nuxt.hook("prepare:types", ({ references }) => {
249
249
  references.push({ path: resolver.resolve("./types/convert.d.ts") });
250
+ references.push({ path: resolver.resolve("./types/google-translate.d.ts") });
250
251
  });
251
252
  }
252
253
  });
@@ -1,152 +1,152 @@
1
1
  <template>
2
- <Drawer v-model="modelValue" title="การแจ้งเตือน" class="w-[748px]">
3
- <div class="flex justify-between items-center mb-[16px]">
4
- <ShadTabs v-model="selectedTab" class="w-full">
5
- <div class="flex justify-between items-center w-full">
6
- <ShadTabsList>
7
- <ShadTabsTrigger
8
- v-for="tab in tabs"
9
- :key="tab.value"
10
- :value="tab.value"
11
- class="px-4 py-2"
12
- >
13
- <Icon name="lucide:layers" />
14
- <div class="flex">
15
- {{ tab.label }}
16
- <div
2
+ <Drawer v-model="modelValue" title="การแจ้งเตือน" class="w-[748px]">
3
+ <div class="flex justify-between items-center mb-[16px]">
4
+ <ShadTabs v-model="selectedTab" class="w-full">
5
+ <div class="flex justify-between items-center w-full">
6
+ <ShadTabsList>
7
+ <ShadTabsTrigger
8
+ v-for="tab in tabs"
9
+ :key="tab.value"
10
+ :value="tab.value"
11
+ class="px-4 py-2"
12
+ >
13
+ <Icon name="lucide:layers" />
14
+ <div class="flex">
15
+ {{ tab.label }}
16
+ <div
17
17
  v-if="
18
18
  tab.value === 'general' ? hasUnreadGeneral : hasUnreadSystem
19
- "
20
- class="bg-destructive rounded-full w-[10px] h-[10px] m-[2px] shrink-0"
21
- />
22
- </div>
23
- </ShadTabsTrigger>
24
- </ShadTabsList>
25
-
26
- <div
27
- v-if="notifications.length > 0"
28
- class="text-primary font-body-medium cursor-pointer"
29
- @click="markAllRead"
30
- >
31
- อ่านทั้งหมด
32
- </div>
33
- </div>
34
-
35
- <ShadTabsContent value="general" class="flex flex-col gap-[8px]">
36
- <template v-if="isLoading && notifications.length === 0">
37
- <div class="flex justify-center py-[40px]">
38
- <Icon
39
- name="lucide:loader-2"
40
- size="24"
41
- class="animate-spin text-gray"
42
- />
43
- </div>
44
- </template>
45
-
46
- <template v-else-if="notifications.length === 0">
47
- <div
48
- class="flex flex-col items-center justify-center py-[40px] gap-[8px]"
49
- >
50
- <Icon name="lucide:bell-off" size="40" class="text-gray" />
51
- <div class="font-body-medium text-gray">ยังไม่มีการแจ้งเตือน</div>
52
- </div>
53
- </template>
54
-
55
- <template v-else>
56
- <Card
57
- v-for="item in notifications"
58
- :key="item.id"
59
- variant="outline"
60
- class="cursor-pointer transition-colors"
61
- :class="{ 'bg-bright': !item.is_read }"
62
- @click="onClickNotification(item)"
63
- >
64
- <div class="flex gap-[8px] items-center">
65
- <div class="flex gap-[8px] items-center w-full">
66
- <Avatar :size="30" :src="item.actor?.avatar ?? void 0" />
67
- <div class="flex flex-col gap-[4px]">
68
- <div class="font-body-medium">
69
- <span
70
- v-if="item.actor"
71
- class="font-body-medium-prominent"
72
- >
73
- {{ item.actor.name }}
74
- </span>
75
- {{ item.message }}
76
- <span
77
- v-if="item.grouped_count && item.grouped_count > 1"
78
- class="text-gray font-body-small"
79
- >
80
- ({{ item.grouped_count }} คน)
81
- </span>
82
- </div>
83
- <div class="text-gray font-body-small">
84
- {{ formatRelativeTime(item.created_at) }}
85
- </div>
86
- </div>
87
- </div>
88
- <div
89
- v-if="!item.is_read"
90
- class="bg-primary rounded-full w-[10px] h-[10px] shrink-0"
91
- />
92
- </div>
93
- </Card>
94
- </template>
95
- </ShadTabsContent>
96
-
97
- <ShadTabsContent value="system" class="flex flex-col gap-[8px]">
98
- <template v-if="isLoading && notifications.length === 0">
99
- <div class="flex justify-center py-[40px]">
100
- <Icon
101
- name="lucide:loader-2"
102
- size="24"
103
- class="animate-spin text-gray"
104
- />
105
- </div>
106
- </template>
107
-
108
- <template v-else-if="notifications.length === 0">
109
- <div
110
- class="flex flex-col items-center justify-center py-[40px] gap-[8px]"
111
- >
112
- <Icon name="lucide:bell-off" size="40" class="text-gray" />
113
- <div class="font-body-medium text-gray">ยังไม่มีการแจ้งเตือนระบบ</div>
114
- </div>
115
- </template>
116
-
117
- <template v-else>
118
- <Card
119
- v-for="item in notifications"
120
- :key="item.id"
121
- variant="outline"
122
- class="cursor-pointer transition-colors"
123
- :class="{ 'bg-bright': !item.is_read }"
124
- @click="onClickNotification(item)"
125
- >
126
- <div class="flex gap-[8px] items-center">
127
- <div class="flex gap-[8px] items-center w-full">
128
- <Icon
129
- name="pukaad:memsg-square"
130
- class="w-[40px] h-[40px] shrink-0"
131
- />
132
- <div class="flex flex-col gap-[4px]">
133
- <div class="font-body-medium">{{ item.message }}</div>
134
- <div class="text-gray font-body-small">
135
- {{ formatRelativeTime(item.created_at) }}
136
- </div>
137
- </div>
138
- </div>
139
- <div
140
- v-if="!item.is_read"
141
- class="bg-primary rounded-full w-[10px] h-[10px] shrink-0"
142
- />
143
- </div>
144
- </Card>
145
- </template>
146
- </ShadTabsContent>
147
- </ShadTabs>
148
- </div>
149
- </Drawer>
19
+ "
20
+ class="bg-destructive rounded-full w-[10px] h-[10px] m-[2px] shrink-0"
21
+ />
22
+ </div>
23
+ </ShadTabsTrigger>
24
+ </ShadTabsList>
25
+
26
+ <div
27
+ v-if="notifications.length > 0"
28
+ class="text-primary font-body-medium cursor-pointer"
29
+ @click="markAllRead"
30
+ >
31
+ อ่านทั้งหมด
32
+ </div>
33
+ </div>
34
+
35
+ <ShadTabsContent value="general" class="flex flex-col gap-[8px]">
36
+ <template v-if="isLoading && notifications.length === 0">
37
+ <div class="flex justify-center py-[40px]">
38
+ <Icon
39
+ name="lucide:loader-2"
40
+ size="24"
41
+ class="animate-spin text-gray"
42
+ />
43
+ </div>
44
+ </template>
45
+
46
+ <template v-else-if="notifications.length === 0">
47
+ <div
48
+ class="flex flex-col items-center justify-center py-[40px] gap-[8px]"
49
+ >
50
+ <Icon name="lucide:bell-off" size="40" class="text-gray" />
51
+ <div class="font-body-medium text-gray">ยังไม่มีการแจ้งเตือน</div>
52
+ </div>
53
+ </template>
54
+
55
+ <template v-else>
56
+ <Card
57
+ v-for="item in notifications"
58
+ :key="item.id"
59
+ variant="outline"
60
+ class="cursor-pointer transition-colors"
61
+ :class="{ 'bg-bright': !item.is_read }"
62
+ @click="onClickNotification(item)"
63
+ >
64
+ <div class="flex gap-[8px] items-center">
65
+ <div class="flex gap-[8px] items-center w-full">
66
+ <Avatar :size="30" :src="item.actor?.avatar ?? void 0" />
67
+ <div class="flex flex-col gap-[4px]">
68
+ <div class="font-body-medium">
69
+ <span
70
+ v-if="item.actor"
71
+ class="font-body-medium-prominent"
72
+ >
73
+ {{ item.actor.name }}
74
+ </span>
75
+ {{ item.message }}
76
+ <span
77
+ v-if="item.grouped_count && item.grouped_count > 1"
78
+ class="text-gray font-body-small"
79
+ >
80
+ ({{ item.grouped_count }} คน)
81
+ </span>
82
+ </div>
83
+ <div class="text-gray font-body-small">
84
+ {{ formatRelativeTime(item.created_at) }}
85
+ </div>
86
+ </div>
87
+ </div>
88
+ <div
89
+ v-if="!item.is_read"
90
+ class="bg-primary rounded-full w-[10px] h-[10px] shrink-0"
91
+ />
92
+ </div>
93
+ </Card>
94
+ </template>
95
+ </ShadTabsContent>
96
+
97
+ <ShadTabsContent value="system" class="flex flex-col gap-[8px]">
98
+ <template v-if="isLoading && notifications.length === 0">
99
+ <div class="flex justify-center py-[40px]">
100
+ <Icon
101
+ name="lucide:loader-2"
102
+ size="24"
103
+ class="animate-spin text-gray"
104
+ />
105
+ </div>
106
+ </template>
107
+
108
+ <template v-else-if="notifications.length === 0">
109
+ <div
110
+ class="flex flex-col items-center justify-center py-[40px] gap-[8px]"
111
+ >
112
+ <Icon name="lucide:bell-off" size="40" class="text-gray" />
113
+ <div class="font-body-medium text-gray">ยังไม่มีการแจ้งเตือนระบบ</div>
114
+ </div>
115
+ </template>
116
+
117
+ <template v-else>
118
+ <Card
119
+ v-for="item in notifications"
120
+ :key="item.id"
121
+ variant="outline"
122
+ class="cursor-pointer transition-colors"
123
+ :class="{ 'bg-bright': !item.is_read }"
124
+ @click="onClickNotification(item)"
125
+ >
126
+ <div class="flex gap-[8px] items-center">
127
+ <div class="flex gap-[8px] items-center w-full">
128
+ <Icon
129
+ name="pukaad:memsg-square"
130
+ class="w-[40px] h-[40px] shrink-0"
131
+ />
132
+ <div class="flex flex-col gap-[4px]">
133
+ <div class="font-body-medium">{{ item.message }}</div>
134
+ <div class="text-gray font-body-small">
135
+ {{ formatRelativeTime(item.created_at) }}
136
+ </div>
137
+ </div>
138
+ </div>
139
+ <div
140
+ v-if="!item.is_read"
141
+ class="bg-primary rounded-full w-[10px] h-[10px] shrink-0"
142
+ />
143
+ </div>
144
+ </Card>
145
+ </template>
146
+ </ShadTabsContent>
147
+ </ShadTabs>
148
+ </div>
149
+ </Drawer>
150
150
  </template>
151
151
 
152
152
  <script setup>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,41 @@
1
+ <template>
2
+ <div id="google_translate_element" class="hidden" />
3
+ </template>
4
+
5
+ <script setup>
6
+ import { onMounted, nextTick } from "vue";
7
+ import { useGoogleTranslate } from "#pukaad-ui/runtime/composables/useGoogleTranslate";
8
+ const { activeLanguage, setLanguage } = useGoogleTranslate();
9
+ const initGoogleTranslate = () => {
10
+ const googleTranslate = window.google?.translate;
11
+ if (!googleTranslate?.TranslateElement) return;
12
+ new googleTranslate.TranslateElement(
13
+ {
14
+ pageLanguage: "th",
15
+ includedLanguages: "th,en",
16
+ autoDisplay: false
17
+ },
18
+ "google_translate_element"
19
+ );
20
+ nextTick(() => setLanguage(activeLanguage.value));
21
+ };
22
+ onMounted(() => {
23
+ window.googleTranslateElementInit = initGoogleTranslate;
24
+ if (window.google?.translate) {
25
+ initGoogleTranslate();
26
+ return;
27
+ }
28
+ const existingScript = document.querySelector(
29
+ 'script[src*="translate.google.com/translate_a/element.js"]'
30
+ );
31
+ if (existingScript) return;
32
+ const script = document.createElement("script");
33
+ script.src = "https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit";
34
+ script.async = true;
35
+ document.head.appendChild(script);
36
+ });
37
+ </script>
38
+
39
+ <style>
40
+ .goog-te-banner-frame.skiptranslate,iframe.skiptranslate{display:none!important}body{top:0!important}
41
+ </style>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -64,15 +64,15 @@ declare const __VLS_export: import("vue").DefineComponent<ImageCropperProps, {
64
64
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ImageCropperProps> & Readonly<{}>, {
65
65
  src: string;
66
66
  center: boolean;
67
+ background: boolean;
68
+ modal: boolean;
67
69
  responsive: boolean;
68
70
  restore: boolean;
69
71
  checkCrossOrigin: boolean;
70
72
  checkOrientation: boolean;
71
73
  crossorigin: "" | "anonymous" | "use-credentials";
72
- modal: boolean;
73
74
  guides: boolean;
74
75
  highlight: boolean;
75
- background: boolean;
76
76
  autoCrop: boolean;
77
77
  movable: boolean;
78
78
  rotatable: boolean;
@@ -64,15 +64,15 @@ declare const __VLS_export: import("vue").DefineComponent<ImageCropperProps, {
64
64
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ImageCropperProps> & Readonly<{}>, {
65
65
  src: string;
66
66
  center: boolean;
67
+ background: boolean;
68
+ modal: boolean;
67
69
  responsive: boolean;
68
70
  restore: boolean;
69
71
  checkCrossOrigin: boolean;
70
72
  checkOrientation: boolean;
71
73
  crossorigin: "" | "anonymous" | "use-credentials";
72
- modal: boolean;
73
74
  guides: boolean;
74
75
  highlight: boolean;
75
- background: boolean;
76
76
  autoCrop: boolean;
77
77
  movable: boolean;
78
78
  rotatable: boolean;
@@ -48,11 +48,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
48
48
  id: string;
49
49
  name: string;
50
50
  required: boolean;
51
- labelKey: string;
52
- placeholder: string;
53
51
  options: AutocompleteOption[] | string[] | number[];
54
52
  description: string;
55
53
  limit: number;
54
+ labelKey: string;
55
+ placeholder: string;
56
56
  disabledErrorMessage: boolean;
57
57
  disabledBorder: boolean;
58
58
  showCounter: boolean;
@@ -48,11 +48,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
48
48
  id: string;
49
49
  name: string;
50
50
  required: boolean;
51
- labelKey: string;
52
- placeholder: string;
53
51
  options: AutocompleteOption[] | string[] | number[];
54
52
  description: string;
55
53
  limit: number;
54
+ labelKey: string;
55
+ placeholder: string;
56
56
  disabledErrorMessage: boolean;
57
57
  disabledBorder: boolean;
58
58
  showCounter: boolean;
@@ -55,8 +55,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
55
55
  }>, {
56
56
  pageSize: number;
57
57
  name: string;
58
- labelKey: string;
59
58
  limit: number;
59
+ labelKey: string;
60
60
  valueKey: string;
61
61
  multiple: boolean;
62
62
  placeholderSearch: string;
@@ -55,8 +55,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
55
55
  }>, {
56
56
  pageSize: number;
57
57
  name: string;
58
- labelKey: string;
59
58
  limit: number;
59
+ labelKey: string;
60
60
  valueKey: string;
61
61
  multiple: boolean;
62
62
  placeholderSearch: string;
@@ -11,9 +11,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
11
11
  label: string;
12
12
  name: string;
13
13
  modelValue: LocalizedNameItem[];
14
- placeholder: string;
15
14
  options: InputSelectItem[];
16
15
  limit: number;
16
+ placeholder: string;
17
17
  showCounter: boolean;
18
18
  addLabel: string;
19
19
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -11,9 +11,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
11
11
  label: string;
12
12
  name: string;
13
13
  modelValue: LocalizedNameItem[];
14
- placeholder: string;
15
14
  options: InputSelectItem[];
16
15
  limit: number;
16
+ placeholder: string;
17
17
  showCounter: boolean;
18
18
  addLabel: string;
19
19
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -19,10 +19,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
19
19
  id: string;
20
20
  name: string;
21
21
  required: boolean;
22
- labelKey: string;
23
- placeholder: string;
24
22
  description: string;
25
23
  limit: number;
24
+ labelKey: string;
25
+ placeholder: string;
26
26
  disabledErrorMessage: boolean;
27
27
  disabledBorder: boolean;
28
28
  showCounter: boolean;
@@ -19,10 +19,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
19
19
  id: string;
20
20
  name: string;
21
21
  required: boolean;
22
- labelKey: string;
23
- placeholder: string;
24
22
  description: string;
25
23
  limit: number;
24
+ labelKey: string;
25
+ placeholder: string;
26
26
  disabledErrorMessage: boolean;
27
27
  disabledBorder: boolean;
28
28
  showCounter: boolean;
@@ -25,9 +25,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
25
25
  "onUpdate:modelValue"?: ((value: SelectedTag[]) => any) | undefined;
26
26
  }>, {
27
27
  name: string;
28
- placeholder: string;
29
28
  state: "user" | "admin";
30
29
  limit: number;
30
+ placeholder: string;
31
31
  ignore: string[];
32
32
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
33
33
  declare const _default: typeof __VLS_export;
@@ -25,9 +25,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
25
25
  "onUpdate:modelValue"?: ((value: SelectedTag[]) => any) | undefined;
26
26
  }>, {
27
27
  name: string;
28
- placeholder: string;
29
28
  state: "user" | "admin";
30
29
  limit: number;
30
+ placeholder: string;
31
31
  ignore: string[];
32
32
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
33
33
  declare const _default: typeof __VLS_export;
@@ -46,8 +46,8 @@ 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
  limit: number;
50
+ rows: number;
51
51
  disabledErrorMessage: boolean;
52
52
  disabledBorder: boolean;
53
53
  showCounter: boolean;
@@ -46,8 +46,8 @@ 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
  limit: number;
50
+ rows: number;
51
51
  disabledErrorMessage: boolean;
52
52
  disabledBorder: boolean;
53
53
  showCounter: boolean;
@@ -2,8 +2,6 @@ import type { HTMLAttributes } from "vue";
2
2
  export type LabelCardContentOverflow = "slide" | "ellipsis";
3
3
  export type LabelCardContentItem = {
4
4
  text: string;
5
- color: string;
6
- isSpecial?: boolean;
7
5
  };
8
6
  export interface LabelCardContentProps {
9
7
  class?: HTMLAttributes["class"];
@@ -10,12 +10,10 @@
10
10
  v-for="(item, index) in labels"
11
11
  :key="`${item.text}-${index}`"
12
12
  :class="[
13
- 'inline-flex items-center rounded-[2px] border-2 border-solid px-[6px] py-[2px] font-title-small-prominent',
14
- item.isSpecial === false ? 'bg-white' : 'text-white',
13
+ 'inline-flex items-center rounded-[2px] bg-mercury px-[4px] py-[2px] font-label-sans-serif-large',
15
14
  isEllipsis ? 'min-w-0' : 'shrink-0',
16
15
  props.clickable && 'cursor-pointer'
17
16
  ]"
18
- :style="itemStyles(item)"
19
17
  @click="props.clickable && emit('click', item)"
20
18
  >
21
19
  <span class="min-w-0 overflow-hidden text-ellipsis whitespace-nowrap">{{
@@ -70,10 +68,6 @@ const labels = computed(
70
68
  );
71
69
  const isEllipsis = computed(() => props.overflow === "ellipsis");
72
70
  const canSlide = computed(() => !isEllipsis.value);
73
- const itemStyles = (item) => {
74
- const color = item.color?.startsWith("#") ? item.color : `#${item.color}`;
75
- return item.isSpecial === false ? { color, borderColor: color } : { backgroundColor: color, borderColor: color };
76
- };
77
71
  const scroller = ref(null);
78
72
  const canScrollLeft = ref(false);
79
73
  const canScrollRight = ref(false);
@@ -2,8 +2,6 @@ import type { HTMLAttributes } from "vue";
2
2
  export type LabelCardContentOverflow = "slide" | "ellipsis";
3
3
  export type LabelCardContentItem = {
4
4
  text: string;
5
- color: string;
6
- isSpecial?: boolean;
7
5
  };
8
6
  export interface LabelCardContentProps {
9
7
  class?: HTMLAttributes["class"];
@@ -1,4 +1,4 @@
1
- import type { ModalReportProps } from "#pukaad-ui/types/components/modal/modal-report";
1
+ import type { ModalReportProps, ModalReportSubmitPayload } from "#pukaad-ui/types/components/modal/modal-report";
2
2
  type __VLS_Props = ModalReportProps;
3
3
  type __VLS_ModelProps = {
4
4
  modelValue?: boolean;
@@ -7,15 +7,9 @@ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
7
7
  declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
8
8
  "update:modelValue": (value: boolean) => any;
9
9
  } & {
10
- submit: (payload: {
11
- value: string;
12
- detail: string;
13
- }) => any;
10
+ submit: (payload: ModalReportSubmitPayload) => any;
14
11
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
15
- onSubmit?: ((payload: {
16
- value: string;
17
- detail: string;
18
- }) => any) | undefined;
12
+ onSubmit?: ((payload: ModalReportSubmitPayload) => any) | undefined;
19
13
  "onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
20
14
  }>, {
21
15
  loading: boolean;
@@ -17,33 +17,34 @@
17
17
  name="report_value"
18
18
  :label="item[0]?.label"
19
19
  :items="item"
20
- v-model="formState.report_value"
20
+ v-model="formState.selectedValue"
21
21
  />
22
22
  <div
23
- v-show="formState.report_value === item[0]?.value"
23
+ v-show="formState.selectedValue === item[0]?.value"
24
+ class="mt-[8px]"
24
25
  >
25
26
  <InputTextarea
26
27
  name="report_detail"
27
28
  rows="4"
28
29
  height-scroll
29
- placeholder="คำอธิบายประกอบการรายงาน"
30
- v-model="formState.report_detail"
30
+ :placeholder="placeholderText"
31
+ v-model="formState.description"
31
32
  />
32
33
  </div>
33
34
  </div>
34
35
  </div>
35
36
  <template #footer>
36
- <Button class="w-full" variant="outline" type="button" @click="onCancel">
37
- ยกเลิก
38
- </Button>
39
- <Button
40
- class="w-full"
41
- type="submit"
42
- color="primary"
43
- :disabled="formState.report_value === ''"
44
- >
45
- ส่ง
46
- </Button>
37
+ <Button class="w-full" variant="outline" type="button" @click="onCancel">
38
+ ยกเลิก
39
+ </Button>
40
+ <Button
41
+ class="w-full"
42
+ type="submit"
43
+ color="primary"
44
+ :disabled="formState.selectedValue === ''"
45
+ >
46
+ ส่ง
47
+ </Button>
47
48
  </template>
48
49
  </Modal>
49
50
  </template>
@@ -55,46 +56,102 @@ const props = defineProps({
55
56
  state: { type: String, required: true },
56
57
  loading: { type: Boolean, required: false, default: false }
57
58
  });
58
- const initItems = [
59
- "\u0E40\u0E19\u0E37\u0E49\u0E2D\u0E2B\u0E32\u0E44\u0E21\u0E48\u0E40\u0E01\u0E35\u0E48\u0E22\u0E27\u0E02\u0E49\u0E2D\u0E07",
60
- "\u0E2B\u0E22\u0E32\u0E1A\u0E04\u0E32\u0E22 / \u0E44\u0E21\u0E48\u0E40\u0E2B\u0E21\u0E32\u0E30\u0E2A\u0E21",
61
- "\u0E25\u0E32\u0E21\u0E01\u0E2D\u0E19\u0E32\u0E08\u0E32\u0E23",
62
- "\u0E04\u0E27\u0E32\u0E21\u0E23\u0E38\u0E19\u0E41\u0E23\u0E07",
63
- "\u0E02\u0E21\u0E02\u0E39\u0E48 \u0E04\u0E38\u0E01\u0E04\u0E32\u0E21",
64
- "\u0E01\u0E25\u0E31\u0E48\u0E19\u0E41\u0E01\u0E25\u0E49\u0E07",
65
- "\u0E2A\u0E23\u0E49\u0E32\u0E07\u0E04\u0E27\u0E32\u0E21\u0E40\u0E01\u0E25\u0E35\u0E22\u0E14\u0E0A\u0E31\u0E07\u0E2B\u0E23\u0E37\u0E2D\u0E02\u0E31\u0E14\u0E41\u0E22\u0E49\u0E07",
66
- "\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E0B\u0E49\u0E33\u0E2B\u0E23\u0E37\u0E2D\u0E2A\u0E41\u0E1B\u0E21",
67
- "\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E40\u0E17\u0E47\u0E08",
68
- "\u0E25\u0E30\u0E40\u0E21\u0E34\u0E14\u0E17\u0E23\u0E31\u0E1E\u0E22\u0E4C\u0E2A\u0E34\u0E19\u0E17\u0E32\u0E07\u0E1B\u0E31\u0E0D\u0E0D\u0E32",
69
- "\u0E25\u0E30\u0E40\u0E21\u0E34\u0E14\u0E02\u0E49\u0E2D\u0E15\u0E01\u0E25\u0E07\u0E01\u0E32\u0E23\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19",
70
- "\u0E1C\u0E34\u0E14\u0E01\u0E0E\u0E2B\u0E21\u0E32\u0E22",
71
- "\u0E2A\u0E48\u0E07\u0E1C\u0E25\u0E01\u0E23\u0E30\u0E17\u0E1A\u0E15\u0E48\u0E2D\u0E1A\u0E38\u0E04\u0E04\u0E25",
72
- "\u0E40\u0E02\u0E49\u0E32\u0E02\u0E48\u0E32\u0E22\u0E2B\u0E25\u0E2D\u0E01\u0E25\u0E27\u0E07",
73
- "\u0E2D\u0E37\u0E48\u0E19\u0E46"
59
+ const placeEditOptions = [
60
+ { label: "\u0E1B\u0E34\u0E14\u0E2B\u0E23\u0E37\u0E2D\u0E2B\u0E22\u0E38\u0E14\u0E01\u0E34\u0E08\u0E01\u0E32\u0E23\u0E41\u0E25\u0E49\u0E27", value: "closed" },
61
+ { label: "\u0E44\u0E21\u0E48\u0E2D\u0E22\u0E39\u0E48\u0E17\u0E35\u0E48\u0E19\u0E35\u0E48", value: "not_exist" },
62
+ { label: "\u0E0B\u0E49\u0E33\u0E01\u0E31\u0E1A\u0E2A\u0E16\u0E32\u0E19\u0E17\u0E35\u0E48\u0E2D\u0E37\u0E48\u0E19", value: "duplicate" },
63
+ { label: "\u0E22\u0E49\u0E32\u0E22\u0E44\u0E1B\u0E22\u0E31\u0E07\u0E15\u0E33\u0E41\u0E2B\u0E19\u0E48\u0E07\u0E17\u0E35\u0E48\u0E15\u0E31\u0E49\u0E07\u0E43\u0E2B\u0E21\u0E48\u0E41\u0E25\u0E49\u0E27", value: "relocated" },
64
+ { label: "\u0E2D\u0E37\u0E48\u0E19\u0E46", value: "other" }
65
+ ];
66
+ const placeCloseDuplicateOptions = [
67
+ { label: "\u0E1B\u0E34\u0E14\u0E2B\u0E23\u0E37\u0E2D\u0E2B\u0E22\u0E38\u0E14\u0E01\u0E34\u0E08\u0E01\u0E32\u0E23\u0E41\u0E25\u0E49\u0E27", value: "closed" },
68
+ { label: "\u0E44\u0E21\u0E48\u0E2D\u0E22\u0E39\u0E48\u0E17\u0E35\u0E48\u0E19\u0E35\u0E48", value: "not_exist" },
69
+ { label: "\u0E0B\u0E49\u0E33\u0E01\u0E31\u0E1A\u0E2A\u0E16\u0E32\u0E19\u0E17\u0E35\u0E48\u0E2D\u0E37\u0E48\u0E19", value: "duplicate" },
70
+ { label: "\u0E2D\u0E37\u0E48\u0E19\u0E46", value: "other" }
71
+ ];
72
+ const placeReportOptions = [
73
+ { label: "\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E2A\u0E16\u0E32\u0E19\u0E17\u0E35\u0E48\u0E17\u0E35\u0E48\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07", value: "invalid_info" },
74
+ { label: "\u0E2A\u0E16\u0E32\u0E19\u0E17\u0E35\u0E48\u0E19\u0E35\u0E49\u0E44\u0E21\u0E48\u0E21\u0E35\u0E2D\u0E22\u0E39\u0E48\u0E08\u0E23\u0E34\u0E07", value: "fake_place" },
75
+ { label: "\u0E2A\u0E16\u0E32\u0E19\u0E17\u0E35\u0E48\u0E0B\u0E49\u0E33", value: "duplicate_place" },
76
+ { label: "\u0E2B\u0E21\u0E27\u0E14\u0E2B\u0E21\u0E39\u0E48\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07", value: "invalid_category" },
77
+ { label: "\u0E1E\u0E34\u0E01\u0E31\u0E14\u0E2A\u0E16\u0E32\u0E19\u0E17\u0E35\u0E48\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07", value: "invalid_location" },
78
+ { label: "\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E18\u0E38\u0E23\u0E01\u0E34\u0E08\u0E40\u0E1B\u0E47\u0E19\u0E40\u0E17\u0E47\u0E08\u0E2B\u0E23\u0E37\u0E2D\u0E41\u0E2D\u0E1A\u0E2D\u0E49\u0E32\u0E07", value: "impersonation_business" },
79
+ { label: "\u0E0A\u0E37\u0E48\u0E2D\u0E2B\u0E23\u0E37\u0E2D\u0E23\u0E32\u0E22\u0E25\u0E30\u0E40\u0E2D\u0E35\u0E22\u0E14\u0E21\u0E35\u0E2A\u0E41\u0E1B\u0E21\u0E2B\u0E23\u0E37\u0E2D\u0E42\u0E06\u0E29\u0E13\u0E32", value: "spam_advertising" },
80
+ { label: "\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E2B\u0E23\u0E37\u0E2D\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E25\u0E30\u0E40\u0E21\u0E34\u0E14\u0E25\u0E34\u0E02\u0E2A\u0E34\u0E17\u0E18\u0E34\u0E4C", value: "copyright_infringement" },
81
+ { label: "\u0E40\u0E19\u0E37\u0E49\u0E2D\u0E2B\u0E32\u0E44\u0E21\u0E48\u0E40\u0E2B\u0E21\u0E32\u0E30\u0E2A\u0E21\u0E2B\u0E23\u0E37\u0E2D\u0E1C\u0E34\u0E14\u0E01\u0E0E\u0E2B\u0E21\u0E32\u0E22", value: "inappropriate_illegal" },
82
+ { label: "\u0E2D\u0E37\u0E48\u0E19\u0E46", value: "other" }
83
+ ];
84
+ const mediaOptions = [
85
+ { label: "\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E2B\u0E23\u0E37\u0E2D\u0E27\u0E34\u0E14\u0E35\u0E42\u0E2D\u0E44\u0E21\u0E48\u0E40\u0E2B\u0E21\u0E32\u0E30\u0E2A\u0E21", value: "inappropriate" },
86
+ { label: "\u0E02\u0E49\u0E2D\u0E01\u0E31\u0E07\u0E27\u0E25\u0E40\u0E01\u0E35\u0E48\u0E22\u0E27\u0E01\u0E31\u0E1A\u0E04\u0E27\u0E32\u0E21\u0E40\u0E1B\u0E47\u0E19\u0E2A\u0E48\u0E27\u0E19\u0E15\u0E31\u0E27", value: "privacy" },
87
+ { label: "\u0E04\u0E38\u0E13\u0E20\u0E32\u0E1E\u0E15\u0E48\u0E33", value: "low_quality" },
88
+ { label: "\u0E40\u0E19\u0E37\u0E49\u0E2D\u0E2B\u0E32\u0E17\u0E35\u0E48\u0E21\u0E38\u0E48\u0E07\u0E23\u0E49\u0E32\u0E22 \u0E40\u0E1B\u0E47\u0E19\u0E2D\u0E31\u0E19\u0E15\u0E23\u0E32\u0E22 \u0E2B\u0E23\u0E37\u0E2D\u0E21\u0E35\u0E04\u0E27\u0E32\u0E21\u0E23\u0E38\u0E19\u0E41\u0E23\u0E07", value: "harmful" },
89
+ { label: "\u0E44\u0E21\u0E48\u0E43\u0E0A\u0E48\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E2B\u0E23\u0E37\u0E2D\u0E27\u0E34\u0E14\u0E35\u0E42\u0E2D\u0E02\u0E2D\u0E07\u0E2A\u0E16\u0E32\u0E19\u0E17\u0E35\u0E48\u0E19\u0E35\u0E49", value: "wrong_place" },
90
+ { label: "\u0E2D\u0E37\u0E48\u0E19\u0E46", value: "other" }
91
+ ];
92
+ const reviewOptions = [
93
+ { label: "\u0E40\u0E19\u0E37\u0E49\u0E2D\u0E2B\u0E32\u0E44\u0E21\u0E48\u0E40\u0E01\u0E35\u0E48\u0E22\u0E27\u0E02\u0E49\u0E2D\u0E07", value: "irrelevant" },
94
+ { label: "\u0E2B\u0E22\u0E32\u0E1A\u0E04\u0E32\u0E22 / \u0E44\u0E21\u0E48\u0E40\u0E2B\u0E21\u0E32\u0E30\u0E2A\u0E21", value: "inappropriate" },
95
+ { label: "\u0E25\u0E32\u0E21\u0E01\u0E2D\u0E19\u0E32\u0E08\u0E32\u0E23", value: "pornographic" },
96
+ { label: "\u0E04\u0E27\u0E32\u0E21\u0E23\u0E38\u0E19\u0E41\u0E23\u0E07", value: "violence" },
97
+ { label: "\u0E02\u0E48\u0E21\u0E02\u0E39\u0E48 \u0E04\u0E38\u0E01\u0E04\u0E32\u0E21", value: "harassment" },
98
+ { label: "\u0E01\u0E25\u0E31\u0E48\u0E19\u0E41\u0E01\u0E25\u0E49\u0E07", value: "bullying" },
99
+ { label: "\u0E2A\u0E23\u0E49\u0E32\u0E07\u0E04\u0E27\u0E32\u0E21\u0E40\u0E01\u0E25\u0E35\u0E22\u0E14\u0E0A\u0E31\u0E07\u0E2B\u0E23\u0E37\u0E2D\u0E02\u0E31\u0E14\u0E41\u0E22\u0E49\u0E07", value: "hate_speech" },
100
+ { label: "\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E0B\u0E49\u0E33\u0E2B\u0E23\u0E37\u0E2D\u0E2A\u0E41\u0E1B\u0E21", value: "spam" },
101
+ { label: "\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E40\u0E17\u0E47\u0E08", value: "fake_info" },
102
+ { label: "\u0E25\u0E30\u0E40\u0E21\u0E34\u0E14\u0E17\u0E23\u0E31\u0E1E\u0E22\u0E4C\u0E2A\u0E34\u0E19\u0E17\u0E32\u0E07\u0E1B\u0E31\u0E0D\u0E0D\u0E32", value: "copyright" },
103
+ { label: "\u0E25\u0E30\u0E40\u0E21\u0E34\u0E14\u0E02\u0E49\u0E2D\u0E15\u0E01\u0E25\u0E07\u0E01\u0E32\u0E23\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19", value: "terms_violation" },
104
+ { label: "\u0E1C\u0E34\u0E14\u0E01\u0E0E\u0E2B\u0E21\u0E32\u0E22", value: "illegal" },
105
+ { label: "\u0E2A\u0E48\u0E07\u0E1C\u0E25\u0E01\u0E23\u0E30\u0E17\u0E1A\u0E15\u0E48\u0E2D\u0E1A\u0E38\u0E04\u0E04\u0E25", value: "personal_impact" },
106
+ { label: "\u0E40\u0E02\u0E49\u0E32\u0E02\u0E48\u0E32\u0E22\u0E2B\u0E25\u0E2D\u0E01\u0E25\u0E27\u0E07", value: "scam" },
107
+ { label: "\u0E2D\u0E37\u0E48\u0E19\u0E46", value: "other" }
74
108
  ];
75
109
  const title = computed(() => {
76
- if (props.state === "place") return "\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E40\u0E19\u0E37\u0E49\u0E2D\u0E2B\u0E32\u0E19\u0E35\u0E49";
77
- if (props.state === "profile") return "\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E42\u0E1B\u0E23\u0E44\u0E1F\u0E25\u0E4C\u0E19\u0E35\u0E49";
78
- if (props.state === "review") return "\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E40\u0E19\u0E37\u0E49\u0E2D\u0E2B\u0E32\u0E19\u0E35\u0E49";
79
- if (props.state === "announce") return "\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E23\u0E35\u0E27\u0E34\u0E27\u0E19\u0E35\u0E49";
80
- if (props.state === "blog") return "\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E1A\u0E25\u0E47\u0E2D\u0E01\u0E19\u0E35\u0E49";
81
- if (props.state === "comment") return "\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E04\u0E2D\u0E21\u0E40\u0E21\u0E19\u0E19\u0E35\u0E49";
82
- return "\u0E40\u0E1E\u0E34\u0E48\u0E21\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E43\u0E19 ModalReport";
110
+ if (props.state === "place-edit") return "\u0E41\u0E08\u0E49\u0E07\u0E41\u0E01\u0E49\u0E44\u0E02\u0E2A\u0E16\u0E32\u0E19\u0E17\u0E35\u0E48\u0E19\u0E35\u0E49";
111
+ if (props.state === "place-close-duplicate") return "\u0E41\u0E08\u0E49\u0E07\u0E1B\u0E34\u0E14\u0E2B\u0E23\u0E37\u0E2D\u0E0B\u0E49\u0E33";
112
+ if (props.state === "place") return "\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E2A\u0E16\u0E32\u0E19\u0E17\u0E35\u0E48\u0E19\u0E35\u0E49";
113
+ if (props.state === "media") return "\u0E41\u0E08\u0E49\u0E07\u0E41\u0E01\u0E49\u0E44\u0E02\u0E2A\u0E37\u0E48\u0E2D\u0E19\u0E35\u0E49";
114
+ if (props.state === "review") return "\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E23\u0E35\u0E27\u0E34\u0E27\u0E19\u0E35\u0E49";
115
+ return "";
116
+ });
117
+ const placeholderText = computed(() => {
118
+ if (props.state === "place" || props.state === "review") {
119
+ return "\u0E04\u0E33\u0E2D\u0E18\u0E34\u0E1A\u0E32\u0E22\u0E1B\u0E23\u0E30\u0E01\u0E2D\u0E1A\u0E01\u0E32\u0E23\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19";
120
+ }
121
+ return "\u0E04\u0E33\u0E2D\u0E18\u0E34\u0E1A\u0E32\u0E22\u0E1B\u0E23\u0E30\u0E01\u0E2D\u0E1A\u0E01\u0E32\u0E23\u0E41\u0E08\u0E49\u0E07";
83
122
  });
84
123
  const modelValue = defineModel({ type: Boolean, ...{
85
124
  default: false
86
125
  } });
87
126
  const formState = ref({
88
- report_value: "",
89
- report_detail: ""
127
+ selectedValue: "",
128
+ description: ""
129
+ });
130
+ const currentOptions = computed(() => {
131
+ if (props.state === "place-edit") {
132
+ return placeEditOptions;
133
+ }
134
+ if (props.state === "place-close-duplicate") {
135
+ return placeCloseDuplicateOptions;
136
+ }
137
+ if (props.state === "place") {
138
+ return placeReportOptions;
139
+ }
140
+ if (props.state === "media") {
141
+ return mediaOptions;
142
+ }
143
+ if (props.state === "review") {
144
+ return reviewOptions;
145
+ }
146
+ return [];
90
147
  });
91
148
  const items = computed(() => {
92
- return initItems.map((item) => [{ label: item, value: item }]);
149
+ return currentOptions.value.map((opt) => [opt]);
93
150
  });
94
151
  const reset = () => {
95
152
  formState.value = {
96
- report_value: "",
97
- report_detail: ""
153
+ selectedValue: "",
154
+ description: ""
98
155
  };
99
156
  };
100
157
  const onCancel = () => {
@@ -102,9 +159,13 @@ const onCancel = () => {
102
159
  modelValue.value = false;
103
160
  };
104
161
  const onSendReport = () => {
162
+ const selectedOpt = currentOptions.value.find(
163
+ (opt) => opt.value === formState.value.selectedValue
164
+ );
105
165
  emit("submit", {
106
- value: formState.value.report_value,
107
- detail: formState.value.report_detail
166
+ value: formState.value.selectedValue,
167
+ label: selectedOpt?.label || "",
168
+ description: formState.value.description
108
169
  });
109
170
  };
110
171
  watch(modelValue, (isOpen) => {
@@ -1,4 +1,4 @@
1
- import type { ModalReportProps } from "#pukaad-ui/types/components/modal/modal-report";
1
+ import type { ModalReportProps, ModalReportSubmitPayload } from "#pukaad-ui/types/components/modal/modal-report";
2
2
  type __VLS_Props = ModalReportProps;
3
3
  type __VLS_ModelProps = {
4
4
  modelValue?: boolean;
@@ -7,15 +7,9 @@ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
7
7
  declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
8
8
  "update:modelValue": (value: boolean) => any;
9
9
  } & {
10
- submit: (payload: {
11
- value: string;
12
- detail: string;
13
- }) => any;
10
+ submit: (payload: ModalReportSubmitPayload) => any;
14
11
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
15
- onSubmit?: ((payload: {
16
- value: string;
17
- detail: string;
18
- }) => any) | undefined;
12
+ onSubmit?: ((payload: ModalReportSubmitPayload) => any) | undefined;
19
13
  "onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
20
14
  }>, {
21
15
  loading: boolean;
@@ -12,6 +12,7 @@ declare const __VLS_export: import("vue").DefineComponent<PickerOptionMenuUserPr
12
12
  "review-reply": () => any;
13
13
  "reply-edit": () => any;
14
14
  "profile-name-updated": (name: string) => any;
15
+ "place-close-duplicate": () => any;
15
16
  "profile-edit": () => any;
16
17
  "profile-share": () => any;
17
18
  "profile-follower-delete": () => any;
@@ -19,7 +20,6 @@ declare const __VLS_export: import("vue").DefineComponent<PickerOptionMenuUserPr
19
20
  "report-blog": () => any;
20
21
  "report-place": () => any;
21
22
  "report-profile": () => any;
22
- "place-close-duplicate": () => any;
23
23
  archive: () => any;
24
24
  }, string, import("vue").PublicProps, Readonly<PickerOptionMenuUserProps> & Readonly<{
25
25
  "onBlog-edit"?: (() => any) | undefined;
@@ -34,6 +34,7 @@ declare const __VLS_export: import("vue").DefineComponent<PickerOptionMenuUserPr
34
34
  "onReview-reply"?: (() => any) | undefined;
35
35
  "onReply-edit"?: (() => any) | undefined;
36
36
  "onProfile-name-updated"?: ((name: string) => any) | undefined;
37
+ "onPlace-close-duplicate"?: (() => any) | undefined;
37
38
  "onProfile-edit"?: (() => any) | undefined;
38
39
  "onProfile-share"?: (() => any) | undefined;
39
40
  "onProfile-follower-delete"?: (() => any) | undefined;
@@ -41,7 +42,6 @@ declare const __VLS_export: import("vue").DefineComponent<PickerOptionMenuUserPr
41
42
  "onReport-blog"?: (() => any) | undefined;
42
43
  "onReport-place"?: (() => any) | undefined;
43
44
  "onReport-profile"?: (() => any) | undefined;
44
- "onPlace-close-duplicate"?: (() => any) | undefined;
45
45
  onArchive?: (() => any) | undefined;
46
46
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
47
47
  declare const _default: typeof __VLS_export;
@@ -12,6 +12,7 @@ declare const __VLS_export: import("vue").DefineComponent<PickerOptionMenuUserPr
12
12
  "review-reply": () => any;
13
13
  "reply-edit": () => any;
14
14
  "profile-name-updated": (name: string) => any;
15
+ "place-close-duplicate": () => any;
15
16
  "profile-edit": () => any;
16
17
  "profile-share": () => any;
17
18
  "profile-follower-delete": () => any;
@@ -19,7 +20,6 @@ declare const __VLS_export: import("vue").DefineComponent<PickerOptionMenuUserPr
19
20
  "report-blog": () => any;
20
21
  "report-place": () => any;
21
22
  "report-profile": () => any;
22
- "place-close-duplicate": () => any;
23
23
  archive: () => any;
24
24
  }, string, import("vue").PublicProps, Readonly<PickerOptionMenuUserProps> & Readonly<{
25
25
  "onBlog-edit"?: (() => any) | undefined;
@@ -34,6 +34,7 @@ declare const __VLS_export: import("vue").DefineComponent<PickerOptionMenuUserPr
34
34
  "onReview-reply"?: (() => any) | undefined;
35
35
  "onReply-edit"?: (() => any) | undefined;
36
36
  "onProfile-name-updated"?: ((name: string) => any) | undefined;
37
+ "onPlace-close-duplicate"?: (() => any) | undefined;
37
38
  "onProfile-edit"?: (() => any) | undefined;
38
39
  "onProfile-share"?: (() => any) | undefined;
39
40
  "onProfile-follower-delete"?: (() => any) | undefined;
@@ -41,7 +42,6 @@ declare const __VLS_export: import("vue").DefineComponent<PickerOptionMenuUserPr
41
42
  "onReport-blog"?: (() => any) | undefined;
42
43
  "onReport-place"?: (() => any) | undefined;
43
44
  "onReport-profile"?: (() => any) | undefined;
44
- "onPlace-close-duplicate"?: (() => any) | undefined;
45
45
  onArchive?: (() => any) | undefined;
46
46
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
47
47
  declare const _default: typeof __VLS_export;
@@ -0,0 +1,4 @@
1
+ export declare const useGoogleTranslate: () => {
2
+ activeLanguage: import("vue").Ref<string, string>;
3
+ setLanguage: (language: string) => void;
4
+ };
@@ -0,0 +1,42 @@
1
+ import { ref, nextTick } from "vue";
2
+ const activeLanguage = ref("th");
3
+ const GOOGLE_TRANSLATE_COOKIE = "googtrans";
4
+ const getBrowserLanguage = () => {
5
+ if (import.meta.server) return "th";
6
+ return localStorage.getItem("google_translate_language") || "th";
7
+ };
8
+ const setTranslateCookie = (language) => {
9
+ if (import.meta.server) return;
10
+ const value = language === "th" ? "" : `/th/${language}`;
11
+ const expires = "expires=Thu, 01 Jan 1970 00:00:00 GMT";
12
+ if (!value) {
13
+ document.cookie = `${GOOGLE_TRANSLATE_COOKIE}=; path=/; ${expires}`;
14
+ document.cookie = `${GOOGLE_TRANSLATE_COOKIE}=; path=/; domain=.${location.hostname}; ${expires}`;
15
+ return;
16
+ }
17
+ document.cookie = `${GOOGLE_TRANSLATE_COOKIE}=${value}; path=/`;
18
+ };
19
+ const applyGoogleTranslateLanguage = (language) => {
20
+ if (import.meta.server) return;
21
+ const select = document.querySelector(".goog-te-combo");
22
+ if (!select) return;
23
+ select.value = language;
24
+ select.dispatchEvent(new Event("change"));
25
+ };
26
+ export const useGoogleTranslate = () => {
27
+ const setLanguage = (language) => {
28
+ activeLanguage.value = language;
29
+ if (import.meta.client) {
30
+ localStorage.setItem("google_translate_language", language);
31
+ setTranslateCookie(language);
32
+ nextTick(() => applyGoogleTranslateLanguage(language));
33
+ }
34
+ };
35
+ if (import.meta.client && activeLanguage.value === "th") {
36
+ activeLanguage.value = getBrowserLanguage();
37
+ }
38
+ return {
39
+ activeLanguage,
40
+ setLanguage
41
+ };
42
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pukaad-ui-lib",
3
- "version": "1.355.0",
3
+ "version": "1.357.0",
4
4
  "description": "pukaad-ui for MeMSG",
5
5
  "repository": {
6
6
  "type": "git",