contactstudiocstools 1.0.224

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/README.md +94 -0
  2. package/dist/module.cjs +5 -0
  3. package/dist/module.d.ts +7 -0
  4. package/dist/module.json +5 -0
  5. package/dist/module.mjs +72 -0
  6. package/dist/runtime/components/Atom.Alert.vue +46 -0
  7. package/dist/runtime/components/Atom.Auth.vue +37 -0
  8. package/dist/runtime/components/Atom.BannerChatEmpty.vue +18 -0
  9. package/dist/runtime/components/Atom.BannerPage404.vue +28 -0
  10. package/dist/runtime/components/Atom.BannerPageUnauthorized.vue +18 -0
  11. package/dist/runtime/components/Atom.Breadcrumb.vue +26 -0
  12. package/dist/runtime/components/Atom.ChatContact.vue +136 -0
  13. package/dist/runtime/components/Atom.ChatContactSchedule.vue +87 -0
  14. package/dist/runtime/components/Atom.ChatMessageFooter.vue +25 -0
  15. package/dist/runtime/components/Atom.DarkMode.vue +67 -0
  16. package/dist/runtime/components/Atom.DraggableWindow.vue +102 -0
  17. package/dist/runtime/components/Atom.Dropdown.vue +9 -0
  18. package/dist/runtime/components/Atom.DropdownSearchable.vue +25 -0
  19. package/dist/runtime/components/Atom.Fetch.vue +46 -0
  20. package/dist/runtime/components/Atom.Field.vue +43 -0
  21. package/dist/runtime/components/Atom.FieldDate.vue +19 -0
  22. package/dist/runtime/components/Atom.FieldNumber.vue +19 -0
  23. package/dist/runtime/components/Atom.FieldPhone.vue +92 -0
  24. package/dist/runtime/components/Atom.FieldSelect.vue +28 -0
  25. package/dist/runtime/components/Atom.FieldSelectMultiple.vue +49 -0
  26. package/dist/runtime/components/Atom.FieldText.vue +19 -0
  27. package/dist/runtime/components/Atom.FieldTextarea.vue +41 -0
  28. package/dist/runtime/components/Atom.Loading.vue +80 -0
  29. package/dist/runtime/components/Atom.Notification.vue +48 -0
  30. package/dist/runtime/components/Atom.Ringtone.vue +23 -0
  31. package/dist/runtime/components/Atom.SelectTreeField.vue +49 -0
  32. package/dist/runtime/components/Atom.Snapshot.vue +33 -0
  33. package/dist/runtime/components/Atom.Tabs.vue +60 -0
  34. package/dist/runtime/components/Molecule.ChatMessageFile.vue +102 -0
  35. package/dist/runtime/components/Molecule.ChatMessageOption.vue +85 -0
  36. package/dist/runtime/components/Molecule.ChatMessageText.vue +36 -0
  37. package/dist/runtime/components/Molecule.ClientHistory.vue +62 -0
  38. package/dist/runtime/components/Molecule.DropdownDDI.vue +333 -0
  39. package/dist/runtime/components/Molecule.FieldGroup.vue +73 -0
  40. package/dist/runtime/components/Molecule.FieldSelectMultiple.vue +19 -0
  41. package/dist/runtime/components/Molecule.File.vue +84 -0
  42. package/dist/runtime/components/Molecule.SelectTreeSearchable.vue +126 -0
  43. package/dist/runtime/components/Molecule.Status.vue +154 -0
  44. package/dist/runtime/components/Molecule.TimeDaily.vue +9 -0
  45. package/dist/runtime/components/Organism.Attachments.vue +139 -0
  46. package/dist/runtime/components/Organism.ChatMessages.vue +31 -0
  47. package/dist/runtime/components/Organism.ChatRoom.vue +342 -0
  48. package/dist/runtime/components/Organism.ChatSchedule.vue +110 -0
  49. package/dist/runtime/components/Organism.ClientHistoryTable.vue +85 -0
  50. package/dist/runtime/components/Organism.ClientHistoryTimeline.vue +77 -0
  51. package/dist/runtime/components/Organism.FAQ.vue +88 -0
  52. package/dist/runtime/components/Organism.Form.vue +67 -0
  53. package/dist/runtime/components/Organism.FormMailing.vue +112 -0
  54. package/dist/runtime/components/Organism.HeaderMain.vue +79 -0
  55. package/dist/runtime/components/Organism.Manifestation.vue +146 -0
  56. package/dist/runtime/components/Organism.Nav.vue +27 -0
  57. package/dist/runtime/components/Organism.NavMain.vue +187 -0
  58. package/dist/runtime/components/Organism.PageContainer.vue +22 -0
  59. package/dist/runtime/components/Organism.Schedule.vue +170 -0
  60. package/dist/runtime/components/Organism.Tabulation.vue +237 -0
  61. package/dist/runtime/components/types/dto.d.ts +16 -0
  62. package/dist/runtime/components/types/dto.mjs +236 -0
  63. package/dist/runtime/components/types/helpers.d.ts +39 -0
  64. package/dist/runtime/components/types/helpers.mjs +295 -0
  65. package/dist/runtime/components/types/index.d.ts +4 -0
  66. package/dist/runtime/components/types/index.mjs +4 -0
  67. package/dist/runtime/components/types/types.d.ts +198 -0
  68. package/dist/runtime/components/types/types.mjs +35 -0
  69. package/dist/runtime/index.css +1 -0
  70. package/dist/runtime/plugins/clickOutside.d.ts +2 -0
  71. package/dist/runtime/plugins/clickOutside.mjs +16 -0
  72. package/dist/runtime/plugins/emitter.d.ts +2 -0
  73. package/dist/runtime/plugins/emitter.mjs +17 -0
  74. package/dist/runtime/public/192x192.png +0 -0
  75. package/dist/runtime/public/404.svg +1 -0
  76. package/dist/runtime/public/512x512.png +0 -0
  77. package/dist/runtime/public/chat.svg +138 -0
  78. package/dist/runtime/public/chatbg.png +0 -0
  79. package/dist/runtime/public/dev-sw.d.ts +0 -0
  80. package/dist/runtime/public/dev-sw.mjs +0 -0
  81. package/dist/runtime/public/empty.svg +1 -0
  82. package/dist/runtime/public/loading.svg +1 -0
  83. package/dist/runtime/public/messages.svg +1 -0
  84. package/dist/runtime/public/privacy.svg +1 -0
  85. package/dist/runtime/public/ringtone.mp3 +0 -0
  86. package/dist/runtime/public/security.svg +188 -0
  87. package/dist/runtime/public/snapshot.d.ts +15 -0
  88. package/dist/runtime/public/snapshot.mjs +77 -0
  89. package/dist/runtime/public/unauthorized.svg +1 -0
  90. package/dist/types.d.ts +10 -0
  91. package/package.json +50 -0
