contactstudiocstools 1.0.258 → 1.0.259
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
CHANGED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- contact -->
|
|
3
|
+
<li class="chat-contact flex items-center !pl-3 max-h-none !rounded-none">
|
|
4
|
+
<!-- avatar -->
|
|
5
|
+
<figure
|
|
6
|
+
:class="[getStatusClass]"
|
|
7
|
+
:notifications="contact.notifications"
|
|
8
|
+
class="w-9 h-9 rounded-full avatar-glass avatar-soft-secondary"
|
|
9
|
+
>
|
|
10
|
+
<img
|
|
11
|
+
v-if="contact.avatar"
|
|
12
|
+
:src="contact.avatar"
|
|
13
|
+
class="rounded-md"
|
|
14
|
+
>
|
|
15
|
+
<i
|
|
16
|
+
v-else
|
|
17
|
+
class="bi-person-fill text-2xl"
|
|
18
|
+
/>
|
|
19
|
+
</figure>
|
|
20
|
+
|
|
21
|
+
<!-- info -->
|
|
22
|
+
<div
|
|
23
|
+
class="flex-1 ml-3 py-2 !pr-3 w-24 chat-contact-border"
|
|
24
|
+
:class="{'border-t-2': index === 0}"
|
|
25
|
+
>
|
|
26
|
+
<p class="flex justify-between items-center overflow-hidden text-ellipsis whitespace-nowrap mb-1">
|
|
27
|
+
<!-- label -->
|
|
28
|
+
<span class="text-xs">
|
|
29
|
+
{{ contact.label }}
|
|
30
|
+
</span>
|
|
31
|
+
|
|
32
|
+
<!-- hours
|
|
33
|
+
<span
|
|
34
|
+
v-if="entryDateExists"
|
|
35
|
+
class="badge badge-outline-secondary ml-2"
|
|
36
|
+
tooltip="Tempo em atendimento"
|
|
37
|
+
>
|
|
38
|
+
{{ new Date(milliseconds).toISOString().slice(11, 19) }}
|
|
39
|
+
</span>
|
|
40
|
+
-->
|
|
41
|
+
|
|
42
|
+
<div class="flex items-center gap-1">
|
|
43
|
+
<!-- date message -->
|
|
44
|
+
<p
|
|
45
|
+
class="badge !p-0 text-secondary"
|
|
46
|
+
tooltip="Horário da última mensagem"
|
|
47
|
+
>
|
|
48
|
+
{{ getDate }}
|
|
49
|
+
</p>
|
|
50
|
+
<!-- expirate -->
|
|
51
|
+
<div
|
|
52
|
+
v-if="expirated"
|
|
53
|
+
tooltip="Envie uma mensagem para o cliente!"
|
|
54
|
+
class="flex justify-center items-center relative"
|
|
55
|
+
>
|
|
56
|
+
<div class="flex justify-center items-center rounded-full bg-error h-4 w-4">
|
|
57
|
+
<i class="bi bi-bell-fill text-white text-[8.4px] ml-[1px]" />
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
</p>
|
|
62
|
+
<!-- typing -->
|
|
63
|
+
<p
|
|
64
|
+
v-if="contact.typing"
|
|
65
|
+
class="text-2xs text-success"
|
|
66
|
+
>
|
|
67
|
+
Digitando...
|
|
68
|
+
</p>
|
|
69
|
+
<!-- message -->
|
|
70
|
+
<div
|
|
71
|
+
v-else
|
|
72
|
+
class="markdown text-2xs opacity-50 w-full overflow-hidden text-ellipsis whitespace-nowrap"
|
|
73
|
+
v-html="marked(props.contact.message ?? '')"
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
</li>
|
|
77
|
+
</template>
|
|
78
|
+
|
|
79
|
+
<script setup lang="ts">
|
|
80
|
+
import { marked } from "marked";
|
|
81
|
+
import { ref, computed, onMounted } from "vue";
|
|
82
|
+
import { getMinutesBetweenDates, getTimeByDate, IChatContact } from "./types";
|
|
83
|
+
|
|
84
|
+
// props
|
|
85
|
+
interface IProps {
|
|
86
|
+
contact: IChatContact;
|
|
87
|
+
timeout: number;
|
|
88
|
+
index: number;
|
|
89
|
+
}
|
|
90
|
+
const props = defineProps<IProps>();
|
|
91
|
+
|
|
92
|
+
// mounted
|
|
93
|
+
onMounted(() => {
|
|
94
|
+
setInterval(validateExpiration, 1000);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// computed
|
|
98
|
+
const getDate = computed<string>(() => {
|
|
99
|
+
const date = props.contact.date;
|
|
100
|
+
if (!date) return "";
|
|
101
|
+
return getTimeByDate(date);
|
|
102
|
+
});
|
|
103
|
+
const entryDateExists = computed<boolean>(() => !!props.contact.entrydate)
|
|
104
|
+
const getStatusClass = computed<string>(() => {
|
|
105
|
+
if (props.contact.on) return "avatar-status-success";
|
|
106
|
+
return "avatar-status-error";
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// data
|
|
110
|
+
const expirated = ref<boolean>(false);
|
|
111
|
+
const milliseconds = ref<number>(0)
|
|
112
|
+
|
|
113
|
+
// methods
|
|
114
|
+
function validateExpiration() {
|
|
115
|
+
if (!props.contact.date) return;
|
|
116
|
+
expirated.value =
|
|
117
|
+
getMinutesBetweenDates(new Date(), props.contact.date) >= props.timeout;
|
|
118
|
+
}
|
|
119
|
+
async function setTimerContact(): Promise<void> {
|
|
120
|
+
if (!props.contact.entrydate) return
|
|
121
|
+
|
|
122
|
+
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
123
|
+
|
|
124
|
+
const now = new Date().getTime()
|
|
125
|
+
const entry = props.contact.entrydate.getTime()
|
|
126
|
+
|
|
127
|
+
milliseconds.value = Math.abs(now - entry)
|
|
128
|
+
|
|
129
|
+
setTimerContact()
|
|
130
|
+
}
|
|
131
|
+
setTimerContact()
|
|
132
|
+
</script>
|
|
133
|
+
|
|
134
|
+
<style scoped>
|
|
135
|
+
.min-w-40px {
|
|
136
|
+
min-width: 40px;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.text-2xs {
|
|
140
|
+
font-size: 0.7rem;
|
|
141
|
+
}
|
|
142
|
+
.avatar-glass {
|
|
143
|
+
align-items: center;
|
|
144
|
+
display: flex;
|
|
145
|
+
font-weight: 500;
|
|
146
|
+
justify-content: center;
|
|
147
|
+
position: relative;
|
|
148
|
+
text-transform: uppercase;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.avatar-glass:after,.avatar-glass:not(.avatar-glass[notifications]):after {
|
|
152
|
+
border-radius: 99999px;
|
|
153
|
+
border: 3px solid #ffffff;
|
|
154
|
+
color: #fff;
|
|
155
|
+
font-size: 11px;
|
|
156
|
+
height: 15px;
|
|
157
|
+
width: 15px;
|
|
158
|
+
position: absolute;
|
|
159
|
+
right: 0;
|
|
160
|
+
top: 0;
|
|
161
|
+
transform: translate(40%,-40%)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.avatar-glass:not([notifications=""]):after {
|
|
165
|
+
content: attr(notifications);
|
|
166
|
+
width: 25px;
|
|
167
|
+
height: 25px;
|
|
168
|
+
display: flex;
|
|
169
|
+
justify-content: center;
|
|
170
|
+
align-items: center
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.chat-contact:hover {
|
|
174
|
+
cursor: pointer;
|
|
175
|
+
background-color: rgba(0, 0, 0, 0.05);
|
|
176
|
+
}
|
|
177
|
+
.dark .chat-contact:hover {
|
|
178
|
+
background-color: rgba(255, 255, 255, 0.05);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.chat-contact-border {
|
|
182
|
+
border-bottom: 2px;
|
|
183
|
+
border-style: solid;
|
|
184
|
+
border-color: rgba(0, 0, 0, 0.2);
|
|
185
|
+
}
|
|
186
|
+
</style>
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div class="flex items-center text-xs">
|
|
4
|
+
<span class="w-full px-6 py-5 text-xl">
|
|
5
|
+
Conversas
|
|
6
|
+
</span>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<article class="overflow-auto max-h-full scrollbar pb-24">
|
|
10
|
+
<!-- contacts -->
|
|
11
|
+
<div
|
|
12
|
+
v-for="(contact, i) in contacts"
|
|
13
|
+
v-show="!visibleSchedules"
|
|
14
|
+
:key="i"
|
|
15
|
+
>
|
|
16
|
+
<ul class="list">
|
|
17
|
+
<AtomChatContactGlass
|
|
18
|
+
:timeout="timeout"
|
|
19
|
+
:contact="contact"
|
|
20
|
+
:class="getSelectedClass(contact)"
|
|
21
|
+
:index="i"
|
|
22
|
+
@click="select(contact)"
|
|
23
|
+
/>
|
|
24
|
+
</ul>
|
|
25
|
+
</div>
|
|
26
|
+
</article>
|
|
27
|
+
</div>
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<script setup lang="ts">
|
|
31
|
+
import { ref, computed } from "vue";
|
|
32
|
+
import { IChatContact, IChatContacts, IPortfolioSchedules } from "./types";
|
|
33
|
+
|
|
34
|
+
// props
|
|
35
|
+
interface IProps {
|
|
36
|
+
contacts: IChatContacts;
|
|
37
|
+
schedules: IPortfolioSchedules;
|
|
38
|
+
selected?: IChatContact;
|
|
39
|
+
timeout: number;
|
|
40
|
+
}
|
|
41
|
+
const props = defineProps<IProps>();
|
|
42
|
+
|
|
43
|
+
// emits
|
|
44
|
+
interface IEmits {
|
|
45
|
+
(e: "select", contact: IChatContact): void;
|
|
46
|
+
(e: "schedule", schedule: boolean): void;
|
|
47
|
+
}
|
|
48
|
+
const emit = defineEmits<IEmits>();
|
|
49
|
+
|
|
50
|
+
// computed
|
|
51
|
+
const getSelectedClass = computed<Function>(() => (contact: IChatContact) => {
|
|
52
|
+
if (props.selected?.id === contact.id)
|
|
53
|
+
return "bg-slate-100 dark:bg-slate-800";
|
|
54
|
+
return "";
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// data
|
|
58
|
+
const visibleSchedules = ref<boolean>(false)
|
|
59
|
+
|
|
60
|
+
// methods
|
|
61
|
+
function select(contact: IChatContact): void {
|
|
62
|
+
emit("select", contact);
|
|
63
|
+
}
|
|
64
|
+
function changeSchedule(): void {
|
|
65
|
+
visibleSchedules.value = !visibleSchedules.value
|
|
66
|
+
emit("schedule", visibleSchedules.value);
|
|
67
|
+
}
|
|
68
|
+
</script>
|
|
69
|
+
|
|
70
|
+
<style scoped>
|
|
71
|
+
.text-2xs {
|
|
72
|
+
font-size: 0.7rem;
|
|
73
|
+
}
|
|
74
|
+
</style>
|