@phonghq/go-chat 1.0.11 → 1.0.14
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/assets/icons/IconAiCheck.vue.d.ts +2 -0
- package/dist/assets/icons/call/IconClose.vue.d.ts +2 -0
- package/dist/assets/icons/call/IconSoundDownload.vue.d.ts +2 -0
- package/dist/chat/App.vue.d.ts +7 -2
- package/dist/chat/page/customer-detail/CustomerDetail.vue.d.ts +1 -1
- package/dist/chat/page/home/ChatList.vue.d.ts +29 -1
- package/dist/chat/page/home/ChatMessage.vue.d.ts +2 -1
- package/dist/chat/page/home/Home.vue.d.ts +1 -1
- package/dist/components/chat/ScrollEvent/ScrollEvent.vue.d.ts +1 -0
- package/dist/components/chat/call/Calling.vue.d.ts +8 -2
- package/dist/components/chat/common/input/InputSearch.vue.d.ts +1 -1
- package/dist/components/chat/select/SelectBase.vue.d.ts +22 -0
- package/dist/components/common/drawer/DrawerBase.vue.d.ts +1 -1
- package/dist/components/common/modal/ModalBase.vue.d.ts +1 -1
- package/dist/composable/useCallHelper.d.ts +7 -2
- package/dist/composable/useInitData.d.ts +2 -4
- package/dist/composable/usePlivo.d.ts +9 -0
- package/dist/go-chat.es.js +14676 -12322
- package/dist/go-chat.umd.js +44 -14
- package/dist/plugins/websocket.d.ts +12 -2
- package/dist/router/index.d.ts +2 -0
- package/dist/style.css +1 -1
- package/dist/test/assets/icons/IconAiCheck.vue.js +28 -0
- package/dist/test/assets/icons/call/IconClose.vue.js +26 -0
- package/dist/test/assets/icons/call/IconMic.vue.js +9 -9
- package/dist/test/assets/icons/call/IconSoundDownload.vue.js +50 -0
- package/dist/test/chat/App.vue.js +144 -90
- package/dist/test/chat/page/customer-detail/CustomerDetail.vue.js +6 -5
- package/dist/test/chat/page/home/ChatList.vue.js +30 -9
- package/dist/test/chat/page/home/ChatMessage.vue.js +23 -12
- package/dist/test/chat/page/home/Home.vue.js +4 -3
- package/dist/test/chat/page/home/NewCustomer.vue.js +0 -12
- package/dist/test/components/chat/ScrollEvent/ScrollEvent.vue.js +7 -1
- package/dist/test/components/chat/call/Calling.vue.js +277 -111
- package/dist/test/components/chat/common/input/InputSearch.vue.js +2 -2
- package/dist/test/components/chat/select/SelectBase.vue.js +98 -0
- package/dist/test/components/common/drawer/DrawerBaseCustom.vue.js +0 -1
- package/dist/test/composable/data.json +32 -0
- package/dist/test/composable/useCallHelper.js +146 -33
- package/dist/test/composable/useDigibot.js +1 -1
- package/dist/test/composable/useInitData.js +17 -12
- package/dist/test/composable/usePlivo.js +138 -0
- package/dist/test/constant/color.js +1 -1
- package/dist/test/plugins/axios.js +2 -1
- package/dist/test/plugins/mqtt.js +11 -8
- package/dist/test/plugins/websocket.js +108 -19
- package/dist/test/router/index.js +39 -0
- package/dist/test/types/call.js +10 -1
- package/dist/test/utils/chat/auth.js +10 -2
- package/dist/test/utils/chat/call.js +48 -8
- package/dist/test/utils/chat/phone-string.js +4 -0
- package/dist/test/utils/chat/user.js +7 -2
- package/dist/test/views/NotFound.vue.js +47 -0
- package/dist/test/views/TenantPhone.vue.js +270 -0
- package/dist/types/call.d.ts +9 -0
- package/dist/types/chat/global.d.ts +4 -0
- package/dist/utils/chat/auth.d.ts +5 -1
- package/dist/utils/chat/call.d.ts +6 -2
- package/dist/utils/chat/phone-string.d.ts +1 -0
- package/dist/utils/chat/user.d.ts +4 -0
- package/dist/views/NotFound.vue.d.ts +2 -0
- package/dist/views/TenantPhone.vue.d.ts +2 -0
- package/package.json +2 -1
- package/dist/composable/TestSound.d.ts +0 -64
- package/dist/test/composable/TestSound.js +0 -196
|
@@ -1,24 +1,43 @@
|
|
|
1
1
|
import { tryParseJson } from '../utils/json';
|
|
2
|
+
import { dataProfile } from '../utils/chat/auth';
|
|
2
3
|
let socket = null;
|
|
3
4
|
let dataCallBack = [];
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
5
|
+
let callId = '';
|
|
6
|
+
// const BASE_URL = 'wss://web-socket.dev01.dtsmart.dev/web-stream'
|
|
7
|
+
const BASE_URL = 'wss://web-socket-test.dev01.dtsmart.dev/web-stream';
|
|
8
|
+
const BARE_URL_INBOUND = 'https://web-socket.dev01.dtsmart.dev';
|
|
9
|
+
export function initWebSocket() {
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
if (socket && socket.readyState === 1) {
|
|
12
|
+
console.log("WebSocket đã kết nối, bỏ qua connect.");
|
|
13
|
+
resolve('Connected');
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const timer = setTimeout(() => {
|
|
17
|
+
socket?.close?.();
|
|
18
|
+
reject(new Error("WebSocket connection timeout"));
|
|
19
|
+
}, 5000);
|
|
20
|
+
// socket = new WebSocket('wss://' + callId)
|
|
21
|
+
socket = new WebSocket(BASE_URL);
|
|
22
|
+
socket.binaryType = 'arraybuffer';
|
|
23
|
+
socket.onopen = (event) => {
|
|
24
|
+
clearTimeout(timer);
|
|
25
|
+
resolve('Connected');
|
|
26
|
+
};
|
|
27
|
+
socket.onmessage = (event) => {
|
|
28
|
+
const data = tryParseJson(event.data);
|
|
29
|
+
dataCallBack.forEach((e) => {
|
|
30
|
+
e.callBack(data);
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
socket.onclose = (event) => {
|
|
34
|
+
console.log('Disconnected:', event.reason);
|
|
35
|
+
};
|
|
36
|
+
socket.onerror = (event) => {
|
|
37
|
+
console.error('Socket error:', event);
|
|
38
|
+
reject(event);
|
|
39
|
+
};
|
|
40
|
+
});
|
|
22
41
|
}
|
|
23
42
|
export const socketSend = (data) => {
|
|
24
43
|
try {
|
|
@@ -35,9 +54,10 @@ export const getWebSocket = async () => {
|
|
|
35
54
|
const response = await fetch(url, {
|
|
36
55
|
method: 'POST',
|
|
37
56
|
body: JSON.stringify({
|
|
38
|
-
clientId:
|
|
57
|
+
clientId: dataProfile.value?.tenant_id
|
|
39
58
|
}),
|
|
40
59
|
headers: {
|
|
60
|
+
"Content-Type": "application/json",
|
|
41
61
|
Authorization: 'Bearer -Qixt-ZztiBA5Dxl-EIWG7f2TDhK-ZCj'
|
|
42
62
|
}
|
|
43
63
|
});
|
|
@@ -45,6 +65,8 @@ export const getWebSocket = async () => {
|
|
|
45
65
|
throw new Error(`Response status: ${response.status}`);
|
|
46
66
|
}
|
|
47
67
|
const result = await response.json();
|
|
68
|
+
callId = result?.wsUrl;
|
|
69
|
+
return result;
|
|
48
70
|
}
|
|
49
71
|
catch (error) {
|
|
50
72
|
console.error(error.message);
|
|
@@ -60,3 +82,70 @@ export const removeHandleWebSK = (key) => {
|
|
|
60
82
|
dataCallBack.splice(index, 1);
|
|
61
83
|
}
|
|
62
84
|
};
|
|
85
|
+
export class WebSocketClient {
|
|
86
|
+
socket = null;
|
|
87
|
+
dataCallbacks = null;
|
|
88
|
+
server;
|
|
89
|
+
constructor(server, callBack) {
|
|
90
|
+
this.server = server;
|
|
91
|
+
this.dataCallbacks = callBack;
|
|
92
|
+
}
|
|
93
|
+
async init() {
|
|
94
|
+
return new Promise((resolve, reject) => {
|
|
95
|
+
if (!this.server)
|
|
96
|
+
reject(new Error("Missing uuid!"));
|
|
97
|
+
this.socket = new WebSocket(BASE_URL + '?call_uuid=' + this.server);
|
|
98
|
+
console.log(BASE_URL + '?call_uuid=' + this.server);
|
|
99
|
+
this.socket.binaryType = "arraybuffer";
|
|
100
|
+
const timeout = setTimeout(() => {
|
|
101
|
+
reject(new Error("⏰ WebSocket connection timeout"));
|
|
102
|
+
}, 5000); // 5s timeout
|
|
103
|
+
this.socket.onopen = () => {
|
|
104
|
+
clearTimeout(timeout);
|
|
105
|
+
resolve(); // Kết nối thành công
|
|
106
|
+
};
|
|
107
|
+
this.socket.onmessage = (event) => {
|
|
108
|
+
const data = tryParseJson(event.data);
|
|
109
|
+
console.log(data);
|
|
110
|
+
this.dataCallbacks?.(data);
|
|
111
|
+
};
|
|
112
|
+
this.socket.onclose = (event) => {
|
|
113
|
+
};
|
|
114
|
+
this.socket.onerror = (event) => {
|
|
115
|
+
clearTimeout(timeout);
|
|
116
|
+
reject(new Error("WebSocket connection error"));
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
send(data) {
|
|
121
|
+
try {
|
|
122
|
+
const message = typeof data === 'string' ? data : JSON.stringify(data);
|
|
123
|
+
this.socket?.send(message);
|
|
124
|
+
}
|
|
125
|
+
catch (e) {
|
|
126
|
+
console.error('Send error:', e);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
sendDefault(data) {
|
|
130
|
+
try {
|
|
131
|
+
this.socket?.send(data);
|
|
132
|
+
}
|
|
133
|
+
catch (e) {
|
|
134
|
+
console.error('Send error:', e);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
disconnect() {
|
|
138
|
+
if (this.socket) {
|
|
139
|
+
this.socket.onopen = null;
|
|
140
|
+
this.socket.onmessage = null;
|
|
141
|
+
this.socket.onclose = null;
|
|
142
|
+
this.socket.onerror = null;
|
|
143
|
+
if (this.socket.readyState === WebSocket.OPEN) {
|
|
144
|
+
this.socket.close(1000, "Manual disconnect");
|
|
145
|
+
console.log("🔌 WebSocket closed manually");
|
|
146
|
+
}
|
|
147
|
+
this.socket = null;
|
|
148
|
+
}
|
|
149
|
+
this.dataCallbacks = null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createRouter, createWebHistory } from "vue-router";
|
|
2
|
+
import Index from "../chat/App.vue";
|
|
3
|
+
import NotFound from "../views/NotFound.vue";
|
|
4
|
+
import TenantPhone from "../views/TenantPhone.vue";
|
|
5
|
+
const router = createRouter({
|
|
6
|
+
history: createWebHistory(import.meta.env.BASE_URL),
|
|
7
|
+
routes: [
|
|
8
|
+
{
|
|
9
|
+
path: '/',
|
|
10
|
+
alias: '/index.html',
|
|
11
|
+
name: "home",
|
|
12
|
+
component: Index,
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
path: '/tenant',
|
|
16
|
+
alias: '/index.html',
|
|
17
|
+
name: "client-home",
|
|
18
|
+
component: Index,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
path: '/tenant-phone',
|
|
22
|
+
alias: '/index.html',
|
|
23
|
+
name: "tenant-phone",
|
|
24
|
+
component: TenantPhone,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
path: '/:pathMatch(.*)*',
|
|
28
|
+
alias: '/index.html',
|
|
29
|
+
name: "not-found",
|
|
30
|
+
component: NotFound,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
});
|
|
34
|
+
// router.beforeEach(async (to, from): Promise<any> => {
|
|
35
|
+
// if (to.name != "home") {
|
|
36
|
+
// return { name: "home" };
|
|
37
|
+
// }
|
|
38
|
+
// });
|
|
39
|
+
export default router;
|
package/dist/test/types/call.js
CHANGED
|
@@ -1 +1,10 @@
|
|
|
1
|
-
export
|
|
1
|
+
export var PLIVO_CALL_STATUS;
|
|
2
|
+
(function (PLIVO_CALL_STATUS) {
|
|
3
|
+
PLIVO_CALL_STATUS["CONNECTING"] = "Connecting...";
|
|
4
|
+
PLIVO_CALL_STATUS["CALLING"] = "calling";
|
|
5
|
+
PLIVO_CALL_STATUS["RINGING"] = "ringing";
|
|
6
|
+
PLIVO_CALL_STATUS["CONNECT_FAILED"] = "failed";
|
|
7
|
+
PLIVO_CALL_STATUS["CALL_START"] = "in-progress";
|
|
8
|
+
PLIVO_CALL_STATUS["CALL_END"] = "completed";
|
|
9
|
+
PLIVO_CALL_STATUS["NO_ANSWER"] = "no-answer";
|
|
10
|
+
})(PLIVO_CALL_STATUS || (PLIVO_CALL_STATUS = {}));
|
|
@@ -31,21 +31,29 @@ export const loginLink = async (params) => {
|
|
|
31
31
|
};
|
|
32
32
|
export const getProfile = async () => {
|
|
33
33
|
const res = await axios.get('/api/v1/message/user/me');
|
|
34
|
-
localStorage.setItem('chat_user', JSON.stringify(res
|
|
34
|
+
localStorage.setItem('chat_user', JSON.stringify(res));
|
|
35
35
|
dataProfile.value = res;
|
|
36
36
|
return res;
|
|
37
37
|
};
|
|
38
|
+
export const submitTenantPhone = async (body) => {
|
|
39
|
+
const res = await axios.post('/api/v1/message/tenant/update-phone', body);
|
|
40
|
+
dataLoginLink.value = res;
|
|
41
|
+
console.log(res);
|
|
42
|
+
return res;
|
|
43
|
+
};
|
|
38
44
|
export const logout = async () => {
|
|
39
45
|
dataLogin = { id: '', token: '', domain: '' };
|
|
40
46
|
dataProfile.value = null;
|
|
41
47
|
localStorage.removeItem('chat_accessToken');
|
|
42
48
|
localStorage.removeItem('chat_domain');
|
|
43
49
|
localStorage.removeItem('chat_id');
|
|
44
|
-
window.location.href = '/login';
|
|
45
50
|
try {
|
|
46
51
|
if (gapMiniAppSdk?.getInstance()?.getBridge()) {
|
|
47
52
|
gapMiniAppSdk?.getInstance()?.closeApp();
|
|
48
53
|
}
|
|
54
|
+
else {
|
|
55
|
+
window.location.href = '/login';
|
|
56
|
+
}
|
|
49
57
|
}
|
|
50
58
|
catch (error) { }
|
|
51
59
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import axios from '../../plugins/axios';
|
|
2
2
|
import { dataProfile } from '../../utils/chat/auth';
|
|
3
|
-
const BARE_WEBSOCKET_URL = 'https://web-socket.dev01.dtsmart.dev'
|
|
3
|
+
// const BARE_WEBSOCKET_URL = 'https://web-socket.dev01.dtsmart.dev'
|
|
4
|
+
const BARE_WEBSOCKET_URL = 'https://web-socket-test.dev01.dtsmart.dev';
|
|
4
5
|
// const BARE_WEBSOCKET_URL = 'http://192.168.1.173:3000'
|
|
5
6
|
export const getIceService = async () => {
|
|
6
7
|
const res = await axios.post('/api/v1/message/call/ice-servers', {
|
|
@@ -16,12 +17,12 @@ export const getIceService = async () => {
|
|
|
16
17
|
// })
|
|
17
18
|
// return res
|
|
18
19
|
// }
|
|
19
|
-
export const callClient = async (
|
|
20
|
-
const url = BARE_WEBSOCKET_URL + '/
|
|
20
|
+
export const callClient = async (data) => {
|
|
21
|
+
const url = BARE_WEBSOCKET_URL + '/ws/answer';
|
|
21
22
|
try {
|
|
22
23
|
const response = await fetch(url, {
|
|
23
24
|
method: 'POST',
|
|
24
|
-
body: JSON.stringify(
|
|
25
|
+
body: JSON.stringify(data),
|
|
25
26
|
headers: {
|
|
26
27
|
['Content-Type']: 'application/json'
|
|
27
28
|
}
|
|
@@ -64,8 +65,10 @@ export const plivoCall = async (user) => {
|
|
|
64
65
|
const response = await fetch(url, {
|
|
65
66
|
method: 'POST',
|
|
66
67
|
body: JSON.stringify({
|
|
68
|
+
// from: '18668259612' || dataProfile.value?.phone,
|
|
67
69
|
from: '18668259612' || dataProfile.value?.phone,
|
|
68
|
-
to: user?.phone || ''
|
|
70
|
+
to: user?.phone || '',
|
|
71
|
+
// clientId: dataProfile.value?.tenant_id
|
|
69
72
|
}),
|
|
70
73
|
headers: {
|
|
71
74
|
['Content-Type']: 'application/json'
|
|
@@ -74,13 +77,11 @@ export const plivoCall = async (user) => {
|
|
|
74
77
|
if (!response.ok) {
|
|
75
78
|
throw new Error(`Response status: ${response.status}`);
|
|
76
79
|
}
|
|
77
|
-
console.log(response);
|
|
78
80
|
const result = await response.json();
|
|
79
|
-
console.log(result);
|
|
80
81
|
return result;
|
|
81
82
|
};
|
|
82
83
|
export const plivoEndCall = async (uuid) => {
|
|
83
|
-
const url = BARE_WEBSOCKET_URL + '/
|
|
84
|
+
const url = BARE_WEBSOCKET_URL + '/ws/end-call';
|
|
84
85
|
const response = await fetch(url, {
|
|
85
86
|
method: 'POST',
|
|
86
87
|
body: JSON.stringify({
|
|
@@ -96,3 +97,42 @@ export const plivoEndCall = async (uuid) => {
|
|
|
96
97
|
const result = await response.json();
|
|
97
98
|
console.log(result);
|
|
98
99
|
};
|
|
100
|
+
export const downloadRecord = async (url_pub) => {
|
|
101
|
+
const url = BARE_WEBSOCKET_URL + '/ws/download-record';
|
|
102
|
+
const response = await fetch(url, {
|
|
103
|
+
method: 'POST',
|
|
104
|
+
body: JSON.stringify({
|
|
105
|
+
url: url_pub
|
|
106
|
+
}),
|
|
107
|
+
headers: {
|
|
108
|
+
['Content-Type']: 'application/json'
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
if (!response.ok) {
|
|
112
|
+
throw new Error(`Response status: ${response.status}`);
|
|
113
|
+
}
|
|
114
|
+
const blob = await response.blob();
|
|
115
|
+
const url_blob = window.URL.createObjectURL(blob);
|
|
116
|
+
const a = document.createElement("a");
|
|
117
|
+
a.href = url_blob;
|
|
118
|
+
a.download = "recording.mp3";
|
|
119
|
+
a.click();
|
|
120
|
+
a.remove();
|
|
121
|
+
};
|
|
122
|
+
export const getPlivoAccessToken = async () => {
|
|
123
|
+
const url = BARE_WEBSOCKET_URL + '/ws/generate-token';
|
|
124
|
+
const response = await fetch(url, {
|
|
125
|
+
method: 'POST',
|
|
126
|
+
body: JSON.stringify({
|
|
127
|
+
clientId: dataProfile.value?.tenant_id,
|
|
128
|
+
}),
|
|
129
|
+
headers: {
|
|
130
|
+
['Content-Type']: 'application/json'
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
if (!response.ok) {
|
|
134
|
+
throw new Error(`Response status: ${response.status}`);
|
|
135
|
+
}
|
|
136
|
+
const result = await response.json();
|
|
137
|
+
return result?.accessToken;
|
|
138
|
+
};
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { ref } from 'vue';
|
|
2
|
-
import
|
|
2
|
+
import axios_gci from '../../plugins/axios-gci';
|
|
3
|
+
import axios from '../../plugins/axios';
|
|
3
4
|
import dayjs from 'dayjs';
|
|
4
5
|
export const user = ref(null);
|
|
5
6
|
export const userHistory = ref(null);
|
|
6
7
|
export const getUserHistory = async (phone) => {
|
|
7
|
-
const res = await
|
|
8
|
+
const res = await axios_gci.get(`/v1/pos/customer/site/history?phone=${phone}`);
|
|
9
|
+
return res;
|
|
10
|
+
};
|
|
11
|
+
export const getUserDetailChat = async (params) => {
|
|
12
|
+
const res = await axios.get('/api/v1/message/customer/info', { params });
|
|
8
13
|
return res;
|
|
9
14
|
};
|
|
10
15
|
export function getItemsByYear(data, key = 'created_at') {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/// <reference types="C:/phonghq/go-chat-v2/node_modules/.vue-global-types/vue_3.5_0.d.ts" />
|
|
2
|
+
const goToHome = () => {
|
|
3
|
+
window.location.href = '/'; // Replace with your desired home page URL
|
|
4
|
+
};
|
|
5
|
+
debugger; /* PartiallyEnd: #3632/scriptSetup.vue */
|
|
6
|
+
const __VLS_ctx = {
|
|
7
|
+
...{},
|
|
8
|
+
...{},
|
|
9
|
+
};
|
|
10
|
+
let __VLS_elements;
|
|
11
|
+
let __VLS_components;
|
|
12
|
+
let __VLS_directives;
|
|
13
|
+
__VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
|
|
14
|
+
...{ class: "py-10 grow place-content-center" },
|
|
15
|
+
});
|
|
16
|
+
__VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
|
|
17
|
+
...{ class: "text-center font-semibold" },
|
|
18
|
+
});
|
|
19
|
+
__VLS_asFunctionalElement(__VLS_elements.h1, __VLS_elements.h1)({
|
|
20
|
+
...{ class: "text-primary text-6xl md:text-8xl mb-2" },
|
|
21
|
+
});
|
|
22
|
+
__VLS_asFunctionalElement(__VLS_elements.h2, __VLS_elements.h2)({
|
|
23
|
+
...{ class: "text-2xl mb-3" },
|
|
24
|
+
});
|
|
25
|
+
__VLS_asFunctionalElement(__VLS_elements.button, __VLS_elements.button)({
|
|
26
|
+
...{ onClick: (...[$event]) => {
|
|
27
|
+
__VLS_ctx.$router.push({ name: 'home' });
|
|
28
|
+
// @ts-ignore
|
|
29
|
+
[$router,];
|
|
30
|
+
} },
|
|
31
|
+
...{ class: "btn btn-primary" },
|
|
32
|
+
});
|
|
33
|
+
/** @type {__VLS_StyleScopedClasses['py-10']} */ ;
|
|
34
|
+
/** @type {__VLS_StyleScopedClasses['grow']} */ ;
|
|
35
|
+
/** @type {__VLS_StyleScopedClasses['place-content-center']} */ ;
|
|
36
|
+
/** @type {__VLS_StyleScopedClasses['text-center']} */ ;
|
|
37
|
+
/** @type {__VLS_StyleScopedClasses['font-semibold']} */ ;
|
|
38
|
+
/** @type {__VLS_StyleScopedClasses['text-primary']} */ ;
|
|
39
|
+
/** @type {__VLS_StyleScopedClasses['text-6xl']} */ ;
|
|
40
|
+
/** @type {__VLS_StyleScopedClasses['md:text-8xl']} */ ;
|
|
41
|
+
/** @type {__VLS_StyleScopedClasses['mb-2']} */ ;
|
|
42
|
+
/** @type {__VLS_StyleScopedClasses['text-2xl']} */ ;
|
|
43
|
+
/** @type {__VLS_StyleScopedClasses['mb-3']} */ ;
|
|
44
|
+
/** @type {__VLS_StyleScopedClasses['btn']} */ ;
|
|
45
|
+
/** @type {__VLS_StyleScopedClasses['btn-primary']} */ ;
|
|
46
|
+
const __VLS_export = (await import('vue')).defineComponent({});
|
|
47
|
+
export default {};
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/// <reference types="C:/phonghq/go-chat-v2/node_modules/.vue-global-types/vue_3.5_0.d.ts" />
|
|
2
|
+
import { ref } from 'vue';
|
|
3
|
+
import CSpin from '../components/common/spin/CSpin.vue';
|
|
4
|
+
import { dataProfile, submitTenantPhone } from '../utils/chat/auth';
|
|
5
|
+
import router from '../router';
|
|
6
|
+
const open = ref(false);
|
|
7
|
+
const phoneValue = ref('');
|
|
8
|
+
const countries = [
|
|
9
|
+
// { code: 'VN', name: 'Vietnam', dial: 84, flag: '🇻🇳' },
|
|
10
|
+
{ code: 'US', name: 'United States', dial: 1, flag: '🇺🇸' }
|
|
11
|
+
// { code: 'KR', name: 'Korea', dial: 82, flag: '🇰🇷' },
|
|
12
|
+
// { code: 'JP', name: 'Japan', dial: 81, flag: '🇯🇵' },
|
|
13
|
+
// { code: 'TH', name: 'Thailand', dial: 66, flag: '🇹🇭' },
|
|
14
|
+
];
|
|
15
|
+
const selected = ref(countries[0]);
|
|
16
|
+
const error = ref('');
|
|
17
|
+
const loading = ref(false);
|
|
18
|
+
const select = (c) => {
|
|
19
|
+
selected.value = c;
|
|
20
|
+
open.value = false;
|
|
21
|
+
};
|
|
22
|
+
const isPhoneMatchDial = (countryDial, phone) => {
|
|
23
|
+
const dial = phone.replace('+', '');
|
|
24
|
+
return phone.startsWith(countryDial.toString());
|
|
25
|
+
};
|
|
26
|
+
const keepOnlyNumbers = (str) => {
|
|
27
|
+
return str.replace(/\D/g, '');
|
|
28
|
+
};
|
|
29
|
+
const handleInput = () => {
|
|
30
|
+
error.value = '';
|
|
31
|
+
phoneValue.value = keepOnlyNumbers(phoneValue.value);
|
|
32
|
+
};
|
|
33
|
+
const onSubmit = async () => {
|
|
34
|
+
try {
|
|
35
|
+
if (isPhoneMatchDial(selected.value.dial, phoneValue.value)) {
|
|
36
|
+
error.value = `Phone number does not match country code ${selected.value.name}`;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
loading.value = true;
|
|
40
|
+
const param = {
|
|
41
|
+
phone: selected.value.dial + phoneValue.value,
|
|
42
|
+
tenant_id: dataProfile.value?.tenant_id ?? ''
|
|
43
|
+
};
|
|
44
|
+
await submitTenantPhone(param);
|
|
45
|
+
router.push({ name: 'home' });
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
console.log(e);
|
|
49
|
+
}
|
|
50
|
+
loading.value = false;
|
|
51
|
+
};
|
|
52
|
+
debugger; /* PartiallyEnd: #3632/scriptSetup.vue */
|
|
53
|
+
const __VLS_ctx = {
|
|
54
|
+
...{},
|
|
55
|
+
...{},
|
|
56
|
+
};
|
|
57
|
+
let __VLS_elements;
|
|
58
|
+
let __VLS_components;
|
|
59
|
+
let __VLS_directives;
|
|
60
|
+
__VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
|
|
61
|
+
...{ class: "flex flex-col w-[700px] h-full mx-auto justify-center pb-40" },
|
|
62
|
+
});
|
|
63
|
+
__VLS_asFunctionalElement(__VLS_elements.label, __VLS_elements.label)({
|
|
64
|
+
...{ class: "text-[28px] font-medium text-chat-haze-700 mb-1 block mb-2" },
|
|
65
|
+
});
|
|
66
|
+
__VLS_asFunctionalElement(__VLS_elements.p, __VLS_elements.p)({
|
|
67
|
+
...{ class: "text-xl text-chat-haze-600 mb-4" },
|
|
68
|
+
});
|
|
69
|
+
__VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
|
|
70
|
+
...{ class: "flex items-center gap-2 chat-input border border-chat-haze-200 p-2 bg-white shadow-md" },
|
|
71
|
+
});
|
|
72
|
+
__VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
|
|
73
|
+
...{ class: "relative" },
|
|
74
|
+
});
|
|
75
|
+
__VLS_asFunctionalElement(__VLS_elements.button, __VLS_elements.button)({
|
|
76
|
+
...{ onClick: (...[$event]) => {
|
|
77
|
+
__VLS_ctx.open = !__VLS_ctx.open;
|
|
78
|
+
// @ts-ignore
|
|
79
|
+
[open, open,];
|
|
80
|
+
} },
|
|
81
|
+
...{ class: "flex items-center gap-1 px-2 py-1 rounded-lg hover:bg-gray-100" },
|
|
82
|
+
});
|
|
83
|
+
__VLS_asFunctionalElement(__VLS_elements.span, __VLS_elements.span)({});
|
|
84
|
+
(__VLS_ctx.selected.flag);
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
[selected,];
|
|
87
|
+
__VLS_asFunctionalElement(__VLS_elements.span, __VLS_elements.span)({
|
|
88
|
+
...{ class: "text-sm text-chat-haze-700" },
|
|
89
|
+
});
|
|
90
|
+
(__VLS_ctx.selected.dial);
|
|
91
|
+
// @ts-ignore
|
|
92
|
+
[selected,];
|
|
93
|
+
__VLS_asFunctionalElement(__VLS_elements.svg, __VLS_elements.svg)({
|
|
94
|
+
...{ class: "w-4 h-4 text-chat-haze-500" },
|
|
95
|
+
fill: "none",
|
|
96
|
+
stroke: "currentColor",
|
|
97
|
+
viewBox: "0 0 20 20",
|
|
98
|
+
});
|
|
99
|
+
__VLS_asFunctionalElement(__VLS_elements.path)({
|
|
100
|
+
'stroke-linecap': "round",
|
|
101
|
+
'stroke-linejoin': "round",
|
|
102
|
+
'stroke-width': "2",
|
|
103
|
+
d: "M5 7l5 5 5-5",
|
|
104
|
+
});
|
|
105
|
+
if (__VLS_ctx.open) {
|
|
106
|
+
// @ts-ignore
|
|
107
|
+
[open,];
|
|
108
|
+
__VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
|
|
109
|
+
...{ class: "absolute z-10 bg-white border shadow-lg rounded-xl mt-4 w-40 max-h-52 overflow-auto border border-chat-haze-200" },
|
|
110
|
+
});
|
|
111
|
+
for (const [c] of __VLS_getVForSourceType((__VLS_ctx.countries))) {
|
|
112
|
+
// @ts-ignore
|
|
113
|
+
[countries,];
|
|
114
|
+
__VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
|
|
115
|
+
...{ onClick: (...[$event]) => {
|
|
116
|
+
if (!(__VLS_ctx.open))
|
|
117
|
+
return;
|
|
118
|
+
__VLS_ctx.select(c);
|
|
119
|
+
// @ts-ignore
|
|
120
|
+
[select,];
|
|
121
|
+
} },
|
|
122
|
+
key: (c.code),
|
|
123
|
+
...{ class: "flex items-center gap-2 px-3 py-2 hover:bg-gray-100 cursor-pointer" },
|
|
124
|
+
});
|
|
125
|
+
__VLS_asFunctionalElement(__VLS_elements.span, __VLS_elements.span)({});
|
|
126
|
+
(c.flag);
|
|
127
|
+
__VLS_asFunctionalElement(__VLS_elements.span, __VLS_elements.span)({
|
|
128
|
+
...{ class: "text-sm" },
|
|
129
|
+
});
|
|
130
|
+
(c.dial);
|
|
131
|
+
__VLS_asFunctionalElement(__VLS_elements.span, __VLS_elements.span)({
|
|
132
|
+
...{ class: "text-xs text-chat-haze-500 ml-auto" },
|
|
133
|
+
});
|
|
134
|
+
(c.code);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
__VLS_asFunctionalElement(__VLS_elements.input)({
|
|
138
|
+
...{ onInput: (__VLS_ctx.handleInput) },
|
|
139
|
+
...{ onKeyup: (__VLS_ctx.onSubmit) },
|
|
140
|
+
...{ class: "!outline-none" },
|
|
141
|
+
type: "tel",
|
|
142
|
+
maxlength: (10),
|
|
143
|
+
placeholder: "Enter phone number",
|
|
144
|
+
});
|
|
145
|
+
(__VLS_ctx.phoneValue);
|
|
146
|
+
// @ts-ignore
|
|
147
|
+
[handleInput, onSubmit, phoneValue,];
|
|
148
|
+
if (__VLS_ctx.error) {
|
|
149
|
+
// @ts-ignore
|
|
150
|
+
[error,];
|
|
151
|
+
__VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
|
|
152
|
+
...{ class: "mt-2 ml-1 text-sm text-chat-error flex items-center gap-1" },
|
|
153
|
+
});
|
|
154
|
+
__VLS_asFunctionalElement(__VLS_elements.svg, __VLS_elements.svg)({
|
|
155
|
+
...{ class: "w-4 h-4" },
|
|
156
|
+
fill: "none",
|
|
157
|
+
stroke: "currentColor",
|
|
158
|
+
viewBox: "0 0 24 24",
|
|
159
|
+
});
|
|
160
|
+
__VLS_asFunctionalElement(__VLS_elements.path)({
|
|
161
|
+
'stroke-linecap': "round",
|
|
162
|
+
'stroke-linejoin': "round",
|
|
163
|
+
'stroke-width': "2",
|
|
164
|
+
d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.662 1.732-3L13.732 4c-.77-1.338-2.694-1.338-3.464 0L4.34 16c-.77 1.338.192 3 1.732 3z",
|
|
165
|
+
});
|
|
166
|
+
(__VLS_ctx.error);
|
|
167
|
+
// @ts-ignore
|
|
168
|
+
[error,];
|
|
169
|
+
}
|
|
170
|
+
__VLS_asFunctionalElement(__VLS_elements.button, __VLS_elements.button)({
|
|
171
|
+
...{ onClick: (__VLS_ctx.onSubmit) },
|
|
172
|
+
...{ class: "mt-4 w-full bg-chat-primary text-white p-2 rounded-lg hover:bg-blue-700" },
|
|
173
|
+
});
|
|
174
|
+
// @ts-ignore
|
|
175
|
+
[onSubmit,];
|
|
176
|
+
if (__VLS_ctx.loading) {
|
|
177
|
+
// @ts-ignore
|
|
178
|
+
[loading,];
|
|
179
|
+
/** @type {[typeof CSpin, typeof CSpin, ]} */ ;
|
|
180
|
+
// @ts-ignore
|
|
181
|
+
const __VLS_0 = __VLS_asFunctionalComponent(CSpin, new CSpin({
|
|
182
|
+
size: (30),
|
|
183
|
+
}));
|
|
184
|
+
const __VLS_1 = __VLS_0({
|
|
185
|
+
size: (30),
|
|
186
|
+
}, ...__VLS_functionalComponentArgsRest(__VLS_0));
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
__VLS_asFunctionalElement(__VLS_elements.span, __VLS_elements.span)({});
|
|
190
|
+
}
|
|
191
|
+
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
|
|
192
|
+
/** @type {__VLS_StyleScopedClasses['flex-col']} */ ;
|
|
193
|
+
/** @type {__VLS_StyleScopedClasses['w-[700px]']} */ ;
|
|
194
|
+
/** @type {__VLS_StyleScopedClasses['h-full']} */ ;
|
|
195
|
+
/** @type {__VLS_StyleScopedClasses['mx-auto']} */ ;
|
|
196
|
+
/** @type {__VLS_StyleScopedClasses['justify-center']} */ ;
|
|
197
|
+
/** @type {__VLS_StyleScopedClasses['pb-40']} */ ;
|
|
198
|
+
/** @type {__VLS_StyleScopedClasses['text-[28px]']} */ ;
|
|
199
|
+
/** @type {__VLS_StyleScopedClasses['font-medium']} */ ;
|
|
200
|
+
/** @type {__VLS_StyleScopedClasses['text-chat-haze-700']} */ ;
|
|
201
|
+
/** @type {__VLS_StyleScopedClasses['mb-1']} */ ;
|
|
202
|
+
/** @type {__VLS_StyleScopedClasses['block']} */ ;
|
|
203
|
+
/** @type {__VLS_StyleScopedClasses['mb-2']} */ ;
|
|
204
|
+
/** @type {__VLS_StyleScopedClasses['text-xl']} */ ;
|
|
205
|
+
/** @type {__VLS_StyleScopedClasses['text-chat-haze-600']} */ ;
|
|
206
|
+
/** @type {__VLS_StyleScopedClasses['mb-4']} */ ;
|
|
207
|
+
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
|
|
208
|
+
/** @type {__VLS_StyleScopedClasses['items-center']} */ ;
|
|
209
|
+
/** @type {__VLS_StyleScopedClasses['gap-2']} */ ;
|
|
210
|
+
/** @type {__VLS_StyleScopedClasses['chat-input']} */ ;
|
|
211
|
+
/** @type {__VLS_StyleScopedClasses['border']} */ ;
|
|
212
|
+
/** @type {__VLS_StyleScopedClasses['border-chat-haze-200']} */ ;
|
|
213
|
+
/** @type {__VLS_StyleScopedClasses['p-2']} */ ;
|
|
214
|
+
/** @type {__VLS_StyleScopedClasses['bg-white']} */ ;
|
|
215
|
+
/** @type {__VLS_StyleScopedClasses['shadow-md']} */ ;
|
|
216
|
+
/** @type {__VLS_StyleScopedClasses['relative']} */ ;
|
|
217
|
+
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
|
|
218
|
+
/** @type {__VLS_StyleScopedClasses['items-center']} */ ;
|
|
219
|
+
/** @type {__VLS_StyleScopedClasses['gap-1']} */ ;
|
|
220
|
+
/** @type {__VLS_StyleScopedClasses['px-2']} */ ;
|
|
221
|
+
/** @type {__VLS_StyleScopedClasses['py-1']} */ ;
|
|
222
|
+
/** @type {__VLS_StyleScopedClasses['rounded-lg']} */ ;
|
|
223
|
+
/** @type {__VLS_StyleScopedClasses['hover:bg-gray-100']} */ ;
|
|
224
|
+
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
|
|
225
|
+
/** @type {__VLS_StyleScopedClasses['text-chat-haze-700']} */ ;
|
|
226
|
+
/** @type {__VLS_StyleScopedClasses['w-4']} */ ;
|
|
227
|
+
/** @type {__VLS_StyleScopedClasses['h-4']} */ ;
|
|
228
|
+
/** @type {__VLS_StyleScopedClasses['text-chat-haze-500']} */ ;
|
|
229
|
+
/** @type {__VLS_StyleScopedClasses['absolute']} */ ;
|
|
230
|
+
/** @type {__VLS_StyleScopedClasses['z-10']} */ ;
|
|
231
|
+
/** @type {__VLS_StyleScopedClasses['bg-white']} */ ;
|
|
232
|
+
/** @type {__VLS_StyleScopedClasses['border']} */ ;
|
|
233
|
+
/** @type {__VLS_StyleScopedClasses['shadow-lg']} */ ;
|
|
234
|
+
/** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
|
|
235
|
+
/** @type {__VLS_StyleScopedClasses['mt-4']} */ ;
|
|
236
|
+
/** @type {__VLS_StyleScopedClasses['w-40']} */ ;
|
|
237
|
+
/** @type {__VLS_StyleScopedClasses['max-h-52']} */ ;
|
|
238
|
+
/** @type {__VLS_StyleScopedClasses['overflow-auto']} */ ;
|
|
239
|
+
/** @type {__VLS_StyleScopedClasses['border']} */ ;
|
|
240
|
+
/** @type {__VLS_StyleScopedClasses['border-chat-haze-200']} */ ;
|
|
241
|
+
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
|
|
242
|
+
/** @type {__VLS_StyleScopedClasses['items-center']} */ ;
|
|
243
|
+
/** @type {__VLS_StyleScopedClasses['gap-2']} */ ;
|
|
244
|
+
/** @type {__VLS_StyleScopedClasses['px-3']} */ ;
|
|
245
|
+
/** @type {__VLS_StyleScopedClasses['py-2']} */ ;
|
|
246
|
+
/** @type {__VLS_StyleScopedClasses['hover:bg-gray-100']} */ ;
|
|
247
|
+
/** @type {__VLS_StyleScopedClasses['cursor-pointer']} */ ;
|
|
248
|
+
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
|
|
249
|
+
/** @type {__VLS_StyleScopedClasses['text-xs']} */ ;
|
|
250
|
+
/** @type {__VLS_StyleScopedClasses['text-chat-haze-500']} */ ;
|
|
251
|
+
/** @type {__VLS_StyleScopedClasses['ml-auto']} */ ;
|
|
252
|
+
/** @type {__VLS_StyleScopedClasses['!outline-none']} */ ;
|
|
253
|
+
/** @type {__VLS_StyleScopedClasses['mt-2']} */ ;
|
|
254
|
+
/** @type {__VLS_StyleScopedClasses['ml-1']} */ ;
|
|
255
|
+
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
|
|
256
|
+
/** @type {__VLS_StyleScopedClasses['text-chat-error']} */ ;
|
|
257
|
+
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
|
|
258
|
+
/** @type {__VLS_StyleScopedClasses['items-center']} */ ;
|
|
259
|
+
/** @type {__VLS_StyleScopedClasses['gap-1']} */ ;
|
|
260
|
+
/** @type {__VLS_StyleScopedClasses['w-4']} */ ;
|
|
261
|
+
/** @type {__VLS_StyleScopedClasses['h-4']} */ ;
|
|
262
|
+
/** @type {__VLS_StyleScopedClasses['mt-4']} */ ;
|
|
263
|
+
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
|
|
264
|
+
/** @type {__VLS_StyleScopedClasses['bg-chat-primary']} */ ;
|
|
265
|
+
/** @type {__VLS_StyleScopedClasses['text-white']} */ ;
|
|
266
|
+
/** @type {__VLS_StyleScopedClasses['p-2']} */ ;
|
|
267
|
+
/** @type {__VLS_StyleScopedClasses['rounded-lg']} */ ;
|
|
268
|
+
/** @type {__VLS_StyleScopedClasses['hover:bg-blue-700']} */ ;
|
|
269
|
+
const __VLS_export = (await import('vue')).defineComponent({});
|
|
270
|
+
export default {};
|