@@ -0,0 +1,146 @@
1
+ <template>
2
+ <article class="flex flex-col">
3
+ <MoleculeSelectTreeSearchable
4
+ ref="MoleculeSelectTreeSearchableEl"
5
+ :select-tree="selectTree"
6
+ :class="{ error: !isValid }"
7
+ label="Manifestação"
8
+ @add="add"
9
+ />
10
+
11
+ <div class="accordion accordion-bordered mt-3">
12
+ <details
13
+ v-for="(levels, i) in manifestations"
14
+ :key="i"
15
+ class="item"
16
+ >
17
+ <summary
18
+ arrow=""
19
+ class="!px-2 flex justify-between"
20
+ >
21
+ <div
22
+ class="flex flex-1 flex-wrap gap-1"
23
+ @click="link(i)"
24
+ >
25
+ <div class="px-1">
26
+ <i
27
+ v-if="levelLinked === i"
28
+ class="bi-check-circle-fill text-success"
29
+ />
30
+ <i
31
+ v-else
32
+ class="bi-check-circle-fill text-secondary opacity-50"
33
+ />
34
+ </div>
35
+
36
+ <span
37
+ v-for="({ label }, j) in levels"
38
+ :key="j"
39
+ class="badge badge-soft-secondary"
40
+ v-text="label"
41
+ />
42
+ </div>
43
+
44
+ <i
45
+ class="bi-x-circle-fill text-error px-2"
46
+ @click="remove(i)"
47
+ />
48
+ </summary>
49
+ </details>
50
+ </div>
51
+ </article>
52
+ </template>
53
+
54
+ <script setup lang="ts">
55
+ import { ref, reactive, computed } from "vue";
56
+ import { ISelectTree, INodes } from "./types";
57
+ import MoleculeSelectTreeSearchable from "./Molecule.SelectTreeSearchable.vue";
58
+ import { deepEqual } from "./types"
59
+
60
+ // props
61
+ interface Props {
62
+ selectTree: ISelectTree;
63
+ persist?: Function;
64
+ defaults?: INodes[];
65
+ }
66
+ const props = defineProps<Props>();
67
+
68
+ // computed
69
+ const isValid = computed<boolean>(() => !!manifestations.length);
70
+
71
+ // data
72
+ const MoleculeSelectTreeSearchableEl = ref<InstanceType<
73
+ typeof MoleculeSelectTreeSearchable
74
+ > | null>(null);
75
+ const manifestations = reactive<INodes[]>(props.defaults ?? []);
76
+ const levelLinked = ref<number | null>(null)
77
+
78
+ // methods
79
+ function link(index: number): void {
80
+ if (levelLinked.value === index) {
81
+ return unlink()
82
+ }
83
+
84
+ levelLinked.value = index
85
+ emit("link", manifestations[index])
86
+ }
87
+ function unlink(): void {
88
+ levelLinked.value = null
89
+ emit("unlink")
90
+ }
91
+ function remove(index: number) {
92
+ manifestations.splice(index, 1);
93
+ persist();
94
+ unlink()
95
+ }
96
+ function add(nodes: INodes): void {
97
+ if (thisNodesExists(nodes)) return;
98
+
99
+ manifestations.push(nodes);
100
+
101
+ persist();
102
+ }
103
+ function thisNodesExists(nodes: INodes): boolean {
104
+ if (!manifestations.length) return false;
105
+
106
+ for (const manifestation of manifestations) {
107
+ let equals = 0;
108
+
109
+ for (const index in nodes) {
110
+ if (deepEqual(manifestation[index], nodes[index])) {
111
+ equals++;
112
+ }
113
+ }
114
+
115
+ if (equals === nodes.length) {
116
+ return true;
117
+ }
118
+ }
119
+
120
+ return false;
121
+ }
122
+ function persist(): void {
123
+ if (!props.persist) return;
124
+
125
+ props.persist(manifestations)
126
+ }
127
+ function append(nodes: INodes[]): void {
128
+ manifestations.push(...nodes);
129
+ }
130
+ function reset(): void {
131
+ manifestations.length = 0;
132
+ unlink()
133
+ }
134
+
135
+ // emits
136
+ interface IEmits {
137
+ (e: "link", node: INodes): void
138
+ (e: "unlink"): void
139
+ }
140
+ const emit = defineEmits<IEmits>()
141
+
142
+ // expose
143
+ defineExpose({ manifestations, isValid, append, reset });
144
+ </script>
145
+
146
+ <style scoped></style>
@@ -0,0 +1,27 @@
1
+ <template>
2
+ <nav
3
+ :class="{ visible }"
4
+ class="sidenav scrollbar flex flex-col justify-between pt-20 pb-5"
5
+ @mouseenter="show"
6
+ @mouseleave="hide"
7
+ >
8
+ <slot />
9
+ </nav>
10
+ </template>
11
+
12
+ <script setup lang="ts">
13
+ import { ref } from "vue";
14
+
15
+ // data
16
+ const visible = ref<boolean>(false);
17
+
18
+ // methods
19
+ function show(): void {
20
+ visible.value = true;
21
+ }
22
+ function hide(): void {
23
+ visible.value = false;
24
+ }
25
+ </script>
26
+
27
+ <style scoped></style>
@@ -0,0 +1,187 @@
1
+ <template>
2
+ <nav
3
+ v-click-outside="outside"
4
+ :class="{ visible }"
5
+ class="sidenav flex flex-col justify-between pt-[64px] max-sm:w-0 pb-5 px-0"
6
+ @mouseenter="show"
7
+ @mouseleave="hide"
8
+ >
9
+ <div>
10
+ <!-- warns -->
11
+ <ul
12
+ :disabled="!warns?.length"
13
+ class="accordion mx-1 pt-2"
14
+ >
15
+ <details
16
+ id="accordion-warns"
17
+ class="item sidenav-item-full"
18
+ >
19
+ <summary class="flex items-center h-12 -mb-1 -mt-1">
20
+ <i
21
+ class="bi-exclamation-triangle-fill leading-none text-base text-warn -translate-x-[2px] mr-5"
22
+ />
23
+ <span class="inline-flex w-40">Avisos</span>
24
+
25
+ <span
26
+ v-if="warns?.length"
27
+ class="badge badge-solid-warn rounded w-5 h-5 flex justify-center items-center !p-0"
28
+ v-text="warns?.length"
29
+ />
30
+ </summary>
31
+ <article class="!pt-0 warn-items">
32
+ <p
33
+ v-for="(warn, i) in warns"
34
+ :key="i"
35
+ class="text-xs w-60 my-2"
36
+ v-text="warn"
37
+ />
38
+ </article>
39
+ </details>
40
+ </ul>
41
+
42
+ <div class="divider" />
43
+
44
+ <!-- pages -->
45
+ <NuxtLink
46
+ v-for="({ icon, label, path, name }, i) in pages"
47
+ :key="i"
48
+ :to="path"
49
+ class="list sidenav-item-full"
50
+ @click="outside"
51
+ >
52
+ <li
53
+ class="item sidenav-item mb-2 mx-1"
54
+ :class="{ 'bg-slate-100 dark:bg-slate-800': isPageActive(name) }"
55
+ >
56
+ <i
57
+ :class="icon"
58
+ class="text-base leading-none -translate-x-[2px] mr-5"
59
+ />
60
+ {{ label }}
61
+ </li>
62
+ </NuxtLink>
63
+
64
+ <div class="divider my-3" />
65
+
66
+ <!-- FAQ -->
67
+ <aside
68
+ v-if="FAQIsNotEmpty"
69
+ class="mx-1"
70
+ >
71
+ <ul
72
+ v-show="!visible"
73
+ class="list"
74
+ >
75
+ <li class="item">
76
+ <i class="bi-search -translate-x-[2px]" />
77
+ </li>
78
+ </ul>
79
+
80
+ <div v-show="visible">
81
+ <OrganismFAQ
82
+ :doubts="doubts ?? []"
83
+ class="w-72 max-h-72 overflow-y-auto scrollbar px-2"
84
+ />
85
+ </div>
86
+ <div class="divider my-3" />
87
+ </aside>
88
+ </div>
89
+
90
+ <div>
91
+ <!-- darkmode -->
92
+ <ul class="list sidenav-item-full px-1 mt-1">
93
+ <li
94
+ class="item flex justify-between items-center sidenav-item active"
95
+ @click="changeMode"
96
+ >
97
+ <span v-if="visible">Aparência</span>
98
+ <AtomDarkMode class="-ml-3 pointer-events-none" />
99
+ </li>
100
+ </ul>
101
+ <div class="divider" />
102
+
103
+ <!-- exit -->
104
+ <ul
105
+ :disabled="!exit"
106
+ class="list sidenav-item-full px-1"
107
+ >
108
+ <li
109
+ class="item sidenav-item !text-error"
110
+ @click="logout"
111
+ >
112
+ <i class="bi-box-arrow-in-left text-lg leading-none mr-5" />
113
+ Sair
114
+ </li>
115
+ </ul>
116
+ </div>
117
+ </nav>
118
+ </template>
119
+
120
+ <script setup lang="ts">
121
+ import { ref, computed } from "vue";
122
+ import { useRoute, useNuxtApp } from "#app";
123
+ import { IDoubts, IPages } from "./types";
124
+
125
+ // props
126
+ interface IProps {
127
+ pages: IPages;
128
+ warns?: string[];
129
+ doubts?: IDoubts;
130
+ exit?: boolean;
131
+ logout?: Function;
132
+ }
133
+ const props = defineProps<IProps>();
134
+
135
+ // app
136
+ const { $listen, $emit } = useNuxtApp();
137
+
138
+ // computed
139
+ const isPageActive = computed<Function>(() => (page: string) => {
140
+ return page === useRoute().name;
141
+ });
142
+ const FAQIsNotEmpty = computed<boolean>(() => !!props.doubts?.length);
143
+
144
+ // data
145
+
146
+ const visible = ref<boolean>(false);
147
+
148
+ // methods
149
+ function show(): void {
150
+ visible.value = true;
151
+ }
152
+ function hide(): void {
153
+ visible.value = false;
154
+ closeWarns();
155
+ }
156
+ function outside(e: MouseEvent): void {
157
+ const isOpenNavButton = (e.target as HTMLElement).id === "navopen";
158
+
159
+ if (isOpenNavButton && visible.value) return;
160
+
161
+ $emit("nav:hide");
162
+
163
+ hide();
164
+ }
165
+ function closeWarns(): void {
166
+ document.getElementById("accordion-warns")?.removeAttribute("open");
167
+ }
168
+ function logout(): void {
169
+ if (props.logout) props.logout();
170
+ }
171
+ function changeMode(): void {
172
+ $emit("darkmode:change")
173
+ }
174
+
175
+ // emits
176
+ $listen("nav:show", show);
177
+ </script>
178
+
179
+ <style scoped>
180
+ nav {
181
+ transition: all 0.3s;
182
+ }
183
+
184
+ .warn-items {
185
+ overflow-wrap: break-word;
186
+ }
187
+ </style>
@@ -0,0 +1,22 @@
1
+ <template>
2
+ <article
3
+ v-if="allowed"
4
+ class="text-sm min-h-screen overflow-hidden pt-[64px] sm:pl-[60px] dark:text-white"
5
+ >
6
+ <slot />
7
+ </article>
8
+ <AtomBannerPageUnauthorized
9
+ v-else
10
+ class="min-h-screen max-h-screen"
11
+ />
12
+ </template>
13
+
14
+ <script setup lang="ts">
15
+ // props
16
+ interface IProps {
17
+ allowed?: boolean;
18
+ }
19
+ defineProps<IProps>();
20
+ </script>
21
+
22
+ <style scoped></style>
@@ -0,0 +1,170 @@
1
+ <template>
2
+ <div class="accordion accordion-bordered">
3
+ <!-- items -->
4
+ <details
5
+ v-for="(schedule, i) in schedules"
6
+ :key="i"
7
+ class="item"
8
+ >
9
+ <!-- header -->
10
+ <summary class="flex justify-between items-center">
11
+ <!-- info -->
12
+ <div class="flex flex-wrap items-center">
13
+ <span
14
+ :class="getPriorityColor(schedule)"
15
+ class="h-2 w-2 rounded-full mr-2"
16
+ />
17
+
18
+ <span
19
+ v-if="schedule.customerID"
20
+ class="badge badge-solid-secondary mr-2"
21
+ v-text="schedule.customerID"
22
+ />
23
+ <span class="badge badge-soft-secondary mr-2">
24
+ <i class="bi-clock-history" />
25
+ {{ schedule.scheduling.toDateString() }}
26
+ </span>
27
+ <span v-text="schedule.contactName" />
28
+ </div>
29
+
30
+ <!-- treat button -->
31
+ <button
32
+ class="btn btn-outline-secondary mr-2"
33
+ @click="treat(schedule)"
34
+ >
35
+ Tratar Caso
36
+ </button>
37
+ </summary>
38
+
39
+ <!-- content -->
40
+ <article>
41
+ <AtomTabs
42
+ :tabs="['contact', 'mailing']"
43
+ @change="(tab: string) => change(tab, schedule)"
44
+ >
45
+ <!-- contact -->
46
+ <template #hcontact>
47
+ <i class="bi-person-fill mr-1" /> Contato
48
+ </template>
49
+ <template #contact>
50
+ <div class="flex flex-wrap">
51
+ <!-- cardID -->
52
+ <div class="m-2">
53
+ <p class="font-medium text-xs mb-2">
54
+ CardID
55
+ </p>
56
+ <span
57
+ class="badge badge-soft-secondary"
58
+ v-text="schedule.cardID"
59
+ />
60
+ </div>
61
+ <!-- lastInteraction -->
62
+ <div class="m-2">
63
+ <p class="font-medium text-xs mb-2">
64
+ Ultima Interação
65
+ </p>
66
+ <span class="badge badge-soft-secondary">
67
+ <i class="bi-calendar-check" />
68
+ {{ schedule.lastInteraction.toDateString() }}
69
+ </span>
70
+ </div>
71
+ <!-- lastTabulation -->
72
+ <div class="m-2">
73
+ <p class="font-medium text-xs mb-2">
74
+ Ultima Tabulação
75
+ </p>
76
+ <span class="badge badge-soft-secondary">
77
+ <i class="bi-calendar-check" />
78
+ {{ schedule.lastTabulation.toDateString() }}
79
+ </span>
80
+ </div>
81
+ <!-- scheduling -->
82
+ <div class="m-2">
83
+ <p class="font-medium text-xs mb-2">
84
+ Agendamento
85
+ </p>
86
+ <span class="badge badge-soft-secondary">
87
+ <i class="bi-calendar-plus" />
88
+ {{ schedule.scheduling.toDateString() }}
89
+ </span>
90
+ </div>
91
+ </div>
92
+ </template>
93
+
94
+ <!-- mailing -->
95
+ <template #hmailing>
96
+ <i class="bi-pen-fill mr-1" /> Dados
97
+ </template>
98
+ <template #mailing>
99
+ <article class="flex flex-wrap">
100
+ <i
101
+ v-if="mailingIsEmpty"
102
+ class="spin"
103
+ />
104
+
105
+ <div
106
+ v-for="(field, label) in mailing[schedule.cardID]"
107
+ :key="label"
108
+ class="m-2"
109
+ >
110
+ <p
111
+ class="font-medium text-xs mb-2"
112
+ v-text="label"
113
+ />
114
+ <span
115
+ class="badge badge-soft-secondary"
116
+ v-text="field"
117
+ />
118
+ </div>
119
+ </article>
120
+ </template>
121
+ </AtomTabs>
122
+ </article>
123
+ </details>
124
+ </div>
125
+ </template>
126
+
127
+ <script setup lang="ts">
128
+ import { computed, reactive } from "vue";
129
+ import { ISchedule, ISchedules } from "./types";
130
+
131
+ // props
132
+ interface IProps {
133
+ schedules: ISchedules;
134
+ load: Function;
135
+ }
136
+ const props = defineProps<IProps>();
137
+
138
+ // emits
139
+ interface IEmits {
140
+ (e: "treat", schedule: ISchedule): void;
141
+ }
142
+ const emit = defineEmits<IEmits>();
143
+
144
+ // computed
145
+ const getPriorityColor = computed<Function>(() => ({ priority }: ISchedule) => {
146
+ if (!priority) return "bg-green-500";
147
+ if (priority === 1) return "bg-amber-500";
148
+ if (priority === 2) return "bg-red-500";
149
+ });
150
+ const mailingIsEmpty = computed<boolean>(() => {
151
+ return !Object.keys(mailing).length;
152
+ });
153
+
154
+ // data
155
+ const mailing = reactive<any>({});
156
+
157
+ // methods
158
+ function treat(schedule: ISchedule): void {
159
+ emit("treat", schedule);
160
+ }
161
+ async function change(tab: string, schedule: ISchedule): Promise<void> {
162
+ if (tab !== "mailing") return;
163
+
164
+ if (mailing[schedule.cardID]) return;
165
+
166
+ mailing[schedule.cardID] = await props.load(schedule);
167
+ }
168
+ </script>
169
+
170
+ <style scoped></style>