PageSourceSearch

https://bolsa-de-trabajo-upy.lovable.app/assets/dashboard.student-CL9Qcj0f.js

js bolsa-de-trabajo-upy.lovable.app collected 2026-10-03 03:24:44 UTC 16,034 bytes, 1 lines download raw bytes

1import{h as te,i as le,u as ie,r as x,s as h,j as e,f as H,t as j,k as ne,L as ce,B as y}from"./index-BbGE8qkG.js";import{D as Q,P as oe}from"./DashboardShell-BDFNOg_Y.js";import{C as b}from"./card-Ds54rD6_.js";import{B as u}from"./index-DYh2uD_S.js";import{I as A}from"./input-CSJwpke0.js";import{C as de,D as me,a as ue,b as pe,c as xe}from"./dialog-BpjMoqYZ.js";import{d as he,S as fe,T as ge,a as je,b as R,c as U,e as ve,M as ye}from"./switch-2e1wfRey.js";import{S as _,a as w,b as C,c as q,d as c}from"./select-DoutvRKW.js";import{g as Ne,A as be,a as _e,P as we}from"./alert-X9mhTgpU.js";import{a as Ce,O as qe,U as Se,b as M,d as B,p as $,l as ke,s as Ee}from"./talent-match-B0YqvE3h.js";import{G as Te}from"./graduation-cap-Bs8SWSV0.js";import{S as Ve}from"./search-Dlgea-N0.js";import{B as Ae}from"./briefcase-CWdg0wKY.js";import{B as Y}from"./building-2-BIjueyg7.js";import{M as Le}from"./map-pin-YX5L1dQw.js";import{S as K}from"./sparkles-CN4IEGSS.js";import"./SiteHeader-D8I_CEt1.js";function es(){const{user:t,role:m,loading:l}
1=te(),f=le(),W=ie(Ne),[o,P]=x.useState(null),[X,Z]=x.useState([]),[N,D]=x.useState({}),[S,k]=x.useState({}),[Pe,I]=x.useState({}),[ee,se]=x.useState(!0),[a,p]=x.useState({q:"",modality:"all",type:"all",career:"all",minQuarter:"all",english:"all",skill:"",location:""}),[E,ae]=x.useState("suggested"),[i,v]=x.useState({open:!1,job:null,busy:!1,result:null});x.useEffect(()=>{if(!l){if(!t){f({to:"/auth"});return}if(m&&m!=="student"){f({to:m==="company"?"/dashboard/company":"/admin"});return}m&&(async()=>{const{data:s}=await h.from("student_profiles").select("*").eq("user_id",t.id).maybeSingle();if(!s){f({to:"/onboarding/student"});return}P(s);const r=await W({data:{}});Z(r);const{data:n}=await h.from("matches").select("job_id, score").eq("student_id",s.id),d={};(n??[]).forEach(g=>d[g.job_id]=g.score),D(d);const[{data:G},{data:V}]=await Promise.all([h.from("saved_jobs").select("id, job_id").eq("student_id",s.id),h.from("job_applications").select("id, job_id").eq("student_id",s.id)]);k(Object.fromEntries((G??[]).map(g=>[g.job_id,g.id]))),I(Object.fromEntries((V??[]).map(g=>[g.job_id,g.id]))),se(!1)})()}},[t,m,l,f]);const T=X.filter(s=>{const r=a.q.toLowerCase().trim();if(r&&!s.title.toLowerCase().includes(r)&&!s.company_profiles?.company_name.toLowerCase().includes(r)||a.modality!=="all"&&s.modality!==a.modality||a.type!=="all"&&s.opportunity_type!==a.type||a.career!=="all"&&s.career_required&&s.career_required!==a.career||a.minQuarter!=="all"&&(s.min_quarter??0)>Number(a.minQuarter)||a.english!=="all"&&s.english_required&&s.english_required!==a.english)return!1;if(a.skill.trim()){const n=a.skill.toLowerCase().trim();if(!(s.skills_required??[]).some(d=>d.toLowerCase().includes(n)))return!1}if(a.location.trim()){const n=a.location.toLowerCase().trim();if(!s.company_profiles?.location?.toLowerCase().includes(n))return!1}return!0}),J=[...T].filter(s=>N[s.id]!=null&&N[s.id]>=55).sort((s,r)=>(N[r.id]??0)-(N[s.id]??0)),O=E==="suggested"?J:T,z=async s=>{v({open:!0,job:s,busy:!0,result:null});try{const{data:r,error:n}=await h.functions.invoke("compute-match",{body:{jobId:s.id}});if(n)throw n;if(r?.error)throw new Error(r.error);v(d=>({...d,busy:!1,result:r})),D(d=>({...d,[s.id]:r.score}))}catch(r){const n=r instanceof Error?r.message:"Error verificando match";j.error(n),v({open:!1,job:null,busy:!1,result:null})}},re=async s=>{if(!o)return;const{error:r}=await h.from("job_applications").upsert({student_id:o.id,job_id:s.id,status:"applied"});if(r)return j.error(r.message);I(n=>({...n,[s.id]:s.id})),j.success("Aplicación registrada")},F=async s=>{if(!o)return;if(S[s.id]){const{error:d}=await h.from("saved_jobs").delete().eq("id",S[s.id]);if(d)return j.error(d.message);k(({[s.id]:G,...V})=>V),j.success("Vacante quitada de guardados");return}const{data:r,error:n}=await h.from("saved_jobs").insert({student_id:o.id,job_id:s.id}).select("id").single();if(n)return j.error(n.message);k(d=>({...d,[s.id]:r.id})),j.success("Vacante guardada")};return l||ee?e.jsx(Q,{title:"Mi panel",children:e.jsx("div",{className:"flex h-64 items-center justify-center",children:e.jsx(H,{className:"h-6 w-6 animate-spin text-primary"})})}):e.jsxs(Q,{title:`Hola, ${o.full_name?.split(" ")[0]??""} 👋`,description:"Aquí tienes las vacantes activas. Verifica tu match para conocer tu compatibilidad.",actions:e.jsxs(y,{variant:"outline",onClick:()=>f({to:"/onboarding/student"}),children:[e.jsx(oe,{})," Editar perfil"]}),children:[e.jsxs("div",{className:"mb-6 grid gap-4 lg:grid-cols-3",children:[e.jsxs(b,{className:"p-4 lg:col-span-1",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm font-medium mb-2",children:[e.jsx(Te,{className:"h-4 w-4 text-primary"})," Grado académico"]}),o.academic_level?e.jsx(u,{variant:"secondary",className:"text-sm",children:Ce(o.academic_level)}):e.jsxs(be,{variant:"destructive",className:"py-2",children:[e.jsx(he,{className:"h-4 w-4"}),e.jsx(_e,{className:"text-xs",children:"Completa tu grado académico — es clave para el matching."})]}),e.jsxs("div",{className:"mt-4 flex items-center gap-2",children:[e.jsx(fe,{id:"show-contact",checked:!!o.show_contact,onCheckedChange:async s=>{P({...o,show_contact:s}),await h.from("student_profiles").update({show_contact:s}
1).eq("id",o.id),j.success(s?"Tu contacto será visible para empresas verificadas":"Tu contacto está oculto")}}),e.jsx(ne,{htmlFor:"show-contact",className:"text-xs cursor-pointer",children:"Mostrar mi contacto a empresas verificadas"})]})]}),e.jsx(we,{profile:o,kind:"student",className:"lg:col-span-2"})]}),e.jsx("div",{className:"mb-4 flex flex-wrap items-center gap-3",children:e.jsxs(ge,{value:E,onValueChange:s=>ae(s),children:[e.jsxs(je,{children:[e.jsxs(R,{value:"suggested",children:["Sugeridas (",J.length,")"]}),e.jsxs(R,{value:"explore",children:["Explorar vacantes (",T.length,")"]}),e.jsx(ce,{to:"/empresas-estadias",className:"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",children:"Empresas para Estancias y Estadías"})]}),e.jsx(U,{value:"suggested",className:"mt-2",children:e.jsx("p",{className:"text-xs text-muted-foreground",children:"Las mejores oportunidades según tu perfil. Verifica tu match en cualquier vacante para que aparezca aquí."})}),e.jsx(U,{value:"explore",className:"mt-2",children:e.jsx("p",{className:"text-xs text-muted-foreground",children:"Explora todas las vacantes activas, incluso las que aún no tienen match calculado."})})]})}),e.jsxs(b,{className:"mb-6 p-4",children:[e.jsxs("div",{className:"grid gap-3 md:grid-cols-3 lg:grid-cols-4",children:[e.jsxs("div",{className:"relative md:col-span-2 lg:col-span-2",children:[e.jsx(Ve,{className:"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsx(A,{value:a.q,onChange:s=>p({...a,q:s.target.value}),placeholder:"Buscar puesto o empresa...",className:"pl-9"})]}),e.jsxs(_,{value:a.modality,onValueChange:s=>p({...a,modality:s}),children:[e.jsx(w,{children:e.jsx(C,{placeholder:"Modalidad"})}),e.jsxs(q,{children:[e.jsx(c,{value:"all",children:"Todas las modalidades"}),e.jsx(c,{value:"onsite",children:"Presencial"}),e.jsx(c,{value:"remote",children:"Remoto"}),e.jsx(c,{value:"hybrid",children:"Híbrido"})]})]}),e.jsxs(_,{value:a.type,onValueChange:s=>p({...a,type:s}),children:[e.jsx(w,{children:e.jsx(C,{placeholder:"Oportunidad"})}),e.jsxs(q,{children:[e.jsx(c,{value:"all",children:"Todos los tipos"}),qe.map(s=>e.jsx(c,{value:s.value,children:s.label},s.value))]})]}),e.jsxs(_,{value:a.career,onValueChange:s=>p({...a,career:s}),children:[e.jsx(w,{children:e.jsx(C,{placeholder:"Carrera"})}),e.jsxs(q,{children:[e.jsx(c,{value:"all",children:"Todas las carreras"}),Se.map(s=>e.jsx(c,{value:s,children:s},s))]})]}),e.jsxs(_,{value:a.minQuarter,onValueChange:s=>p({...a,minQuarter:s}),children:[e.jsx(w,{children:e.jsx(C,{placeholder:"Cuatri mínimo"})}),e.jsxs(q,{children:[e.jsx(c,{value:"all",children:"Cualquier cuatri"}),[4,5,6,7,8,9,10].map(s=>e.jsx(c,{value:String(s),children:`Hasta ${s}° cuatri`},s))]})]}),e.jsxs(_,{value:a.english,onValueChange:s=>p({...a,english:s}),children:[e.jsx(w,{children:e.jsx(C,{placeholder:"Inglés requerido"})}),e.jsxs(q,{children:[e.jsx(c,{value:"all",children:"Cualquier nivel"}),e.jsx(c,{value:"A1",children:"A1"}),e.jsx(c,{value:"A2",children:"A2"}),e.jsx(c,{value:"B1",children:"B1"}),e.jsx(c,{value:"B2",children:"B2"}),e.jsx(c,{value:"C1",children:"C1"}),e.jsx(c,{value:"C2",children:"C2"})]})]}),e.jsx(A,{value:a.skill,onChange:s=>p({...a,skill:s.target.value}),placeholder:"Habilidad (ej. React)"}),e.jsx(A,{value:a.location,onChange:s=>p({...a,location:s.target.value}),placeholder:"Ubicación"})]}),e.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"Filtros activos:"}),Object.entries(a).filter(([,s])=>s&&s!=="all").map(([s,r])=>e.jsxs(u,{variant:"secondary",className:"gap-1",children:[s,": ",String(r),e.jsx("button",{className:"ml-1 text-muted-foreground hover:text-foreground",onClick:()=>p({...a,[s]:typeof r=="string"&&(r==="all"||["q","skill","location"].includes(s))?"":"all"}),children:"×"})]},s)),e.jsx(y,{size:"sm",variant:"ghost",className:"ml-auto",onClick:()=>p({q:"",modality:"all",type:"all",career:"all",minQuarter:"all",english:"all",skill:"",location:""}),children:"Limpiar"})]})]}),O.length===0?e.jsxs(b,{className:"p-10 text-center text-muted-foreground",children:[e.jsx(Ae,{className:"mx-auto mb-3 h-10 w-10 opacity-40"}),E==="suggested"?"Aún no tienes vacantes sugeridas. Verifica tu match en alguna vacante de “Explorar”.":"No hay vacantes que coincidan con tus filtros."]}):e.jsx("div",{className:"grid gap-4 md:grid-cols-2 lg:grid-cols-3",children:O.map(s=>{const r=N[s.id];return e.jsxs(b,{className:"flex flex-col overflow-hidden p-5 transition-all hover:-translate-y-0.5 hover:shadow-[var(--shadow-card)]",children:[e.jsxs("div",{className:"mb-3 flex items-start gap-3",children:[s.company_profiles?.logo_url?e.jsx("img",{src:s.company_profiles.logo_url,alt:s.company_profiles.company_name,className:"h-10 w-10 rounded-lg border border-border object-contain"}):e.jsx("div",{className:"flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10 text-primary",children:e.jsx(Y,{className:"h-5 w-5"})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("h3",{className:"line-clamp-2 text-sm font-semibold leading-tight",children:s.title}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:s.company_profiles?.company_name}),s.company_profiles?.status==="verified"&&e.jsxs(u,{className:"bg-success text-success-foreground text-[9px] px-1.5 py-0 h-4 gap-0.5",children:[e.jsx(de,{className:"h-2.5 w-2.5"})," Verificada"]})]})]}),r!=null?e.jsxs(u,{variant:r>=80?"default":r>=55?"secondary":"destructive",className:"shrink-0",children:[r,"%"]}):e.jsx(u,{variant:"outline",className:"shrink-0 text-[10px]",children:"Sin match"})]}),e.jsxs("div",{className:"mb-3 flex flex-wrap gap-1.5",children:[e.jsx(u,{variant:"outline",className:"text-[10px]",children:M(s.opportunity_type)}),e.jsx(u,{variant:"outline",className:"text-[10px]",children:B(s.modality)}),s.english_required&&e.jsxs(u,{variant:"outline",className:"text-[10px]",children:["Inglés ",s.english_required]})]}),s.company_profiles?.location&&e.jsxs("p",{className:"mb-2 flex items-center gap-1 text-xs text-muted-foreground",children:[e.jsx(Le,{className:"h-3 w-3"})," ",s.company_profiles.location]}),s.skills_required&&s.skills_required.length>0&&e.jsx("div",{className:"mb-3 flex flex-wrap gap-1",children:s.skills_required.slice(0,4).map(n=>e.jsx("span",{className:"rounded-full bg-muted px-2 py-0.5 text-[10px] text-muted-foreground",children:n},n))}),e.jsxs("div",{className:"mt-auto space-y-3 pt-3",children:[e.jsx(y,{variant:"outline",size:"sm",className:"w-full",onClick:()=>v({open:!0,job:s,busy:!1,result:null}),children:"Ver detalle"}),e.jsxs(y,{variant:"ghost",size:"sm",className:"w-full",onClick:()=>F(s),children:[e.jsx(ve,{className:"h-4 w-4"})," ",S[s.id]?"Guardada":"Guardar"]}),e.jsxs(y,{variant:"hero",size:"sm",className:"w-full",onClick:()=>z(s),children:[e.jsx(K,{})," Verificar mi match"]})]})]},s.id)})}),$(o.status,"student")&&e.jsxs(b,{className:"mb-6 border-accent/50 bg-accent/5 p-4 text-sm",children:[e.jsx("div",{className:"mb-2 flex items-center gap-2",children:e.jsx(u,{variant:Ee(o.status),children:ke(o.status)})}),e.jsx("p",{className:"text-muted-foreground",children:$(o.status,"student")})]}),e.jsx(me,{open:i.open,onOpenChange:s=>!s&&v({...i,open:!1}),children:e.jsxs(ue,{className:"max-h-[90vh] max-w-4xl overflow-y-auto",children:[e.jsx(pe,{children:e.jsx(xe,{children:i.busy?"Calculando tu match...":"Tu match"})}),i.job&&!i.busy&&!i.result&&e.jsx(Me,{job:i.job,onVerify:()=>z(i.job)}),i.busy&&e.jsxs("div",{className:"flex h-40 flex-col items-center justify-center gap-3 text-muted-foreground",children:[e.jsx(H,{className:"h-8 w-8 animate-spin text-primary"}),e.jsx("p",{className:"text-sm",children:"Analizando tu perfil con IA..."})]}),i.result&&e.jsx(ye,{data:i.result,companyName:i.job?.company_profiles?.company_name,companyLogo:i.job?.company_profiles?.logo_url,title:i.job?.title,onApply:i.job?()=>re(i.job):void 0,onSave:i.job?()=>F(i.job):void 0,onDetail:i.job?()=>v(s=>({...s,result:null})):void 0})]})})]})}function Me({job:t,onVerify:m}){const l=t.company_profiles;return e.jsxs("div",{className:"max-h-[70vh] space-y-5 overflow-y-auto pr-1",children:[e.jsxs("div",{className:"flex items-start gap-4",children:[l?.logo_url?e.jsx("img",{src:l.logo_url,alt:l.company_name,className:"h-16 w-16 rounded-lg border border-border object-contain"}):e.jsx("div",{className:"flex h-16 w-16 items-center justify-center rounded-lg bg-primary/10 text-primary",children:e.jsx(Y,{})}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold",children:t.title}),e.jsx("p",{className:"text-sm text-muted-foreground",children:l?.company_name??"Empresa"}),e.jsxs("div",{className:"mt-2 flex flex-wrap gap-1.5",children:[e.jsx(u,{variant:"outline",children:M(t.opportunity_type)}),e.jsx(u,{variant:"outline",children:B(t.modality)})]})]})]}),l?.flyer_url&&e.jsx("img",{src:l.flyer_url,alt:`Flyer de ${l.company_name}`,className:"max-h-72 w-full rounded-lg border border-border object-contain"}),e.jsx(Be,{items:[["Empresa",l?.company_name],["Industria",l?.industry],["Ubicación",l?.location],["Puesto",t.title],["Tipo",M(t.opportunity_type)],["Modalidad",B(t.modality)],["Carrera buscada",t.career_required],["Cuatrimestre mínimo",t.min_quarter],["Inglés requerido",t.english_required],["Sueldo / apoyo",t.salary]]}),l?.description&&e.jsx(L,{title:"Descripción de la empresa",value:l.description}),t.activities&&e.jsx(L,{title:"Actividades principales",value:t.activities}),t.ideal_profile&&e.jsx(L,{title:"Perfil ideal",value:t.ideal_profile}),t.skills_required?.length?e.jsxs("div",{children:[e.jsx("h4",{className:"mb-2 text-sm font-semibold",children:"Habilidades requeridas"}),e.jsx("div",{className:"flex flex-wrap gap-1.5",children:t.skills_required.map(f=>e.jsx(u,{variant:"secondary",children:f},f))})]}):null,e.jsxs(y,{variant:"hero",className:"w-full",onClick:m,children:[e.jsx(K,{})," Verificar mi match"]})]})}function Be({items:t}){return e.jsx("div",{className:"grid gap-3 md:grid-cols-2",children:t.map(([m,l])=>e.jsxs("div",{className:"rounded-md border border-border p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:m}),e.jsx("p",{className:"text-sm font-medium",children:l?String(l):"—"})]},m))})}function L({title:t,value:m}){return e.jsxs("div",{children:[e.jsx("h4",{className:"mb-1 text-sm font-semibold",children:t}),e.jsx("p",{className:"text-sm text-muted-foreground",children:m})]})}
1export{es 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.