PageSourceSearch

https://ployee.ai/assets/Phase5_BiometricConfirm-DElZnUF3.js

js ployee.ai collected 2026-10-05 15:24:54 UTC 18,552 bytes, 1 lines download raw bytes

1import{j as e,A as H,m as i}from"./motion-BgEW6oN1.js";import{a as g}from"./icons-DjSNXlmb.js";import{s as S,t as T}from"./index-BJJ7ZIrZ.js";import{u as V}from"./ProDashboardLayout-ByFodCPK.js";import"./charts-CHWzEtoQ.js";import"./supabase-dTDx1jjQ.js";import"./firebase-CrZtMQPV.js";import"./card-sAuwV7f5.js";import"./index-8Rok_0Nq.js";import"./svg-j1kdzfu0q3-jwbxGJZK.js";import"./destinoPendiente-CeOytndD.js";import"./index-BIXX7ZkW.js";import"./index-yKpwrCAF.js";import"./index-CpxZqy6W.js";import"./dialog-CVq1wF8C.js";import"./badge-CLgeKGVh.js";import"./input-D2KAYQHq.js";import"./select-Ds-c3FBD.js";import"./index-D6S39GvL.js";import"./textarea-Bml3DXnv.js";import"./switch-DwxZFNYA.js";import"./label-C0edyV1Q.js";import"./useCFOBilling-C1v8lqoo.js";import"./index-Dse2OQke.js";import"./useGoogleCalendar-DD-8wRXB.js";import"./DeleteAccountModal-sI461MUY.js";import"./AvisoDeError-CoqofE58.js";import"./mensajeDeEdgeFunction-D7G8yCcD.js";import"./enlacesPublicos-B24aTbgJ.js";const Q=t=>t==="parents"?"parent":t==="teachers"?"teacher":t==="staff"?"staff":"student";async function W(t){const{data:{user:o},error:a}=await S.auth.getUser();if(a||!o)throw new Error("Necesitas una sesión de administrador activa para importar. Inicia sesión e intenta de nuevo.");const n=o.id,l=t.columnMappings.filter(r=>r.targetField&&(r.userConfirmed||r.confidence>=60)),d={};for(const r of l){const m=t.rawHeaders.indexOf(r.sourceCol);m>=0&&(d[r.targetField]=m)}const c=Q(t.cohortType),p=t.allRows.map((r,m)=>{const f={};t.rawHeaders.forEach((_,u)=>{f[_]=r[u]??""});const x={};for(const[_,u]of Object.entries(d)){const y=(r[u]??"").trim();y&&(x[_]=y)}return{bp_id:n,row_number:m+1,person_type:c,raw_data:f,normalized_data:x,validation_status:"valid",import_status:"pending",school_group:x.group_section??null,school_division:x.division??null,school_shift:x.shift??null}}),w=p.filter(r=>Object.keys(r.normalized_data).length>0).length,{data:k,error:E}=await S.from("enrollment_batches").insert({bp_id:n,batch_name:t.batchName||`Importación ${t.schoolYear}`,school_year:t.schoolYear,cohort_type:t.cohortType??"students",total_records:p.length,valid_records:w,warning_records:0,error_records:0,column_mapping:Object.fromEntries(l.map(r=>[r.sourceCol,r.targetField])),status:"ready",current_phase:5,consents:t.consents,created_by:o.id,import_source:"web_drag_drop",file_name:t.fileName??null}).select("id").single();if(E||!k)throw new Error(`No se pudo crear el lote de importación: ${E?.message??"desconocido"}`);const v=k.id,A=500;for(let r=0;r<p.length;r+=A){const m=p.slice(r,r+A).map(x=>({...x,batch_id:v})),{error:f}=await S.from("enrollment_records").insert(m);if(f)throw new Error(`Error al guardar registros (${r+1}–${r+m.length}): ${f.message}`)}const{data:P,error:D}=await S.rpc("bulk_enroll_cohort",{p_batch_id:v,p_signed_by:o.id,p_signature_hash:t.signatureHash,p_consents:t.consents});if(D)throw new Error(`El lote se guardó pero la inscripción falló: ${D.message}`);const b=P??{};return{imported:b.imported??w,skipped:b.skipped??0,errors:b.errors??[],batchId:v}}async function K(t){const a=new TextEncoder().encode(t),n=await crypto.subtle.digest("SHA-256",a);return Array.from(new Uint8Array(n)).map(d=>d.toString(16).padStart(2,"0")).join("")}const J=({students:t,parents:o,teachers:a,total:n,batchName:l,schoolYear:d,groups:c})=>e.jsxs(i.div,{initial:{opacity:0,y:8},animate:{opacity:1,y:0},transition:{type:"spring",stiffness:280,damping:22},className:"rounded-2xl border border-blue-100 p-5",style:{background:"linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%)"},children:[e.jsx("p",{className:"text-[10px] font-black uppercase tracking-widest text-blue-400 mb-3",children:"Resumen del batch"}),e.jsxs("div",{className:"flex items-end justify-between mb-4",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-xl font-extrabold text-blue-900 truncate",children:l||"Batch escolar"}),e.jsxs("p",{className:"text-xs text-blue-600 font-semibold mt-0.5",children:["Ciclo ",d]})]}),e.jsxs("div",{className:"text-right",children:[e.jsx("p",{className:"text-3xl font-extrabold text-blue-800",children:n}),e.jsx("p",{className:"text-[10px] font-black uppercase tracking-widest text-blue-400",children:"personas"})]})]}),e.jsxs("div",{className:"flex gap-3 flex-wrap mb-4",children:[t>0&&e.jsxs("span",{className:"text-xs font-bold text-blue-700 bg-blue-100 rounded-lg px-3 py-1.5",children:["🎓 ",t," Estudiantes"]}),o>0&&e.jsxs("span",{className:"text-xs font-bold text-teal-700 bg-teal-100 rounded-lg px-3 py-1.5",children:["👨‍👩‍👧 ",o," Padres"]}),a>0&&e.jsxs("span",{className:"text-xs font-bold text-purple-700 bg-purple-100 rounded-lg px-3 py-1.5",children:["👩‍🏫 ",a," Docentes"]})]}),c.length>0&&e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-black uppercase tracking-widest text-blue-400 mb-1.5",children:"Grupos a crear"}),e.jsxs("div",{className:"flex flex-wrap gap-1.5",children:[c.slice(0,12).map(p=>e.jsx("span",{className:"text-[11px] font-extrabold text-blue-600 bg-blue-50 border border-blue-200 rounded-md px-2 py-0.5",children:p},p)),c.length>12&&e.jsxs("span",{className:"text-[11px] font-semibold text-blue-400",children:["+",c.length-12," más"]})]})]})]}),I=({label:t,subLabel:o,checked:a,onChange:n,required:l,warning:d})=>{const c=l&&a;return e.jsxs(i.label,{whileHover:c?{}:{backgroundColor:"#F9FAFB"},className:`flex items-start gap-4 px-4 py-3.5 rounded-xl transition-colors ${c?"cursor-default":"cursor-pointer"}`,children:[e.jsxs("div",{className:"relative mt-0.5",children:[e.jsx("input",{type:"checkbox",checked:a,disabled:c,onChange:p=>n?.(p.target.checked),className:"sr-only"}),e.jsx(i.div,{animate:{backgroundColor:a?c?"#6B7280":"#1A6CF5":"#F3F4F6",borderColor:a?c?"#6B7280":"#1A6CF5":"#D1D5DB"},className:"w-5 h-5 rounded-md border-2 flex items-center justify-center",children:a&&e.jsx(i.svg,{initial:{scale:0},animate:{scale:1}
1,className:"w-3 h-3 text-white",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:3,children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 13l4 4L19 7"})})})]}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("p",{className:"text-sm font-semibold text-gray-800 flex items-center gap-2",children:[t,c&&e.jsx("span",{className:"text-[9px] font-black uppercase tracking-widest bg-gray-100 text-gray-400 rounded px-1.5 py-0.5",children:"Requerido"})]}),o&&e.jsx("p",{className:"text-xs text-gray-400 mt-0.5",children:o})]}),d&&e.jsx("span",{className:"text-[10px] font-black uppercase tracking-wider text-amber-600 bg-amber-50 border border-amber-200 rounded-lg px-2 py-1 whitespace-nowrap shrink-0",children:"Consentimiento individual"})]})},X={idle:{label:"Confirmar con Face ID",icon:"🔐",color:"#1A6CF5"},scanning:{label:"Escaneando…",icon:"👁️",color:"#F59E0B"},verifying:{label:"Verificando identidad…",icon:"🔒",color:"#8B5CF6"},confirmed:{label:"¡Identidad confirmada!",icon:"✅",color:"#00B67A"}},Z=({phase:t,onStart:o})=>{const a=X[t],n=t!=="idle"&&t!=="confirmed";return e.jsxs("div",{className:"flex flex-col items-center gap-6",children:[e.jsxs("div",{className:"relative flex items-center justify-center",children:[n&&e.jsxs(e.Fragment,{children:[e.jsx(i.div,{className:"absolute rounded-full border-4",style:{width:112,height:112,borderColor:a.color+"40"},animate:{scale:[1,1.2,1],opacity:[.8,.2,.8]},transition:{repeat:1/0,duration:1.4,ease:"easeInOut"}}),e.jsx(i.div,{className:"absolute rounded-full border-4",style:{width:96,height:96,borderColor:a.color+"60"},animate:{scale:[1,1.15,1],opacity:[.6,.1,.6]},transition:{repeat:1/0,duration:1.4,delay:.2,ease:"easeInOut"}})]}),e.jsx(i.button,{onClick:t==="idle"?o:void 0,disabled:n,whileHover:t==="idle"?{scale:1.05}:{},whileTap:t==="idle"?{scale:.95}:{},className:"relative w-24 h-24 rounded-full flex items-center justify-center text-4xl shadow-[0_8px_32px_rgba(26,108,245,0.35)] border-4 border-white",style:{background:`radial-gradient(circle, ${a.color}CC, ${a.color})`},animate:{scale:n?[1,1.04,1]:1},transition:{repeat:n?1/0:0,duration:.8},children:e.jsx(H,{mode:"wait",children:e.jsx(i.span,{initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:{type:"spring",stiffness:400,damping:24},children:a.icon},t)})})]}),e.jsx(H,{mode:"wait",children:e.jsx(i.p,{initial:{opacity:0,y:6},animate:{opacity:1,y:0},exit:{opacity:0,y:-6},className:"text-sm font-extrabold text-gray-700 text-center",children:a.label},t)}),n&&e.jsx("div",{className:"w-48 bg-gray-100 rounded-full h-1.5 overflow-hidden",children:e.jsx(i.div,{className:"h-full rounded-full",style:{background:a.color},initial:{width:"0%"},animate:{width:t==="scanning"?"50%":"100%"},transition:{duration:1,ease:"easeInOut"}})})]})},ee=({total:t,hash:o,onViewSummary:a})=>e.jsxs(i.div,{initial:{opacity:0,scale:.92},animate:{opacity:1,scale:1},transition:{type:"spring",stiffness:260,damping:22},className:"flex flex-col items-center gap-6 py-8",children:[e.jsxs(i.div,{initial:{scale:0},animate:{scale:1},transition:{type:"spring",stiffness:300,damping:18,delay:.1},className:"relative w-28 h-28 flex items-center justify-center",children:[e.jsx(i.div,{className:"absolute inset-0 rounded-full",style:{background:"radial-gradient(circle, #ECFDF5, #D1FAE5)"},animate:{scale:[1,1.12,1]},transition:{repeat:3,duration:.6}}),e.jsx("svg",{className:"relative w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"#00B67A",strokeWidth:2.5,children:e.jsx(i.path,{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z",initial:{pathLength:0},animate:{pathLength:1},transition:{duration:.8,delay:.2,ease:"easeOut"}})})]}),e.jsxs(i.div,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},transition:{delay:.4},className:"text-center",children:[e.jsx("h2",{className:"text-2xl font-extrabold text-gray-900",children:"🎉 ¡Onboarding completado!"}),e.jsxs("p",{className:"text-base font-semibold text-gray-500 mt-1",children:[t.toLocaleString()," personas registradas exitosamente"]})]}),e.jsxs(i.div,{initial:{opacity:0,y:12}
1,animate:{opacity:1,y:0},transition:{delay:.55},className:"w-full space-y-3",children:[e.jsxs("div",{className:"rounded-xl border border-green-100 bg-green-50 p-4 flex items-start gap-3",children:[e.jsx("span",{className:"text-xl",children:"🔏"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-extrabold text-green-800",children:"Constancia digital generada"}),e.jsxs("p",{className:"text-xs text-green-600 mt-0.5 font-mono",children:["Hash: ",o.slice(0,8).toUpperCase(),"…",e.jsx("span",{className:"text-green-400 ml-1 text-[10px]",children:"(SHA-256)"})]})]})]}),e.jsxs("div",{className:"rounded-xl border border-purple-100 bg-purple-50 p-4 flex items-start gap-3",children:[e.jsx("span",{className:"text-xl",children:"📲"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-extrabold text-purple-800",children:"Acceso pendiente de confirmación QR"}),e.jsx("p",{className:"text-xs text-purple-600 mt-0.5",children:"Los padres recibirán una pre-autorización que confirmarán al escanear el QR del establecimiento"})]})]})]}),e.jsx(i.button,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},transition:{delay:.7},whileHover:{scale:1.02,translateY:-2},whileTap:{scale:.97},onClick:a,className:"w-full rounded-xl font-extrabold py-4 text-sm text-white shadow-[0_4px_16px_rgba(26,108,245,0.35)] hover:-translate-y-0.5 transition-all",style:{background:"linear-gradient(135deg, #1A6CF5, #0D4FBF)"},children:"Ver resumen completo →"})]}),De=()=>{const{records:t,batchName:o,schoolYear:a,groupsDetected:n,consents:l,signedByName:d,signedByRole:c,isSigning:p,signatureHash:w,importResult:k,rawHeaders:E,allRows:v,columnMappings:A,cohortType:P,file:D,setConsents:b,setIsSigning:r,setSignatureHash:m,setImportResult:f,setBatchId:x,goPrevPhase:_}=V(s=>s),[u,y]=g.useState("idle"),[B,O]=g.useState(d),[R,$]=g.useState(c),j=g.useMemo(()=>t.filter(s=>s.validationStatus!=="skipped"&&s.importStatus!=="skipped"),[t]),M=g.useMemo(()=>j.filter(s=>s.personType==="student").length,[j]),z=g.useMemo(()=>j.filter(s=>s.personType==="parent").length,[j]),Y=g.useMemo(()=>j.filter(s=>s.personType==="teacher").length,[j]),q=j.length,G=g.useMemo(()=>{if(n.length>0)return n.map(N=>N.label);const s=new Set;return t.forEach(N=>N.schoolGroup&&s.add(N.schoolGroup)),Array.from(s).sort()},[n,t]),C=l.academic&&B.trim().length>2&&u==="idle"&&!w,L=async()=>{if(!C)return;r(!0),y("scanning"),await new Promise(h=>setTimeout(h,1200)),y("verifying"),await new Promise(h=>setTimeout(h,800)),y("confirmed");const s=`${B}|${R}|${o}|${a}|${Date.now()}`,N=await K(s);m(N);try{const h=v.length>0?v:t.map(U=>Object.values(U.rawData)),F=await W({rawHeaders:E,allRows:h,columnMappings:A,cohortType:P,batchName:o,schoolYear:a,consents:l,signatureHash:N,signedByRole:R,fileName:D?.name});f({imported:F.imported,skipped:F.skipped,errors:F.errors}),x(F.batchId),T.success(`${F.imported} registros importados a EDYEN`,{description:"La base de datos quedó guardada en Supabase y firmada digitalmente."})}catch(h){console.error("[Phase5] commitEnrollment:",h),y("idle"),m(""),T.error("No se pudo completar la importación",{description:h?.message??"Revisa tu conexión e intenta de nuevo."})}finally{r(!1)}};return k&&w?e.jsx(ee,{total:k.imported,hash:w,onViewSummary:()=>{console.log("View full summary")}}):e.jsxs("div",{className:"flex flex-col gap-6 pb-32",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-black uppercase tracking-widest text-gray-400 mb-1",children:"Fase 5 · Confirmación biométrica"}),e.jsx("h2",{className:"text-2xl font-extrabold text-gray-900",children:"Firma y autorización"}),e.jsx("p",{className:"text-sm text-gray-500 mt-0.5",children:"Revisa el resumen, acepta el aviso de privacidad y confirma con Face ID"})]}),e.jsx(J,{students:M,parents:z,teachers:Y,total:q,batchName:o,schoolYear:a,groups:G}),e.jsxs("div",{className:"rounded-2xl border border-gray-100 bg-white overflow-hidden",children:[e.jsxs("div",{className:"px-5 pt-5 pb-3",children:[e.jsx("p",{className:"text-[10px] font-black uppercase tracking-widest text-gray-400 mb-0.5",children:"Aviso de privacidad institucional"}),e.jsx("p",{className:"text-xs text-gray-500",children:"Conforme a la LFPDPPP Art. 9 y NOM-151, el responsable declara que los datos se tratarán únicamente con las finalidades descritas."})]}),e.jsxs("div",{className:"divide-y divide-gray-50",children:[e.jsx(I,{label:"☑ Datos académicos y de contacto",subLabel:"Nombre, matrícula, grupo, email, teléfono",checked:l.academic,required:!0}),e.jsx(I,{label:"☑ Datos financieros (mensualidades EDYEN)",subLabel:"Historial de pagos y adeudos internos",checked:l.financial,onCh
1ange:s=>b({financial:s})}),e.jsx(I,{label:"☑ Datos de movilidad (ruta escolar)",subLabel:"Geolocalización de rutas y horarios de transporte",checked:l.mobility,onChange:s=>b({mobility:s})}),e.jsx(I,{label:"☐ Datos de salud",subLabel:"Historial médico, alergias y vacunas",checked:l.medical,onChange:s=>b({medical:s}),warning:!0})]}),e.jsx("div",{className:"px-5 pb-5 pt-3",children:e.jsx("p",{className:"text-[10px] text-gray-400 leading-relaxed",children:"Fundamento legal: LFPDPPP Art. 9 · NOM-151-SCFI-2016 · Acuerdo SEP 25/01/22. El titular podrá ejercer derechos ARCO ante el DPO institucional."})})]}),e.jsxs("div",{className:"rounded-2xl border border-gray-100 bg-white p-5 space-y-4",children:[e.jsx("p",{className:"text-[10px] font-black uppercase tracking-widest text-gray-400",children:"Datos del responsable"}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-[10px] font-black uppercase tracking-widest text-gray-400 block mb-1",children:"Nombre completo"}),e.jsx("input",{type:"text",placeholder:"Dr. / Dra. Nombre",value:B,onChange:s=>O(s.target.value),className:"w-full px-4 py-3 rounded-xl border border-gray-200 text-sm font-semibold text-gray-800 focus:outline-none focus:ring-2 focus:ring-[#1A6CF5]/30 bg-gray-50 transition"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-[10px] font-black uppercase tracking-widest text-gray-400 block mb-1",children:"Cargo"}),e.jsx("input",{type:"text",placeholder:"Director General",value:R,onChange:s=>$(s.target.value),className:"w-full px-4 py-3 rounded-xl border border-gray-200 text-sm font-semibold text-gray-800 focus:outline-none focus:ring-2 focus:ring-[#1A6CF5]/30 bg-gray-50 transition"})]})]})]}),e.jsx("div",{className:"rounded-2xl border border-gray-100 bg-white p-8",children:e.jsx(H,{mode:"wait",children:u!=="confirmed"?e.jsxs(i.div,{initial:{opacity:0}
1,animate:{opacity:1},exit:{opacity:0},children:[e.jsx(Z,{phase:u,onStart:L}),!C&&u==="idle"&&e.jsx(i.p,{initial:{opacity:0},animate:{opacity:1},className:"text-xs text-center text-gray-400 mt-4",children:l.academic?B.trim().length<=2?"⚠️ Ingresa el nombre del responsable":"":"⚠️ Acepta los datos académicos para continuar"})]},"biometric"):e.jsxs(i.div,{initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1},className:"flex flex-col items-center gap-4",children:[e.jsx(i.div,{animate:{rotate:360},transition:{repeat:1/0,duration:1,ease:"linear"},className:"w-12 h-12 border-4 border-[#00B67A] border-t-transparent rounded-full"}),e.jsx("p",{className:"text-sm font-extrabold text-gray-700",children:"Importando registros…"}),e.jsx("p",{className:"text-xs text-gray-400",children:"Esto puede tomar unos segundos"})]},"verifying")})}),e.jsx(i.div,{initial:{y:40,opacity:0},animate:{y:0,opacity:1},transition:{delay:.4,type:"spring",stiffness:260,damping:22},className:"fixed bottom-0 left-0 right-0 z-50 px-4 pb-safe",children:e.jsxs("div",{className:"max-w-3xl mx-auto bg-white/90 backdrop-blur-xl border border-gray-200 rounded-2xl shadow-[0_-4px_40px_rgba(0,0,0,0.12)] p-4 flex gap-3",children:[e.jsx(i.button,{whileTap:{scale:.97},onClick:_,disabled:u!=="idle",className:"px-6 py-3 rounded-xl font-extrabold text-sm text-gray-600 bg-gray-100 border border-gray-200 hover:bg-gray-200 transition-colors disabled:opacity-40",children:"← Atrás"}),e.jsx(i.button,{whileHover:C?{scale:1.02,translateY:-2}:{},whileTap:C?{scale:.97}:{},onClick:L,disabled:!C,className:"flex-1 rounded-xl font-extrabold py-3 text-sm text-white shadow-[0_4px_16px_rgba(26,108,245,0.35)] hover:-translate-y-0.5 transition-all disabled:opacity-50",style:{background:"linear-gradient(135deg, #1A6CF5, #0D4FBF)"},children:"🔐 Confirmar con Face ID"})]})})]})};export{De as Phase5_BiometricConfirm,De as default};

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.