PageSourceSearch

https://nomadcareers.online/assets/AdminVisas-BL4LfSvK.js

js nomadcareers.online collected 2026-10-07 19:01:30 UTC 10,767 bytes, 1 lines download raw bytes

1import{r as d,c as V,j as e}from"./vendor-react-D47JvSX0.js";import{w as F,s as g,N as D,F as A,B as m,I as t}from"./index-CyolZPlc.js";import{C as I,a as k,c as R,b as T}from"./card-DNf18MTj.js";import{D as M,f as P,a as B,b as L,c as Y,d as z}from"./dialog-BDRJmGBt.js";import{L as r}from"./label-WUQZf4s-.js";import{S as O,a as H,b as K,c as U,d as $}from"./select-D9mWH3NW.js";import{h as S,as as X,ai as G,al as J,X as E}from"./vendor-icons-CpgEi55e.js";import"./vendor-supabase-BZ1YugtK.js";import"./vendor-ui-CcHuJjDu.js";import"./vendor-utils-Dd_H0aph.js";function ce(){const[w,C]=d.useState(!0),[q,i]=d.useState(!1),[a,v]=d.useState([]),[h,u]=d.useState(null),[_,p]=d.useState(!1),{toast:l}=F(),j=V(),y={country:"",flag:"",visa_type:"Digital Nomad Visa",duration:"",renewable:"Yes",minimum_income_monthly:"",minimum_income_annual:"",cost:"",processing_time:"",region:"Europe",application_url:"",benefits:[],requirements:[],dependents_allowed:"Yes",income_tax:"Exempt for first year"};d.useEffect(()=>{N()},[]);const N=async()=>{try{const{data:{session:n},error:c}=await g.auth.getSession();if(c||!n){l({title:"Authentication Required",description:"Please log in to access this page",variant:"destructive"}),j("/");return}const{data:b,error:x}=await g.rpc("has_role",{_user_id:n.user.id,_role:"admin"});if(x||!b){l({title:"Access Denied",description:"You don't have permission to access this page",variant:"destructive"}),j("/");return}i(!0),f()}catch(n){console.error("Auth check error:",n),j("/")}finally{C(!1)}},f=async()=>{const{data:n,error:c}=await g.from("nomad_visas").select("*").order("country",{ascending:!0});if(c){l({title:"Error loading visas",description:c.message,variant:"destructive"});return}v(n||[])},s=async n=>{const{id:c,...b}=n;if(c){const{error:x}=await g.from("nomad_visas").update(b).eq("id",c);if(x){l({title:"Error updating visa",description:x.message,variant:"destructive"});return}l({title:"Visa updated successfully"})}else{const{error:x}=await g.from("nomad_visas").insert([b]);if(x){l({title:"Error creating visa",description:x.message,variant:"destructive"});return}l({title:"Visa created successfully"})}p(!1),u(null),f()},o=async n=>{if(!confirm("Are you sure you want to delete this visa?"))return;const{error:c}=await g.from("nomad_visas").delete().eq("id",n);if(c){l({title:"Error deleting visa",description:c.message,variant:"destructive"});return}l({title:"Visa deleted successfully"}),f()};return w?e.jsxs("div",{className:"min-h-screen flex flex-col",children:[e.jsx(D,{}),e.jsx("main",{className:"flex-1 py-12 flex items-center justify-center",children:e.jsxs("div",{className:"text-center",children:[e.jsx(S,{className:"h-12 w-12 mx-auto mb-4 animate-pulse"}),e.jsx("p",{className:"text-muted-foreground",children:"Verifying permissions..."})]})}),e.jsx(A,{})]}):q?e.jsxs("div",{className:"min-h-screen flex flex-col",children:[e.jsx(D,{}),e.jsx("main",{className:"flex-1 py-12",children:e.jsxs("div",{className:"container mx-auto px-4 max-w-6xl",children:[e.jsxs("div",{className:"flex items-center justify-between mb-8",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(S,{className:"h-8 w-8 text-primary"}),e.jsx("h1",{className:"text-4xl font-bold",children:"Manage Digital Nomad Visas"})]}),e.jsxs(M,{open:_,onOpenChange:p,children:[e.jsx(P,{asChild:!0,children:e.jsxs(m,{onClick:()=>u({...y,id:""}),children:[e.jsx(X,{className:"h-4 w-4 mr-2"}),"Add Visa"]})}),e.jsxs(B,{className:"max-w-2xl max-h-[90vh] overflow-y-auto",children:[e.jsxs(L,{children:[e.jsx(Y,{children:h!=null&&h.id?"Edit Visa":"Add New Visa"}),e.jsx(z,{children:"Fill in the visa information below"})]}),e.jsx(Q,{visa:h||{...y,id:""},onSave:s,onCancel:()=>{p(!1),u(null)}})]})]})]}),e.jsx("div",{className:"grid gap-4",children:a.map(n=>e.jsxs(I,{children:[e.jsxs(k,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsxs(R,{className:"text-2xl font-bold flex items-center gap-2",children:[e.jsx("span",{className:"text-3xl",children:n.flag}),n.country]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(m,{variant:"outline",size:"sm",onClick:()=>{u(n),p(!0)},children:e.jsx(G,{className:"h-4 w-4"})}),e.jsx(m,{variant:"destructive",size:"sm",onClick:()=>
1o(n.id),children:e.jsx(J,{className:"h-4 w-4"})})]})]}),e.jsx(T,{children:e.jsxs("div",{className:"grid md:grid-cols-2 gap-4 text-sm",children:[e.jsxs("div",{children:[e.jsx("strong",{children:"Visa Type:"})," ",n.visa_type]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Duration:"})," ",n.duration]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Renewable:"})," ",n.renewable]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Min Income (Monthly):"})," ",n.minimum_income_monthly]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Min Income (Annual):"})," ",n.minimum_income_annual]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Cost:"})," ",n.cost]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Income Tax:"})," ",n.income_tax]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Processing Time:"})," ",n.processing_time]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Region:"})," ",n.region]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Dependents Allowed:"})," ",n.dependents_allowed]}),e.jsxs("div",{className:"md:col-span-2",children:[e.jsx("strong",{children:"URL:"})," ",e.jsx("a",{href:n.application_url,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:n.application_url})]})]})})]},n.id))})]})}),e.jsx(A,{})]}):null}function Q({visa:w,onSave:C,onCancel:q}){const[i,a]=d.useState(w),[v,h]=d.useState(""),[u,_]=d.useState(""),p=["Europe","Asia","Americas","Middle East","Africa","Europe/Asia","Oceania"],l=s=>{s.preventDefault(),C(i)},j=()=>{v.trim()&&(a({...i,benefits:[...i.benefits,v.trim()]}),h(""))},y=s=>{a({...i,benefits:i.benefits.filter((o,n)=>n!==s)})},N=()=>{u.trim()&&(a({...i,requirements:[...i.requirements,u.trim()]}),_(""))},f=s=>{a({...i,requirements:i.requirements.filter((o,n)=>n!==s)})};return e.jsxs("form",{onSubmit:l,className:"space-y-4",children:[e.jsxs("div",{className:"grid md:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx(r,{htmlFor:"country",children:"Country"}),e.jsx(t,{id:"country",value:i.country,onChange:s=>a({...i,country:s.target.value}),required:!0})]}),e.jsxs("div",{children:[e.jsx(r,{htmlFor:"flag",children:"Flag Emoji"}),e.jsx(t,{id:"flag",value:i.flag,onChange:s=>a({...i,flag:s.target.value}),required:!0,placeholder:"🇵🇹"})]})]}),e.jsxs("div",{className:"grid md:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx(r,{htmlFor:"visa_type",children:"Visa Type"}),e.jsx(t,{id:"visa_type",value:i.visa_type,onChange:s=>a({...i,visa_type:s.target.value}),required:!0,placeholder:"Digital Nomad Visa"})]}),e.jsxs("div",{children:[e.jsx(r,{htmlFor:"duration",children:"Duration"}),e.jsx(t,{id:"duration",value:i.duration,onChange:s=>a({...i,duration:s.target.value}),required:!0,placeholder:"1 year"})]})]}),e.jsxs("div",{className:"grid md:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx(r,{htmlFor:"renewable",children:"Renewable"}),e.jsx(t,{id:"renewable",value:i.renewable,onChange:s=>a({...i,renewable:s.target.value}),required:!0,placeholder:"Yes"})]}),e.jsxs("div",{children:[e.jsx(r,{htmlFor:"minimum_income_monthly",children:"Minimum Income (Monthly)"}),e.jsx(t,{id:"minimum_income_monthly",value:i.minimum_income_monthly,onChange:s=>a({...i,minimum_income_monthly:s.target.value}),placeholder:"$2,800/month"})]})]}),e.jsxs("div",{className:"grid md:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx(r,{htmlFor:"minimum_income_annual",children:"Minimum Income (Annual)"}),e.jsx(t,{id:"minimum_income_annual",value:i.minimum_income_annual,onChange:s=>a({...i,minimum_income_annual:s.target.value}),placeholder:"$33,600/year"})]}),e.jsxs("div",{children:[e.jsx(r,{htmlFor:"cost",children:"Cost"}),e.jsx(t,{id:"cost",value:i.cost,onChange:s=>a({...i,cost:s.target.value}),required:!0,placeholder:"€75-300"})]}),e.jsxs("div",{children:[e.jsx(r,{htmlFor:"processing_time",children:"Processing Time"}),e.jsx(t,{id:"processing_time",value:i.processing_time,onChange:s=>a({...i,processing_time:s.target.value}),required:!0,placeholder:"2-3 months"})]})]}),e.jsxs("div",{className:"grid md:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx(r,{htmlFor:"dependents_allowed",children:"Dependents Allowed"}),e.jsx(t,{id:"dependents_allowed",value:i.dependents_allowed,onChange:s=>a({...i,dependents_allowed:s.target.value}),required:!0,placeholder:"Yes"})]}),e.jsxs("div",{children:[e.jsx(r,{htmlFor:"income_tax",children:"Income Tax"}),e.jsx(t,{id:"income_tax",value:i.income_tax,onChange:s=>a({...i,income_tax:s.target.value}),required:!0,placeholder:"Exempt for first year"})]})]}),e.jsxs("div",{children:[e.jsx(r,{htmlFor:"region",children:"Region"}),e.jsxs(O,{value:i.region,onValueChange:s=>a({...i,region:s}),children:[e.jsx(H,{children:e.jsx(K,{placeholder:"Select region"})}),e.jsx(U,{className:"bg-background",children:p.map(s=>e.jsx($,{value:s,children:s},s))})]})]}),e.jsxs("div",{children:[e.jsx(r,{htmlFor:"application_url",children:"Application URL"}),e.jsx(t,{id:"application_url",type:"url",value:i.application_url,onChange:s=>a({...i,application_url:s.target.value}),required:!0,placeholder:"https://..."})]}),e.jsxs("div",{children:[e.jsx(r,{children:"Benefits"}),e.jsxs("div",{className:"flex gap-2 mb-2",children:[e.jsx(t,{value:v,onCh
1ange:s=>h(s.target.value),placeholder:"Add a benefit",onKeyPress:s=>s.key==="Enter"&&(s.preventDefault(),j())}),e.jsx(m,{type:"button",onClick:j,children:"Add"})]}),e.jsx("div",{className:"space-y-1",children:i.benefits.map((s,o)=>e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx("span",{className:"flex-1",children:s}),e.jsx(m,{type:"button",variant:"ghost",size:"sm",onClick:()=>y(o),children:e.jsx(E,{className:"h-4 w-4"})})]},o))})]}),e.jsxs("div",{children:[e.jsx(r,{children:"Requirements"}),e.jsxs("div",{className:"flex gap-2 mb-2",children:[e.jsx(t,{value:u,onChange:s=>_(s.target.value),placeholder:"Add a requirement",onKeyPress:s=>s.key==="Enter"&&(s.preventDefault(),N())}),e.jsx(m,{type:"button",onClick:N,children:"Add"})]}),e.jsx("div",{className:"space-y-1",children:i.requirements.map((s,o)=>e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx("span",{className:"flex-1",children:s}),e.jsx(m,{type:"button",variant:"ghost",size:"sm",onClick:()=>f(o),children:e.jsx(E,{className:"h-4 w-4"})})]},o))})]}),e.jsxs("div",{className:"flex justify-end gap-2 pt-4",children:[e.jsx(m,{type:"button",variant:"outline",onClick:q,children:"Cancel"}),e.jsx(m,{type:"submit",children:"Save Visa"})]})]})}export{ce 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.