rio-assist-widget 0.1.35 → 0.1.36

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.
@@ -0,0 +1,46 @@
1
+ export type ConsultantAgentOption = {
2
+ id: string;
3
+ label: string;
4
+ };
5
+
6
+ export type ConsultantFollowUp = {
7
+ topicId: string;
8
+ topicLabel: string;
9
+ questions: string[];
10
+ };
11
+
12
+ export const CONSULTANT_AGENT_INTRO =
13
+ 'Olá! Sou o Agente Consultor. Em qual assunto posso ajudar você hoje?';
14
+
15
+ export const CONSULTANT_AGENT_OPTIONS: ConsultantAgentOption[] = [
16
+ { id: 'process-efficiency', label: 'Eficiência de Processo' },
17
+ { id: 'failure-modes', label: 'Modos de Falha' },
18
+ { id: 'network-performance', label: 'Performance de Rede' },
19
+ { id: 'tactical-management-aging', label: 'Gestão tática (Aging)' },
20
+ ];
21
+
22
+ export const CONSULTANT_AGENT_FOLLOW_UPS: Record<string, string[]> = {
23
+ 'process-efficiency': [
24
+ 'Qual é o gargalo médio de tempo antes do mecânico tocar no veículo?',
25
+ 'Por que temos uma média alta de 6,1 dias na abertura?',
26
+ 'O tempo de aprovação do cliente é alto. O que isso indica?',
27
+ ],
28
+ 'failure-modes': [
29
+ 'Qual é o componente nº 1 em volume de falhas?',
30
+ 'Como aplicar a estratégia de "ação massiva e acelerada" para Motor?',
31
+ 'O tempo de diagnóstico de Motor é alto. Qual a causa provável?',
32
+ ],
33
+ 'network-performance': [
34
+ 'Qual a diferença principal entre os problemas do Grupo Resende e Grupo Mônaco?',
35
+ "Onde o problema de 'Peças em Trânsito' é mais grave?",
36
+ 'Como identificar concessionárias com falta de boxes físicos?',
37
+ ],
38
+ 'tactical-management-aging': [
39
+ 'Quantos veículos estão parados por falta de peça há mais de 8 dias?',
40
+ "Quais casos de 'Aguardando Diagnóstico' são prioritários?",
41
+ 'Qual a proporção de chamados proativos vs. reativos?',
42
+ ],
43
+ };
44
+
45
+ export const buildConsultantFollowUpText = (topicLabel: string) =>
46
+ `Certo! Reuni abaixo as principais dúvidas sobre ${topicLabel}. Escolha uma delas ou faça sua pergunta.`;
@@ -0,0 +1,37 @@
1
+ import { html } from 'lit';
2
+ import type { RioAssistWidget } from '../components/rio-assist/rio-assist';
3
+
4
+ export const renderConsultantAgentHero = (component: RioAssistWidget) => {
5
+ const { consultantAgentVisible, consultantAgentIntro, consultantAgentOptions } = component;
6
+
7
+ return html`
8
+ <div class="consultant-agent">
9
+ <button
10
+ class="consultant-agent__button"
11
+ type="button"
12
+ @click=${() => component.handleConsultantAgentOpen()}
13
+ >
14
+ Fale com um consultor
15
+ </button>
16
+
17
+ ${consultantAgentVisible
18
+ ? html`
19
+ <div class="consultant-agent__intro">${consultantAgentIntro}</div>
20
+ <div class="consultant-agent__options">
21
+ ${consultantAgentOptions.map(
22
+ (option) => html`
23
+ <button
24
+ class="consultant-agent__option"
25
+ type="button"
26
+ @click=${() => component.handleConsultantAgentOption(option)}
27
+ >
28
+ ${option.label}
29
+ </button>
30
+ `,
31
+ )}
32
+ </div>
33
+ `
34
+ : null}
35
+ </div>
36
+ `;
37
+ };
@@ -0,0 +1,45 @@
1
+ import {
2
+ CONSULTANT_AGENT_INTRO,
3
+ CONSULTANT_AGENT_OPTIONS,
4
+ CONSULTANT_AGENT_FOLLOW_UPS,
5
+ buildConsultantFollowUpText,
6
+ type ConsultantAgentOption,
7
+ type ConsultantFollowUp,
8
+ } from './consultant-agent-mocks';
9
+
10
+ export type ConsultantAgentState = {
11
+ isVisible: boolean;
12
+ introText: string;
13
+ options: ConsultantAgentOption[];
14
+ };
15
+
16
+ export function getConsultantFollowUp(topicId: string, topicLabel: string): ConsultantFollowUp {
17
+ const questions = CONSULTANT_AGENT_FOLLOW_UPS[topicId] ?? [];
18
+ return {
19
+ topicId,
20
+ topicLabel,
21
+ questions,
22
+ };
23
+ }
24
+
25
+ export function createConsultantAgentState(): ConsultantAgentState {
26
+ return {
27
+ isVisible: false,
28
+ introText: CONSULTANT_AGENT_INTRO,
29
+ options: [...CONSULTANT_AGENT_OPTIONS],
30
+ };
31
+ }
32
+
33
+ export async function loadConsultantAgentOptions(): Promise<ConsultantAgentOption[]> {
34
+ // Mantido separado para facilitar a troca para dados vindos do backend futuramente.
35
+ return [...CONSULTANT_AGENT_OPTIONS];
36
+ }
37
+
38
+ export {
39
+ CONSULTANT_AGENT_INTRO,
40
+ CONSULTANT_AGENT_OPTIONS,
41
+ CONSULTANT_AGENT_FOLLOW_UPS,
42
+ buildConsultantFollowUpText,
43
+ type ConsultantAgentOption,
44
+ type ConsultantFollowUp,
45
+ };
package/src/main.ts CHANGED
@@ -9,6 +9,7 @@ export type RioAssistOptions = {
9
9
  accentColor?: string;
10
10
  apiBaseUrl?: string;
11
11
  rioToken?: string;
12
+ floatingOffset?: number;
12
13
  };
13
14
 
14
15
  const DEFAULT_OPTIONS: Required<Omit<RioAssistOptions, 'target'>> = {
@@ -29,6 +30,7 @@ const DEFAULT_OPTIONS: Required<Omit<RioAssistOptions, 'target'>> = {
29
30
  accentColor: '#008B9A',
30
31
  apiBaseUrl: '',
31
32
  rioToken: '',
33
+ floatingOffset: 32,
32
34
  };
33
35
 
34
36
  const widgetTagName = 'rio-assist-widget';
@@ -46,7 +48,17 @@ function ensureElement(options: RioAssistOptions = {}) {
46
48
  target.appendChild(widget);
47
49
  }
48
50
 
49
- const mergedOptions = { ...DEFAULT_OPTIONS, ...rest };
51
+ const topMargin = 96;
52
+ const buttonHeight = 64;
53
+ const viewport =
54
+ typeof window !== 'undefined'
55
+ ? window.innerHeight || document.documentElement.clientHeight || 0
56
+ : 0;
57
+ const computedFloatingOffset =
58
+ rest.floatingOffset ??
59
+ (viewport ? Math.max(12, viewport - topMargin - buttonHeight) : DEFAULT_OPTIONS.floatingOffset);
60
+
61
+ const mergedOptions = { ...DEFAULT_OPTIONS, ...rest, floatingOffset: computedFloatingOffset };
50
62
 
51
63
  Object.entries(mergedOptions).forEach(([key, value]) => {
52
64
  if (value === undefined) {
@@ -77,4 +89,3 @@ if (typeof window !== 'undefined') {
77
89
 
78
90
 
79
91
 
80
-