PageSourceSearch

https://www.centroatencaooftalmologia.com.br/assets/admin.tutorial-DycQIm4P.js

js centroatencaooftalmologia.com.br collected 2026-10-09 22:03:48 UTC 40,697 bytes, 1 lines download raw bytes

vendor: 10,910 bytes, line 1
1import{l as X,d as c,a6 as P,a7 as ve,j as o,a8 as R,a9 as W,aa as Se,ab as w,ac as C,ad as ye,ae as Ce,af as ee,ag as V,U,V as F,I as we,ah as Ae,a4 as je,ai as Pe,aj as Ne,M as Ee,a0 as Re,ak as ke,h as Te,x as De,al as _e,w as oe}from"./index-BjLsg-Ak.js";import{D as qe,a as Le,b as Oe,c as Ie,d as We}from"./dialog-B9fRFhMx.js";import{D as Me}from"./download-yDR7tvJH.js";import{S as ze}from"./search-BrMqtyiZ.js";import{F as He}from"./file-text-B24Ik-iR.js";import{C as Be}from"./chevron-right-f-TaOkac.js";const Ue=[["path",{d:"M9 9.003a1 1 0 0 1 1.517-.859l4.997 2.997a1 1 0 0 1 0 1.718l-4.997 2.997A1 1 0 0 1 9 14.996z",key:"kmsa83"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]],Fe=X("circle-play",Ue);const Ve=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20",key:"13o1zl"}],["path",{d:"M2 12h20",key:"9i4pu4"}]],Xe=X("globe",Ve);const Ye=[["line",{x1:"10",x2:"14",y1:"2",y2:"2",key:"14vaq8"}],["line",{x1:"12",x2:"15",y1:"14",y2:"11",key:"17fdiu"}],["circle",{cx:"12",cy:"14",r:"8",key:"1e1u0o"}]],ae=X("timer",Ye);function Qe(e,r){return c.useReducer((a,n)=>r[a][n]??a,e)}var Y="ScrollArea",[re]=Se(Y),[$e,b]=re(Y),te=c.forwardRef((e,r)=>{const{__scopeScrollArea:a,type:n="hover",dir:t,scrollHideDelay:i=600,...l}=e,[d,s]=c.useState(null),[p,m]=c.useState(null),[h,u]=c.useState(null),[f,v]=c.useState(null),[N,H]=c.useState(null),[y,k]=c.useState(0),[B,T]=c.useState(0),[D,E]=c.useState(!1),[_,q]=c.useState(!1),g=P(r,A=>s(A)),x=ve(t);return o.jsx($e,{scope:a,type:n,dir:x,scrollHideDelay:i,scrollArea:d,viewport:p,onViewportChange:m,content:h,onContentChange:u,scrollbarX:f,onScrollbarXChange:v,scrollbarXEnabled:D,onScrollbarXEnabledChange:E,scrollbarY:N,onScrollbarYChange:H,scrollbarYEnabled:_,onScrollbarYEnabledChange:q,onCornerWidthChange:k,onCornerHeightChange:T,children:o.jsx(R.div,{dir:x,...l,ref:g,style:{position:"relative","--radix-scroll-area-corner-width":y+"px","--radix-scroll-area-corner-height":B+"px",...e.style}})})});te.displayName=Y;var se="ScrollAreaViewport",ne=c.forwardRef((e,r)=>{const{__scopeScrollArea:a,children:n,nonce:t,...i}=e,l=b(se,a),d=c.useRef(null),s=P(r,d,l.onViewportChange);return o.jsxs(o.Fragment,{children:[o.jsx("style",{dangerouslySetInnerHTML:{__html:"[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}"},nonce:t}),o.jsx(R.div,{"data-radix-scroll-area-viewport":"",...i,ref:s,style:{overflowX:l.scrollbarXEnabled?"scroll":"hidden",overflowY:l.scrollbarYEnabled?"scroll":"hidden",...e.style},children:o.jsx("div",{ref:l.onContentChange,style:{minWidth:"100%",display:"table"},children:n})})]})});ne.displayName=se;var S="ScrollAreaScrollbar",Q=c.forwardRef((e,r)=>{const{forceMount:a,...n}=e,t=b(S,e.__scopeScrollArea),{onScrollbarXEnabledChange:i,onScrollbarYEnabledChange:l}=t,d=e.orientation==="horizontal";return c.useEffect(()=>(d?i(!0):l(!0),()=>{d?i(!1):l(!1)}),[d,i,l]),t.type==="hover"?o.jsx(Ge,{...n,ref:r,forceMount:a}):t.type==="scroll"?o.jsx(Je,{...n,ref:r,forceMount:a}):t.type==="auto"?o.jsx(ie,{...n,ref:r,forceMount:a}):t.type==="always"?o.jsx($,{...n,ref:r}):null});Q.displayName=S;var Ge=c.forwardRef((e,r)=>{const{forceMount:a,...n}=e,t=b(S,e.__scopeScrollArea),[i,l]=c.useState(!1);return c.useEffect(()=>{const d=t.scrollArea;let s=0;if(d){const p=()=>{window.clearTimeout(s),l(!0)},m=()=>{s=window.setTimeout(()=>l(!1),t.scrollHideDelay)};return d.addEventListener("pointerenter",p),d.addEventListener("pointerleave",m),()=>{window.clearTimeout(s),d.removeEventListener("pointerenter",p),d.removeEventListener("pointerleave",m)}}},[t.scrollArea,t.scrollHideDelay]),o.jsx(W,{present:a||i,children:o.jsx(ie,{"data-state":i?"visible":"hidden",...n,ref:r})})}),Je=c.forwardRef((e,r)=>{const{forceMount:a,...n}=e,t=b(S,e.__scopeScrollArea),i=e.orientation==="horizontal",l=z(()=>s("SCROLL_END"),100),[d,s]=Qe("hidden",{hidden:{SCROLL:"scrolling"},scrolling:{SCROLL_END:"idle",POINTER_ENTER:"interacting"},interacting:{SCROLL:"interacting",POINTER_LEAVE:"idle"},idle:{HIDE:"hidden",SCROLL:"scrolling",POINTER_ENTER:"interacting"}});return c.useEffect(()=>{if(d==="idle"){const p=window.setTimeout(()=>s("HIDE"),t.scrollHideDelay);return()=>window.clearTimeout(p)}},[d,t.scrollHideDelay,s]),c.useEffect(()=>{const p=t.viewport,m=i?"scrollLeft":"scrollTop";if(p){let h=p[m];const u=()=>{const f=p[m];h!==f&&(s("SCROLL"),l()),h=f};return p.addEventListener("scroll",u),()=>p.removeEventListener("scroll",u)}},[t.viewport,i,s,l]),o.jsx(W,{present:a||d!=="hidden",children:o.jsx($,{"data-state":d==="hidden"?"hidden":"visible",...n,ref:r,onPointerEnter:w(e.onPointerEnter,()=>s("POINTER_ENTER")),onPointerLeave:w(e.onPointerLeave,()=>s("POINTER_LEAVE"))})})}),ie=c.forwardRef((e,r)=>{const a=b(S,e.__scopeScrollArea),{forceMount:n,...t}=e,[i,l]=c.useState(!1),d=e.orientation==="horizontal",s=z(()=>{if(a.viewport){const p=a.viewport.offsetWidth<a.viewport.scrollWidth,m=a.viewport.offsetHeight<a.viewport.scrollHeight;l(d?p:m)}},10);return j(a.viewport,s),j(a.content,s),o.jsx(W,{present:n||i,children:o.jsx($,{"data-state":i?"visible":"hidden",...t,ref:r})})}),$=c.forwardRef((e,r)=>{const{orientation:a="vertical",...n}=e,t=b(S,e.__scopeScrollArea),i=c.useRef(null),l=c.useRef(0),[d,s]=c.useState({content:0,viewport:0,scrollbar:{size:0,paddingStart:0,paddingEnd:0}}),p=pe(d.viewport,d.content),m={...n,sizes:d,onSizesChange:s,hasThumb:p>0&&p<1,onThumbChange:u=>i.current=u,onThumbPointerUp:()=>l.current=0,onThumbPointerDown:u=>l.current=u};function h(u,f){return ro(u,l.current,d,f)}return a==="horizontal"?o.jsx(Ke,{...m,ref:r,onThumbPositionChange:()=>{if(t.viewport&&i.current){const u=t.viewport.scrollLeft,f=J(u,d,t.dir);i.current.style.transform=`translate3d(${f}px, 0, 0)`}},onWheelScroll:u=>{t.viewport&&(t.viewport.scrollLeft=u)},onDragScroll:u=>{t.viewport&&(t.viewport.scrollLeft=h(u,t.dir))}}):a==="vertical"?o.jsx(Ze,{...m,ref:r,onThumbPositionChange:()=>{if(t.viewport&&i.current){const u=t.viewport.scrollTop,f=J(u,d);i.current.style.transform=`translate3d(0, ${f}px, 0)`}},onWheelScroll:u=>{t.viewport&&(t.viewport.scrollTop=u)},onDragScroll:u=>{t.viewport&&(t.viewport.scrollTop=h(u))}}):null}),Ke=c.forwardRef((e,r)=>{const{sizes:a,onSizesChange:n,...t}=e,i=b(S,e.__scopeScrollArea),[l,d]=c.useState(),s=c.useRef(null),p=P(r,s,i.onScrollbarXChange);return c.useEffect(()=>{s.current&&d(getComputedStyle(s.current))},[s]),o.jsx(le,{"data-orientation":"horizontal",...t,ref:p,sizes:a,style:{bottom:0,left:i.dir==="rtl"?"var(--radix-scroll-area-corner-width)":0,right:i.dir==="ltr"?"var(--radix-scroll-area-corner-width)":0,"--radix-scroll-area-thumb-width":M(a)+"px",...e.style},onThumbPointerDown:m=>e.onThumbPointerDown(m.x),onDragScroll:m=>e.onDragScroll(m.x),onWheelScroll:(m,h)=>{if(i.viewport){const u=i.viewport.scrollLeft+m.deltaX;e.onWheelScroll(u),he(u,h)&&m.preventDefault()}},onResize:()=>{s.current&&i.viewport&&l&&n({content:i.viewport.scrollWidth,viewport:i.viewport.offsetWidth,scrollbar:{size:s.current.clientWidth,paddingStart:O(l.paddingLeft),paddingEnd:O(l.paddingRight)}})}})}),Ze=c.forwardRef((e,r)=>{const{sizes:a,onSizesChange:n,...t}=e,i=b(S,e.__scopeScrollArea),[l,d]=c.useState(),s=c.useRef(null),p=P(r,s,i.onScrollbarYChange);return c.useEffect(()=>{s.current&&d(getComputedStyle(s.current))},[s]),o.jsx(le,{"data-orientation":"vertical",...t,ref:p,sizes:a,style:{top:0,right:i.dir==="ltr"?0:void 0,left:i.dir==="rtl"?0:void 0,bottom:"var(--radix-scroll-area-corner-height)","--radix-scroll-area-thumb-height":M(a)+"px",...e.style},onThumbPointerDown:m=>e.onThumbPointerDown(m.y),onDragScroll:m=>e.onDragScroll(m.y),onWheelScroll:(m,h)=>{if(i.viewport){const u=i.viewport.scrollTop+m.deltaY;e.onWheelScroll(u),he(u,h)&&m.preventDefault()}},onResize:()=>{s.current&&i.viewport&&l&&n({content:i.viewport.scrollHeight,viewport:i.viewport.offsetHeight,scrollbar:{size:s.current.clientHeight,paddingStart:O(l.paddingTop),paddingEnd:O(l.paddingBottom)}})}})}),[eo,ce]=re(S),le=c.forwardRef((e,r)=>{const{__scopeScrollArea:a,sizes:n,hasThumb:t,onThumbChange:i,onThumbPointerUp:l,onThumbPointerDown:d,onThumbPositionChange:s,onDragScroll:p,onWheelScroll:m,onResize:h,...u}=e,f=b(S,a),[v,N]=c.useState(null),H=P(r,g=>N(g)),y=c.useRef(null),k=c.useRef(""),B=f.viewport,T=n.content-n.viewport,D=C(m),E=C(s),_=z(h,10);function q(g){if(y.current){const x=g.clientX-y.current.left,A=g.clientY-y.current.top;p({x,y:A})}}return c.useEffect(()=>{const g=x=>{const A=x.target;v?.contains(A)&&D(x,T)};return document.addEventListener("wheel",g,{passive:!1}),()=>document.removeEventListener("wheel",g,{passive:!1})},[B,v,T,D]),c.useEffect(E,[n,E]),j(v,_),j(f.content,_),o.jsx(eo,{scope:a,scrollbar:v,hasThumb:t,onThumbChange:C(i),onThumbPointerUp:C(l),onThumbPositionChange:E,onThumbPointerDown:C(d),children:o.jsx(R.div,{...u,ref:H,style:{position:"absolute",...u.style},onPointerDown:w(e.onPointerDown,g=>{g.button===0&&(g.target.setPointerCapture(g.pointerId),y.current=v.getBoundingClientRect(),k.current=document.body.style.webkitUserSelect,document.body.style.webkitUserSelect="none",f.viewport&&(f.viewport.style.scrollBehavior="auto"),q(g))}),onPointerMove:w(e.onPointerMove,q),onPointerUp:w(e.onPointerUp,g=>{const x=g.target;x.hasPointerCapture(g.pointerId)&&x.releasePointerCapture(g.pointerId),document.body.style.webkitUserSelect=k.current,f.viewport&&(f.viewport.style.scrollBehavior=""),y.current=null})})})}),L="ScrollAreaThumb",de=c.forwardRef((e,r)=>{const{forceMount:a,...n}=e,t=ce(L,e.__scopeScrollArea);return o.jsx(W,{present:a||t.hasThumb,children:o.jsx(oo,{ref:r,...n})})}),oo=c.forwardRef((e,r)=>{const{__scopeScrollArea:a,style:n,...t}=e,i=b(L,a),l=ce(L,a),{onThumbPositionChange:d}=l,s=P(r,h=>l.onThumbChange(h)),p=c.useRef(void 0),m=z(()=>{p.current&&(p.current(),p.current=void 0)},100);return c.useEffect(()=>{const h=i.viewport;if(h){const u=()=>{if(m(),!p.current){const f=to(h,d);p.current=f,d()}};return d(),h.addEventListener("scroll",u),()=>h.removeEventListener("scroll",u)}},[i.viewport,m,d]),o.jsx(R.div,{"data-state":l.hasThumb?"visible":"hidden",...t,ref:s,style:{width:"var(--radix-scroll-area-thumb-width)",height:"var(--radix-scroll-area-thumb-height)",...n},onPointerDownCapture:w(e.onPointerDownCapture,h=>{const f=h.target.getBoundingClientRect(),v=h.clientX-f.left,N=h.clientY-f.top;l.onThumbPointerDown({x:v,y:N})}),onPointerUp:w(e.onPointerUp,l.onThumbPointerUp)})});de.displayName=L;var G="ScrollAreaCorner",me=c.forwardRef((e,r)=>{const a=b(G,e.__scopeScrollArea),n=!!(a.scrollbarX&&a.scrollbarY);return a.type!=="scroll"&&n?o.jsx(ao,{...e,ref:r}):null});me.displayName=G;var ao=c.forwardRef((e,r)=>{const{__scopeScrollArea:a,...n}=e,t=b(G,a),[i,l]=c.useState(0),[d,s]=c.useState(0),p=!!(i&&d);return j(t.scrollbarX,()=>{const m=t.scrollbarX?.offsetHeight||0;
vendor: 6,984 bytes, line 1
1t.onCornerHeightChange(m),s(m)}),j(t.scrollbarY,()=>{const m=t.scrollbarY?.offsetWidth||0;t.onCornerWidthChange(m),l(m)}),p?o.jsx(R.div,{...n,ref:r,style:{width:i,height:d,position:"absolute",right:t.dir==="ltr"?0:void 0,left:t.dir==="rtl"?0:void 0,bottom:0,...e.style}}):null});function O(e){return e?parseInt(e,10):0}function pe(e,r){const a=e/r;return isNaN(a)?0:a}function M(e){const r=pe(e.viewport,e.content),a=e.scrollbar.paddingStart+e.scrollbar.paddingEnd,n=(e.scrollbar.size-a)*r;return Math.max(n,18)}function ro(e,r,a,n="ltr"){const t=M(a),i=t/2,l=r||i,d=t-l,s=a.scrollbar.paddingStart+l,p=a.scrollbar.size-a.scrollbar.paddingEnd-d,m=a.content-a.viewport,h=n==="ltr"?[0,m]:[m*-1,0];return ue([s,p],h)(e)}function J(e,r,a="ltr"){const n=M(r),t=r.scrollbar.paddingStart+r.scrollbar.paddingEnd,i=r.scrollbar.size-t,l=r.content-r.viewport,d=i-n,s=a==="ltr"?[0,l]:[l*-1,0],p=Ce(e,s);return ue([0,l],[0,d])(p)}function ue(e,r){return a=>{if(e[0]===e[1]||r[0]===r[1])return r[0];const n=(r[1]-r[0])/(e[1]-e[0]);return r[0]+n*(a-e[0])}}function he(e,r){return e>0&&e<r}var to=(e,r=()=>{})=>{let a={left:e.scrollLeft,top:e.scrollTop},n=0;return(function t(){const i={left:e.scrollLeft,top:e.scrollTop},l=a.left!==i.left,d=a.top!==i.top;(l||d)&&r(),a=i,n=window.requestAnimationFrame(t)})(),()=>window.cancelAnimationFrame(n)};function z(e,r){const a=C(e),n=c.useRef(0);return c.useEffect(()=>()=>window.clearTimeout(n.current),[]),c.useCallback(()=>{window.clearTimeout(n.current),n.current=window.setTimeout(a,r)},[a,r])}function j(e,r){const a=C(r);ye(()=>{let n=0;if(e){const t=new ResizeObserver(()=>{cancelAnimationFrame(n),n=window.requestAnimationFrame(a)});return t.observe(e),()=>{window.cancelAnimationFrame(n),t.unobserve(e)}}},[e,a])}var fe=te,so=ne,no=me;const ge=c.forwardRef(({className:e,children:r,...a},n)=>o.jsxs(fe,{ref:n,className:ee("relative overflow-hidden",e),...a,children:[o.jsx(so,{className:"h-full w-full rounded-[inherit]",children:r}),o.jsx(be,{}),o.jsx(no,{})]}));ge.displayName=fe.displayName;const be=c.forwardRef(({className:e,orientation:r="vertical",...a},n)=>o.jsx(Q,{ref:n,orientation:r,className:ee("flex touch-none select-none transition-colors",r==="vertical"&&"h-full w-2.5 border-l border-l-transparent p-[1px]",r==="horizontal"&&"h-2.5 flex-col border-t border-t-transparent p-[1px]",e),...a,children:o.jsx(de,{className:"relative flex-1 rounded-full bg-border"})}));be.displayName=Q.displayName;const K=[{id:"agenda-basico",category:"agenda",title:"Agenda — Marcar, editar e acompanhar consultas",subtitle:"Como criar um agendamento, mover, editar status e cancelar.",icon:"CalendarDays",sections:[{heading:"Visão geral da agenda",blocks:[{type:"paragraph",text:"A Agenda mostra todas as consultas da clínica organizadas por dia, médico e horário. Cada consulta tem um paciente, um médico, um ou mais procedimentos, uma duração e um status (agendado, confirmado, atendido, faltou, cancelado)."},{type:"paragraph",text:"A coluna da esquerda lista os médicos ativos. As colunas centrais mostram os horários de atendimento da clínica, respeitando o horário de funcionamento configurado em Horários e os horários específicos de cada profissional."}]},{heading:"Criar uma nova consulta",blocks:[{type:"steps",items:["Clique em um horário vazio na coluna do médico desejado.","Selecione o paciente já cadastrado ou clique em ‘Novo paciente’ para abrir o cadastro rápido (nome, telefone com máscara e CPF).","Escolha um ou mais procedimentos. A duração total é somada automaticamente; você pode ajustar manualmente.","Confirme o horário, adicione observação (opcional) e clique em Salvar."]},{type:"tip",text:"Se o médico não atende naquele horário ou o procedimento exige um turno específico, o sistema bloqueia a criação e mostra o motivo."}]},{heading:"Mover, editar e cancelar",blocks:[{type:"list",items:["Arraste o bloco da consulta para outro horário para reagendar.","Clique no bloco para abrir os detalhes: alterar paciente, médico, procedimentos, duração e observação.","No mesmo painel, mude o status para Confirmado, Atendido, Faltou ou Cancelado.","Ao cancelar, o horário fica livre imediatamente para outra marcação."]},{type:"warning",text:"Cancelar é definitivo: o histórico fica registrado, mas o paciente não recebe lembrete automático após o cancelamento."}]},{heading:"Filtros e busca",blocks:[{type:"paragraph",text:"Use os filtros no topo da agenda para alternar entre dia, semana ou mês, escolher um médico específico ou exibir apenas um status (por exemplo, somente Confirmados). A busca encontra um paciente pelo nome ou telefone em todas as datas."}]}]},{id:"horarios-clinica",category:"agenda",title:"Horários de atendimento da clínica",subtitle:"Definir os dias e turnos em que a clínica está aberta.",icon:"Clock",sections:[{heading:"Para que serve",blocks:[{type:"paragraph",text:"Os horários da clínica são o ‘envelope’ geral: nenhuma consulta pode acontecer fora dele, nem no agendamento interno nem no link público que o paciente usa."}]},{heading:"Como configurar",blocks:[{type:"steps",items:["Acesse Horários de atendimento no menu lateral.","Para cada dia da semana, defina um turno único (ex.: 08:00–18:00) ou deixe vazio se a clínica fecha naquele dia.","Defina o tamanho do slot padrão (15, 20, 30, 40, 60 minutos). É a granularidade que aparece na agenda.","Salve. As mudanças valem imediatamente para o público e para o painel."]},{type:"tip",text:"O slot padrão pode ser sobrescrito por procedimento (cada procedimento tem sua própria duração)."}]}]},{id:"profissionais-horarios",category:"agenda",title:"Profissionais e horários por médico",subtitle:"Cadastrar médicos, definir horários e restrições por procedimento.",icon:"Stethoscope",sections:[{heading:"Cadastro do profissional",blocks:[{type:"steps",items:["Vá em Profissionais & horários.","Clique em ‘Novo profissional’ e preencha nome, CRM, UF, especialidade e telefone com máscara.","Marque os procedimentos que esse médico realiza.","Defina o horário padrão dele para cada dia da semana (manhã e tarde).","Salve."]}]},{heading:"Horários específicos por procedimento",blocks:[{type:"paragraph",text:"Alguns procedimentos só são feitos em determinados dias ou turnos. Por exemplo: ‘Mapeamento de Retina’ só na quarta de manhã. Você pode configurar isso por médico."},{type:"steps",items:["Abra o profissional e role até ‘Horários específicos por procedimento’.","Escolha o procedimento e marque os dias e turnos em que ele está disponível.","Deixe em branco para usar o horário padrão do médico (sem restrição).","Salve."]},{type:"tip",text:"O sistema usa a interseção: a vaga só aparece se o médico estiver aberto E o procedimento estiver liberado naquele horário. Sempre o mais restritivo prevalece."}]}]},{id:"pacientes-cadastro",category:"pacientes",title:"Cadastro de pacientes",subtitle:"Como cadastrar c
1om máscaras, CEP automático e dados completos.",icon:"UserRound",sections:[{heading:"Criar um paciente",blocks:[{type:"steps",items:["Acesse Pacientes no menu e clique em ‘Novo paciente’.","Digite o nome completo, telefone (a máscara (00) 00000-0000 é aplicada automaticamente) e e-mail (opcional).","Informe CPF (com máscara), data de nascimento e sexo.","Preencha o CEP — o endereço (rua, bairro, cidade e UF) é completado automaticamente via consulta pública.","Confirme o número e o complemento, e salve."]},{type:"tip",text:"Se o CEP não preencher, verifique se está com 8 dígitos. Você pode editar o endereço manualmente em qualquer momento."}]},{heading:"Histórico do paciente",blocks:[{type:"paragraph",text:"Ao abrir um paciente, você vê: consultas passadas e futuras, prontuários, pagamentos, observações e o link público para o paciente reagendar/cancelar."}]},{heading:"Boas práticas",blocks:[{type:"list",items:["Sempre confirme o telefone com DDD — é o canal de WhatsApp para lembretes.","Atualize o e-mail se o paciente trocar — comprovantes e receitas podem ser enviados por e-mail.","Use o campo Observações para informações úteis na recepção (preferências, alergias gerais, restrições)."]}]}]},{id:"prontuario-completo",category:"prontuario",title:"Prontuário eletrônico — Anamnese, exame e prescrição",subtitle:"Como registrar uma consulta completa e imprimir/enviar para o paciente.",icon:"FileText",sections:[{heading:"Abrir o prontuário de uma consulta",blocks:[{type:"steps",items:["Na Agenda, clique na consulta e em ‘Abrir prontuário’.","Ou vá em Prontuário no menu e busque pelo paciente."]}]},{heading:"Estrutura do prontuário",blocks:[{type:"list",title:"Blocos do prontuário",items:["Queixa principal — o motivo da consulta em uma frase.","Anamnese — histórico, sintomas, antecedentes, medicações em uso. Texto livre estruturado.","Exame oftalmológico — campos para acuidade visual, pressão intraocular, biomicroscopia, fundoscopia, refração.","Diagnóstico — texto livre com sugestões da IA (opcional).","Prescrição — adicione um ou mais medicamentos com posologia.","Conduta — orientações ao paciente, retorno, exames complementares.","Observações internas — não aparecem na via do paciente."]}]},{heading:"Imprimir e enviar",blocks:[{type:"steps",items:["Clique em ‘Imprimir prontuário’ para abrir a versão pronta para impressão (sem observações internas).","Use o botão de envio por WhatsApp para mandar a receita/orientações ao paciente."]},{type:"warning",text:"Para enviar pelo WhatsApp, a instância da clínica precisa estar conectada (veja o tutorial WhatsApp / Evolution)."}]},{heading:"Assistente de IA no prontuário",blocks:[{type:"paragraph",text:"Se a feature de IA estiver liberada para sua clínica, o botão ‘Assistente’ abre um chat com contexto do paciente atual: ele ajuda a resumir histórico, sugerir hipóteses diagnósticas e redigir orientações. A IA nunca substitui o julgamento médico — sempre revise antes de salvar."}]}]},{id:"whatsapp-conectar",category:"comunicacao",title:"WhatsApp — Conectar a instância da clínica",subtitle:"Conectar o WhatsApp via QR Code para enviar mensagens e lembretes.",icon:"MessageSquare",sections:[{heading:"Como conectar pela primeira vez",blocks:[{type:"steps",items:["Acesse WhatsApp / Evolution no menu.","Clique em ‘Gerar QR Code’.","Abra o WhatsApp no celular da clínica → Configurações → Aparelhos conectados → Conectar um aparelho.","Aponte a câmera para o QR Code na tela.","Aguarde alguns segundos — o status deve mudar para Conectado e mostrar o número."]},{type:"tip",text:"Use um número exclusivo da clínica, dedicado a este sistema. Evite usar o WhatsApp pessoal do médico."}]},{heading:"Status da conexão",blocks:[{type:"list",items:["Conectado — pode enviar e receber mensagens.","Desconectado — o QR expirou ou o celular ficou offline. Gere um novo QR.","Conectando — aguardando confirmação do servidor."]}]},{heading:"Quando reconectar",blocks:[{type:"paragraph",text:"Se o celular ficar muito tempo sem internet ou se o WhatsApp for desconectado manualmente, será necessário gerar um novo QR. Os lembretes automáticos só rodam com o status Conectado."}]}]},{id:"mensagens-templates",category:"comunicacao",title:"Mensagens e templates",subtitle:"Personalizar lembretes, confirmações e pesquisas de satisfação.",icon:"MessageCircle",sections:[{heading:"O que são templates",blocks:[{type:"paragraph",text:"Templates são modelos de mensagem usados nas automações (confirmação no momento do agendamento, lembrete 48h e 24h antes, agradecimento depois). Cada template usa variáveis como {paciente}, {medico}, {data}, {hora} e {clinica}, que são substituídas automaticamente."}]},{heading:"Editar um template",blocks:[{type:"steps",items:["Acesse Mensagens (Templates) no menu.","
1Escolha o template (Confirmação, Lembrete 48h, Lembrete 24h, Agradecimento, Reagendamento).","Edite o texto mantendo as variáveis entre chaves.","Salve. O novo texto vale para todas as mensagens enviadas a partir daquele momento."]},{type:"tip",text:"Use tom cordial e objetivo. Pacientes leem em poucos segundos no WhatsApp — vá direto ao ponto."}]}]},{id:"publico-agendamento",category:"publico",title:"Agendamento público — Link para pacientes",subtitle:"Como o paciente marca uma consulta pela internet, sem precisar ligar.",icon:"Globe",sections:[{heading:"O link público da clínica",blocks:[{type:"paragraph",text:"Cada clínica tem uma página pública de agendamento. Esse link pode ficar no site da clínica, no Instagram, no botão do WhatsApp Business e em peças impressas. O paciente escolhe procedimento, médico (ou ‘Sem preferência’), data e horário disponível."},{type:"paragraph",text:"Os horários mostrados respeitam: o horário da clínica, o horário do médico e os horários específicos do procedimento. Datas e horários sem vaga não aparecem."}]},{heading:"Como o paciente marca",blocks:[{type:"steps",items:["O paciente abre o link público da clínica.","Escolhe o procedimento desejado.","Escolhe um médico ou ‘Sem preferência’.","Seleciona o dia e o horário entre as opções disponíveis.","Preenche nome, telefone (com máscara) e CPF.","Confirma. Ele recebe a confirmação no WhatsApp na hora."]}]},{heading:"Reagendamento e cancelamento pelo paciente",blocks:[{type:"paragraph",text:"Na mensagem de confirmação enviada pelo WhatsApp, o paciente recebe um link exclusivo daquele agendamento. Ao clicar, ele entra direto na tela de reagendamento ou cancelamento — sem precisar criar conta, sem precisar achar nada. O link continua válido até a data da consulta."},{type:"tip",text:"Você não precisa fazer nada: o link já vai na confirmação. Basta o paciente clicar para abrir a página da clínica com o agendamento dele carregado."}]}]},{id:"financeiro-basico",category:"financeiro",title:"Financeiro — Receitas, despesas e fluxo",subtitle:"Registrar pagamentos de consultas, despesas e ver o saldo.",icon:"CreditCard",sections:[{heading:"Registrar um pagamento de consulta",blocks:[{type:"steps",items:["Na Agenda, ao marcar uma consulta como Atendido, clique em ‘Registrar pagamento’.","Escolha o método (Dinheiro, Pix, Cartão de crédito/débito, Convênio, Boleto).","Informe o valor recebido e a data.","Salve. A transação aparece em Financeiro como Receita Paga."]}]},{heading:"Despesas",blocks:[{type:"steps",items:["Em Financeiro, clique em ‘Nova despesa’.","Informe descrição, valor, vencimento, categoria e método.","Marque como Paga se já foi quitada, ou deixe como Pendente."]}]},{heading:"Visão consolidada",blocks:[{type:"list",items:["Filtros por período (hoje, semana, mês, intervalo customizado).","Totais de Receita Recebida, Receita Prevista, Despesa Paga, Despesa Pendente, Saldo do período.","Exportação dos lançamentos para CSV."]}]}]},{id:"procedimentos-valores",category:"configuracao",title:"Procedimentos e valores",subtitle:"Cadastrar consultas, exames e cirurgias com preço por convênio.",icon:"Tag",sections:[{heading:"Cadastrar um procedimento",blocks:[{type:"steps",items:["Acesse Procedimentos & Valores.","Clique em ‘Novo procedimento’.","Informe nome, descrição curta, duração padrão (em minutos) e ícone.","Defina o valor particular.","Adicione valores por convênio (Unimed, Bradesco, Amil etc.) — cada um com nome e valor.","Salve."]},{type:"tip",text:"A duração definida aqui é usada quando o procedimento for selecionado na agenda. Vários procedimentos juntos somam a duração."}]}]},{id:"usuarios-papeis",category:"configuracao",title:"Usuários e papéis",subtitle:"Cadastrar médicos, secretárias e administradores da clínica.",icon:"Users",sections:[{heading:"Papéis disponíveis",blocks:[{type:"list",items:["Administrador da clínica — acesso total à clínica, incluindo configurações, financeiro e relatórios.","Médico — agenda, pacientes, prontuário e WhatsApp.","Secretária — agenda, pacientes, financeiro e WhatsApp (não acessa prontuário)."]}]},{heading:"Criar um usuário",blocks:[{type:"steps",items:["Acesse Usuários & Papéis.","Clique em ‘Novo usuário’.","Preencha nome, telefone (com máscara) — o login será feito pelo telefone — e senha provisória.","Escolha um ou mais papéis.","Para médicos, informe CRM, UF e especialidade.","Salve. O usuário deverá trocar a senha no primeiro acesso."]},{type:"warning",text:"O telefone é o identificador único do usuário no sistema. Se mudar, atualize aqui — caso contrário ele não consegue mais entrar."}]}]},{id:"ia-assistente",category:"ia",title:"Assistente de IA e Base de Conhecimento",subtitle:"Como o assistente responde dúvidas e c
1omo ensinar coisas para ele.",icon:"Sparkles",sections:[{heading:"O assistente da clínica",blocks:[{type:"paragraph",text:"O assistente de IA pode ser usado em dois lugares: dentro do prontuário (ajuda o médico a redigir e raciocinar) e como atendimento ao paciente via WhatsApp (responde dúvidas frequentes, orienta sobre preparo de exames e ajuda a marcar consulta). Em ambos os casos, ele usa a base de conhecimento da clínica."}]},{heading:"Base de conhecimento",blocks:[{type:"steps",items:["Acesse Base de conhecimento.","Clique em ‘Nova entrada’.","Escolha uma categoria (Procedimentos, Preparo de exames, Convênios, Endereço, etc.).","Escreva o título (curto e direto) e o conteúdo (texto explicativo que a IA vai usar como referência).","Salve."]},{type:"tip",text:"Quanto mais entradas claras e específicas, melhor a IA responde. Pense em todas as perguntas que a recepção responde no dia a dia — e cadastre cada uma como uma entrada."}]},{heading:"Configurar o assistente",blocks:[{type:"steps",items:["Acesse IA & Automações.","Defina o nome do assistente, a mensagem de boas-vindas e o ‘tom de voz’ (prompt do sistema).","Indique os horários em que ele pode oferecer agendamento automático ao paciente.","Ative ou desative as automações de lembrete (48h, 24h, agradecimento pós-consulta).","Salve."]},{type:"warning",text:"A IA nunca dá diagnóstico ao paciente. Ela apenas orienta, marca consultas e responde dúvidas administrativas baseadas na base de conhecimento."}]}]}];function xe(e){const r=io(e);return r<60?`${r} s de leitura`:`${Math.round(r/60)} min de leitura`}function io(e){const r=co(e),a=Math.round(r/200*60);return Math.max(30,a)}function co(e){let r=0;for(const a of e.sections){r+=a.heading.split(/\s+/).filter(Boolean).length;for(const n of a.blocks)if(n.type==="paragraph"||n.type==="tip"||n.type==="warning")r+=n.text.split(/\s+/).filter(Boolean).length;else{n.title&&(r+=n.title.split(/\s+/).filter(Boolean).length);for(const t of n.items)r+=t.split(/\s+/).filter(Boolean).length}}return r}const I={agenda:{label:"Agenda",color:"bg-blue-500/10 text-blue-700 dark:text-blue-300"},pacientes:{label:"Pacientes",color:"bg-emerald-500/10 text-emerald-700 dark:text-emerald-300"},prontuario:{label:"Prontuário",color:"bg-violet-500/10 text-violet-700 dark:text-violet-300"},comunicacao:{label:"Comunicação",color:"bg-orange-500/10 text-orange-700 dark:text-orange-300"},financeiro:{label:"Financeiro",color:"bg-amber-500/10 text-amber-700 dark:text-amber-300"},configuracao:{label:"Configuração",color:"bg-slate-500/10 text-slate-700 dark:text-slate-300"},ia:{label:"IA",color:"bg-pink-500/10 text-pink-700 dark:text-pink-300"},publico:{label:"Público",color:"bg-cyan-500/10 text-cyan-700 dark:text-cyan-300"}},lo=[{id:"horarios-dias-atendimento",title:"Dias, horários e intervalos de atendimento do profissional",description:"Passo a passo completo: abrir Profissionais & horários, ligar/desligar um dia (inclusive o sábado), definir manhã e tarde com intervalo de almoço, a duração da consulta, salvar e conferir se gravou. Mostra também que a agenda do médico prevalece sobre a da clínica e que o horário específico por procedimento tem botão próprio de salvar.",url:"/tutoriais/10-horarios-dias-atendimento.mp4"},{id:"cadastro-rapido-e-reagendamento",title:"Cadastro rápido na Agenda, ficha incompleta e link de reagendamento",description:"Como a secretária cadastra o paciente só com nome e telefone dentro da própria Agenda, como identificar quem está com ficha incompleta e como funciona o link de reagendamento enviado ao paciente.",url:"/tutoriais/09-cadastro-rapido-e-reagendamento.mp4"},{id:"tutorial-completo-paciente",title:"Vídeo completo: busca de paciente, histórico e anotações",description:"Do login até o fim: busca rápida pelo nome na Agenda, histórico de consultas em Pacientes e a nova aba de Anotações (registrar, ver o autor e excluir).",url:"/tutoriais/08-tutorial-completo-paciente.mp4"},{id:"busca-paciente-historico",title:"Busca rápida de paciente e histórico de consultas",description:"Como digitar as primeiras letras do nome na Agenda para achar o paciente e como abrir o histórico de consultas em Pacientes.",url:"/__l5e/assets-v1/99763655-0ebb-4d0c-b155-25d79021b9dc/07-busca-paciente-e-historico.mp4"},{id:"bloquear-agenda",title:"Bloquear dias e horários na agenda",description:"Como impedir agendamentos em férias, feriados ou períodos específicos.",url:"/__l5e/assets-v1/6029fe74-988c-44e2-a7d6-bd35b27c6c56/01-bloquear-agenda.mp4"},{id:"conectar-whatsapp",title:"Conectar o WhatsApp",description:"Como criar a conexão e ler o QR Code para o envio das mensagens.",url:"/__l5e/assets-v1/c730ee18-20c7-4b6a-b85b-4561e6317c26/02-conectar-whatsapp.mp4"},{id:"agenda-e-pacientes",title:"Agenda e cadastro de pacientes",description:"Como navegar pela agenda e cadastrar/editar pacientes.",url:"/__l5e/assets-v1/23bd69f6-396a-4a97-b49d-adb75728e0cb/03-agenda-e-pacientes.mp4"},{id:"horarios-do-profissional",title:"Horários do profissional",description:"Como definir os dias e horários de atendimento de cada médico.",url:"/__l5e/assets-v1/ca01ded2-09bb-48a6-b567-c49ea2f6f14d/04-horarios-do-profissional.mp4"},{id:"alterar-valores",title:"Alterar valores dos procedimentos",description:"Como mudar o preço particular de um exame ou consulta.",url:"/__l5e/assets-v1/b4d87166-9f48-4e1b-a6f2-7661ad6e763a/05-alterar-valores.mp4"}
1,{id:"agendamento-pelo-paciente",title:"Agendamento feito pelo paciente",description:"Como o paciente marca a consulta pela página pública.",url:"/__l5e/assets-v1/4da3717f-d069-4290-9359-fdac4e838141/06-agendamento-pelo-paciente.mp4"}],mo={CalendarDays:_e,Clock:De,Stethoscope:Te,UserRound:ke,FileText:He,MessageSquare:Re,MessageCircle:Ee,Globe:Xe,CreditCard:Ne,Tag:Pe,Users:je,Sparkles:Ae,BookOpen:V};function yo(){const[e,r]=c.useState(""),[a,n]=c.useState("all"),[t,i]=c.useState(null),l=c.useMemo(()=>{const s=e.trim().toLowerCase();return K.filter(p=>a!=="all"&&p.category!==a?!1:s?p.title.toLowerCase().includes(s)||p.subtitle.toLowerCase().includes(s)||p.sections.some(m=>m.heading.toLowerCase().includes(s)):!0)},[e,a]),d=c.useMemo(()=>{const s=new Set(K.map(p=>p.category));return Array.from(s)},[]);return o.jsxs("div",{className:"space-y-6",children:[o.jsx("div",{className:"flex flex-col gap-2",children:o.jsxs("div",{className:"flex items-center gap-3",children:[o.jsx("div",{className:"rounded-lg bg-primary/10 p-2 text-primary",children:o.jsx(V,{className:"h-6 w-6"})}),o.jsxs("div",{children:[o.jsx("h1",{className:"text-2xl font-semibold tracking-tight",children:"Tutorial do Sistema"}),o.jsx("p",{className:"text-sm text-muted-foreground",children:"Aprenda a usar cada funcionalidade do Quattre Med. Conteúdo passo a passo, com tempo de leitura real."})]})]})}),o.jsx(U,{children:o.jsxs(F,{className:"space-y-4 p-4 md:p-5",children:[o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Fe,{className:"h-5 w-5 text-primary"}),o.jsx("h2",{className:"text-lg font-semibold",children:"Vídeos passo a passo"})]}),o.jsx("p",{className:"text-sm text-muted-foreground",children:"Gravados nas telas reais do sistema. Clique para assistir aqui mesmo ou baixe para o seu computador."}),o.jsx("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3",children:lo.map(s=>o.jsxs("div",{className:"overflow-hidden rounded-lg border",children:[o.jsx("video",{src:s.url,controls:!0,preload:"metadata",className:"w-full bg-black"}),o.jsxs("div",{className:"space-y-1 p-3",children:[o.jsx("h3",{className:"text-sm font-semibold leading-tight",children:s.title}),o.jsx("p",{className:"text-xs text-muted-foreground",children:s.description}),o.jsxs("a",{href:s.url,download:!0,className:"inline-flex items-center gap-1 pt-1 text-xs font-medium text-primary hover:underline",children:[o.jsx(Me,{className:"h-3.5 w-3.5"})," Baixar vídeo"]})]})]},s.id))})]})}),o.jsx(U,{children:o.jsxs(F,{className:"flex flex-col gap-3 p-4 md:flex-row md:items-center",children:[o.jsxs("div",{className:"relative flex-1",children:[o.jsx(ze,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),o.jsx(we,{value:e,onChange:s=>r(s.target.value),placeholder:"Buscar por título, resumo ou seção...",className:"pl-9"})]}),o.jsxs("div",{className:"flex flex-wrap gap-2",children:[o.jsx(Z,{label:"Todos",active:a==="all",onClick:()=>n("all")}),d.map(s=>o.jsx(Z,{label:I[s].label,active:a===s,onClick:()=>n(s)},s))]})]})}),o.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3",children:[l.map(s=>{const p=mo[s.icon]??V,m=I[s.category];return o.jsx("button",{onClick:()=>i(s),className:"group text-left",children:o.jsx(U,{className:"h-full transition-all hover:-translate-y-0.5 hover:shadow-md",children:o.jsxs(F,{className:"flex h-full flex-col gap-3 p-5",children:[o.jsxs("div",{className:"flex items-start justify-between gap-3",children:[o.jsx("div",{className:"rounded-lg bg-primary/10 p-2 text-primary",children:o.jsx(p,{className:"h-5 w-5"})}),o.jsx(oe,{variant:"secondary",className:m.color,children:m.label})]}),o.jsxs("div",{className:"flex-1",children:[o.jsx("h3",{className:"font-semibold leading-tight",children:s.title}),o.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:s.subtitle})]}),o.jsxs("div",{className:"flex items-center justify-between border-t pt-3 text-xs text-muted-foreground",children:[o.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[o.jsx(ae,{className:"h-3.5 w-3.5"}),xe(s)]}),o.jsxs("span",{className:"inline-flex items-center gap-1 font-medium text-primary group-hover:gap-2 transition-all",children:["Ler tutorial",o.jsx(Be,{className:"h-3.5 w-3.5"})]})]})]})})},s.id)}),l.length===0&&o.jsx("div",{className:"col-span-full rounded-lg border border-dashed p-10 text-center text-sm text-muted-foreground",children:"Nenhum tutorial encontrado para essa busca."})]}),o.jsx(po,{tutorial:t,onClose:()=>i(null)})]})}function Z({label:e,active:r,onClick:a}){return o.jsx("button",{type:"button",onClick:a,className:`rounded-full border px-3 py-1 text-xs font-medium transition-colors ${r?"border-primary bg-primary text-primary-foreground":"border-border bg-background text-muted-foreground hover:bg-muted"}`,children:e})}function po({tutorial:e,onClose:r}){return o.jsx(qe,{open:!!e,onOpenChange:a=>!a&&r(),children:o.jsx(Le,{className:"max-w-3xl max-h-[90vh] overflow-hidden p-0",children:e&&o.jsxs(o.Fragment,{children:[o.jsxs(Oe,{className:"border-b px-6 py-4",children:[o.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[o.jsx(oe,{variant:"secondary",className:I[e.category].color,children:I[e.category].label}),o.jsxs("span",{className:"inline-flex items-center gap-1",children:[o.jsx(ae,{className:"h-3.5 w-3.5"}),xe(e)]})]}),o.jsx(Ie,{className:"mt-2 text-xl",children:e.title}
1),o.jsx(We,{children:e.subtitle})]}),o.jsx(ge,{className:"max-h-[70vh] px-6 py-5",children:o.jsx("div",{className:"space-y-8 pb-6",children:e.sections.map((a,n)=>o.jsxs("section",{className:"space-y-3",children:[o.jsx("h3",{className:"border-l-4 border-primary pl-3 text-base font-semibold",children:a.heading}),o.jsx("div",{className:"space-y-3",children:a.blocks.map((t,i)=>o.jsx(uo,{block:t},i))})]},n))})})]})})})}function uo({block:e}){return e.type==="paragraph"?o.jsx("p",{className:"text-sm leading-relaxed text-foreground/90",children:e.text}):e.type==="steps"?o.jsxs("div",{className:"space-y-2",children:[e.title&&o.jsx("p",{className:"text-sm font-semibold",children:e.title}),o.jsx("ol",{className:"space-y-2",children:e.items.map((r,a)=>o.jsxs("li",{className:"flex gap-3 text-sm leading-relaxed",children:[o.jsx("span",{className:"flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-primary/10 text-xs font-semibold text-primary",children:a+1}),o.jsx("span",{className:"flex-1",children:r})]},a))})]}):e.type==="list"?o.jsxs("div",{className:"space-y-2",children:[e.title&&o.jsx("p",{className:"text-sm font-semibold",children:e.title}),o.jsx("ul",{className:"space-y-1.5",children:e.items.map((r,a)=>o.jsxs("li",{className:"flex gap-2 text-sm leading-relaxed",children:[o.jsx("span",{className:"mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-primary"}),o.jsx("span",{className:"flex-1",children:r})]},a))})]}):e.type==="tip"?o.jsxs("div",{className:"rounded-md border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-900 dark:border-emerald-900/40 dark:bg-emerald-950/30 dark:text-emerald-100",children:[o.jsx("strong",{className:"font-semibold",children:"Dica:"})," ",e.text]}):e.type==="warning"?o.jsxs("div",{className:"rounded-md border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900 dark:border-amber-900/40 dark:bg-amber-950/30 dark:text-amber-100",children:[o.jsx("strong",{className:"font-semibold",children:"Atenção:"})," ",e.text]}):null}export{yo 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.