vue-wiguet-chatweb 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <svg
3
+ viewBox="0 0 24 24"
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ style="width: 28px; height: 28px"
6
+ >
7
+ <path
8
+ d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
9
+ opacity=".25"
10
+ />
11
+ <path
12
+ d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"
13
+ class="spinner_ajPY"
14
+ />
15
+ </svg>
16
+ </template>
17
+
18
+ <script setup lang="ts"></script>
19
+
20
+ <style scoped>
21
+ .spinner_ajPY {
22
+ fill: #fe6d00;
23
+ transform-origin: center;
24
+ animation: spinner_AtaB 0.75s infinite linear;
25
+ }
26
+ @keyframes spinner_AtaB {
27
+ 100% {
28
+ transform: rotate(360deg);
29
+ }
30
+ }
31
+ </style>
@@ -0,0 +1,210 @@
1
+ <template>
2
+ <div ref="target" class="target"></div>
3
+ <div
4
+ v-for="message in props.messages"
5
+ :key="message.id"
6
+ style="width: 100%"
7
+ :class="message.esCliente ? 'message-left' : 'message-right'"
8
+ >
9
+ <div class="message-container">
10
+ <div v-if="message.error && message.esCliente" class="btn-container">
11
+ <button
12
+ text
13
+ rounded
14
+ class="btn-danger"
15
+ icon="fa-solid fa-circle-exclamation"
16
+ aria-label="Cancel"
17
+ @click="emit('retry', message)"
18
+ >
19
+ <DangerIcon />
20
+ </button>
21
+ </div>
22
+ <div class="chat-message">
23
+ <div class="bubble" :class="message.esCliente ? 'left' : 'right'">
24
+ <div :class="message.esCliente ? 'content-left' : 'content-right'">
25
+ <div class="message">
26
+ {{ message.message }}
27
+ </div>
28
+ <div class="detail-message flex justify-content-between">
29
+ <span class="mr-5" v-if="message.sender?.nombreCompleto">
30
+ {{ message.sender?.nombreCompleto }}
31
+ </span>
32
+ <span class="mr-5" v-else> </span>
33
+ <span>
34
+ {{
35
+ DateTime.fromISO(message.createdAt).toFormat(
36
+ "dd-MM-yyyy HH:mm"
37
+ )
38
+ }}
39
+ </span>
40
+ </div>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ </template>
47
+
48
+ <script setup lang="ts">
49
+ import { PropType, onBeforeMount, ref, watch } from "vue";
50
+ import { useIntersectionObserver } from "@vueuse/core";
51
+ import { type Message } from "../dto/app.dto";
52
+ import { DateTime } from "luxon";
53
+ import DangerIcon from "./DangerIcon.vue";
54
+
55
+ const emit = defineEmits(["loadMore", "retry"]);
56
+ const props = defineProps({
57
+ messages: {
58
+ type: Array as PropType<Message[]>,
59
+ default: () => [],
60
+ },
61
+ canLoadMoreMessages: {
62
+ type: Boolean,
63
+ default: false,
64
+ },
65
+ });
66
+
67
+ const target = ref();
68
+
69
+ const { pause, resume } = useIntersectionObserver(
70
+ target,
71
+ ([{ isIntersecting }]) => {
72
+ if (isIntersecting) {
73
+ emit("loadMore");
74
+ }
75
+ }
76
+ );
77
+
78
+ onBeforeMount(() => {
79
+ if (!props.canLoadMoreMessages) {
80
+ pause();
81
+ }
82
+ });
83
+ watch(
84
+ () => props.canLoadMoreMessages,
85
+ (current) => {
86
+ if (current) {
87
+ resume();
88
+ return;
89
+ }
90
+ pause();
91
+ }
92
+ );
93
+ </script>
94
+
95
+ <style scoped>
96
+ .bubble {
97
+ --r: 25px;
98
+ /* the radius */
99
+ --t: 30px;
100
+ /* the size of the tail */
101
+
102
+ max-width: 50%;
103
+ min-width: 250px;
104
+ padding: calc(2 * var(--r) / 3);
105
+ -webkit-mask: radial-gradient(var(--t) at var(--_d) 0, #0000 98%, #000 102%)
106
+ var(--_d) 100% / calc(100% - var(--r)) var(--t) no-repeat,
107
+ conic-gradient(at var(--r) var(--r), #000 75%, #0000 0) calc(var(--r) / -2)
108
+ calc(var(--r) / -2) padding-box,
109
+ radial-gradient(50% 50%, #000 98%, #0000 101%) 0 0 / var(--r) var(--r) space
110
+ padding-box;
111
+ mask: radial-gradient(var(--t) at var(--_d) 0, #0000 98%, #000 102%) var(--_d)
112
+ 100% / calc(100% - var(--r)) var(--t) no-repeat,
113
+ conic-gradient(at var(--r) var(--r), #000 75%, #0000 0) calc(var(--r) / -2)
114
+ calc(var(--r) / -2) padding-box,
115
+ radial-gradient(50% 50%, #000 98%, #0000 101%) 0 0 / var(--r) var(--r) space
116
+ padding-box;
117
+ /* background: linear-gradient(135deg, #FE6D00, #1384C5) border-box; */
118
+ color: #fff;
119
+ }
120
+
121
+ .left {
122
+ border-left: var(--t) solid #0000;
123
+ margin-right: var(--t);
124
+ background-color: #fcd7ae;
125
+ color: #4d4d4d;
126
+ place-self: start;
127
+ }
128
+
129
+ .bubble > .content-left {
130
+ margin-right: 10px;
131
+ margin-bottom: 1px;
132
+ }
133
+
134
+ .right {
135
+ border-right: var(--t) solid #0000;
136
+ margin-left: var(--t);
137
+ background-color: #fdeedb;
138
+ color: #4d4d4d;
139
+ place-self: end;
140
+ }
141
+
142
+ .bubble > .content-right {
143
+ margin-bottom: 1px;
144
+ margin-right: 10px;
145
+ }
146
+
147
+ .message {
148
+ text-align: initial;
149
+ word-break: break-all;
150
+ margin-bottom: 10px;
151
+ }
152
+ .detail-message {
153
+ font-size: 10px;
154
+ color: #808080;
155
+ display: flex;
156
+ justify-content: space-between;
157
+ }
158
+
159
+ .chat-message {
160
+ max-width: 90%;
161
+ min-width: 90%;
162
+ display: flex;
163
+ flex-direction: column;
164
+ justify-content: center;
165
+ margin-bottom: 0.5rem;
166
+ /* box-shadow: 0 2px 8px rgba(0, 0, 0, 20%); */
167
+ }
168
+
169
+ .message-left {
170
+ display: flex;
171
+ justify-content: start;
172
+ }
173
+ .message-right {
174
+ display: flex;
175
+ justify-content: end;
176
+ }
177
+ .target {
178
+ padding: 0.5rem 0;
179
+ width: 100%;
180
+ }
181
+
182
+ .btn-danger {
183
+ background-color: transparent;
184
+ border: 0;
185
+ border-radius: 50%;
186
+ cursor: pointer;
187
+ padding: 0;
188
+ width: 30px;
189
+ height: 30px;
190
+ display: flex;
191
+ align-items: center;
192
+ justify-content: center;
193
+ & svg {
194
+ width: 24px;
195
+ height: 24px;
196
+ }
197
+ &:hover {
198
+ background-color: rgba(255, 0, 0, 0.226);
199
+ }
200
+ }
201
+
202
+ .btn-container {
203
+ display: flex;
204
+ align-items: center;
205
+ }
206
+
207
+ .message-container {
208
+ display: flex;
209
+ }
210
+ </style>
@@ -1,35 +1,71 @@
1
- <template>
2
- <div>
3
- <div>
4
- <div id="chat-circle" @click="toggleChat">
5
- <IconWidget />
6
- </div>
7
- <div class="chat-box" v-if="isChatBoxVisible">
8
- <Chat :titlePrincipal="titlePrincipal" :toggleChat="toggleChat" :tokenAuth="tokenAuth" :phoneUser="phoneUser" />
9
- </div>
10
- </div>
11
- </div>
12
- </template>
13
-
14
- <script setup lang="ts">
15
- import { ref } from 'vue'
16
- import Chat from './Chat.vue';
17
- import IconWidget from './IconWidget.vue'
18
-
19
- const isChatBoxVisible = ref(false);
20
- const toggleChat = () => {
21
- isChatBoxVisible.value = !isChatBoxVisible.value;
22
- };
23
-
24
- defineProps({
25
- tokenAuth:{ type: String, required: true },
26
- phoneUser:{ type: String, required: true },
27
- titlePrincipal:{ type: String }
28
- });
29
-
30
- </script>
31
-
32
- <style scoped>
33
- @import url(../style.css);
34
- </style>
35
-
1
+ <template>
2
+ <div>
3
+ <div id="chat-circle" @click="toggleChat" class="widget-container">
4
+ <div class="new-message-badge" v-if="newMessages">
5
+ {{ newMessages > 9 ? "9+" : newMessages }}
6
+ </div>
7
+ <IconWidget />
8
+ </div>
9
+ <div class="chat-box" v-show="isChatBoxVisible">
10
+ <Chat
11
+ :visible="isChatBoxVisible"
12
+ :titlePrincipal="titlePrincipal"
13
+ :toggleChat="toggleChat"
14
+ :tokenAuth="tokenAuth"
15
+ :user="user"
16
+ @show-toast="(data) => emit('show-toast', data)"
17
+ @show-confirm="(data) => emit('show-confirm', data)"
18
+ @clear-new-messages="newMessages = 0"
19
+ @new-message="() => newMessages++"
20
+ />
21
+ </div>
22
+ </div>
23
+ </template>
24
+
25
+ <script setup lang="ts">
26
+ import { PropType, ref } from "vue";
27
+ import Chat from "./Chat.vue";
28
+ import IconWidget from "./IconWidget.vue";
29
+
30
+ const emit = defineEmits(["show-toast", "show-confirm"]);
31
+
32
+ const isChatBoxVisible = ref(false);
33
+ const newMessages = ref(0);
34
+ const toggleChat = () => {
35
+ isChatBoxVisible.value = !isChatBoxVisible.value;
36
+ };
37
+
38
+ defineProps({
39
+ tokenAuth: { type: String, required: true },
40
+ titlePrincipal: { type: String },
41
+ user: {
42
+ type: Object as PropType<{
43
+ nombreCompleto: string;
44
+ ci: string;
45
+ msPersonaId: number;
46
+ }>,
47
+ required: true,
48
+ },
49
+ });
50
+ </script>
51
+
52
+ <style scoped>
53
+ @import url(../style.css);
54
+ .widget-container {
55
+ position: relative;
56
+ }
57
+ .new-message-badge {
58
+ position: absolute;
59
+ background-color: red;
60
+ width: 30px;
61
+ height: 30px;
62
+ display: flex;
63
+ font-family: "Roboto", sans-serif;
64
+ align-items: center;
65
+ font-weight: 500;
66
+ justify-content: center;
67
+ border-radius: 50%;
68
+ right: -2px;
69
+ top: -4px;
70
+ }
71
+ </style>
@@ -1,104 +0,0 @@
1
- <template>
2
- <div class="chat-message">
3
-
4
- <div class="bubble" :class="self ? 'left' : 'right'">
5
- <div :class="self ? 'content-left' : 'content-right'">
6
- <div class="message">
7
- {{ message.messages.dataMessage }}
8
- </div>
9
- <div class="detail-message flex justify-content-between">
10
- <span class="mr-5" v-if="message.messages.user?.nombreCompleto">
11
- {{ textCapitalize(message.messages.user.nombreCompleto) }}
12
- </span>
13
- <span class="mr-5" v-else>
14
- </span>
15
- <span>
16
- {{ formatTimeAPDate(message.messages.createdAt) }}
17
- </span>
18
- </div>
19
- </div>
20
- </div>
21
- </div>
22
- </template>
23
-
24
- <script setup lang="ts">
25
- import {computed } from 'vue';
26
- import { formatTimeAPDate,textCapitalize } from '../resources/functions.helpers'
27
- const props = defineProps({
28
- message:{ type: Object, required: true },
29
- });
30
-
31
- const self = computed(() => {
32
- return props.message.messages.responseOrigin;
33
- });
34
-
35
- </script>
36
-
37
- <style scoped>
38
- .bubble {
39
- --r: 25px;
40
- /* the radius */
41
- --t: 30px;
42
- /* the size of the tail */
43
-
44
- max-width: 50%;
45
- min-width: 250px;
46
- padding: calc(2*var(--r)/3);
47
- -webkit-mask:
48
- radial-gradient(var(--t) at var(--_d) 0, #0000 98%, #000 102%) var(--_d) 100%/calc(100% - var(--r)) var(--t) no-repeat,
49
- conic-gradient(at var(--r) var(--r), #000 75%, #0000 0) calc(var(--r)/-2) calc(var(--r)/-2) padding-box,
50
- radial-gradient(50% 50%, #000 98%, #0000 101%) 0 0/var(--r) var(--r) space padding-box;
51
- /* background: linear-gradient(135deg, #FE6D00, #1384C5) border-box; */
52
- color: #fff;
53
- }
54
-
55
- .left {
56
- --_d: 0%;
57
- border-left: var(--t) solid #0000;
58
- margin-right: var(--t);
59
- background-color: #fcd7ae;
60
- color:#4d4d4d;
61
- place-self: start;
62
- }
63
-
64
- .bubble > .content-left{
65
- margin-right: 10px;
66
- margin-bottom: 1px;
67
- }
68
-
69
- .right {
70
- --_d: 100%;
71
- border-right: var(--t) solid #0000;
72
- margin-left: var(--t);
73
- background-color: #fdeedb;
74
- color:#4d4d4d;
75
- place-self: end;
76
- }
77
-
78
- .bubble > .content-right{
79
- margin-bottom: 1px;
80
- margin-right: 10px;
81
- }
82
-
83
- .message{
84
- text-align: initial;
85
- word-break: break-all;
86
- margin-bottom: 10px;
87
- }
88
- .detail-message{
89
- font-size: 10px;
90
- color: #808080;
91
- display: flex;
92
- justify-content:space-between;
93
- }
94
-
95
- .chat-message {
96
- max-width: 250px;
97
- min-width: 90%;
98
- display: flex;
99
- flex-direction: column;
100
- justify-content: center;
101
- /* box-shadow: 0 2px 8px rgba(0, 0, 0, 20%); */
102
- }
103
-
104
- </style>