1import{j as e,c as x,N as h,bq as m,aV as g,d as L,$ as H,cj as Y,bs as V,w as q,bX as W}from"./index-0qbe4j-K.js";import{b as _,L as A}from"./react-vendor-CuqwDvgQ.js";import{C as w,a as N,c as S,d as I,b as k,e as J}from"./card-DYAlVeWP.js";import{B as D}from"./badge-DDqArN_7.js";import{S as R}from"./skeleton-BJ8OkINw.js";import{A as v}from"./app-icon-AzWZizR9.js";import{S as X}from"./index-BqofzlGR.js";import{S as E}from"./settings-section-CQjic8__.js";function Q({className:t,...a}){return e.jsx("div",{"data-slot":"table-container",className:"relative w-full overflow-x-auto",children:e.jsx("table",{"data-slot":"table",className:x("w-full caption-bottom text-sm",t),...a})})}function Z({className:t,...a}){return e.jsx("thead",{"data-slot":"table-header",className:x("[&_tr]:border-b",t),...a})}function K({className:t,...a}){return e.jsx("tbody",{"data-slot":"table-body",className:x("[&_tr:last-child]:border-0",t),...a})}function U({className:t,...a}){return e.jsx("tr",{"data-slot":"table-row",className:x("hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors",t),...a})}function C({className:t,...a}){return e.jsx("th",{"data-slot":"table-head",className:x("text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",t),...a})}function P({className:t,...a}){return e.jsx("td",{"data-slot":"table-cell",className:x("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",t),...a})}const M={free:{monitored_emails:5,incidents_open:10,disclosure_reports:"basic",audit_export:!1,alert_delay_hours:24,support_response_hours:48,breach_sources:["hibp","leakcheck","leakpeek","dehashed","snusbase"],dark_web_checks_monthly:0,dark_web_automatic:!1,dark_web_scraper:!1,breach_alert_delay_hours:24},professional:{monitored_emails:-1,incidents_open:-1,disclosure_reports:"full",audit_export:!0,alert_delay_hours:0,support_response_hours:4,breach_sources:["hibp","leakcheck","leakpeek","dehashed","snusbase"],advanced_ai:!0,dark_web_checks_monthly:-1,dark_web_automatic:!1,dark_web_scraper:!1,breach_alert_delay_hours:0}},T={free:{key:"free",name:"Free",description:"Every Securoxen tool, unlimited, no account required.",price_monthly:0,price_yearly:0,currency:"AUD",limits:M.free,features:["JWT Decoder","Secure Generator","Secret Strength Checker","Scrub for AI","Metadata Stripper","Everything runs in your browser"],cta:"Use the tools",available:!0},professional:{key:"professional",name:"Professional",description:"No longer offered for new subscribers. A supporter tier is planned for the future with pricing yet to be announced.",price_monthly:29,price_yearly:290,currency:"AUD",limits:M.professional,popular:!1,features:[],available:!1}},ee={shield:"professional",sentinel:"professional",starter:"professional",pro:"professional",hobby:"free",standard:"professional",enterprise:"professional"};function F(t){return ee[t]||t}const G="/settings/plan";function te(t,a){const n=t.find(c=>c.key===a)?.price_monthly??T[a]?.price_monthly;return n==null||n===0?"A$0/month":`A$${n}/month`}function O(t,a){const r=t.find(n=>n.key===a);return r?.name?r.name:T[a]?.name??a.replace(/_/g," ")}const $=t=>{if(!t)return"N/A";const a=new Date(t);return isNaN(a.getTime())?"N/A":a.toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})};function ae(t,a){const r=F(t.plan_key||t.plan||"free"),n=t.has_paid_subscription===!0&&r==="professional",c=n?"professional":"free",b=(n?t.status:t.billing_status)||"active",f=String(b).toLowerCase(),d=t.current_period_start?new Date(t.current_period_start):null,p=t.current_period_end?new Date(t.current_period_end):null,y=d&&p?p.getTime()-d.getTime():0,o=d?Date.now()-d.getTime():0,u=y>0?Math.max(1,Math.ceil(y/864e5)):30,s=y>0?Math.max(0,Math.min(u,Math.ceil(o/864e5))):0,i=Math.max(0,u-s),j=u>0?Math.min(100,Math.round(s/u*100)):0,l=n&&["past_due","unpaid","incomplete","canceled"].includes(f),B=t.pending_plan_key?F(t.pending_plan_key):null;return{id:c,hasPaidSubscription:n,planName:O(a,c),price:te(a,c),nextBilling:n?$(t.current_period_end):"N/A",status:n?f.replace("_"," ").replace(/\b\w/g,z=>z.toUpperCase()):"Free",pendingCheckout:!n&&B?`Checkout not completed (${O(a,B)})`:null,daysUsed:s,totalDays:u,progress:j,remainingDays:i,needsAttention:l}}function se(t){return Array.isArray(t)?t.map((a,r)=>
1({id:r+1,date:$(a.paid_at||a.created_at),description:a.stripe_subscription_id?"Previous product subscription":"Payment",amount:typeof a.amount_cents=="number"?new Intl.NumberFormat("en-US",{style:"currency",currency:(a.currency||"usd").toUpperCase()}).format(a.amount_cents/100):"$0.00",status:(a.status||"paid").replace("_"," ").replace(/\b\w/g,n=>n.toUpperCase())})):[]}function pe(){const[t,a]=_.useState(!0),[r,n]=_.useState(null),[c,b]=_.useState([]),[f,d]=_.useState(!1),p=async()=>{try{a(!0);let s=[];try{s=(await h.get(m.BILLING.PLANS)).data?.plans??[]}catch{s=Object.values(T).map(l=>({key:l.key,name:l.name,description:l.description,price_monthly:l.price_monthly,price_yearly:l.price_yearly}))}const i=await h.get(m.BILLING.SUBSCRIPTION),j=ae(i.data,s);n(j);try{const l=await h.get(m.BILLING.PAYMENT_HISTORY);b(se(l.data))}catch{b([])}}catch{g.error("Failed to load subscription")}finally{a(!1)}};_.useEffect(()=>{(async()=>{const s=new URLSearchParams(window.location.search);if(s.get("success")==="true"){const i=s.get("session_id");if(i)try{await h.post(m.BILLING.SYNC_CHECKOUT_SESSION,{session_id:i})}catch{}await p(),(await h.get(m.BILLING.SUBSCRIPTION)).data?.has_paid_subscription?g.success("Subscription active",{description:"Your paid plan is now active."}):g.info("Still on Free plan",{description:"Checkout did not complete yet. If you paid, wait a moment and refresh, or try again."}),window.history.replaceState({},"",G)}else s.get("canceled")==="true"?(g.info("Checkout canceled"),window.history.replaceState({},"",G),await p()):await p()})()},[]);const y=async()=>{d(!0);try{const s=await h.post(m.BILLING.CREATE_PORTAL);s.data.url&&(window.location.href=s.data.url)}catch(s){const i=s;g.error("Failed to open billing portal",{description:i.response?.data?.error||W(s)})}finally{d(!1)}},o=!!r?.hasPaidSubscription,u=s=>{const i=s.toLowerCase();return i==="active"?"success":i.includes("past")||i.includes("unpaid")?"warning":i.includes("canceled")?"destructive":"secondary"};return t?e.jsxs("div",{className:"space-y-4",children:[e.jsx(R,{className:"h-32 w-full"}),e.jsx(R,{className:"h-48 w-full"})]}):o?e.jsx(E,{title:"Subscription",children:e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsxs(w,{children:[e.jsxs(N,{children:[e.jsx(S,{children:"Current plan"}),e.jsx(I,{children:r?o?`${r.planName} · ${r.price}`:`You're on ${r.planName}. No active paid subscription.`:"Unable to load plan."}),o&&e.jsx(J,{children:e.jsx(L,{variant:"outline",size:"sm",onClick:y,disabled:f,children:f?e.jsxs(e.Fragment,{children:[e.jsx(v,{icon:H,size:16,className:"mr-2 animate-spin"}),"Openingâ¦"]}):e.jsxs(e.Fragment,{children:[e.jsx(v,{icon:X,size:16,className:"mr-2"}),"Billing portal"]})})})]}),r&&e.jsxs(k,{className:"space-y-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx(v,{icon:Y,size:20,className:o?"text-amber-500":"text-muted-foreground"}),e.jsx("span",{className:"font-semibold",children:r.planName}),e.jsx(D,{variant:o?u(r.status):"outline",children:o?r.status:"Free tier"}),o&&r.nextBilling!=="N/A"&&e.jsxs("span",{className:"text-sm text-muted-foreground sm:ml-auto",children:["Renews ",r.nextBilling]})]}),!o&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"You do not have an active paid subscription - every tool is free and unlimited either way."}),r.pendingCheckout&&e.jsx("p",{className:"text-sm text-amber-600 dark:text-amber-400",children:r.pendingCheckout}),r.needsAttention&&e.jsxs("div",{className:"flex gap-3 rounded-lg border border-amber-500/40 bg-amber-500/5 p-4",children:[e.jsx(v,{icon:V,size:20,className:"shrink-0 text-amber-500"}),e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsx("p",{className:"text-sm font-medium",children:"Payment needs attention"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Update your payment method in the billing portal."}),e.jsx(q,{value:r.progress,className:"h-1.5"})]})]})]})]}),e.jsxs(w,{children:[e.jsx(N,{children:e.jsx(S,{children:"Payment history"})}),e.jsx(k,{children:c.length===0?e.jsx("p",{className:"py-6 text-center text-sm text-muted-foreground",children:"No payments yet."}):e.jsxs(Q,{children:[e.jsx(Z,{children:e.jsxs(U,{children:[e.jsx(C,{children:"Date"}),e.jsx(C,{children:"Description"}),e.jsx(C,{children:"Status"}),e.jsx(C,{className:"text-right",children:"Amount"})]})}),e.jsx(K,{children:c.map(s=>e.jsxs(U,{children:[e.jsx(P,{children:s.date}),e.jsx(P,{children:s.description}),e.jsx(P,{children:e.jsx(D,{variant:s.status.toLowerCase()==="paid"?"success":s.status.toLowerCase().includes("pending")?"warning":"destructive",children:s.status})}),e.jsx(P,{className:"text-right font-medium",children:s.amount})]},s.id))})]})})]}),!o&&e.jsxs(w,{children:[e.jsxs(N,{children:[e.jsx(S,{children:"Supporter tier"}),e.jsx(I,{children:"Every tool is free and unlimited. There's no paid plan to buy right now."})]}),e.jsx(k,{children:e.jsxs("p",{className:"text-sm text-muted-foreground",children:["We're planning an optional supporter tier in the future to help fund development. Pricing hasn't been decided, and today's tools will stay free and unlimited either way. How the tools are funded is set out on the"," ",e.jsx(A,{to:"/about",className:"underline underline-offset-4",children:"about page"}),"."]})})]})]})}):e.jsx(E,{title:"Subscription",children:e.jsxs(w,{children:[e.jsxs(N,{children:[e.jsx(S,{children:"Nothing to manage"}),e.jsx(I,{children:"Every tool on Securoxen is free and unlimited, with no subscription and nothing held back. There is no plan attached to your account."})]}),e.jsxs(k,{className:"flex flex-col gap-4",children:[e.jsx("p",{className:"text-muted-foreground text-sm leading-relaxed",children:"Consulting is the paid side of Securoxen, and it is invoiced per engagement rather than billed monthly. Anything we have invoiced you appears under Payments."}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsx(L,{asChild:!0,variant:"outline",children:e.jsx(A,{to:"/payments",children:"View payments"})}),e.jsx(L,{asChild:!0,variant:"outline",children:e.jsx(A,{to:"/tools",children:"Go to the tools"})})]})]})]})})}export{pe 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.