1import{u as T,r as A,o as $,j as e,U as B,ap as R,B as h,b as U,V as Y,W as H,Y as W,Z as G,a9 as E,C as J,a4 as xe,an as he,a as y,aa as pe,N as je,d as I,A as Z,cs as _,T as X,e as ee,f as se,h as te,i as ie,k as ne,l as ae,m as re,ah as ge,I as O,K as fe,E as V,F as K,G as L,H as M,J as k,Q as C,q as v}from"./index-CU4TP-S4.js";import{u as le,t as ce,F as de,a as j,b as g,c as f,d as b,f as D,e as P}from"./form-D-xzwno4.js";import{i as q}from"./authUtils-CcDzk6i0.js";import{S as oe}from"./switch-DUkPOpLP.js";import{A as be,a as ve,b as ye,c as Ce}from"./accordion-BvVHCqL-.js";import{T as Ne,a as we,b as ue,c as S,d as De,e as F}from"./table-Br-uzwVA.js";import{j as Te}from"./schema-CEA6AeVK.js";import{P as me}from"./pencil-C0OXxJ_w.js";import{P as Ae}from"./percent-BqRk4fKS.js";import{o as Ee,s as Q,e as Se,b as Fe}from"./types-BmAflJw1.js";import"./index-ONlxBG-K.js";const z=[{name:"Wine Club",description:"Our standard wine club membership with exclusive discounts on experiences"},{name:"Reserve Wine Club",description:"Premium membership with enhanced discounts and priority reservations"},{name:"Barrel Club",description:"VIP membership tier with the best discounts and exclusive access"},{name:"Founders Club",description:"Our most exclusive membership with maximum benefits and complimentary experiences"}];function He(){T();const[s,t]=A.useState(!1),[a,l]=A.useState(null),{data:d,isLoading:r}=$({queryKey:["/api/resy/clubs"]}),{data:o}=$({queryKey:["/api/resy/experiences"]}),{data:c}=$({queryKey:["/api/club-discounts"]}),i=x=>{l(x),t(!0)},m=()=>{l(null),t(!0)},N=(o==null?void 0:o.filter(x=>!x.isExternal&&x.isActive))||[];return e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"font-serif text-3xl md:text-4xl font-semibold mb-2",children:"Club Management"}),e.jsx("p",{className:"text-muted-foreground",children:"Manage membership clubs and their experience discounts"})]}),e.jsxs(B,{open:s,onOpenChange:t,children:[e.jsx(R,{asChild:!0,children:e.jsxs(h,{onClick:m,"data-testid":"button-add-club",children:[e.jsx(U,{className:"w-4 h-4 mr-2"}),"Add Club"]})}
1),e.jsxs(Y,{className:"max-w-lg",children:[e.jsxs(H,{children:[e.jsx(W,{children:a?"Edit Club":"Add New Club"}),e.jsx(G,{children:a?"Update the details of this club":"Create a new membership club tier"})]}),e.jsx(ke,{club:a,onSuccess:()=>{t(!1),l(null)}})]})]})]}),r?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(E,{className:"w-8 h-8 animate-spin text-muted-foreground"})}):d&&d.length>0?e.jsx("div",{className:"space-y-4",children:d.map(x=>e.jsx(Pe,{club:x,experiences:N,clubDiscounts:(c==null?void 0:c.filter(w=>w.clubId===x.id))||[],onEdit:i},x.id))}):e.jsx(J,{children:e.jsx(xe,{className:"py-12",children:e.jsxs("div",{className:"text-center space-y-4",children:[e.jsx(he,{className:"w-12 h-12 mx-auto text-muted-foreground"}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-medium text-lg mb-1",children:"No Clubs Yet"}),e.jsx("p",{className:"text-muted-foreground mb-4",children:"Create membership clubs to offer experience discounts to your loyal customers"})]}),e.jsxs("div",{className:"flex flex-col gap-2 max-w-xs mx-auto",children:[e.jsxs(h,{onClick:m,"data-testid":"button-add-first-club",children:[e.jsx(U,{className:"w-4 h-4 mr-2"}),"Add Your First Club"]}),e.jsx(Ie,{})]})]})})})]})}function Ie(){const{toast:s}=T(),[t,a]=A.useState(!1),l=y({mutationFn:async r=>(await C("POST","/api/resy/clubs",r)).json()}),d=async()=>{a(!0);try{for(let r=0;r<z.length;r++)await l.mutateAsync({...z[r],displayOrder:r});v.invalidateQueries({queryKey:["/api/resy/clubs"]}),s({title:"Clubs Created",description:"Default club tiers have been created successfully"})}catch(r){s({title:"Error",description:r.message,variant:"destructive"})}finally{a(!1)}};return e.jsxs(h,{variant:"outline",onClick:d,disabled:t,"data-testid":"button-create-defaults",children:[t?e.jsx(E,{className:"w-4 h-4 mr-2 animate-spin"}):e.jsx(pe,{className:"w-4 h-4 mr-2"}),"Create Default Clubs"]})}function Pe({club:s,experiences:t,clubDiscounts:a,onEdit:l}){const{toast:d}=T(),[r,o]=A.useState(!1),[c,i]=A.useState(null),m=y({mutationFn:async u=>{await C("DELETE",`/api/clubs/${u}`,{})},onSuccess:()=>{v.invalidateQueries({queryKey:["/api/resy/clubs"]}),v.invalidateQueries({queryKey:["/api/club-discounts"]}),d({title:"Club Deleted",description:"The club has been removed successfully"})},onError:u=>{if(q(u)){d({title:"Unauthorized",description:"You are logged out. Logging in again...",variant:"destructive"}),setTimeout(()=>{window.location.href="/api/login"},500);return}d({title:"Delete Failed",description:u.message,variant:"destructive"})}}),N=u=>{var n;return((n=t.find(p=>p.id===u))==null?void 0:n.name)||"Unknown Experience"},x=()=>{i(null),o(!0)},w=u=>{i(u),o(!0)};return e.jsx(J,{children:e.jsx(be,{type:"single",collapsible:!0,className:"w-full",children:e.jsxs(ve,{value:"details",className:"border-0",children:[e.jsxs("div",{className:"flex items-center justify-between px-6 py-4",children:[e.jsxs("div",{className:"flex items-center gap-4 flex-1",children:[e.jsx(ye,{className:"hover:no-underline p-0 [&[data-state=open]>svg]:rotate-90",children:e.jsx(je,{className:"h-4 w-4 shrink-0 transition-transform duration-200"})}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"font-semibold text-lg",children:s.name}),!s.isActive&&e.jsx(I,{variant:"secondary",children:"Inactive"})]}),s.description&&e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:s.description})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsxs(I,{variant:"outline",className:"whitespace-nowrap",children:[a.length," ",a.length===1?"Discount":"Discounts"]})})]}),e.jsxs("div",{className:"flex items-center gap-2 ml-4",children:[e.jsx(h,{variant:"outline",size:"sm",onClick:()=>l(s),"data-testid":`button-edit-club-${s.id}`,children:e.jsx(me,{className:"w-4 h-4"})}),e.jsxs(Z,{children:[e.jsx(_,{asChild:!0,children:e.jsx(h,{variant:"outline",size:"sm","data-testid":`button-delete-club-${s.id}`,children:e.jsx(X,{className:"w-4 h-4"})})}),e.jsxs(ee,{children:[e.jsxs(se,{children:[e.jsx(te,{children:"Delete Club?"}),e.jsxs(ie,{children:['This will permanently delete "',s.name,'" and all its experience discounts. This action cannot be undone.']})]}),e.jsxs(ne,{children:[e.jsx(ae,{children:"Cancel"}),e.jsx(re,{onClick:()=>m.mutate(s.id),className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:m.isPending?e.jsx(E,{className:"w-4 h-4 animate-spin"}):"Delete"})]})]})]})]})]}),e.jsx(Ce,{className:"px-6 pb-4",children:e.jsxs("div",{className:"border-t pt-4",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsx("h4",{className:"font-medium",children:"Experience Discounts"}),e.jsxs(B,{open:r,onOpenChange:o,children:[e.jsx(R,{asChild:!0,children:e.jsxs(h,{size:"sm",onClick:x,"data-testid":`button-add-discount-${s.id}`,children:[e.jsx(U,{className:"w-4 h-4 mr-2"}),"Add Discount"]})}
1),e.jsxs(Y,{children:[e.jsxs(H,{children:[e.jsx(W,{children:c?"Edit Discount":"Add Experience Discount"}),e.jsx(G,{children:c?`Update discount for ${s.name}`:`Set up a discount for ${s.name} members`})]}),e.jsx(Ue,{clubId:s.id,discount:c,experiences:t,existingDiscounts:a,onSuccess:()=>{o(!1),i(null)}})]})]})]}),a.length>0?e.jsxs(Ne,{children:[e.jsx(we,{children:e.jsxs(ue,{children:[e.jsx(S,{children:"Experience"}),e.jsx(S,{children:"Discount"}),e.jsx(S,{children:"Status"}),e.jsx(S,{className:"text-right",children:"Actions"})]})}),e.jsx(De,{children:a.map(u=>e.jsx($e,{discount:u,experienceName:N(u.experienceId),onEdit:w},u.id))})]}):e.jsxs("div",{className:"text-center py-6 text-muted-foreground border rounded-lg",children:[e.jsx("p",{children:"No discounts configured for this club"}),e.jsx("p",{className:"text-sm mt-1",children:"Add discounts to give members special pricing on experiences"})]})]})})]})})})}function $e({discount:s,experienceName:t,onEdit:a}){const{toast:l}=T(),d=y({mutationFn:async o=>{await C("DELETE",`/api/club-discounts/${o}`,{})},onSuccess:()=>{v.invalidateQueries({queryKey:["/api/club-discounts"]}),l({title:"Discount Deleted",description:"The discount has been removed"})},onError:o=>{l({title:"Delete Failed",description:o.message,variant:"destructive"})}}),r=()=>s.discountType==="percentage"?`${parseFloat(s.discountValue).toFixed(0)}% off`:`$${parseFloat(s.discountValue).toFixed(2)} off`;return e.jsxs(ue,{"data-testid":`discount-row-${s.id}`,children:[e.jsx(F,{className:"font-medium",children:t}),e.jsx(F,{children:e.jsxs("div",{className:"flex items-center gap-1",children:[s.discountType==="percentage"?e.jsx(Ae,{className:"w-4 h-4 text-muted-foreground"}):e.jsx(ge,{className:"w-4 h-4 text-muted-foreground"}),r()]})}),e.jsx(F,{children:s.isActive?e.jsx(I,{variant:"outline",className:"text-green-600 border-green-600",children:"Active"}):e.jsx(I,{variant:"secondary",children:"Inactive"})}),e.jsx(F,{className:"text-right",children:e.jsxs("div",{className:"flex items-center justify-end gap-2",children:[e.jsx(h,{variant:"ghost",size:"sm",onClick:()=>a(s),"data-testid":`button-edit-discount-${s.id}`,children:e.jsx(me,{className:"w-4 h-4"})}),e.jsxs(Z,{children:[e.jsx(_,{asChild:!0,children:e.jsx(h,{variant:"ghost",size:"sm","data-testid":`button-delete-discount-${s.id}`,children:e.jsx(X,{className:"w-4 h-4"})})}),e.jsxs(ee,{children:[e.jsxs(se,{children:[e.jsx(te,{children:"Delete Discount?"}),e.jsxs(ie,{children:["This will remove the discount for ",t,"."]})]}),e.jsxs(ne,{children:[e.jsx(ae,{children:"Cancel"}),e.jsx(re,{onClick:()=>d.mutate(s.id),className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"Delete"})]})]})]})]})})]})}function ke({club:s,onSuccess:t}){const{toast:a}=T(),l=le({resolver:ce(Te),defaultValues:{name:(s==null?void 0:s.name)||"",description:(s==null?void 0:s.description)||"",displayOrder:(s==null?void 0:s.displayOrder)??0,isActive:(s==null?void 0:s.isActive)??!0}}),d=y({mutationFn:async i=>(await C("POST","/api/resy/clubs",i)).json(),onSuccess:()=>{v.invalidateQueries({queryKey:["/api/resy/clubs"]}),a({title:"Club Created",description:"The new club has been created successfully"}),t()},onError:i=>{if(q(i)){a({title:"Unauthorized",description:"You are logged out. Logging in again...",variant:"destructive"}),setTimeout(()=>{window.location.href="/api/login"},500);return}a({title:"Error",description:i.message,variant:"destructive"})}}),r=y({mutationFn:async i=>(await C("PUT",`/api/clubs/${s.id}`,i)).json(),onSuccess:()=>{v.invalidateQueries({queryKey:["/api/resy/clubs"]}),a({title:"Club Updated",description:"The club has been updated successfully"}),t()},onError:i=>{if(q(i)){a({title:"Unauthorized",description:"You are logged out. Logging in again...",variant:"destructive"}),setTimeout(()=>{window.location.href="/api/login"},500);return}a({title:"Error",description:i.message,variant:"destructive"})}}),o=i=>{s?r.mutate(i):d.mutate(i)},c=d.isPending||r.isPending;return e.jsx(de,{...l,children:e.jsxs("form",{onSubmit:l.handleSubmit(o),className:"space-y-4",children:[e.jsx(j,{control:l.control,name:"name",render:({field:i})=>e.jsxs(g,{children:[e.jsx(f,{children:"Club Name"}),e.jsx(b,{children:e.jsx(O,{placeholder:"e.g., Wine Club",...i,"data-testid":"input-club-name"})}),e.jsx(D,{})]})}),e.jsx(j,{control:l.control,name:"description",render:({field:i})=>e.jsxs(g,{children:[e.jsx(f,{children:"Description"}),e.jsx(b,{children:e.jsx(fe,{placeholder:"Describe the benefits of this club membership",...i,value:i.value||"","data-testid":"input-club-description"})}),e.jsx(D,{})]})}),e.jsx(j,{control:l.control,name:"displayOrder",render:({field:i})=>e.jsxs(g,{children:[e.jsx(f,{children:"Display Order"}),e.jsx(b,{children:e.jsx(O,{type:"number",min:0,...i,onChange:m=>i.onChange(parseInt(m.target.value)||0),"data-testid":"input-club-order"})}),e.jsx(P,{children:"Lower numbers appear first"}),e.jsx(D,{})]})}),e.jsx(j,{control:l.control,name:"isActive",render:({field:i})=>e.jsxs(g,{className:"flex flex-row items-center justify-between rounded-lg border p-4",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(f,{className:"text-base",children:"Active"}
1),e.jsx(P,{children:"Inactive clubs won't apply discounts to bookings"})]}),e.jsx(b,{children:e.jsx(oe,{checked:i.value,onCheckedChange:i.onChange,"data-testid":"switch-club-active"})})]})}),e.jsx("div",{className:"flex justify-end gap-2 pt-4",children:e.jsxs(h,{type:"submit",disabled:c,"data-testid":"button-save-club",children:[c&&e.jsx(E,{className:"w-4 h-4 mr-2 animate-spin"}),s?"Update Club":"Create Club"]})})]})})}function Ue({clubId:s,discount:t,experiences:a,existingDiscounts:l,onSuccess:d}){const{toast:r}=T(),o=Ee({experienceId:Q().min(1,"Experience is required"),discountType:Se(["percentage","fixed"]),discountValue:Q().refine(n=>!isNaN(parseFloat(n))&&parseFloat(n)>0,"Must be a positive number"),isActive:Fe().default(!0)}),c=le({resolver:ce(o),defaultValues:{experienceId:(t==null?void 0:t.experienceId)||"",discountType:(t==null?void 0:t.discountType)||"percentage",discountValue:(t==null?void 0:t.discountValue)||"",isActive:(t==null?void 0:t.isActive)??!0}}),i=a.filter(n=>t&&n.id===t.experienceId?!0:!l.some(p=>p.experienceId===n.id)),m=y({mutationFn:async n=>(await C("POST",`/api/clubs/${s}/discounts`,n)).json(),onSuccess:()=>{v.invalidateQueries({queryKey:["/api/club-discounts"]}),r({title:"Discount Created",description:"The experience discount has been added"}),d()},onError:n=>{r({title:"Error",description:n.message,variant:"destructive"})}}),N=y({mutationFn:async n=>(await C("PUT",`/api/club-discounts/${t.id}`,n)).json(),onSuccess:()=>{v.invalidateQueries({queryKey:["/api/club-discounts"]}),r({title:"Discount Updated",description:"The discount has been updated"}),d()},onError:n=>{r({title:"Error",description:n.message,variant:"destructive"})}}),x=n=>{t?N.mutate(n):m.mutate(n)},w=m.isPending||N.isPending,u=c.watch("discountType");return e.jsx(de,{...c,children:e.jsxs("form",{onSubmit:c.handleSubmit(x),className:"space-y-4",children:[e.jsx(j,{control:c.control,name:"experienceId",render:({field:n})=>e.jsxs(g,{children:[e.jsx(f,{children:"Experience"}),e.jsxs(V,{onValueChange:n.onChange,value:n.value,disabled:!!t,children:[e.jsx(b,{children:e.jsx(K,{"data-testid":"select-experience",children:e.jsx(L,{placeholder:"Select an experience"})})}),e.jsx(M,{children:i.map(p=>e.jsx(k,{value:p.id,children:p.name},p.id))})]}),i.length===0&&!t&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"All experiences already have discounts for this club"}),e.jsx(D,{})]})}),e.jsx(j,{control:c.control,name:"discountType",render:({field:n})=>e.jsxs(g,{children:[e.jsx(f,{children:"Discount Type"}),e.jsxs(V,{onValueChange:n.onChange,value:n.value,children:[e.jsx(b,{children:e.jsx(K,{"data-testid":"select-discount-type",children:e.jsx(L,{placeholder:"Select type"})})}),e.jsxs(M,{children:[e.jsx(k,{value:"percentage",children:"Percentage (%)"}),e.jsx(k,{value:"fixed",children:"Fixed Amount ($)"})]})]}),e.jsx(D,{})]})}),e.jsx(j,{control:c.control,name:"discountValue",render:({field:n})=>e.jsxs(g,{children:[e.jsx(f,{children:u==="percentage"?"Discount Percentage":"Discount Amount"}),e.jsx(b,{children:e.jsxs("div",{className:"relative",children:[e.jsx("span",{className:"absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground",children:u==="percentage"?"%":"$"}),e.jsx(O,{type:"number",step:"0.01",min:"0",className:"pl-8",placeholder:u==="percentage"?"e.g., 15":"e.g., 10.00",...n,"data-testid":"input-discount-value"})]})}),e.jsx(P,{children:u==="percentage"?"Enter percentage (e.g., 15 for 15% off)":"Enter dollar amount (e.g., 10.00 for $10 off)"}),e.jsx(D,{})]})}),e.jsx(j,{control:c.control,name:"isActive",render:({field:n})=>e.jsxs(g,{className:"flex flex-row items-center justify-between rounded-lg border p-4",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(f,{className:"text-base",children:"Active"}),e.jsx(P,{children:"Inactive discounts won't be applied to bookings"})]}),e.jsx(b,{children:e.jsx(oe,{checked:n.value,onCheckedChange:n.onChange,"data-testid":"switch-discount-active"})})]})}),e.jsx("div",{className:"flex justify-end gap-2 pt-4",children:e.jsxs(h,{type:"submit",disabled:w||i.length===0&&!t,"data-testid":"button-save-discount",children:[w&&e.jsx(E,{className:"w-4 h-4 mr-2 animate-spin"}),t?"Update Discount":"Add Discount"]})})]})})}export{He 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.