pukaad-ui-lib 1.454.0 → 1.456.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.
- package/dist/module.json +1 -1
- package/dist/runtime/components/card/card-blog.d.vue.ts +1 -1
- package/dist/runtime/components/card/card-blog.vue.d.ts +1 -1
- package/dist/runtime/components/card/card-profile/card-profile-header.d.vue.ts +1 -1
- package/dist/runtime/components/card/card-profile/card-profile-header.vue.d.ts +1 -1
- package/dist/runtime/components/card/card-reaction.d.vue.ts +1 -1
- package/dist/runtime/components/card/card-reaction.vue.d.ts +1 -1
- package/dist/runtime/components/chat/chat-conversation-item.d.vue.ts +3 -3
- package/dist/runtime/components/chat/chat-conversation-item.vue.d.ts +3 -3
- package/dist/runtime/components/display/display-video.d.vue.ts +1 -1
- package/dist/runtime/components/display/display-video.vue.d.ts +1 -1
- package/dist/runtime/components/input/input-address.d.vue.ts +1 -1
- package/dist/runtime/components/input/input-address.vue.d.ts +1 -1
- package/dist/runtime/components/input/input-autocomplete.d.vue.ts +1 -1
- package/dist/runtime/components/input/input-autocomplete.vue.d.ts +1 -1
- package/dist/runtime/components/input/input-birth-date.d.vue.ts +1 -1
- package/dist/runtime/components/input/input-birth-date.vue.d.ts +1 -1
- package/dist/runtime/components/input/input-comment.d.vue.ts +1 -1
- package/dist/runtime/components/input/input-comment.vue.d.ts +1 -1
- package/dist/runtime/components/input/input-date-picker.d.vue.ts +1 -1
- package/dist/runtime/components/input/input-date-picker.vue.d.ts +1 -1
- package/dist/runtime/components/input/input-localized-name.d.vue.ts +1 -1
- package/dist/runtime/components/input/input-localized-name.vue.d.ts +1 -1
- package/dist/runtime/components/input/input-select-place.vue +10 -3
- package/dist/runtime/components/input/input-tag-modal.d.vue.ts +1 -1
- package/dist/runtime/components/input/input-tag-modal.vue.d.ts +1 -1
- package/dist/runtime/components/input/input-tag.d.vue.ts +1 -1
- package/dist/runtime/components/input/input-tag.vue.d.ts +1 -1
- package/dist/runtime/components/modal/modal-password-confirmed.d.vue.ts +1 -1
- package/dist/runtime/components/modal/modal-password-confirmed.vue.d.ts +1 -1
- package/dist/runtime/components/modal/modal-password-verify.d.vue.ts +1 -1
- package/dist/runtime/components/modal/modal-password-verify.vue.d.ts +1 -1
- package/dist/runtime/components/preview/preview-content.d.vue.ts +8 -6
- package/dist/runtime/components/preview/preview-content.vue +203 -115
- package/dist/runtime/components/preview/preview-content.vue.d.ts +8 -6
- package/dist/runtime/components/preview/preview-place.d.vue.ts +0 -10
- package/dist/runtime/components/preview/preview-place.vue +7 -7
- package/dist/runtime/components/preview/preview-place.vue.d.ts +0 -10
- package/dist/runtime/components/ui/chart/ChartTooltipContent.d.vue.ts +1 -1
- package/dist/runtime/components/ui/chart/ChartTooltipContent.vue.d.ts +1 -1
- package/dist/runtime/components/ui/native-select/NativeSelectOptGroup.d.vue.ts +2 -2
- package/dist/runtime/components/ui/native-select/NativeSelectOptGroup.vue.d.ts +2 -2
- package/dist/runtime/components/ui/native-select/NativeSelectOption.d.vue.ts +2 -2
- package/dist/runtime/components/ui/native-select/NativeSelectOption.vue.d.ts +2 -2
- package/dist/runtime/composables/store-chat.d.ts +2 -2
- package/dist/runtime/composables/store-notification.d.ts +1 -1
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -38,8 +38,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
38
38
|
"onBlog-updated"?: ((id: string, data: any) => any) | undefined;
|
|
39
39
|
"onBlog-deleted"?: ((id: string) => any) | undefined;
|
|
40
40
|
}>, {
|
|
41
|
-
disabledMenu: boolean;
|
|
42
41
|
isMyProfile: boolean;
|
|
42
|
+
disabledMenu: boolean;
|
|
43
43
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
44
44
|
declare const _default: typeof __VLS_export;
|
|
45
45
|
export default _default;
|
|
@@ -38,8 +38,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
38
38
|
"onBlog-updated"?: ((id: string, data: any) => any) | undefined;
|
|
39
39
|
"onBlog-deleted"?: ((id: string) => any) | undefined;
|
|
40
40
|
}>, {
|
|
41
|
-
disabledMenu: boolean;
|
|
42
41
|
isMyProfile: boolean;
|
|
42
|
+
disabledMenu: boolean;
|
|
43
43
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
44
44
|
declare const _default: typeof __VLS_export;
|
|
45
45
|
export default _default;
|
|
@@ -7,8 +7,8 @@ declare const __VLS_export: import("vue").DefineComponent<CardProfileAboutProps,
|
|
|
7
7
|
onFollow?: ((isFollowing: boolean) => any) | undefined;
|
|
8
8
|
}>, {
|
|
9
9
|
type: "article" | "media" | "sale-info";
|
|
10
|
-
preview: boolean;
|
|
11
10
|
disabledPadding: boolean;
|
|
11
|
+
preview: boolean;
|
|
12
12
|
optionMenuButtonType: "solid" | "text";
|
|
13
13
|
actionsHidden: boolean;
|
|
14
14
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -7,8 +7,8 @@ declare const __VLS_export: import("vue").DefineComponent<CardProfileAboutProps,
|
|
|
7
7
|
onFollow?: ((isFollowing: boolean) => any) | undefined;
|
|
8
8
|
}>, {
|
|
9
9
|
type: "article" | "media" | "sale-info";
|
|
10
|
-
preview: boolean;
|
|
11
10
|
disabledPadding: boolean;
|
|
11
|
+
preview: boolean;
|
|
12
12
|
optionMenuButtonType: "solid" | "text";
|
|
13
13
|
actionsHidden: boolean;
|
|
14
14
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -25,7 +25,6 @@ type __VLS_Props = {
|
|
|
25
25
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
26
26
|
disabled: boolean;
|
|
27
27
|
id: string;
|
|
28
|
-
state: string;
|
|
29
28
|
itemCount: Count;
|
|
30
29
|
itemActive: Reacted;
|
|
31
30
|
padding: string | number;
|
|
@@ -33,6 +32,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
33
32
|
disabledDividerTop: boolean;
|
|
34
33
|
disabledDividerBottom: boolean;
|
|
35
34
|
iconSize: number | string;
|
|
35
|
+
state: string;
|
|
36
36
|
loginPath: string;
|
|
37
37
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
38
38
|
declare const _default: typeof __VLS_export;
|
|
@@ -25,7 +25,6 @@ type __VLS_Props = {
|
|
|
25
25
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
26
26
|
disabled: boolean;
|
|
27
27
|
id: string;
|
|
28
|
-
state: string;
|
|
29
28
|
itemCount: Count;
|
|
30
29
|
itemActive: Reacted;
|
|
31
30
|
padding: string | number;
|
|
@@ -33,6 +32,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
33
32
|
disabledDividerTop: boolean;
|
|
34
33
|
disabledDividerBottom: boolean;
|
|
35
34
|
iconSize: number | string;
|
|
35
|
+
state: string;
|
|
36
36
|
loginPath: string;
|
|
37
37
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
38
38
|
declare const _default: typeof __VLS_export;
|
|
@@ -26,13 +26,13 @@ declare const __VLS_export: import("vue").DefineComponent<ChatConversationItemPr
|
|
|
26
26
|
name: string;
|
|
27
27
|
avatar: string | null;
|
|
28
28
|
muted: boolean;
|
|
29
|
+
disabledMenu: boolean;
|
|
30
|
+
unreadCount: number;
|
|
31
|
+
pinned: boolean;
|
|
29
32
|
preview: string;
|
|
30
33
|
to: string;
|
|
31
34
|
active: boolean;
|
|
32
35
|
typing: boolean;
|
|
33
|
-
unreadCount: number;
|
|
34
|
-
pinned: boolean;
|
|
35
|
-
disabledMenu: boolean;
|
|
36
36
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
37
37
|
declare const _default: typeof __VLS_export;
|
|
38
38
|
export default _default;
|
|
@@ -26,13 +26,13 @@ declare const __VLS_export: import("vue").DefineComponent<ChatConversationItemPr
|
|
|
26
26
|
name: string;
|
|
27
27
|
avatar: string | null;
|
|
28
28
|
muted: boolean;
|
|
29
|
+
disabledMenu: boolean;
|
|
30
|
+
unreadCount: number;
|
|
31
|
+
pinned: boolean;
|
|
29
32
|
preview: string;
|
|
30
33
|
to: string;
|
|
31
34
|
active: boolean;
|
|
32
35
|
typing: boolean;
|
|
33
|
-
unreadCount: number;
|
|
34
|
-
pinned: boolean;
|
|
35
|
-
disabledMenu: boolean;
|
|
36
36
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
37
37
|
declare const _default: typeof __VLS_export;
|
|
38
38
|
export default _default;
|
|
@@ -102,9 +102,9 @@ declare const __VLS_base: import("vue").DefineComponent<DisplayVideoProps, {
|
|
|
102
102
|
loop: boolean;
|
|
103
103
|
controls: boolean;
|
|
104
104
|
preload: "none" | "metadata" | "auto";
|
|
105
|
-
playsinline: boolean;
|
|
106
105
|
sources: DisplayVideoSource[];
|
|
107
106
|
tracks: DisplayVideoTrack[];
|
|
107
|
+
playsinline: boolean;
|
|
108
108
|
disablePictureInPicture: boolean;
|
|
109
109
|
disableRemotePlayback: boolean;
|
|
110
110
|
volume: number;
|
|
@@ -102,9 +102,9 @@ declare const __VLS_base: import("vue").DefineComponent<DisplayVideoProps, {
|
|
|
102
102
|
loop: boolean;
|
|
103
103
|
controls: boolean;
|
|
104
104
|
preload: "none" | "metadata" | "auto";
|
|
105
|
-
playsinline: boolean;
|
|
106
105
|
sources: DisplayVideoSource[];
|
|
107
106
|
tracks: DisplayVideoTrack[];
|
|
107
|
+
playsinline: boolean;
|
|
108
108
|
disablePictureInPicture: boolean;
|
|
109
109
|
disableRemotePlayback: boolean;
|
|
110
110
|
volume: number;
|
|
@@ -50,8 +50,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
50
50
|
label: string;
|
|
51
51
|
name: string;
|
|
52
52
|
required: boolean;
|
|
53
|
-
layout: "vertical" | "horizontal";
|
|
54
53
|
placeholder: string;
|
|
54
|
+
layout: "vertical" | "horizontal";
|
|
55
55
|
labelDetail: string;
|
|
56
56
|
placeholderDetail: string;
|
|
57
57
|
requiredDetail: boolean;
|
|
@@ -50,8 +50,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
50
50
|
label: string;
|
|
51
51
|
name: string;
|
|
52
52
|
required: boolean;
|
|
53
|
-
layout: "vertical" | "horizontal";
|
|
54
53
|
placeholder: string;
|
|
54
|
+
layout: "vertical" | "horizontal";
|
|
55
55
|
labelDetail: string;
|
|
56
56
|
placeholderDetail: string;
|
|
57
57
|
requiredDetail: boolean;
|
|
@@ -69,9 +69,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
69
69
|
name: string;
|
|
70
70
|
required: boolean;
|
|
71
71
|
description: string;
|
|
72
|
-
options: AutocompleteOption[] | string[] | number[];
|
|
73
72
|
labelKey: string;
|
|
74
73
|
placeholder: string;
|
|
74
|
+
options: AutocompleteOption[] | string[] | number[];
|
|
75
75
|
limit: number;
|
|
76
76
|
disabledErrorMessage: boolean;
|
|
77
77
|
disabledBorder: boolean;
|
|
@@ -69,9 +69,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
69
69
|
name: string;
|
|
70
70
|
required: boolean;
|
|
71
71
|
description: string;
|
|
72
|
-
options: AutocompleteOption[] | string[] | number[];
|
|
73
72
|
labelKey: string;
|
|
74
73
|
placeholder: string;
|
|
74
|
+
options: AutocompleteOption[] | string[] | number[];
|
|
75
75
|
limit: number;
|
|
76
76
|
disabledErrorMessage: boolean;
|
|
77
77
|
disabledBorder: boolean;
|
|
@@ -30,9 +30,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
30
30
|
id: string;
|
|
31
31
|
name: string;
|
|
32
32
|
required: boolean;
|
|
33
|
-
layout: "month-and-year" | "month-only" | "year-only";
|
|
34
33
|
locale: string;
|
|
35
34
|
placeholder: string;
|
|
35
|
+
layout: "month-and-year" | "month-only" | "year-only";
|
|
36
36
|
disabledErrorMessage: boolean;
|
|
37
37
|
dateFormat: string;
|
|
38
38
|
minAge: number;
|
|
@@ -30,9 +30,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
30
30
|
id: string;
|
|
31
31
|
name: string;
|
|
32
32
|
required: boolean;
|
|
33
|
-
layout: "month-and-year" | "month-only" | "year-only";
|
|
34
33
|
locale: string;
|
|
35
34
|
placeholder: string;
|
|
35
|
+
layout: "month-and-year" | "month-only" | "year-only";
|
|
36
36
|
disabledErrorMessage: boolean;
|
|
37
37
|
dateFormat: string;
|
|
38
38
|
minAge: number;
|
|
@@ -46,11 +46,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
46
46
|
}>, {
|
|
47
47
|
loading: boolean;
|
|
48
48
|
disabled: boolean;
|
|
49
|
-
cancelText: string;
|
|
50
49
|
placeholder: string;
|
|
51
50
|
autofocus: boolean;
|
|
52
51
|
disabledAvatar: boolean;
|
|
53
52
|
submitText: string;
|
|
53
|
+
cancelText: string;
|
|
54
54
|
actionsOnFocus: boolean;
|
|
55
55
|
disabledActions: boolean;
|
|
56
56
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -46,11 +46,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
46
46
|
}>, {
|
|
47
47
|
loading: boolean;
|
|
48
48
|
disabled: boolean;
|
|
49
|
-
cancelText: string;
|
|
50
49
|
placeholder: string;
|
|
51
50
|
autofocus: boolean;
|
|
52
51
|
disabledAvatar: boolean;
|
|
53
52
|
submitText: string;
|
|
53
|
+
cancelText: string;
|
|
54
54
|
actionsOnFocus: boolean;
|
|
55
55
|
disabledActions: boolean;
|
|
56
56
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -44,9 +44,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
44
44
|
id: string;
|
|
45
45
|
name: string;
|
|
46
46
|
required: boolean;
|
|
47
|
-
layout: "month-and-year" | "month-only" | "year-only";
|
|
48
47
|
locale: string;
|
|
49
48
|
placeholder: string;
|
|
49
|
+
layout: "month-and-year" | "month-only" | "year-only";
|
|
50
50
|
disabledErrorMessage: boolean;
|
|
51
51
|
dateFormat: string;
|
|
52
52
|
showTime: boolean;
|
|
@@ -44,9 +44,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
44
44
|
id: string;
|
|
45
45
|
name: string;
|
|
46
46
|
required: boolean;
|
|
47
|
-
layout: "month-and-year" | "month-only" | "year-only";
|
|
48
47
|
locale: string;
|
|
49
48
|
placeholder: string;
|
|
49
|
+
layout: "month-and-year" | "month-only" | "year-only";
|
|
50
50
|
disabledErrorMessage: boolean;
|
|
51
51
|
dateFormat: string;
|
|
52
52
|
showTime: boolean;
|
|
@@ -11,8 +11,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
11
11
|
label: string;
|
|
12
12
|
name: string;
|
|
13
13
|
modelValue: LocalizedNameItem[];
|
|
14
|
-
options: InputSelectItem[];
|
|
15
14
|
placeholder: string;
|
|
15
|
+
options: InputSelectItem[];
|
|
16
16
|
limit: number;
|
|
17
17
|
removable: boolean;
|
|
18
18
|
showCounter: boolean;
|
|
@@ -11,8 +11,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
11
11
|
label: string;
|
|
12
12
|
name: string;
|
|
13
13
|
modelValue: LocalizedNameItem[];
|
|
14
|
-
options: InputSelectItem[];
|
|
15
14
|
placeholder: string;
|
|
15
|
+
options: InputSelectItem[];
|
|
16
16
|
limit: number;
|
|
17
17
|
removable: boolean;
|
|
18
18
|
showCounter: boolean;
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="flex flex-col gap-[4px] w-full">
|
|
2
|
+
<div class="relative flex flex-col gap-[4px] w-full">
|
|
3
3
|
<div class="font-body-large-prominent text-gray">
|
|
4
4
|
{{ props.label }}
|
|
5
5
|
<span v-if="props.required" class="text-destructive">*</span>
|
|
6
6
|
</div>
|
|
7
|
-
|
|
7
|
+
<!-- input เป็น anchor ของ popover — ห้ามซ่อนด้วย display:none (v-show) ตอนมีการเลือก ไม่งั้น anchor ไม่มี
|
|
8
|
+
ตำแหน่ง popover ลอยไปมุมซ้ายบนจอ ใช้ invisible + วางทับขอบล่างการ์ดแทน ให้เปิดจากการ์ดแล้วโผล่ใต้การ์ดพอดี -->
|
|
9
|
+
<div
|
|
10
|
+
:class="
|
|
11
|
+
selectedItems.length > 0 ? 'invisible absolute inset-x-0 bottom-0' : ''
|
|
12
|
+
"
|
|
13
|
+
>
|
|
8
14
|
<InputCombobox
|
|
9
15
|
ref="comboboxRef"
|
|
10
16
|
name="input_select_place"
|
|
@@ -96,7 +102,7 @@
|
|
|
96
102
|
</InputCombobox>
|
|
97
103
|
</div>
|
|
98
104
|
|
|
99
|
-
<!-- แสดงแทน input ตอนมีการเลือกอยู่ (input จริงยังอยู่ใน DOM
|
|
105
|
+
<!-- แสดงแทน input ตอนมีการเลือกอยู่ (input จริงยังอยู่ใน DOM แค่ซ่อนแบบ invisible ไว้ ไม่ได้ unmount — กันเสีย
|
|
100
106
|
state/ref ของ InputCombobox) คลิกที่การ์ดเปิด popover กลับมาเพื่อเลือกเพิ่ม/แก้ไขได้ ผ่าน openPopover()
|
|
101
107
|
ที่ expose ไว้ (ไม่ต้องแตะ template ของ input-combobox.vue เลย ปลอดภัยกับ component กลาง) -->
|
|
102
108
|
<div
|
|
@@ -262,6 +268,7 @@ const toggleSelect = (id) => {
|
|
|
262
268
|
}
|
|
263
269
|
if (item) selectedCache.value.set(id, item);
|
|
264
270
|
selectedIds.value = [...selectedIds.value, id];
|
|
271
|
+
comboboxRef.value?.closePopover();
|
|
265
272
|
}
|
|
266
273
|
};
|
|
267
274
|
const selectedItems = computed(
|
|
@@ -40,9 +40,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
40
40
|
id: string;
|
|
41
41
|
name: string;
|
|
42
42
|
required: boolean;
|
|
43
|
-
options: InputTagModalOption[];
|
|
44
43
|
labelKey: string;
|
|
45
44
|
placeholder: string;
|
|
45
|
+
options: InputTagModalOption[];
|
|
46
46
|
disabledErrorMessage: boolean;
|
|
47
47
|
valueKey: string;
|
|
48
48
|
searchPlaceholder: string;
|
|
@@ -40,9 +40,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
40
40
|
id: string;
|
|
41
41
|
name: string;
|
|
42
42
|
required: boolean;
|
|
43
|
-
options: InputTagModalOption[];
|
|
44
43
|
labelKey: string;
|
|
45
44
|
placeholder: string;
|
|
45
|
+
options: InputTagModalOption[];
|
|
46
46
|
disabledErrorMessage: boolean;
|
|
47
47
|
valueKey: string;
|
|
48
48
|
searchPlaceholder: string;
|
|
@@ -26,8 +26,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
26
26
|
"onUpdate:modelValue"?: ((value: SelectedTag[]) => any) | undefined;
|
|
27
27
|
}>, {
|
|
28
28
|
name: string;
|
|
29
|
-
state: "user" | "admin";
|
|
30
29
|
placeholder: string;
|
|
30
|
+
state: "user" | "admin";
|
|
31
31
|
limit: number;
|
|
32
32
|
profileScope: "personal" | "business";
|
|
33
33
|
ignore: string[];
|
|
@@ -26,8 +26,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
26
26
|
"onUpdate:modelValue"?: ((value: SelectedTag[]) => any) | undefined;
|
|
27
27
|
}>, {
|
|
28
28
|
name: string;
|
|
29
|
-
state: "user" | "admin";
|
|
30
29
|
placeholder: string;
|
|
30
|
+
state: "user" | "admin";
|
|
31
31
|
limit: number;
|
|
32
32
|
profileScope: "personal" | "business";
|
|
33
33
|
ignore: string[];
|
|
@@ -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;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { CardReferItem } from "#pukaad-ui/runtime/components/card/card-refer.vue";
|
|
2
|
-
export type PreviewContentState = "personal" | "business";
|
|
2
|
+
export type PreviewContentState = "personal" | "office" | "business";
|
|
3
|
+
export interface PreviewContentMedia {
|
|
4
|
+
id?: string | number;
|
|
5
|
+
media_type: string;
|
|
6
|
+
url: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
}
|
|
3
9
|
export interface PreviewContentData {
|
|
4
10
|
id?: string;
|
|
5
11
|
content_type?: "post_it" | "image" | "video";
|
|
@@ -11,11 +17,7 @@ export interface PreviewContentData {
|
|
|
11
17
|
cover_color?: string;
|
|
12
18
|
video_poster_url?: string;
|
|
13
19
|
description?: string;
|
|
14
|
-
media?:
|
|
15
|
-
media_type: string;
|
|
16
|
-
url: string;
|
|
17
|
-
description?: string;
|
|
18
|
-
}[];
|
|
20
|
+
media?: PreviewContentMedia[];
|
|
19
21
|
tags?: {
|
|
20
22
|
id: string;
|
|
21
23
|
name: string;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<!-- Figma: Preview - Video (2743:66169) — post_it / image ใช้โครงเดียวกัน -->
|
|
3
|
-
<div class="
|
|
3
|
+
<div class="h-screen w-full overflow-hidden bg-white flex flex-col">
|
|
4
4
|
<!-- Figma: Navbar Preview (new tab) — Property 1=Admin -->
|
|
5
|
-
|
|
6
|
-
<div class="sticky top-0 z-overlay w-full bg-cloud">
|
|
5
|
+
<div class="shrink-0 w-full bg-cloud">
|
|
7
6
|
<div class="max-w-[1280px] mx-auto flex justify-end p-[16px]">
|
|
8
7
|
<Button variant="outline" class="rounded-[6px]" @click="emit('exit')">
|
|
9
8
|
ออกจากพรีวิว
|
|
@@ -11,116 +10,131 @@
|
|
|
11
10
|
</div>
|
|
12
11
|
</div>
|
|
13
12
|
|
|
14
|
-
<!--
|
|
15
|
-
<div class="flex
|
|
16
|
-
<!--
|
|
17
|
-
<div class="
|
|
18
|
-
|
|
13
|
+
<!-- เลื่อนในกล่องนี้ ไม่พึ่ง scroll ของหน้า (บางแอปล็อก html/body ไว้) -->
|
|
14
|
+
<div class="flex-1 overflow-y-auto">
|
|
15
|
+
<!-- Figma: เนื้อหาเริ่มห่างจากแถบ 22px (ช่องว่าง 6 + padding 16) -->
|
|
16
|
+
<div class="flex justify-center px-[16px] pt-[22px] pb-[16px]">
|
|
17
|
+
<!-- กว้าง 844 เท่าวิดีโอ — DisplayVideo ยืดตามความกว้างกล่องนี้ ปุ่มเล่นจะได้อยู่กลางวิดีโอ -->
|
|
18
|
+
<div class="w-[844px] flex flex-col gap-[16px]">
|
|
19
|
+
<Label v-if="labelItems.length" :items="labelItems" />
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
<div
|
|
22
|
-
v-if="content.content_type === 'post_it'"
|
|
23
|
-
class="flex gap-[16px] py-[16px] items-center"
|
|
24
|
-
>
|
|
21
|
+
<!-- Post-it -->
|
|
25
22
|
<div
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
v-if="contentData.content_type === 'post_it'"
|
|
24
|
+
class="flex gap-[16px] py-[16px] items-center"
|
|
25
|
+
>
|
|
26
|
+
<div
|
|
27
|
+
class="w-[6px] h-full shrink-0"
|
|
28
|
+
:style="{ backgroundColor: contentData.cover_color }"
|
|
29
|
+
/>
|
|
30
|
+
<div class="font-headline-large-prominent min-w-0 break-words">
|
|
31
|
+
{{ contentData.cover_text }}
|
|
32
|
+
</div>
|
|
31
33
|
</div>
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
/>
|
|
34
|
+
<!-- Image -->
|
|
35
|
+
<DisplayImage
|
|
36
|
+
v-else-if="contentData.content_type === 'image'"
|
|
37
|
+
:items="contentData.media"
|
|
38
|
+
item-src="url"
|
|
39
|
+
/>
|
|
40
|
+
<!-- Video -->
|
|
41
|
+
<DisplayVideo
|
|
42
|
+
v-else-if="contentData.content_type === 'video'"
|
|
43
|
+
:src="contentData.media?.[0]?.url"
|
|
44
|
+
:poster="contentData.video_poster_url"
|
|
45
|
+
play-button
|
|
46
|
+
width="844"
|
|
47
|
+
height="475"
|
|
48
|
+
preload="metadata"
|
|
49
|
+
class="bg-black"
|
|
50
|
+
/>
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
<CardRefer
|
|
53
|
+
v-if="contentData.mentions?.[0]"
|
|
54
|
+
:item="contentData.mentions[0]"
|
|
55
|
+
/>
|
|
52
56
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
</div>
|
|
64
|
-
<div class="flex gap-[8px] font-body-large">
|
|
65
|
-
<div class="flex gap-[4px]">
|
|
66
|
-
<span class="text-gray">ผู้ติดตาม</span>
|
|
67
|
-
{{ convertNumber(content.author.follower_count ?? 0) }}
|
|
68
|
-
</div>
|
|
69
|
-
<div class="flex gap-[4px]">
|
|
70
|
-
<span class="text-gray">กำลังเผยแพร่</span>
|
|
71
|
-
{{ convertNumber(content.author.published_count ?? 0) }}
|
|
57
|
+
<!-- Figma: Announce Description -->
|
|
58
|
+
<div
|
|
59
|
+
v-if="contentData.author"
|
|
60
|
+
class="flex items-center justify-between gap-[16px]"
|
|
61
|
+
>
|
|
62
|
+
<div class="flex items-center gap-[8px] min-w-0">
|
|
63
|
+
<Avatar :src="contentData.author.avatar ?? ''" :size="40" />
|
|
64
|
+
<div class="flex flex-col gap-[4px] min-w-0">
|
|
65
|
+
<div class="font-body-large-prominent truncate">
|
|
66
|
+
{{ contentData.author.name }}
|
|
72
67
|
</div>
|
|
73
|
-
<div
|
|
74
|
-
|
|
75
|
-
|
|
68
|
+
<div
|
|
69
|
+
v-if="authorStats.length"
|
|
70
|
+
class="flex gap-[8px] font-body-large"
|
|
71
|
+
>
|
|
72
|
+
<div
|
|
73
|
+
v-for="stat in authorStats"
|
|
74
|
+
:key="stat.label"
|
|
75
|
+
class="flex gap-[4px]"
|
|
76
|
+
>
|
|
77
|
+
<span class="text-gray">{{ stat.label }}</span>
|
|
78
|
+
{{ stat.value }}
|
|
79
|
+
</div>
|
|
76
80
|
</div>
|
|
77
81
|
</div>
|
|
78
82
|
</div>
|
|
83
|
+
<!-- พรีวิว = ดูหน้าตาได้แต่กดไม่ได้ -->
|
|
84
|
+
<Button circle size="icon-sm" class="shrink-0" inert>
|
|
85
|
+
<Icon name="lucide:ellipsis-vertical" />
|
|
86
|
+
</Button>
|
|
79
87
|
</div>
|
|
80
|
-
<!-- พรีวิว = ดูหน้าตาได้แต่กดไม่ได้ -->
|
|
81
|
-
<Button circle size="icon-sm" class="shrink-0" inert>
|
|
82
|
-
<Icon name="lucide:ellipsis-vertical" />
|
|
83
|
-
</Button>
|
|
84
|
-
</div>
|
|
85
88
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
<div
|
|
90
|
+
v-if="contentData.description"
|
|
91
|
+
class="font-body-large whitespace-pre-wrap"
|
|
92
|
+
>
|
|
93
|
+
{{ contentData.description }}
|
|
94
|
+
</div>
|
|
92
95
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
<div v-if="place" class="flex gap-[8px] font-body-large">
|
|
97
|
+
<span class="text-gray">อยู่ที่</span>
|
|
98
|
+
<span class="text-primary">{{ place.name }}</span>
|
|
99
|
+
</div>
|
|
97
100
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
<div v-if="contentData.tags?.length" class="flex flex-wrap gap-[8px]">
|
|
102
|
+
<Chip v-for="tag in contentData.tags" :key="tag.id" color="bright">
|
|
103
|
+
{{ tag.name }}
|
|
104
|
+
</Chip>
|
|
105
|
+
</div>
|
|
103
106
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
liked:
|
|
107
|
-
bookmarked:
|
|
108
|
-
shared:
|
|
107
|
+
<CardReaction
|
|
108
|
+
:item-count="{
|
|
109
|
+
liked: contentData.like_count ?? 0,
|
|
110
|
+
bookmarked: contentData.bookmark_count ?? 0,
|
|
111
|
+
shared: contentData.share_count ?? 0
|
|
109
112
|
}"
|
|
110
|
-
|
|
111
|
-
|
|
113
|
+
disabled
|
|
114
|
+
/>
|
|
112
115
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
116
|
+
<!-- Figma: Spotlight -->
|
|
117
|
+
<div v-if="recommendedContents.length" inert>
|
|
118
|
+
<CardContentRecommend :items="recommendedContents" />
|
|
119
|
+
</div>
|
|
117
120
|
|
|
118
|
-
|
|
119
|
-
<
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
<!-- ส่งรายการเข้าไปเอง (ไม่ใช้ fetchFn) เพราะ fetchFn โหลดหน้าถัดไปจาก window scroll -->
|
|
122
|
+
<div inert>
|
|
123
|
+
<Comment
|
|
124
|
+
:comments="comments"
|
|
125
|
+
:comment-count="commentTotal"
|
|
126
|
+
:current-user="previewUser"
|
|
127
|
+
/>
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
<div ref="sentinel" class="h-[1px]" />
|
|
131
|
+
<div v-if="isLoadingComments" class="flex justify-center py-[16px]">
|
|
132
|
+
<Icon
|
|
133
|
+
name="lucide:loader-circle"
|
|
134
|
+
:size="40"
|
|
135
|
+
class="animate-spin text-cloud"
|
|
136
|
+
/>
|
|
137
|
+
</div>
|
|
124
138
|
</div>
|
|
125
139
|
</div>
|
|
126
140
|
</div>
|
|
@@ -128,7 +142,8 @@
|
|
|
128
142
|
</template>
|
|
129
143
|
|
|
130
144
|
<script setup>
|
|
131
|
-
import { computed, onMounted, ref, watch } from "vue";
|
|
145
|
+
import { computed, onMounted, ref, useTemplateRef, watch } from "vue";
|
|
146
|
+
import { useElementVisibility } from "@vueuse/core";
|
|
132
147
|
import { useApi } from "#pukaad-ui/runtime/composables/useApi";
|
|
133
148
|
import { useConvert } from "#pukaad-ui/runtime/composables/useConvert";
|
|
134
149
|
import { mapContentToCard } from "#pukaad-ui/runtime/composables/useContentCard";
|
|
@@ -141,24 +156,73 @@ const api = useApi();
|
|
|
141
156
|
const { convertNumber } = useConvert();
|
|
142
157
|
const endpointMap = {
|
|
143
158
|
personal: "/contents",
|
|
159
|
+
// endpoint เดียวกับที่หน้าจัดการป้ายกำกับเนื้อหาของ office ใช้
|
|
160
|
+
office: "/office/content-labels/contents",
|
|
144
161
|
business: "/business/contents"
|
|
145
162
|
};
|
|
146
|
-
const
|
|
163
|
+
const endpoint = computed(() => endpointMap[props.state]);
|
|
164
|
+
const contentData = ref({});
|
|
147
165
|
const recommendedContents = ref([]);
|
|
166
|
+
const comments = ref([]);
|
|
167
|
+
const commentTotal = ref(0);
|
|
168
|
+
const commentPage = ref(1);
|
|
169
|
+
const commentTotalPages = ref(1);
|
|
170
|
+
const commentPageSize = 20;
|
|
171
|
+
const isLoadingComments = ref(false);
|
|
172
|
+
const hasMoreComments = computed(
|
|
173
|
+
() => commentPage.value < commentTotalPages.value
|
|
174
|
+
);
|
|
148
175
|
const previewUser = { id: "", name: "", avatar: "" };
|
|
149
176
|
const labelItems = computed(
|
|
150
|
-
() => (
|
|
177
|
+
() => (contentData.value.labels ?? []).map((label) => ({
|
|
151
178
|
id: label.id,
|
|
152
179
|
label: label.name
|
|
153
180
|
}))
|
|
154
181
|
);
|
|
155
|
-
const place = computed(() =>
|
|
156
|
-
const
|
|
182
|
+
const place = computed(() => contentData.value.places?.[0]);
|
|
183
|
+
const authorStats = computed(() => {
|
|
184
|
+
const author = contentData.value.author;
|
|
185
|
+
const stats = [];
|
|
186
|
+
if (author?.follower_count !== void 0) {
|
|
187
|
+
stats.push({
|
|
188
|
+
label: "\u0E1C\u0E39\u0E49\u0E15\u0E34\u0E14\u0E15\u0E32\u0E21",
|
|
189
|
+
value: convertNumber(author.follower_count)
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
if (author?.published_count !== void 0) {
|
|
193
|
+
stats.push({
|
|
194
|
+
label: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E40\u0E1C\u0E22\u0E41\u0E1E\u0E23\u0E48",
|
|
195
|
+
value: convertNumber(author.published_count)
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
if (author?.response_rate !== void 0) {
|
|
199
|
+
stats.push({ label: "\u0E2D\u0E31\u0E15\u0E23\u0E32\u0E15\u0E2D\u0E1A\u0E41\u0E0A\u0E17", value: `${author.response_rate}%` });
|
|
200
|
+
}
|
|
201
|
+
return stats;
|
|
202
|
+
});
|
|
203
|
+
const fromOfficeContent = (data) => {
|
|
204
|
+
if (!data?.content) return {};
|
|
205
|
+
const { profile_name, profile_avatar, ...rest } = data.content;
|
|
206
|
+
return {
|
|
207
|
+
...rest,
|
|
208
|
+
media: data.media,
|
|
209
|
+
author: {
|
|
210
|
+
id: "",
|
|
211
|
+
name: profile_name ?? "",
|
|
212
|
+
avatar: profile_avatar ?? null
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
const fetchContentData = async () => {
|
|
217
|
+
const url = `${endpoint.value}/${props.contentId}`;
|
|
157
218
|
try {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
219
|
+
if (props.state === "office") {
|
|
220
|
+
const res = await api(url);
|
|
221
|
+
contentData.value = fromOfficeContent(res.data);
|
|
222
|
+
} else {
|
|
223
|
+
const res = await api(url);
|
|
224
|
+
contentData.value = res.data ?? {};
|
|
225
|
+
}
|
|
162
226
|
} catch (err) {
|
|
163
227
|
console.error(err);
|
|
164
228
|
}
|
|
@@ -200,20 +264,44 @@ const toCommentItem = (raw) => ({
|
|
|
200
264
|
is_liked: r.is_liked ?? false
|
|
201
265
|
}))
|
|
202
266
|
});
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
267
|
+
let commentRequestId = 0;
|
|
268
|
+
const fetchComments = async (page = 1) => {
|
|
269
|
+
if (page > 1 && isLoadingComments.value) return;
|
|
270
|
+
const requestId = ++commentRequestId;
|
|
271
|
+
isLoadingComments.value = true;
|
|
272
|
+
try {
|
|
273
|
+
const res = await api(`/contents/${props.contentId}/comments`, {
|
|
274
|
+
query: {
|
|
275
|
+
limit: commentPageSize,
|
|
276
|
+
offset: (page - 1) * commentPageSize
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
if (requestId !== commentRequestId) return;
|
|
280
|
+
const items = (res.data ?? []).map(toCommentItem);
|
|
281
|
+
comments.value = page === 1 ? items : [...comments.value, ...items];
|
|
282
|
+
commentTotal.value = res.meta?.total_comments ?? 0;
|
|
283
|
+
commentTotalPages.value = res.meta?.total_pages ?? 1;
|
|
284
|
+
commentPage.value = page;
|
|
285
|
+
} catch (err) {
|
|
286
|
+
console.error(err);
|
|
287
|
+
if (requestId === commentRequestId && page === 1) comments.value = [];
|
|
288
|
+
} finally {
|
|
289
|
+
if (requestId === commentRequestId) isLoadingComments.value = false;
|
|
290
|
+
}
|
|
212
291
|
};
|
|
213
292
|
const loadAll = () => {
|
|
214
|
-
|
|
293
|
+
fetchContentData();
|
|
215
294
|
fetchRecommendations();
|
|
295
|
+
fetchComments(1);
|
|
216
296
|
};
|
|
297
|
+
const sentinel = useTemplateRef("sentinel");
|
|
298
|
+
const isSentinelVisible = useElementVisibility(sentinel);
|
|
299
|
+
watch(
|
|
300
|
+
[isSentinelVisible, hasMoreComments, isLoadingComments],
|
|
301
|
+
([visible, more, loading]) => {
|
|
302
|
+
if (visible && more && !loading) fetchComments(commentPage.value + 1);
|
|
303
|
+
}
|
|
304
|
+
);
|
|
217
305
|
watch(() => [props.contentId, props.state], loadAll);
|
|
218
306
|
onMounted(loadAll);
|
|
219
307
|
</script>
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { CardReferItem } from "#pukaad-ui/runtime/components/card/card-refer.vue";
|
|
2
|
-
export type PreviewContentState = "personal" | "business";
|
|
2
|
+
export type PreviewContentState = "personal" | "office" | "business";
|
|
3
|
+
export interface PreviewContentMedia {
|
|
4
|
+
id?: string | number;
|
|
5
|
+
media_type: string;
|
|
6
|
+
url: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
}
|
|
3
9
|
export interface PreviewContentData {
|
|
4
10
|
id?: string;
|
|
5
11
|
content_type?: "post_it" | "image" | "video";
|
|
@@ -11,11 +17,7 @@ export interface PreviewContentData {
|
|
|
11
17
|
cover_color?: string;
|
|
12
18
|
video_poster_url?: string;
|
|
13
19
|
description?: string;
|
|
14
|
-
media?:
|
|
15
|
-
media_type: string;
|
|
16
|
-
url: string;
|
|
17
|
-
description?: string;
|
|
18
|
-
}[];
|
|
20
|
+
media?: PreviewContentMedia[];
|
|
19
21
|
tags?: {
|
|
20
22
|
id: string;
|
|
21
23
|
name: string;
|
|
@@ -31,19 +31,10 @@ export interface PreviewPlaceData {
|
|
|
31
31
|
opening_hours?: OpeningHour[];
|
|
32
32
|
special_days?: SpecialDay[];
|
|
33
33
|
}
|
|
34
|
-
export interface PreviewPlaceRecommendItem {
|
|
35
|
-
id: string | number;
|
|
36
|
-
title: string;
|
|
37
|
-
image: string;
|
|
38
|
-
rating: number;
|
|
39
|
-
review_count: number;
|
|
40
|
-
}
|
|
41
34
|
type __VLS_Props = {
|
|
42
35
|
placeId: string | number;
|
|
43
36
|
/** เลือก endpoint ตามแอปที่เปิดพรีวิว */
|
|
44
37
|
state?: PreviewPlaceState;
|
|
45
|
-
/** "ที่ไหนน่าสนใจ" — ยังไม่มี API ให้แอปส่งมาเอง ไม่ส่ง = ซ่อนการ์ด */
|
|
46
|
-
recommendedPlaces?: PreviewPlaceRecommendItem[];
|
|
47
38
|
};
|
|
48
39
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
49
40
|
exit: () => any;
|
|
@@ -51,7 +42,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
51
42
|
onExit?: (() => any) | undefined;
|
|
52
43
|
}>, {
|
|
53
44
|
state: PreviewPlaceState;
|
|
54
|
-
recommendedPlaces: PreviewPlaceRecommendItem[];
|
|
55
45
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
56
46
|
declare const _default: typeof __VLS_export;
|
|
57
47
|
export default _default;
|
|
@@ -4,10 +4,13 @@
|
|
|
4
4
|
<!-- Figma: Navbar Preview (new tab) — Property 1=Admin -->
|
|
5
5
|
<div class="shrink-0 w-full bg-cloud">
|
|
6
6
|
<div class="max-w-[1280px] mx-auto flex justify-end p-[16px]">
|
|
7
|
-
<Button variant="outline" @click="emit('exit')"
|
|
7
|
+
<Button variant="outline" class="rounded-[6px]" @click="emit('exit')">
|
|
8
|
+
ออกจากพรีวิว
|
|
9
|
+
</Button>
|
|
8
10
|
</div>
|
|
9
11
|
</div>
|
|
10
12
|
|
|
13
|
+
<!-- เลื่อนในกล่องนี้ ไม่พึ่ง scroll ของหน้า (บางแอปล็อก html/body ไว้) -->
|
|
11
14
|
<div class="flex-1 overflow-y-auto">
|
|
12
15
|
<div class="max-w-[1280px] mx-auto p-[16px] flex flex-col gap-[16px]">
|
|
13
16
|
<!-- Place Cover -->
|
|
@@ -181,12 +184,10 @@
|
|
|
181
184
|
</div>
|
|
182
185
|
</div>
|
|
183
186
|
|
|
184
|
-
<!-- ขวา: Place About
|
|
187
|
+
<!-- ขวา: Place About -->
|
|
188
|
+
<!-- TODO: "ที่ไหนน่าสนใจ" (Figma: Reccommended Places) — ยังไม่มี API -->
|
|
185
189
|
<div class="w-[380px] shrink-0 flex flex-col gap-[16px]">
|
|
186
190
|
<CardPlaceDetail :item="placeDetailItem" />
|
|
187
|
-
<div v-if="props.recommendedPlaces.length > 0" inert>
|
|
188
|
-
<CardRecommendPlace :items="props.recommendedPlaces" />
|
|
189
|
-
</div>
|
|
190
191
|
</div>
|
|
191
192
|
</div>
|
|
192
193
|
</div>
|
|
@@ -201,8 +202,7 @@ import { useApi } from "#pukaad-ui/runtime/composables/useApi";
|
|
|
201
202
|
import { useConvert } from "#pukaad-ui/runtime/composables/useConvert";
|
|
202
203
|
const props = defineProps({
|
|
203
204
|
placeId: { type: [String, Number], required: true },
|
|
204
|
-
state: { type: String, required: false, default: "personal" }
|
|
205
|
-
recommendedPlaces: { type: Array, required: false, default: () => [] }
|
|
205
|
+
state: { type: String, required: false, default: "personal" }
|
|
206
206
|
});
|
|
207
207
|
const emit = defineEmits(["exit"]);
|
|
208
208
|
const api = useApi();
|
|
@@ -31,19 +31,10 @@ export interface PreviewPlaceData {
|
|
|
31
31
|
opening_hours?: OpeningHour[];
|
|
32
32
|
special_days?: SpecialDay[];
|
|
33
33
|
}
|
|
34
|
-
export interface PreviewPlaceRecommendItem {
|
|
35
|
-
id: string | number;
|
|
36
|
-
title: string;
|
|
37
|
-
image: string;
|
|
38
|
-
rating: number;
|
|
39
|
-
review_count: number;
|
|
40
|
-
}
|
|
41
34
|
type __VLS_Props = {
|
|
42
35
|
placeId: string | number;
|
|
43
36
|
/** เลือก endpoint ตามแอปที่เปิดพรีวิว */
|
|
44
37
|
state?: PreviewPlaceState;
|
|
45
|
-
/** "ที่ไหนน่าสนใจ" — ยังไม่มี API ให้แอปส่งมาเอง ไม่ส่ง = ซ่อนการ์ด */
|
|
46
|
-
recommendedPlaces?: PreviewPlaceRecommendItem[];
|
|
47
38
|
};
|
|
48
39
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
49
40
|
exit: () => any;
|
|
@@ -51,7 +42,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
51
42
|
onExit?: (() => any) | undefined;
|
|
52
43
|
}>, {
|
|
53
44
|
state: PreviewPlaceState;
|
|
54
|
-
recommendedPlaces: PreviewPlaceRecommendItem[];
|
|
55
45
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
56
46
|
declare const _default: typeof __VLS_export;
|
|
57
47
|
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
|
-
payload: Record<string, any>;
|
|
22
21
|
config: ChartConfig;
|
|
22
|
+
payload: Record<string, any>;
|
|
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
|
-
payload: Record<string, any>;
|
|
22
21
|
config: ChartConfig;
|
|
22
|
+
payload: Record<string, any>;
|
|
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" | "
|
|
17
|
+
enterKeyHint?: "search" | "done" | "next" | "send" | "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" | "
|
|
211
|
+
enterKeyHint?: "search" | "done" | "next" | "send" | "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" | "
|
|
17
|
+
enterKeyHint?: "search" | "done" | "next" | "send" | "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" | "
|
|
211
|
+
enterKeyHint?: "search" | "done" | "next" | "send" | "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" | "
|
|
19
|
+
enterKeyHint?: "search" | "done" | "next" | "send" | "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" | "
|
|
215
|
+
enterKeyHint?: "search" | "done" | "next" | "send" | "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" | "
|
|
19
|
+
enterKeyHint?: "search" | "done" | "next" | "send" | "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" | "
|
|
215
|
+
enterKeyHint?: "search" | "done" | "next" | "send" | "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;
|
|
@@ -121,7 +121,7 @@ export declare const useChatStore: import("pinia").StoreDefinition<"pukaad-chat"
|
|
|
121
121
|
startRealtime: () => void;
|
|
122
122
|
stopRealtime: () => void;
|
|
123
123
|
resync: (activeConversationId?: string) => Promise<void>;
|
|
124
|
-
}, "headers" | "conversations" | "unreadFirst" | "hasMoreConversations" | "hasLoadedConversations" | "isLoadingConversations" | "peerLastRead" | "messages" | "hasOlder" | "isLoadingOlder" | "
|
|
124
|
+
}, "headers" | "isConnected" | "conversations" | "unreadFirst" | "hasMoreConversations" | "hasLoadedConversations" | "isLoadingConversations" | "peerLastRead" | "messages" | "hasOlder" | "isLoadingOlder" | "unreadChatCount">, Pick<{
|
|
125
125
|
conversations: import("vue").Ref<{
|
|
126
126
|
id: string;
|
|
127
127
|
profile: {
|
|
@@ -365,4 +365,4 @@ export declare const useChatStore: import("pinia").StoreDefinition<"pukaad-chat"
|
|
|
365
365
|
startRealtime: () => void;
|
|
366
366
|
stopRealtime: () => void;
|
|
367
367
|
resync: (activeConversationId?: string) => Promise<void>;
|
|
368
|
-
}, "reset" | "setUnreadFirst" | "setMyProfileId" | "fetchConversations" | "fetchConversation" | "fetchLatestMessages" | "fetchOlderMessages" | "sendMessage" | "sendMedia" | "retryMessage" | "
|
|
368
|
+
}, "reset" | "markRead" | "setUnreadFirst" | "setMyProfileId" | "fetchConversations" | "fetchConversation" | "fetchLatestMessages" | "fetchOlderMessages" | "sendMessage" | "sendMedia" | "retryMessage" | "isReadByPeer" | "unreadCountOf" | "startUnreadBadge" | "stopUnreadBadge" | "previewOf" | "sendTyping" | "isPeerTyping" | "deleteMessage" | "startRealtime" | "stopRealtime" | "resync">>;
|
|
@@ -215,4 +215,4 @@ export declare const useNotificationStore: import("pinia").StoreDefinition<"noti
|
|
|
215
215
|
openDrawer: () => void;
|
|
216
216
|
closeDrawer: () => void;
|
|
217
217
|
toggleDrawer: () => void;
|
|
218
|
-
}, "
|
|
218
|
+
}, "fetchList" | "loadMore" | "prefetch" | "markRead" | "markAllRead" | "fetchUnreadCount" | "initRealtime" | "closeRealtime" | "setUnreadCount" | "openDrawer" | "closeDrawer" | "toggleDrawer">>;
|