PageSourceSearch

https://www.escuelacocteleria.es/assets/cocktails-DPk2eEU9.js

js escuelacocteleria.es collected 2026-10-05 23:04:29 UTC 15,869 bytes, 1 lines download raw bytes

1import{a as n,j as e,e as ve,u as V,d as L}from"./vendor-query-BUwfVuOG.js";import{Z as y,B as d,X as ce,ad as fe,W as Ne,ay as ee,V as v,az as A,aA as E,aB as O,aC as P,aD as b,z as ae,A as se,ae as we,af as Ce,b as f,c as be,bA as ye,aY as te,aZ as ie,a_ as ne,a$ as re,aX as le,ah as c,_ as $,ar as U}from"./index-_mdjBuBr.js";import{A as Se,a as ke,b as Ie,c as Te,d as De,e as Ae,f as Ee,g as Oe}from"./alert-dialog-BAeW8rzu.js";import{I as Pe}from"./image-D5iYarE9.js";import{S as Fe}from"./search-C_OCiCqd.js";import{T as ze}from"./trash-2-cShw1216.js";import"./vendor-ui-BV6bAOPF.js";import"./vendor-charts-CsidWLaS.js";import"./vendor-motion-CeFdiwAh.js";import"./vendor-forms-D-pbkChx.js";import"./vendor-dates-Dg9w3qQM.js";function Re({uploadEndpoint:N,onUpload:l,currentImageUrl:S,label:w="Subir imagen"}){const[F,u]=n.useState(S||null),[k,h]=n.useState(!1),[x,p]=n.useState(!1),g=n.useRef(null),j=n.useCallback(async r=>{if(!r.type.startsWith("image/"))return;const m=new FileReader;m.onload=t=>u(t.target?.result),m.readAsDataURL(r),h(!0);try{const t=new FormData;t.append("image",r);const i=await fetch(N,{method:"POST",body:t,credentials:"include"});if(!i.ok)throw new Error("Error al subir imagen");const C=await i.json(),T=C.url||C.imageUrl;u(T),l(T)}catch{u(S||null)}finally{h(!1)}},[N,l,S]),I=n.useCallback(r=>{r.preventDefault(),p(!1);const m=r.dataTransfer.files[0];m&&j(m)},[j]),M=()=>{u(null),l(""),g.current&&(g.current.value="")};return e.jsxs("div",{className:"space-y-2",children:[w&&e.jsx("label",{className:"text-sm font-medium",children:w}),F?e.jsxs("div",{className:"relative rounded-lg overflow-hidden border",children:[e.jsx("img",{src:F,alt:"Preview",className:"w-full h-48 object-cover"}),k&&e.jsx("div",{className:"absolute inset-0 bg-black/50 flex items-center justify-center",children:e.jsx(y,{className:"h-8 w-8 text-white animate-spin"})}),!k&&e.jsx(d,{variant:"destructive",size:"icon",className:"absolute top-2 right-2 h-7 w-7",onClick:M,children:e.jsx(ce,{className:"h-4 w-4"})})]}):e.jsx("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${x?"border-primary bg-primary/5":"border-muted-foreground/25 hover:border-primary/50"}`,onDragOver:r=>{r.preventDefault(),p(!0)},onDragLeave:()=>p(!1),onDrop:I,onClick:()=>g.current?.click(),children:k?e.jsx(y,{className:"h-8 w-8 mx-auto text-muted-foreground animate-spin"}):e.jsxs(e.Fragment,{children:[e.jsx(Pe,{className:"h-8 w-8 mx-auto text-muted-foreground mb-2"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Arrastra una imagen o haz clic para seleccionar"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"JPEG, PNG o WebP (máx. 10MB)"})]})}),e.jsx("input",{ref:g,type:"file",accept:"image/jpeg,image/png,image/webp",className:"hidden",onChange:r=>{const m=r.target.files?.[0];m&&j(m)}})]})}const G={name:"",description:"",occasion:"",prepTime:"",method:"",ingredients:[],recipe:"",allergens:[],photoUrl:"",teacherId:"",activeFrom:"",status:"draft",workshopIds:[]},Le=["aperitivo","digestivo","refrescante","festivo","otro"],Ue=["agitado","removido","directo","licuado","otro"],K=[{value:"draft",label:"Borrador"},{value:"active",label:"Activo"},{value:"archived",label:"Archivado"}],H=["Gluten","Crustáceos","Huevos","Pescado","Cacahuetes","Soja","Lácteos","Frutos de cáscara","Apio","Mostaza","Sésamo","Sulfitos","Altramuces","Moluscos"];function Xe(){const N=ve(),{toast:l}=fe(),[S,w]=n.useState(!1),[F,u]=n.useState(!1),[k,h]=n.useState(!1),[x,p]=n.useState(null),[g,j]=n.useState(null),[I,M]=n.useState(""),[r,m]=n.useState("all"),[t,i]=n.useState(G),[C,T]=n.useState(""),[D,z]=n.useState({name:"",amount:"",unit:""}),{data:Q,isLoading:oe}=V({queryKey:["/api/admin/cocktails"]}),{data:de}=V({queryKey:["/api/admin/teachers"]}),{data:_}=V({queryKey:["/api/admin/workshops"]}),W=L({mutationFn:async a=>(await U("POST","/api/admin/cocktails",a)).json(),onSuccess:()=>{N.invalidateQueries({queryKey:["/api/admin/cocktails"]}),R(),l({title:"Receta creada correctamente"})},onError:()=>{l({title:"Error al crear receta",variant:"destructive"})}}),X=L({mutationFn:async({id:a,data:s})=>(await U("PUT",`/api/admin/cocktails/${a}`,s)).json(),onSuccess:()=>{N.invalidateQueries({queryKey:["/api/admin/cocktails"]}),R(),l({title:"Receta actualizada correctamente"})},onError:()=>{l({title:"Error al actualizar receta",variant:"destructive"})}}),Y=L({mutationFn:async a=>{await U("DELETE",`/api/admin/cocktails/${a}`)},onSuccess:()=>{N.invalidateQueries({queryKey:["/api/admin/cocktails"]}),u(!1),j(null),l({title:"Receta eliminada"})},onError:()=>{l({title:"Error al eliminar receta",variant:"destructive"})}}),q=L({mutationFn:async a=>(await U("POST","/api/admin/cocktails/analyze",{rawText:a})).json(),onSuccess:a=>{i(s=>({...s,name:a.name||s.name,description:a.description||s.description,occasion:a.occasion||s.occasion,prepTime:a.prep_time?.toString()||s.prepTime,method:a.method||s.method,ingredients:a.ingredients||s.ingredients,recipe:a.recipe||s.recipe,allergens:a.allergens?.length?a.allergens.map(o=>H.find(B=>B.toLowerCase()===o.toLowerCase())||o).filter(o=>H.includes(o)):s.allergens})),h(!1),T(""),l({title:"Receta analizada con IA",description:a.warnings?.length?`Avisos: ${a.warnings.join(", ")}`:void 0})},onError:()=>{l({title:"Error al analizar receta",variant:"destructive"})}});function R(){w(!1),p(null),i(G)}function me(){p(null),i(G),w(!0)}function ue(a){p(a.id),i({name:a.name,description:a.description||"",occasion:a.occasion||"",prepTime:a.prepTime?.toString()||"",method:a.method||"",ingredients:a.ingredients||[],recipe:a.recipe||"",allergens:a.allergens||[],photoUrl:a.photoUrl||"",teacherId:a.teacherId?.toString()||"",activeFrom:a.activeFrom||"",status:a.status,workshopIds:a.workshopIds||[]}),w(!0)}function he(){if(!t.name.trim()){l({title:"El nombre es obligatorio",variant:"destructive"});return}const a={id:x||`cocktail-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,name:t.name,description:t.description||null,occasion:t.occasion||null,prepTime:t.prepTime?parseInt(t.prepTime):null,method:t.method||null,ingredients:t.ingredients.length>
10?t.ingredients:null,recipe:t.recipe||null,allergens:t.allergens.length>0?t.allergens:null,photoUrl:t.photoUrl||null,teacherId:t.teacherId?parseInt(t.teacherId):null,activeFrom:t.activeFrom||null,status:t.status,workshopIds:t.workshopIds};x?X.mutate({id:x,data:a}):W.mutate(a)}function xe(){D.name.trim()&&(i(a=>({...a,ingredients:[...a.ingredients,{...D}]})),z({name:"",amount:"",unit:""}))}function pe(a){i(s=>({...s,ingredients:s.ingredients.filter((o,B)=>B!==a)}))}function ge(a){i(s=>({...s,allergens:s.allergens.includes(a)?s.allergens.filter(o=>o!==a):[...s.allergens,a]}))}function je(a){i(s=>({...s,workshopIds:s.workshopIds.includes(a)?s.workshopIds.filter(o=>o!==a):[...s.workshopIds,a]}))}const Z=(Q||[]).filter(a=>{const s=a.name.toLowerCase().includes(I.toLowerCase())||a.description?.toLowerCase().includes(I.toLowerCase()),o=r==="all"||a.status===r;return s&&o}),J=W.isPending||X.isPending;return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[e.jsx(Ne,{className:"h-6 w-6"})," Recetas de Cócteles"]}),e.jsx("p",{className:"text-muted-foreground mt-1",children:"Gestión de recetas para talleres y cursos"})]}),e.jsxs(d,{onClick:me,children:[e.jsx(ee,{className:"h-4 w-4 mr-2"})," Nueva Receta"]})]}),e.jsxs("div",{className:"flex gap-3",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-muted-foreground"}),e.jsx(v,{placeholder:"Buscar receta...",className:"pl-9",value:I,onChange:a=>M(a.target.value)})]}),e.jsxs(A,{value:r,onValueChange:m,children:[e.jsx(E,{className:"w-[150px]",children:e.jsx(O,{})}),e.jsxs(P,{children:[e.jsx(b,{value:"all",children:"Todos"}),K.map(a=>e.jsx(b,{value:a.value,children:a.label},a.value))]})]})]}),oe?e.jsx("div",{className:"flex justify-center py-12",children:e.jsx(y,{className:"h-8 w-8 animate-spin text-muted-foreground"})}):Z.length===0?e.jsx(ae,{children:e.jsx(se,{className:"py-12 text-center text-muted-foreground",children:Q?.length===0?"No hay recetas. Crea la primera.":"No se encontraron recetas con esos filtros."})}):e.jsx("div",{className:"grid gap-4 md:grid-cols-2 lg:grid-cols-3",children:Z.map(a=>e.jsxs(ae,{className:"overflow-hidden",children:[a.photoUrl&&e.jsx("div",{className:"h-40 overflow-hidden",children:e.jsx("img",{src:a.photoUrl,alt:a.name,className:"w-full h-full object-cover"})}),e.jsx(we,{className:"pb-2",children:e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsx(Ce,{className:"text-lg",children:a.name}),e.jsx(f,{variant:a.status==="active"?"default":a.status==="archived"?"secondary":"outline",children:K.find(s=>s.value===a.status)?.label||a.status})]})}),e.jsxs(se,{children:[a.description&&e.jsx("p",{className:"text-sm text-muted-foreground mb-3 line-clamp-2",children:a.description}),e.jsxs("div",{className:"flex flex-wrap gap-1.5 mb-3",children:[a.method&&e.jsx(f,{variant:"outline",className:"text-xs",children:a.method}),a.occasion&&e.jsx(f,{variant:"outline",className:"text-xs",children:a.occasion}),a.prepTime&&e.jsxs(f,{variant:"outline",className:"text-xs",children:[e.jsx(be,{className:"h-3 w-3 mr-1"})," ",a.prepTime," min"]})]}),a.allergens&&a.allergens.length>0&&e.jsx("div",{className:"flex flex-wrap gap-1 mb-3",children:a.allergens.map(s=>e.jsx(f,{variant:"destructive",className:"text-xs",children:s},s))}),e.jsxs("div",{className:"flex gap-2 pt-2 border-t",children:[e.jsxs(d,{variant:"outline",size:"sm",onClick:()=>ue(a),children:[e.jsx(ye,{className:"h-3.5 w-3.5 mr-1"})," Editar"]}),e.jsxs(d,{variant:"outline",size:"sm",className:"text-destructive hover:text-destructive",onClick:()=>{j(a.id),u(!0)},children:[e.jsx(ze,{className:"h-3.5 w-3.5 mr-1"})," Eliminar"]})]})]})]},a.id))}),e.jsx(te,{open:S,onOpenChange:a=>{a||R()},children:e.jsxs(ie,{className:"max-w-3xl max-h-[90vh] overflow-y-auto",children:[e.jsx(ne,{children:e.jsx(re,{children:x?"Editar Receta":"Nueva Receta"})}),e.jsxs("div",{className:"space-y-6",children:[e.jsx("div",{className:"flex justify-end",children:e.jsxs(d,{variant:"outline",size:"sm",onClick:()=>h(!0),children:[e.jsx(le,{className:"h-4 w-4 mr-2"})," Analizar con IA"]})}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"col-span-2",children:[e.jsx(c,{children:"Nombre *"}),e.jsx(v,{value:t.name,onChange:a=>i(s=>({...s,name:a.target.value}))})]}),e.jsxs("div",{className:"col-span-2",children:[e.jsx(c,{children:"Descripción"}),e.jsx($,{value:t.description,onChange:a=>i(s=>({...s,description:a.target.value})),rows:2})]}),e.jsxs("div",{children:[e.jsx(c,{children:"Ocasión"}),e.jsxs(A,{value:t.occasion,onValueChange:a=>i(s=>({...s,occasion:a})),children:[e.jsx(E,{children:e.jsx(O,{placeholder:"Seleccionar..."})}),e.jsx(P,{children:Le.map(a=>e.jsx(b,{value:a,children:a},a))})]})]}),e.jsxs("div",{children:[e.jsx(c,{children:"Método"}),e.jsxs(A,{value:t.method,onValueChange:a=>i(s=>({...s,method:a})),children:[e.jsx(E,{children:e.jsx(O,{placeholder:"Seleccionar..."})}),e.jsx(P,{children:Ue.map(a=>e.jsx(b,{value:a,children:a},a))})]})]}),e.jsxs("div",{children:[e.jsx(c,{children:"Tiempo de preparación (min)"}),e.jsx(v,{type:"number",value:t.prepTime,onChange:a=>i(s=>({...s,prepTime:a.target.value}))})]}),e.jsxs("div",{children:[e.jsx(c,{children:"Estado"}),e.jsxs(A,{value:t.status,onValueChange:a=>i(s=>({...s,status:a})),children:[e.jsx(E,{children:e.jsx(O,{})}),e.jsx(P,{children:K.map(a=>e.jsx(b,{value:a.value,children:a.label},a.value))})]})]})]}),e.jsxs("div",{children:[e.jsx(c,{children:"Ingredientes"}),e.jsxs("div",{className:"space-y-2 mt-2",children:[t.ingredients.map((a,s)=>e.jsxs("div",{className:"flex items-center gap-2 bg-muted/50 p-2 rounded text-sm",children:[e.jsx("span",{className:"flex-1 font-medium",children:a.name}),e.jsxs("span",{children:[a.amount," ",a.unit]}),e.jsx(d,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:()=>pe(s),children:e.jsx(ce,{className:"h-3.5 w-3.5"})})]},s)),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(v,{placeholder:"Ingrediente",className:"flex-1",value:D.name,onChange:a=>z(s=>({...s,name:a.target.value}))}),e.jsx(v,{placeholder:"Cant.",className:"w-20",value:D.amount,onChange:a=>z(s=>({...s,amount:a.target.value}))}),e.jsx(v,{placeholder:"Unidad",className:"w-24",value:D.unit,onChange:a=>z(s=>({...s,unit:a.target.value}))}),e.jsx(d,{variant:"outline",size:"icon",onClick:xe,children:e.jsx(ee,{className:"h-4 w-4"})})]})]})]}),e.jsxs("div",{children:[e.jsx(c,{children:"Elaboración"}),e.jsx($,{value:t.recipe,onChange:a=>i(s=>({...s,recipe:a.target.value})),rows:4})]}),e.jsxs("div",{children:[e.jsx(c,{children:"Alérgenos"}),e.jsx("div",{className:"flex flex-wrap gap-2 mt-2",children:H.map(a=>e.jsx(f,{variant:t.allergens.includes(a)?"destructive":"outline",className:"cursor-pointer",onClick:()=>ge(a),children:a},a))})]}),e.jsxs("div",{children:[e.jsx(c,{children:"Foto"}),e.jsx(Re,{currentImageUrl:t.photoUrl||void 0,onUpload:a=>i(s=>({...s,photoUrl:a})),uploadEndpoint:"/api/admin/cocktails/upload-image"})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx(c,{children:"Profesor"}),e.jsxs(A,{value:t.teacherId,onValueChange:a=>i(s=>({...s,teacherId:a})),children:[e.jsx(E,{children:e.jsx(O,{placeholder:"Sin asignar"})}),e.jsx(P,{children:(de||[]).map(a=>e.jsx(b,{value:a.id.toString(),children:a.name},a.id))})]})]}),e.jsxs("div",{children:[e.jsx(c,{children:"Activo desde"}),e.jsx(v,{type:"date",value:t.activeFrom,onChange:a=>i(s=>({...s,activeFrom:a.target.value}))})]})]}),_&&_.length>0&&e.jsxs("div",{children:[e.jsx(c,{children:"Talleres asociados"}),e.jsx("div",{className:"flex flex-wrap gap-2 mt-2",children:_.map(a=>e.jsx(f,{variant:t.workshopIds.includes(a.id)?"default":"outline",className:"cursor-pointer",onClick:()=>je(a.id),children:a.title},a.id))})]}),e.jsxs("div",{className:"flex justify-end gap-2 pt-4 border-t",children:[e.jsx(d,{variant:"outline",onClick:R,children:"Cancelar"}),e.jsxs(d,{onClick:he,disabled:J,children:[J&&e.jsx(y,{className:"h-4 w-4 mr-2 animate-spin"}),x?"Guardar Cambios":"Crear Receta"]})]})]})]})}),e.jsx(te,{open:k,onOpenChange:h,children:e.jsxs(ie,{children:[e.jsx(ne,{children:e.jsxs(re,{className:"flex items-center gap-2",children:[e.jsx(le,{className:"h-5 w-5"})," Analizar Receta con IA"]})}),e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Pega el texto de una receta de cóctel y la IA extraerá automáticamente los campos estructurados."}),e.jsx($,{placeholder:"Ej: Mojito Clásico - 5 cl de ron blanco, 3 cl de zumo de lima, 2 cucharaditas de azúcar, 6 hojas de menta, soda...",value:C,onChange:a=>T(a.target.value),rows:8}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx(d,{variant:"outline",onClick:()=>h(!1),children:"Cancelar"}),e.jsxs(d,{onClick:()=>q.mutate(C),disabled:!C.trim()||q.isPending,children:[q.isPending&&e.jsx(y,{className:"h-4 w-4 mr-2 animate-spin"}),"Analizar"]})]})]})]})}),e.jsx(Se,{open:F,onOpenChange:u,children:e.jsxs(ke,{children:[e.jsxs(Ie,{children:[e.jsx(Te,{children:"¿Eliminar esta receta?"}),e.jsx(De,{children:"Esta acción no se puede deshacer. La receta será eliminada permanentemente."})]}),e.jsxs(Ae,{children:[e.jsx(Ee,{onClick:()=>j(null),children:"Cancelar"}),e.jsxs(Oe,{className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",onClick:()=>g&&Y.mutate(g),children:[Y.isPending&&e.jsx(y,{className:"h-4 w-4 mr-2 animate-spin"}),"Eliminar"]})]})]})})]})}export{Xe 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.