1 line
11 KiB
JavaScript
1 line
11 KiB
JavaScript
import{j as e,a}from"./vendor-react-BHG7lGYR.js";import{a as M,C as z,b as ie,c as le,v as oe,e as B,K as de,B as p,h as ue,g as Z,D as me,E as A,p as Q,L as pe,S as xe,l as O}from"./index-BWcMVITa.js";import{B as H}from"./badge-CPAgRIoX.js";import{aZ as V,T as he,n as fe,aW as ye,X as ge}from"./vendor-icons-DaGlTw4_.js";import{I as je}from"./input-BGBI2Wze.js";import{S as ve}from"./select-laDQECdR.js";import{L as Y}from"./label-N1Bsuay_.js";import{l as Ne,n as Ce}from"./vendor-IYr-MHu4.js";import{P as Se}from"./Pagination-i598iEQZ.js";import"./vendor-router-D-s5vIeO.js";import"./vendor-tanstack-BzWBL1hV.js";import"./vendor-utils-CgOSfOkx.js";import"./dropdown-BYn_8IId.js";const I={listProducts:async(t,i)=>{const r={...t,page:i?.page||1,limit:i?.limit||12};t?.search&&(r.q=t.search,delete r.search),t?.product_type&&(r.type=t.product_type,delete r.product_type);const o=(await M.get("/marketplace/products",{params:r,_disableRetry:!1})).data||[];return{products:o,total:o.length,page:i?.page||1,limit:i?.limit||12,total_pages:1}},fetchProducts:async(t,i)=>I.listProducts(t,i),createProduct:async t=>(await M.post("/marketplace/products",t)).data,createOrder:async t=>(await M.post("/marketplace/orders",{items:t})).data,purchaseProduct:async t=>I.createOrder([{product_id:t}]),listOrders:async()=>(await M.get("/marketplace/orders")).data};function we({product:t,onPurchase:i,onAddToCart:r,isPurchasing:n=!1}){const o=(l,v)=>new Intl.NumberFormat("fr-FR",{style:"currency",currency:v}).format(l);return e.jsxs(z,{className:"w-full h-full flex flex-col",children:[e.jsx(ie,{children:e.jsxs("div",{className:"flex justify-between items-start",children:[e.jsxs("div",{children:[e.jsx(le,{className:"text-lg font-bold truncate",title:t.title,children:t.title}),e.jsx(oe,{className:"line-clamp-2 mt-1",children:t.description})]}),e.jsx(H,{variant:t.product_type==="track"?"default":"secondary",children:t.product_type})]})}),e.jsxs(B,{className:"flex-grow",children:[e.jsx("div",{className:"w-full h-32 bg-muted rounded-md flex items-center justify-center mb-4",children:e.jsx("span",{className:"text-muted-foreground text-sm",children:"No Cover"})}),e.jsx("div",{className:"text-2xl font-bold",children:o(t.price,t.currency)}),t.license_type&&e.jsxs("div",{className:"text-xs text-muted-foreground mt-1",children:["License: ",t.license_type]})]}),e.jsxs(de,{className:"flex gap-2",children:[r&&e.jsxs(p,{variant:"outline",className:"flex-1",onClick:()=>r(t),children:[e.jsx(V,{className:"mr-2 h-4 w-4"})," Add to Cart"]}),e.jsx(p,{className:r?"flex-1":"w-full",onClick:()=>i(t),disabled:n,children:n?"Processing...":"Buy Now"})]})]})}const G=Ne()(Ce((t,i)=>({items:[],addItem:r=>{t(n=>n.items.find(l=>l.product.id===r.id)?{items:n.items.map(l=>l.product.id===r.id?{...l,quantity:l.quantity+1}:l)}:{items:[...n.items,{product:r,quantity:1}]})},removeItem:r=>{t(n=>({items:n.items.filter(o=>o.product.id!==r)}))},updateQuantity:(r,n)=>{if(n<=0){i().removeItem(r);return}t(o=>({items:o.items.map(l=>l.product.id===r?{...l,quantity:n}:l)}))},clearCart:()=>{t({items:[]})},getTotal:()=>i().items.reduce((r,n)=>r+n.product.price*n.quantity,0),getItemCount:()=>i().items.reduce((r,n)=>r+n.quantity,0)}),{name:"veza-cart-storage"}));function be({isOpen:t,onClose:i}){const{items:r,removeItem:n,updateQuantity:o,clearCart:l,getTotal:v}=G(),{isAuthenticated:N}=ue(),L=Z(),[w,g]=a.useState(!1),[C,x]=a.useState(null),[R,j]=a.useState(null),[S,b]=a.useState(0),h=a.useRef(null),_=(c,y)=>new Intl.NumberFormat("fr-FR",{style:"currency",currency:y||"EUR"}).format(c),F=async()=>{if(x(null),j(null),!N){x("Please log in to checkout");return}if(r.length===0){x("Cart is empty");return}const c=r.map(f=>({product_id:f.product.id})),y=async()=>{await I.createOrder(c),L.success("Order placed successfully!"),l(),i(),j(null),b(0),h.current=null};h.current=y,g(!0);try{await y()}catch(f){const T=Q(f);j(new Error(T.message))}finally{g(!1)}},q=async()=>{if(!(!h.current||S>=3)){b(c=>c+1),g(!0);try{await h.current()}catch{}finally{g(!1)}}};return e.jsx(me,{open:t,onClose:i,title:"Shopping Cart",size:"lg",children:e.jsxs("div",{className:"space-y-4",children:[R&&e.jsx(A,{error:R,variant:"banner",severity:"error",onRetry:S<3?q:void 0,context:{action:"checking out",resource:"cart"},onDismiss:()=>{j(null),b(0),h.current=null}}),C&&e.jsx(A,{error:C,variant:"inline",severity:"error",size:"sm",dismissible:!1}),r.length===0?e.jsxs("div",{className:"text-center py-8 text-muted-foreground",children:[e.jsx(V,{className:"h-12 w-12 mx-auto mb-4 opacity-50"}),e.jsx("p",{children:"Your cart is empty"})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"max-h-96 overflow-y-auto space-y-2",children:r.map(c=>e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("h4",{className:"font-medium",children:c.product.title}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:[_(c.product.price,c.product.currency)," ×"," ",c.quantity]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(p,{variant:"outline",size:"sm",onClick:()=>o(c.product.id,c.quantity-1),children:"-"}),e.jsx("span",{className:"w-8 text-center",children:c.quantity}),e.jsx(p,{variant:"outline",size:"sm",onClick:()=>o(c.product.id,c.quantity+1),children:"+"}),e.jsx(p,{variant:"ghost",size:"sm",onClick:()=>n(c.product.id),children:e.jsx(he,{className:"h-4 w-4"})})]})]},c.product.id))}),e.jsxs("div",{className:"border-t pt-4 space-y-4",children:[e.jsxs("div",{className:"flex justify-between text-lg font-bold",children:[e.jsx("span",{children:"Total:"}),e.jsx("span",{children:r.length>0?_(v(),r[0].product.currency):"€0.00"})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(p,{variant:"outline",onClick:l,className:"flex-1",children:"Clear Cart"}),e.jsx(p,{onClick:F,disabled:w,className:"flex-1",children:w?"Processing...":"Checkout"})]})]})]})]})})}function ze(){const[t,i]=a.useState([]),[r,n]=a.useState(!0),[o,l]=a.useState(null),[v,N]=a.useState(null),[L,w]=a.useState(null),[g,C]=a.useState(0),x=a.useRef(null),[R,j]=a.useState(!1),[S,b]=a.useState(1),[h]=a.useState(12),[_,F]=a.useState(1),[q,c]=a.useState(0),y=a.useRef(!1),[f,T]=a.useState(""),[k,$]=a.useState(""),[m,J]=a.useState([0,1e3]),[K,ee]=a.useState(!1),D=Z(),{addItem:te,getItemCount:U}=G(),W=async()=>{if(y.current){O.debug("MarketplaceHome: loadProducts already in progress, skipping");return}try{y.current=!0,n(!0),l(null);const s={status:"active"};k&&(s.product_type=k),m[0]>0&&(s.min_price=m[0]),m[1]<1e3&&(s.max_price=m[1]),f.trim()&&(s.search=f.trim());const d=await I.fetchProducts(s,{page:S,limit:h});i(d.products),c(d.total),F(d.total_pages)}catch(s){const d=Q(s),P=d.message||"Failed to load marketplace products";let u=0;if(s&&typeof s=="object"&&"httpStatus"in s&&(u=s.httpStatus),u===0&&s&&typeof s=="object"&&"response"in s){const E=s;E.response?.status&&(u=E.response.status)}if(u===0){const E=String(P).toLowerCase();(E.includes("500")||E.includes("internal server error"))&&(u=500)}u===500?(O.debug("Marketplace products endpoint returned 500, treating as empty state",{error:d.message,code:d.code,statusCode:u,request_id:d.request_id}),i([]),c(0),F(1),l(null)):(O.error("Failed to load marketplace products",{error:d.message,code:d.code,statusCode:u,request_id:d.request_id}),D.error(P),l(new Error(P)))}finally{n(!1),y.current=!1}},se=JSON.stringify(m);a.useEffect(()=>{W()},[S,h,k,se,f]);const re=s=>{te(s),D.success(`${s.title} added to cart`)},ae=async s=>{const d=async()=>{await I.purchaseProduct(s.id),D.success(`Successfully purchased ${s.title}`),N(null),C(0),x.current=null};x.current=d,w(s.id),N(null);try{await d()}catch(P){const u=Q(P);O.error("Erreur lors de l'achat du produit",{error:u.message,productId:s.id}),N(new Error(u.message))}finally{w(null)}},ne=async()=>{if(!(!x.current||g>=3)){C(s=>s+1);try{await x.current()}catch{}}},ce=()=>{T(""),$(""),J([0,1e3])},X=f||k||m[0]>0||m[1]<1e3;return r&&t.length===0?e.jsx("div",{className:"container mx-auto px-4 py-8",children:e.jsx("div",{className:"flex items-center justify-center min-h-[400px]",children:e.jsx(pe,{})})}):o&&t.length===0?e.jsx("div",{className:"container mx-auto px-4 py-8",children:e.jsx(A,{error:o,variant:"card",severity:"error",context:{action:"fetching marketplace products",resource:"marketplace"},onRetry:W})}):e.jsxs("div",{className:"container mx-auto px-4 py-8",children:[v&&e.jsx(A,{error:v,variant:"banner",severity:"error",context:{action:"purchasing product",resource:"marketplace"},onRetry:g<3?ne:void 0,onDismiss:()=>{N(null),C(0),x.current=null}}),e.jsxs("div",{className:"mb-6 flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-3xl font-bold mb-2",children:"Marketplace"}),e.jsx("p",{className:"text-muted-foreground",children:"Discover and purchase music products, samples, and licenses"})]}),e.jsxs(p,{onClick:()=>j(!0),className:"relative",variant:"outline",children:[e.jsx(V,{className:"mr-2 h-4 w-4"}),"Cart",U()>0&&e.jsx(H,{className:"ml-2 bg-kodo-cyan",children:U()})]})]}),e.jsx(z,{className:"mb-6",children:e.jsx(B,{className:"p-4",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(fe,{className:"absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-kodo-content-dim"}),e.jsx(je,{type:"text",value:f,onChange:s=>T(s.target.value),placeholder:"Search products...",className:"pl-10"})]}),e.jsxs(p,{variant:"outline",onClick:()=>ee(!K),children:[e.jsx(ye,{className:"mr-2 h-4 w-4"}),"Filters",X&&e.jsx(H,{className:"ml-2",variant:"secondary",children:"Active"})]}),X&&e.jsxs(p,{variant:"ghost",onClick:ce,children:[e.jsx(ge,{className:"mr-2 h-4 w-4"}),"Clear"]})]}),K&&e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 pt-4 border-t",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(Y,{htmlFor:"product-type",children:"Product Type"}),e.jsx(ve,{options:[{value:"",label:"All Types"},{value:"track",label:"Track"},{value:"pack",label:"Pack"},{value:"service",label:"Service"}],value:k,onChange:s=>$(Array.isArray(s)?s[0]:s),name:"product-type"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(Y,{children:["Price Range: €",m[0]," - €",m[1]]}),e.jsx(xe,{min:0,max:1e3,step:10,value:m,onValueChange:s=>J([s[0],s[1]]),className:"w-full"})]})]})]})})}),!r&&e.jsxs("div",{className:"mb-4 text-sm text-muted-foreground",children:["Showing ",t.length," of ",q," products"]}),t.length===0&&!r?e.jsx(z,{children:e.jsx(B,{className:"pt-6",children:e.jsx("div",{className:"text-center py-8",children:e.jsx("p",{className:"text-muted-foreground",children:"No products found. Try adjusting your filters."})})})}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 mb-6",children:t.map(s=>e.jsx(we,{product:s,onPurchase:ae,onAddToCart:re,isPurchasing:L===s.id},s.id))}),e.jsx(Se,{currentPage:S,totalPages:_,onPageChange:b,totalItems:q,itemsPerPage:h,showItemsInfo:!0,className:"mt-6"})]}),e.jsx(be,{isOpen:R,onClose:()=>j(!1)})]})}export{ze as MarketplaceHome};
|