PageSourceSearch

https://chatbotclinicas.lovable.app/assets/widget-CR0sluj5.js

js chatbotclinicas.lovable.app collected 2026-10-03 03:23:46 UTC 9,715 bytes, 1 lines download raw bytes

1import{r,j as t}from"./index-7TS4WVEu.js";import{B as G}from"./bot-Bnd11nYo.js";import{M as P}from"./message-circle-Be8p4gt5.js";import{P as L}from"./phone-call-DmJQQIdI.js";import{M as U}from"./map-pin-Dg_7UkNv.js";import{c as N}from"./createLucideIcon-LmYyGKNQ.js";const B=[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",key:"1ffxy3"}],["path",{d:"m21.854 2.147-10.94 10.939",key:"12cjpa"}]],Q=N("send",B);const $=[["path",{d:"M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z",key:"m61m77"}],["path",{d:"M17 14V2",key:"8ymqnk"}]],K=N("thumbs-down",$);const H=[["path",{d:"M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z",key:"emmmcr"}],["path",{d:"M7 10v12",key:"1qc93n"}]],V=N("thumbs-up",H);function q(){return typeof window>"u"?"bocabocakids":(new URLSearchParams(window.location.search).get("clinic")||"").trim()||"bocabocakids"}const J="bbk_visitor_id",T="bbk_conversation_id",j="bbk_messages_v1",F=720*60*1e3,z=50;function h(c,o){return`${c}_${o}`}function Z(c){try{const o=localStorage.getItem(h(T,c)),g=localStorage.getItem(h(j,c));if(!o||!g)return null;const n=JSON.parse(g);return!n?.conversationId||n.conversationId!==o||!Array.isArray(n.messages)||n.messages.length===0?null:Date.now()-(n.savedAt??0)>F?(localStorage.removeItem(h(j,c)),null):n}catch{return null}}const p={primary_color:"#0ea5e9",welcome_message:"¡Hola! 👋 Soy el asistente de Boca Boca Kids. ¿En qué puedo ayudarte hoy?",header_title:"Boca Boca Kids",header_subtitle:"Te respondemos al momento"},W={"pedir cita":"Quiero pedir cita","información tratamientos":"¿Qué tratamientos ofrecéis?","informacion tratamientos":"¿Qué tratamientos ofrecéis?",tratamientos:"¿Qué tratamientos ofrecéis?",horario:"¿Cuál es vuestro horario?",horarios:"¿Cuál es vuestro horario?",ubicación:"¿Dónde estáis ubicados?",ubicacion:"¿Dónde estáis ubicados?",dirección:"¿Cuál es vuestra dirección?",direccion:"¿Cuál es vuestra dirección?",precios:"¿Cuáles son vuestros precios?",contacto:"¿Cómo puedo contactaros?"};function X(c){const o=c.trim().toLowerCase();return W[o]??c}function Y(){return typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID():"v-"+Math.random().toString(36).slice(2)+Date.now().toString(36)}function re(){const o=r.useRef(typeof window<"u"?q():"bocabocakids").current,g=h(J,o),n=h(T,o),y=h(j,o),[u,D]=r.useState(p),k=r.useRef(typeof window<"u"?Z(o):null),[d,x]=r.useState(k.current?.messages??[{role:"assistant",content:p.welcome_message}]),[w,I]=r.useState(""),[m,R]=r.useState(!1),[E,A]=r.useState([]),v=r.useRef(null),_=r.useRef(null),C=k.current!=null;r.useEffect(()=>{let e=!1;return fetch(`/api/public/widget-config?clinic=${encodeURIComponent(o)}`).then(s=>s.json()).then(s=>{if(e||!s)return;const a={primary_color:s.primary_color??p.primary_color,welcome_message:s.welcome_message??p.welcome_message,header_title:s.header_title??p.header_title,header_subtitle:s.header_subtitle??p.header_subtitle};D(a),x(l=>!C&&l.length===1&&l[0].role==="assistant"?[{role:"assistant",content:a.welcome_message}]:l)}).catch(()=>{}),()=>{e=!0}},[o,C]),r.useEffect(()=>{v.current?.scrollTo({top:v.current.scrollHeight,behavior:"smooth"})},[d,m]),r.useEffect(()=>{_.current?.focus()},[]),r.useEffect(()=>{try{const e=localStorage.getItem(n);if(!e||d.length<=1&&d[0]?.role==="assistant")return;const s={conversationId:e,savedAt:Date.now(),messages:d.slice(-z)};localStorage.setItem(y,JSON.stringify(s))}catch{}},[d,n,y]);async function S(e){const s=(e??w).trim();if(!(!s||m)){e||I(""),A([]),x(a=>[...a,{role:"user",content:s}]),R(!0);try{let a=localStorage.getItem(g);a||(a=Y(),localStorage.setItem(g,a));const l=localStorage.getItem(n),b=await fetch("/api/public/chat",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({clinic:o,visitorId:a,conversationId:l,message:s,pageUrl:document.referrer||window.location.href,userAgent:navigator.userAgent})}),i=await b.json();if(!b.ok)throw new Error(i.error||"Error");
1if(i.conversationId){const f=localStorage.getItem(n);f&&f!==i.conversationId&&localStorage.removeItem(y),localStorage.setItem(n,i.conversationId)}x(f=>[...f,{role:"assistant",content:i.reply??"",action:i.action??null,messageId:i.messageId??null,feedback:null}]),i.quickReplies?.length&&A(i.quickReplies)}catch(a){x(l=>[...l,{role:"assistant",content:a instanceof Error&&a.message?a.message:"Lo siento, ha habido un problema. Inténtalo de nuevo."}])}finally{R(!1),setTimeout(()=>_.current?.focus(),50)}}}async function M(e,s){const a=d[e];if(!a||!a.messageId)return;const l=localStorage.getItem(n);if(l){x(b=>b.map((i,f)=>f===e?{...i,feedback:s}:i));try{await fetch("/api/public/feedback",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({messageId:a.messageId,conversationId:l,rating:s})})}catch{}}}function O(e){e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),S())}return t.jsxs("div",{className:"h-screen w-screen flex flex-col bg-background overflow-hidden",children:[t.jsxs("header",{className:"border-b border-border px-4 py-3 flex items-center gap-3",style:{background:u.primary_color,color:"#fff"},children:[t.jsx("div",{className:"flex h-9 w-9 items-center justify-center rounded-lg bg-white/20",children:t.jsx(G,{className:"h-5 w-5"})}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsx("div",{className:"text-sm font-semibold leading-tight",children:u.header_title}),t.jsxs("div",{className:"text-xs opacity-90 flex items-center gap-1.5",children:[t.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-emerald-300"}),u.header_subtitle]})]})]}),t.jsxs("div",{ref:v,className:"flex-1 overflow-y-auto px-4 py-4 space-y-3",children:[d.map((e,s)=>t.jsx("div",{className:e.role==="user"?"flex justify-end":"flex justify-start",children:e.role==="user"?t.jsx("div",{className:"max-w-[80%] rounded-2xl rounded-br-sm px-3.5 py-2 text-sm whitespace-pre-wrap text-white",style:{background:u.primary_color},children:e.content}):t.jsxs("div",{className:"max-w-[85%] space-y-2",children:[t.jsx("div",{className:"text-sm text-foreground whitespace-pre-wrap leading-relaxed",children:e.content}),e.action?.type==="whatsapp"&&t.jsxs("a",{href:e.action.url,target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium text-white shadow-sm hover:opacity-90 transition-opacity",style:{background:"#25D366"},children:[t.jsx(P,{className:"h-4 w-4"}),e.action.label]}),e.action?.type==="call_confirmed"&&t.jsxs("div",{className:"inline-flex items-center gap-2 rounded-full bg-emerald-50 border border-emerald-200 px-4 py-2 text-sm font-medium text-emerald-700",children:[t.jsx(L,{className:"h-4 w-4"}),e.action.label]}),e.action?.type==="location"&&t.jsxs("div",{className:"space-y-1.5",children:[e.action.address&&t.jsx("div",{className:"text-xs text-muted-foreground",children:e.action.address}),t.jsxs("a",{href:e.action.url,target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium text-white shadow-sm hover:opacity-90 transition-opacity",style:{background:"#1a73e8"},children:[t.jsx(U,{className:"h-4 w-4"}),e.action.label]})]}),e.messageId&&s>0&&t.jsxs("div",{className:"flex items-center gap-1 pt-0.5",children:[t.jsx("button",{onClick:()=>M(s,1),disabled:e.feedback!=null,className:`p-1.5 rounded-full transition-colors ${e.feedback===1?"bg-emerald-100 text-emerald-700":"text-muted-foreground hover:bg-muted disabled:opacity-50"}`,"aria-label":"Útil",children:t.jsx(V,{className:"h-3 w-3"})}),t.jsx("button",{onClick:()=>M(s,-1),disabled:e.feedback!=null,className:`p-1.5 rounded-full transition-colors ${e.feedback===-1?"bg-rose-100 text-rose-700":"text-muted-foreground hover:bg-muted disabled:opacity-50"}`,"aria-label":"No útil",children:t.jsx(K,{className:"h-3 w-3"})})]})]})},s)),m&&t.jsxs("div",{className:"flex items-center gap-1.5 text-sm text-muted-foreground px-2",children:[t.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-muted-foreground animate-bounce",style:{animationDelay:"0ms"}}),t.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-muted-foreground animate-bounce",style:{animationDelay:"150ms"}}),t.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-muted-foreground animate-bounce",style:{animationDelay:"300ms"}})]}),!m&&E.length>0&&t.jsx("div",{className:"flex flex-wrap gap-2 pt-1",children:E.map(e=>t.jsx("button",{onClick:()=>{S(X(e))},className:"px-3 py-1.5 rounded-full border border-border bg-card text-xs font-medium hover:bg-muted transition-colors",children:e},e))})]}),t.jsxs("div",{className:"border-t border-border p-3 bg-card",children:[t.jsxs("div",{className:"flex items-end gap-2 rounded-2xl border border-border bg-background px-3 py-2 focus-within:ring-2 focus-within:ring-ring",children:[t.jsx("textarea",{ref:_,value:w,onChange:e=>I(e.target.value),onKeyDown:O,placeholder:"Escribe tu mensaje…",rows:1,className:"flex-1 resize-none bg-transparent text-sm outline-none max-h-32 py-1",disabled:m}),t.jsx("button",{onClick:()=>{S()},disabled:m||!w.trim(),className:"flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-white disabled:opacity-40 transition-opacity",style:{background:u.primary_color},"aria-label":"Enviar",children:t.jsx(Q,{className:"h-4 w-4"})})]}),t.jsxs("div",{className:"text-[10px] text-muted-foreground text-center mt-2",children:["Asistente con IA · ",u.header_title]})]})]})}export{re as component};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.