@voyage-sdk/core 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var preact=require('preact'),hooks=require('preact/hooks'),jsxRuntime=require('preact/jsx-runtime');function ce(){return jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsxRuntime.jsx("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"})})}function X({onClick:r,label:o,position:e,primaryColor:n}){let[c,l]=hooks.useState(false),[u,s]=hooks.useState(false),p=e==="bottom-right"?{right:"24px"}:{left:"24px"},d=()=>u?"scale(0.95)":c?"scale(1.02) translateY(-2px)":"scale(1)";return jsxRuntime.jsxs("button",{onClick:r,onMouseEnter:()=>l(true),onMouseLeave:()=>{l(false),s(false);},onMouseDown:()=>s(true),onMouseUp:()=>s(false),style:{position:"fixed",bottom:"24px",...p,display:"flex",alignItems:"center",gap:"10px",padding:"14px 24px",border:"none",borderRadius:"50px",cursor:"pointer",fontFamily:"'Quicksand', 'Nunito', system-ui, sans-serif",fontSize:"15px",fontWeight:600,color:"#fff",zIndex:9998,backgroundColor:n,boxShadow:c?`0 8px 32px ${n}60, 0 0 20px ${n}40`:`0 4px 20px ${n}50, 0 0 10px ${n}30`,transform:d(),transition:"all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1)"},children:[jsxRuntime.jsx(ce,{}),jsxRuntime.jsx("span",{children:o})]})}function ge({size:r=24}){return jsxRuntime.jsx("svg",{width:r,height:r,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsxRuntime.jsx("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"})})}function fe(){return jsxRuntime.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("path",{d:"M8 2l1.88 1.88M14.12 3.88L16 2M9 7.13v-1a3.003 3.003 0 116 0v1"}),jsxRuntime.jsx("path",{d:"M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 014-4h4a4 4 0 014 4v3c0 3.3-2.7 6-6 6"}),jsxRuntime.jsx("path",{d:"M12 20v-9M6.53 9C4.6 8.8 3 7.1 3 5M6 13H2M6 17l-4 1M17.47 9c1.93-.2 3.53-1.9 3.53-4M18 13h4M18 17l4 1"})]})}function he(){return jsxRuntime.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("path",{d:"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 006 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"}),jsxRuntime.jsx("path",{d:"M9 18h6M10 22h4"})]})}function me(){return jsxRuntime.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),jsxRuntime.jsx("circle",{cx:"8.5",cy:"8.5",r:"1.5"}),jsxRuntime.jsx("polyline",{points:"21 15 16 10 5 21"})]})}function N(){return jsxRuntime.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),jsxRuntime.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})}function be(){return jsxRuntime.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsxRuntime.jsx("polyline",{points:"20 6 9 17 4 12"})})}var i={bgLight:"#F8FAFC",bgCard:"rgba(255, 255, 255, 0.98)",border:"rgba(0, 0, 0, 0.08)",text:"#1F2937",textMuted:"#6B7280",error:"#EF4444",success:"#22C55E"};function z({config:r,metadata:o,onClose:e,onSubmit:n,onUpload:c}){let[l,u]=hooks.useState(null),[s,p]=hooks.useState(""),[d,y]=hooks.useState(""),[k,x]=hooks.useState(null),[w,v]=hooks.useState(null),[j,R]=hooks.useState(false),[W,B]=hooks.useState(false),[$,m]=hooks.useState(null),[re,ne]=hooks.useState(false),P=hooks.useRef(null),{i18n:C,formFields:J,theme:ie}=r,S=ie.primaryColor||"#0ea5e9",H=400,ae=l==="bug"?C.bugPlaceholder||C.placeholder:C.featurePlaceholder||C.placeholder,se=async f=>{let F=f.target.files?.[0];if(F){if(!F.type.startsWith("image/")){m("Only image files are allowed");return}if(F.size>10*1024*1024){m("Image must be under 10MB");return}B(true),m(null);try{let M=await ye(F,{maxWidth:1920,maxHeight:1080,quality:.8}),D=new FileReader;D.onload=()=>v(D.result),D.readAsDataURL(M);let U=await c(M);B(!1),U?x(U):(m("Failed to upload image"),v(null));}catch(M){console.error("[Voyage] Image processing error:",M),B(false),m("Failed to process image");}}},le=()=>{x(null),v(null),P.current&&(P.current.value="");},de=async()=>{if(!l){m("Please select a type");return}if(!s.trim()){m("Please enter your feedback");return}if(J.email.required&&!d.trim()){m("Please enter your email");return}R(true),m(null);let f={label:l,text:s.trim(),email:d.trim()||void 0,imageUrl:k||void 0,metadata:o},h=await n(f);R(false),h?ne(true):m("Failed to submit. Please try again.");},g=(()=>{let f=`${S}15`;return {overlay:{position:"fixed",top:0,left:0,right:0,bottom:0,backgroundColor:"rgba(0, 0, 0, 0.4)",backdropFilter:"blur(4px)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999,padding:"20px"},modal:{backgroundColor:i.bgCard,backdropFilter:"blur(20px)",borderRadius:"20px",width:"100%",maxWidth:"580px",maxHeight:"90vh",overflowY:"auto",position:"relative",fontFamily:"'Quicksand', 'Nunito', system-ui, sans-serif",border:`1px solid ${i.border}`,boxShadow:"0 25px 50px -12px rgba(0, 0, 0, 0.15)"},colorBar:{height:"4px",backgroundColor:S},header:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"14px 20px",borderBottom:`1px solid ${i.border}`,backgroundColor:i.bgLight},headerIcon:{width:"32px",height:"32px",borderRadius:"10px",backgroundColor:S,display:"flex",alignItems:"center",justifyContent:"center",color:"#fff"},typeButton:h=>({display:"flex",alignItems:"center",justifyContent:"center",gap:"6px",padding:"10px 12px",border:h?`2px solid ${S}`:`1px solid ${i.border}`,borderRadius:"10px",backgroundColor:h?f:i.bgLight,cursor:"pointer",fontWeight:600,fontSize:"13px",color:h?i.text:i.textMuted,transition:"all 0.2s"}),submitButton:h=>({width:"100%",padding:"12px",backgroundColor:h?i.bgLight:S,color:h?i.textMuted:"#fff",border:"none",borderRadius:"12px",fontSize:"15px",fontWeight:700,cursor:h?"not-allowed":"pointer",fontFamily:"inherit",transition:"all 0.2s",boxShadow:h?"none":`0 4px 15px ${S}40`}),primaryButton:{width:"100%",padding:"16px",backgroundColor:S,color:"#fff",border:"none",borderRadius:"12px",fontSize:"15px",fontWeight:700,cursor:"pointer",fontFamily:"inherit",marginTop:"8px"}}})();return re?jsxRuntime.jsx("div",{style:g.overlay,children:jsxRuntime.jsx("div",{style:g.modal,children:jsxRuntime.jsxs("div",{style:Ee,children:[jsxRuntime.jsx("div",{style:Ve,children:jsxRuntime.jsx(be,{})}),jsxRuntime.jsx("h3",{style:Te,children:C.successMessage}),jsxRuntime.jsx("p",{style:Oe,children:"Your voice shapes what we build next."}),jsxRuntime.jsx("button",{onClick:e,style:g.primaryButton,children:"Done"})]})})}):jsxRuntime.jsx("div",{style:g.overlay,onClick:e,children:jsxRuntime.jsxs("div",{style:g.modal,onClick:f=>f.stopPropagation(),children:[jsxRuntime.jsxs("div",{style:g.header,children:[jsxRuntime.jsxs("div",{style:xe,children:[jsxRuntime.jsx("div",{style:g.headerIcon,children:jsxRuntime.jsx(ge,{size:20})}),jsxRuntime.jsx("span",{style:Se,children:"Help Us Improve"})]}),jsxRuntime.jsx("button",{onClick:e,style:Ce,children:jsxRuntime.jsx(N,{})})]}),jsxRuntime.jsx("div",{style:g.colorBar}),jsxRuntime.jsxs("div",{style:ve,children:[jsxRuntime.jsxs("div",{style:_,children:[jsxRuntime.jsx("label",{style:L,children:"Feedback Type"}),jsxRuntime.jsxs("div",{style:ke,children:[jsxRuntime.jsxs("button",{onClick:()=>u("bug"),style:g.typeButton(l==="bug"),children:[jsxRuntime.jsx("span",{style:q(l==="bug","bug"),children:jsxRuntime.jsx(fe,{})}),jsxRuntime.jsx("span",{children:"Bug"})]}),jsxRuntime.jsxs("button",{onClick:()=>u("feature"),style:g.typeButton(l==="feature"),children:[jsxRuntime.jsx("span",{style:q(l==="feature","feature"),children:jsxRuntime.jsx(he,{})}),jsxRuntime.jsx("span",{children:"Feature"})]})]})]}),jsxRuntime.jsxs("div",{style:we,children:[jsxRuntime.jsxs("div",{style:Pe,children:[jsxRuntime.jsx("label",{style:L,children:"Description"}),jsxRuntime.jsxs("div",{style:Le,children:[jsxRuntime.jsx("textarea",{placeholder:ae,value:s,maxLength:H,onInput:f=>p(f.target.value),style:je}),jsxRuntime.jsxs("span",{style:We,children:[s.length,"/",H]})]})]}),jsxRuntime.jsxs("div",{style:Fe,children:[jsxRuntime.jsx("label",{style:L,children:"Screenshot"}),w?jsxRuntime.jsxs("div",{style:Je,children:[jsxRuntime.jsx("img",{src:w,alt:"Preview",style:Ie}),jsxRuntime.jsx("button",{onClick:le,style:De,children:jsxRuntime.jsx(N,{})}),W&&jsxRuntime.jsx("div",{style:Xe,children:"..."})]}):jsxRuntime.jsxs("button",{onClick:()=>P.current?.click(),style:Me,children:[jsxRuntime.jsx(me,{}),jsxRuntime.jsx("span",{style:{fontSize:"11px"},children:"Upload"})]}),jsxRuntime.jsx("input",{ref:P,type:"file",accept:"image/*",onChange:se,style:{display:"none"}})]})]}),J.email.enabled&&jsxRuntime.jsxs("div",{style:_,children:[jsxRuntime.jsxs("label",{style:L,children:["Email ",J.email.required?"":"(optional)"]}),jsxRuntime.jsx("input",{type:"email",placeholder:"your@email.com",value:d,onInput:f=>y(f.target.value),style:Be})]}),$&&jsxRuntime.jsx("p",{style:ze,children:$}),jsxRuntime.jsx("button",{onClick:de,disabled:j||W,style:g.submitButton(j||W),children:j?jsxRuntime.jsxs("span",{style:Re,children:[jsxRuntime.jsx("span",{className:"voyage-spinner"}),"Sending..."]}):C.submitLabel})]})]})})}async function ye(r,o){let{maxWidth:e,maxHeight:n,quality:c}=o;return new Promise((l,u)=>{let s=new Image;s.onload=()=>{let{width:p,height:d}=s;if(p>e||d>n){let x=Math.min(e/p,n/d);p=Math.round(p*x),d=Math.round(d*x);}let y=document.createElement("canvas");y.width=p,y.height=d;let k=y.getContext("2d");if(!k){u(new Error("Failed to get canvas context"));return}k.drawImage(s,0,0,p,d),y.toBlob(x=>{if(!x){u(new Error("Failed to convert image"));return}let w=Date.now(),v=new File([x],`image_${w}.webp`,{type:"image/webp"});l(v);},"image/webp",c);},s.onerror=()=>u(new Error("Failed to load image")),s.src=URL.createObjectURL(r);})}var xe={display:"flex",alignItems:"center",gap:"12px"},Se={fontSize:"16px",fontWeight:700,color:i.text},Ce={background:"transparent",border:"none",color:i.textMuted,cursor:"pointer",padding:"8px",borderRadius:"8px",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s"},ve={padding:"16px 20px"},_={marginBottom:"14px"},L={display:"block",fontSize:"13px",fontWeight:600,color:i.text,marginBottom:"8px"},ke={display:"grid",gridTemplateColumns:"1fr 1fr",gap:"12px"},we={display:"flex",gap:"14px",marginBottom:"14px"},Pe={flex:1,display:"flex",flexDirection:"column"},Fe={width:"120px",flexShrink:0,display:"flex",flexDirection:"column"},Me={width:"100%",aspectRatio:"1",border:`2px dashed ${i.border}`,borderRadius:"10px",backgroundColor:"transparent",cursor:"pointer",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:"4px",color:i.textMuted,fontSize:"12px",transition:"all 0.2s"},Ie={width:"100%",aspectRatio:"1",objectFit:"cover",borderRadius:"10px"},q=(r,o)=>({display:"flex",alignItems:"center",justifyContent:"center",color:r?o==="bug"?i.error:"#F59E0B":i.textMuted}),Le={position:"relative"},je={width:"100%",minHeight:"120px",padding:"14px",border:`1px solid ${i.border}`,borderRadius:"12px",fontSize:"14px",resize:"vertical",boxSizing:"border-box",backgroundColor:i.bgLight,color:i.text,fontFamily:"inherit",outline:"none"},We={position:"absolute",bottom:"12px",right:"14px",fontSize:"12px",color:i.textMuted},Be={width:"100%",padding:"10px 12px",border:`1px solid ${i.border}`,borderRadius:"10px",fontSize:"13px",boxSizing:"border-box",backgroundColor:i.bgLight,color:i.text,fontFamily:"inherit",outline:"none"},Je={position:"relative",display:"inline-block",borderRadius:"12px",overflow:"hidden"},De={position:"absolute",top:"8px",right:"8px",width:"28px",height:"28px",borderRadius:"50%",backgroundColor:"rgba(0, 0, 0, 0.7)",color:"#fff",border:"none",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center"},Xe={position:"absolute",inset:0,backgroundColor:"rgba(0, 0, 0, 0.7)",display:"flex",alignItems:"center",justifyContent:"center",color:"#fff",fontSize:"14px",borderRadius:"12px"},ze={color:i.error,fontSize:"14px",marginBottom:"16px",padding:"12px",backgroundColor:"rgba(239, 68, 68, 0.1)",borderRadius:"8px",border:"1px solid rgba(239, 68, 68, 0.3)"},Ee={padding:"48px 24px",textAlign:"center"},Ve={width:"64px",height:"64px",borderRadius:"50%",backgroundColor:"rgba(34, 197, 94, 0.15)",color:i.success,display:"flex",alignItems:"center",justifyContent:"center",margin:"0 auto 20px"},Te={fontSize:"20px",fontWeight:700,color:i.text,marginBottom:"8px"},Oe={fontSize:"14px",color:i.textMuted,marginBottom:"24px"},Re={display:"flex",alignItems:"center",justifyContent:"center",gap:"8px"};function E({config:r,onSubmit:o,onUpload:e,getMetadata:n,visible:c,defaultOpen:l=false,onOpenChange:u}){let[s,p]=hooks.useState(l);if(hooks.useEffect(()=>{u?.(s);},[s,u]),!c)return null;let{theme:d,i18n:y}=r;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[!s&&jsxRuntime.jsx(X,{onClick:()=>p(true),label:y.buttonLabel,position:d.position,primaryColor:d.primaryColor}),s&&jsxRuntime.jsx(z,{config:r,metadata:n(),onClose:()=>p(false),onSubmit:o,onUpload:e})]})}var Q=()=>{if(typeof document>"u"||document.getElementById("voyage-sdk-styles"))return;let r=document.createElement("style");r.id="voyage-sdk-styles",r.textContent=`
1
+ 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var preact=require('preact'),hooks=require('preact/hooks'),jsxRuntime=require('preact/jsx-runtime');function ge(){return jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsxRuntime.jsx("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"})})}function D({onClick:r,label:o,position:e,primaryColor:i,hasError:p=false}){let[a,u]=hooks.useState(false),[c,l]=hooks.useState(false),d=e==="bottom-right"?{right:"24px"}:{left:"24px"},g=()=>c?"scale(0.95)":a?"scale(1.02) translateY(-2px)":"scale(1)";return jsxRuntime.jsxs("div",{style:{position:"fixed",bottom:"24px",...d,zIndex:9998},children:[jsxRuntime.jsxs("button",{onClick:r,onMouseEnter:()=>u(true),onMouseLeave:()=>{u(false),l(false);},onMouseDown:()=>l(true),onMouseUp:()=>l(false),style:{position:"relative",display:"flex",alignItems:"center",gap:"10px",padding:"14px 24px",border:"none",borderRadius:"50px",cursor:"pointer",fontFamily:"'Quicksand', 'Nunito', system-ui, sans-serif",fontSize:"15px",fontWeight:600,color:"#fff",backgroundColor:i,boxShadow:a?`0 8px 32px ${i}60, 0 0 20px ${i}40`:`0 4px 20px ${i}50, 0 0 10px ${i}30`,transform:g(),transition:"all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1)"},children:[jsxRuntime.jsx(ge,{}),jsxRuntime.jsx("span",{children:o})]}),p&&jsxRuntime.jsx("div",{style:{position:"absolute",top:"-4px",right:"-4px",width:"18px",height:"18px",borderRadius:"50%",backgroundColor:"#EF4444",display:"flex",alignItems:"center",justifyContent:"center",color:"#fff",fontSize:"12px",fontWeight:"bold",boxShadow:"0 2px 6px rgba(239, 68, 68, 0.5)"},children:"!"})]})}function he({size:r=24}){return jsxRuntime.jsx("svg",{width:r,height:r,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsxRuntime.jsx("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"})})}function me(){return jsxRuntime.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("path",{d:"M8 2l1.88 1.88M14.12 3.88L16 2M9 7.13v-1a3.003 3.003 0 116 0v1"}),jsxRuntime.jsx("path",{d:"M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 014-4h4a4 4 0 014 4v3c0 3.3-2.7 6-6 6"}),jsxRuntime.jsx("path",{d:"M12 20v-9M6.53 9C4.6 8.8 3 7.1 3 5M6 13H2M6 17l-4 1M17.47 9c1.93-.2 3.53-1.9 3.53-4M18 13h4M18 17l4 1"})]})}function be(){return jsxRuntime.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("path",{d:"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 006 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"}),jsxRuntime.jsx("path",{d:"M9 18h6M10 22h4"})]})}function ye(){return jsxRuntime.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),jsxRuntime.jsx("circle",{cx:"8.5",cy:"8.5",r:"1.5"}),jsxRuntime.jsx("polyline",{points:"21 15 16 10 5 21"})]})}function _(){return jsxRuntime.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),jsxRuntime.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})}function xe(){return jsxRuntime.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsxRuntime.jsx("polyline",{points:"20 6 9 17 4 12"})})}var n={bgLight:"#F8FAFC",bgCard:"rgba(255, 255, 255, 0.98)",border:"rgba(0, 0, 0, 0.08)",text:"#1F2937",textMuted:"#6B7280",error:"#EF4444",success:"#22C55E"};function X({config:r,metadata:o,onClose:e,onSubmit:i,onUpload:p}){let[a,u]=hooks.useState(null),[c,l]=hooks.useState(""),[d,g]=hooks.useState(""),[v,x]=hooks.useState(null),[P,k]=hooks.useState(null),[L,H]=hooks.useState(false),[j,B]=hooks.useState(false),[U,b]=hooks.useState(null),[se,ae]=hooks.useState(false),F=hooks.useRef(null),{i18n:C,formFields:E,theme:le}=r,S=le.primaryColor||"#0ea5e9",A=400,de=a==="bug"?C.bugPlaceholder||C.placeholder:C.featurePlaceholder||C.placeholder,ce=async h=>{let I=h.target.files?.[0];if(I){if(!I.type.startsWith("image/")){b("Only image files are allowed");return}if(I.size>10*1024*1024){b("Image must be under 10MB");return}B(true),b(null);try{let M=await Se(I,{maxWidth:1920,maxHeight:1080,quality:.8}),J=new FileReader;J.onload=()=>k(J.result),J.readAsDataURL(M);let N=await p(M);B(!1),N?x(N):(b("Failed to upload image"),k(null));}catch(M){console.error("[Voyage] Image processing error:",M),B(false),b("Failed to process image");}}},pe=()=>{x(null),k(null),F.current&&(F.current.value="");},ue=async()=>{if(!a){b("Please select a type");return}if(!c.trim()){b("Please enter your feedback");return}if(E.email.required&&!d.trim()){b("Please enter your email");return}H(true),b(null);let h={label:a,text:c.trim(),email:d.trim()||void 0,imageUrl:v||void 0,metadata:o},m=await i(h);H(false),m?ae(true):b("Failed to submit. Please try again.");},f=(()=>{let h=`${S}15`;return {overlay:{position:"fixed",top:0,left:0,right:0,bottom:0,backgroundColor:"rgba(0, 0, 0, 0.4)",backdropFilter:"blur(4px)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999,padding:"20px"},modal:{backgroundColor:n.bgCard,backdropFilter:"blur(20px)",borderRadius:"20px",width:"100%",maxWidth:"580px",maxHeight:"90vh",overflowY:"auto",position:"relative",fontFamily:"'Quicksand', 'Nunito', system-ui, sans-serif",border:`1px solid ${n.border}`,boxShadow:"0 25px 50px -12px rgba(0, 0, 0, 0.15)"},colorBar:{height:"4px",backgroundColor:S},header:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"14px 20px",borderBottom:`1px solid ${n.border}`,backgroundColor:n.bgLight},headerIcon:{width:"32px",height:"32px",borderRadius:"10px",backgroundColor:S,display:"flex",alignItems:"center",justifyContent:"center",color:"#fff"},typeButton:m=>({display:"flex",alignItems:"center",justifyContent:"center",gap:"6px",padding:"10px 12px",border:m?`2px solid ${S}`:`1px solid ${n.border}`,borderRadius:"10px",backgroundColor:m?h:n.bgLight,cursor:"pointer",fontWeight:600,fontSize:"13px",color:m?n.text:n.textMuted,transition:"all 0.2s"}),submitButton:m=>({width:"100%",padding:"12px",backgroundColor:m?n.bgLight:S,color:m?n.textMuted:"#fff",border:"none",borderRadius:"12px",fontSize:"15px",fontWeight:700,cursor:m?"not-allowed":"pointer",fontFamily:"inherit",transition:"all 0.2s",boxShadow:m?"none":`0 4px 15px ${S}40`}),primaryButton:{width:"100%",padding:"16px",backgroundColor:S,color:"#fff",border:"none",borderRadius:"12px",fontSize:"15px",fontWeight:700,cursor:"pointer",fontFamily:"inherit",marginTop:"8px"}}})();return se?jsxRuntime.jsx("div",{style:f.overlay,children:jsxRuntime.jsx("div",{style:f.modal,children:jsxRuntime.jsxs("div",{style:Te,children:[jsxRuntime.jsx("div",{style:Re,children:jsxRuntime.jsx(xe,{})}),jsxRuntime.jsx("h3",{style:Oe,children:C.successMessage}),jsxRuntime.jsx("p",{style:$e,children:"Your voice shapes what we build next."}),jsxRuntime.jsx("button",{onClick:e,style:f.primaryButton,children:"Done"})]})})}):jsxRuntime.jsx("div",{style:f.overlay,onClick:e,children:jsxRuntime.jsxs("div",{style:f.modal,onClick:h=>h.stopPropagation(),children:[jsxRuntime.jsxs("div",{style:f.header,children:[jsxRuntime.jsxs("div",{style:ve,children:[jsxRuntime.jsx("div",{style:f.headerIcon,children:jsxRuntime.jsx(he,{size:20})}),jsxRuntime.jsx("span",{style:Ce,children:"Help Us Improve"})]}),jsxRuntime.jsx("button",{onClick:e,style:ke,children:jsxRuntime.jsx(_,{})})]}),jsxRuntime.jsx("div",{style:f.colorBar}),jsxRuntime.jsxs("div",{style:we,children:[jsxRuntime.jsxs("div",{style:Q,children:[jsxRuntime.jsx("label",{style:W,children:"Feedback Type"}),jsxRuntime.jsxs("div",{style:Pe,children:[jsxRuntime.jsxs("button",{onClick:()=>u("bug"),style:f.typeButton(a==="bug"),children:[jsxRuntime.jsx("span",{style:Y(a==="bug","bug"),children:jsxRuntime.jsx(me,{})}),jsxRuntime.jsx("span",{children:"Bug"})]}),jsxRuntime.jsxs("button",{onClick:()=>u("feature"),style:f.typeButton(a==="feature"),children:[jsxRuntime.jsx("span",{style:Y(a==="feature","feature"),children:jsxRuntime.jsx(be,{})}),jsxRuntime.jsx("span",{children:"Feature"})]})]})]}),jsxRuntime.jsxs("div",{style:Fe,children:[jsxRuntime.jsxs("div",{style:Ie,children:[jsxRuntime.jsx("label",{style:W,children:"Description"}),jsxRuntime.jsxs("div",{style:je,children:[jsxRuntime.jsx("textarea",{placeholder:de,value:c,maxLength:A,onInput:h=>l(h.target.value),style:Be}),jsxRuntime.jsxs("span",{style:Ee,children:[c.length,"/",A]})]})]}),jsxRuntime.jsxs("div",{style:Me,children:[jsxRuntime.jsx("label",{style:W,children:"Screenshot"}),P?jsxRuntime.jsxs("div",{style:De,children:[jsxRuntime.jsx("img",{src:P,alt:"Preview",style:Le}),jsxRuntime.jsx("button",{onClick:pe,style:Xe,children:jsxRuntime.jsx(_,{})}),j&&jsxRuntime.jsx("div",{style:ze,children:"..."})]}):jsxRuntime.jsxs("button",{onClick:()=>F.current?.click(),style:We,children:[jsxRuntime.jsx(ye,{}),jsxRuntime.jsx("span",{style:{fontSize:"11px"},children:"Upload"})]}),jsxRuntime.jsx("input",{ref:F,type:"file",accept:"image/*",onChange:ce,style:{display:"none"}})]})]}),E.email.enabled&&jsxRuntime.jsxs("div",{style:Q,children:[jsxRuntime.jsxs("label",{style:W,children:["Email ",E.email.required?"":"(optional)"]}),jsxRuntime.jsx("input",{type:"email",placeholder:"your@email.com",value:d,onInput:h=>g(h.target.value),style:Je})]}),U&&jsxRuntime.jsx("p",{style:Ve,children:U}),jsxRuntime.jsx("button",{onClick:ue,disabled:L||j,style:f.submitButton(L||j),children:L?jsxRuntime.jsxs("span",{style:He,children:[jsxRuntime.jsx("span",{className:"voyage-spinner"}),"Sending..."]}):C.submitLabel})]})]})})}async function Se(r,o){let{maxWidth:e,maxHeight:i,quality:p}=o;return new Promise((a,u)=>{let c=new Image;c.onload=()=>{let{width:l,height:d}=c;if(l>e||d>i){let x=Math.min(e/l,i/d);l=Math.round(l*x),d=Math.round(d*x);}let g=document.createElement("canvas");g.width=l,g.height=d;let v=g.getContext("2d");if(!v){u(new Error("Failed to get canvas context"));return}v.drawImage(c,0,0,l,d),g.toBlob(x=>{if(!x){u(new Error("Failed to convert image"));return}let P=Date.now(),k=new File([x],`image_${P}.webp`,{type:"image/webp"});a(k);},"image/webp",p);},c.onerror=()=>u(new Error("Failed to load image")),c.src=URL.createObjectURL(r);})}var ve={display:"flex",alignItems:"center",gap:"12px"},Ce={fontSize:"16px",fontWeight:700,color:n.text},ke={background:"transparent",border:"none",color:n.textMuted,cursor:"pointer",padding:"8px",borderRadius:"8px",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s"},we={padding:"16px 20px"},Q={marginBottom:"14px"},W={display:"block",fontSize:"13px",fontWeight:600,color:n.text,marginBottom:"8px"},Pe={display:"grid",gridTemplateColumns:"1fr 1fr",gap:"12px"},Fe={display:"flex",gap:"14px",marginBottom:"14px"},Ie={flex:1,display:"flex",flexDirection:"column"},Me={width:"120px",flexShrink:0,display:"flex",flexDirection:"column"},We={width:"100%",aspectRatio:"1",border:`2px dashed ${n.border}`,borderRadius:"10px",backgroundColor:"transparent",cursor:"pointer",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:"4px",color:n.textMuted,fontSize:"12px",transition:"all 0.2s"},Le={width:"100%",aspectRatio:"1",objectFit:"cover",borderRadius:"10px"},Y=(r,o)=>({display:"flex",alignItems:"center",justifyContent:"center",color:r?o==="bug"?n.error:"#F59E0B":n.textMuted}),je={position:"relative"},Be={width:"100%",minHeight:"120px",padding:"14px",border:`1px solid ${n.border}`,borderRadius:"12px",fontSize:"14px",resize:"vertical",boxSizing:"border-box",backgroundColor:n.bgLight,color:n.text,fontFamily:"inherit",outline:"none"},Ee={position:"absolute",bottom:"12px",right:"14px",fontSize:"12px",color:n.textMuted},Je={width:"100%",padding:"10px 12px",border:`1px solid ${n.border}`,borderRadius:"10px",fontSize:"13px",boxSizing:"border-box",backgroundColor:n.bgLight,color:n.text,fontFamily:"inherit",outline:"none"},De={position:"relative",display:"inline-block",borderRadius:"12px",overflow:"hidden"},Xe={position:"absolute",top:"8px",right:"8px",width:"28px",height:"28px",borderRadius:"50%",backgroundColor:"rgba(0, 0, 0, 0.7)",color:"#fff",border:"none",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center"},ze={position:"absolute",inset:0,backgroundColor:"rgba(0, 0, 0, 0.7)",display:"flex",alignItems:"center",justifyContent:"center",color:"#fff",fontSize:"14px",borderRadius:"12px"},Ve={color:n.error,fontSize:"14px",marginBottom:"16px",padding:"12px",backgroundColor:"rgba(239, 68, 68, 0.1)",borderRadius:"8px",border:"1px solid rgba(239, 68, 68, 0.3)"},Te={padding:"48px 24px",textAlign:"center"},Re={width:"64px",height:"64px",borderRadius:"50%",backgroundColor:"rgba(34, 197, 94, 0.15)",color:n.success,display:"flex",alignItems:"center",justifyContent:"center",margin:"0 auto 20px"},Oe={fontSize:"20px",fontWeight:700,color:n.text,marginBottom:"8px"},$e={fontSize:"14px",color:n.textMuted,marginBottom:"24px"},He={display:"flex",alignItems:"center",justifyContent:"center",gap:"8px"};function z({config:r,onSubmit:o,onUpload:e,getMetadata:i,visible:p,defaultOpen:a=false,hasError:u=false,onOpenChange:c}){let[l,d]=hooks.useState(a);if(hooks.useEffect(()=>{d(a);},[a]),hooks.useEffect(()=>{c?.(l);},[l,c]),!p)return null;let{theme:g,i18n:v}=r;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[!l&&jsxRuntime.jsx(D,{onClick:()=>d(true),label:v.buttonLabel,position:g.position,primaryColor:g.primaryColor,hasError:u}),l&&jsxRuntime.jsx(X,{config:r,metadata:i(),onClose:()=>d(false),onSubmit:o,onUpload:e})]})}var V=()=>{if(typeof document>"u"||document.getElementById("voyage-sdk-styles"))return;let r=document.createElement("style");r.id="voyage-sdk-styles",r.textContent=`
2
2
  /* Voyage SDK Styles */
3
3
 
4
4
  /* Spinner Animation */
@@ -37,6 +37,6 @@
37
37
 
38
38
  /* Load Quicksand font if not present */
39
39
  @import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@400;500;600;700&display=swap');
40
- `,document.head.appendChild(r);};var V="https://rxflzurkkuqgopjkshjh.supabase.co/functions/v1",G="voyage_config";async function T(r){let o=Y(r);if(o)return o;try{let e=await fetch(`${V}/get-widget-config`,{method:"GET",headers:{"Content-Type":"application/json","x-sdk-key":r}});if(!e.ok)return console.error("[Voyage] Failed to fetch config:",e.status),null;let n=await e.json();return Ne(r,n),n}catch(e){return console.error("[Voyage] Network error:",e),Y(r,true)}}async function Z(r,o){try{let e=await fetch(`${V}/submit-feedback`,{method:"POST",headers:{"Content-Type":"application/json","x-sdk-key":r},body:JSON.stringify({label:o.label,content:o.text,email:o.email,imageUrl:o.imageUrl,metadata:o.metadata})});if(!e.ok){let n=await e.json().catch(()=>({}));return console.error("[Voyage] Failed to submit feedback:",e.status,n),!1}return !0}catch(e){return console.error("[Voyage] Network error:",e),false}}async function ee(r,o){if(!o.type.startsWith("image/"))return console.error("[Voyage] Only image files are allowed"),null;if(o.size>5*1024*1024)return console.error("[Voyage] Image must be under 5MB"),null;try{let e=new FormData;e.append("file",o);let n=await fetch(`${V}/upload-feedback-image`,{method:"POST",headers:{"x-sdk-key":r},body:e});if(!n.ok){let l=await n.json().catch(()=>({}));return console.error("[Voyage] Failed to upload image:",n.status,l),null}return (await n.json()).url}catch(e){return console.error("[Voyage] Network error:",e),null}}function Y(r,o=false){try{let e=localStorage.getItem(`${G}_${r}`);if(!e)return null;let n=JSON.parse(e);return Date.now()-n.timestamp>36e5&&!o?null:n.config}catch{return null}}function Ne(r,o){try{let e={config:o,timestamp:Date.now()};localStorage.setItem(`${G}_${r}`,JSON.stringify(e));}catch{}}function te(){return {url:window.location.href,pathname:window.location.pathname,browser:navigator.userAgent,viewport:`${window.innerWidth}x${window.innerHeight}`,title:document.title,timestamp:new Date().toISOString(),locale:navigator.language,referrer:document.referrer}}var qe={projectId:"",formFields:{email:{enabled:true,required:false},category:{enabled:true,options:["bug","feature"]}},theme:{primaryColor:"#0ea5e9",position:"bottom-right"},i18n:{buttonLabel:"To : the Maker",placeholder:"Describe your ideas to improve our product",bugPlaceholder:"Please describe the bug in detail (e.g., clicked a button and it didn't work)",featurePlaceholder:"Describe your ideas to improve our product (e.g., I want to export TASK.md to Linear tickets)",submitLabel:"Send to the Maker",successMessage:"Thank you for your feedback!"}},O=class{constructor(){this.config=null;this.serverConfig=null;this.container=null;this.isWidgetVisible=false;this.isModalOpen=false;}async init(o){if(this.config=o,!o.sdkKey){console.error("[Voyage] Invalid SDK Key");return}if(Q(),!this.shouldDisplay()){console.log("[Voyage] Widget hidden by display rules");return}let e=await T(o.sdkKey);this.serverConfig=this.mergeConfig(e,o),this.isWidgetVisible=true,this.renderWidget(),console.log("[Voyage] Initialized");}show(){if(!this.config){console.warn("[Voyage] SDK not initialized");return}this.isWidgetVisible=true,this.renderWidget();}hide(){this.isWidgetVisible=false,this.renderWidget();}open(){if(!this.config){console.warn("[Voyage] SDK not initialized");return}this.isModalOpen=true,this.renderWidget();}close(){this.isModalOpen=false,this.renderWidget();}isOpen(){return this.isModalOpen}isVisible(){return this.isWidgetVisible}async refreshConfig(){if(!this.config)return;let o=await T(this.config.sdkKey);this.serverConfig=this.mergeConfig(o,this.config),this.renderWidget();}destroy(){this.container&&(preact.render(null,this.container),this.container.remove(),this.container=null),this.config=null,this.serverConfig=null,this.isWidgetVisible=false,this.isModalOpen=false;}renderWidget(){if(!this.serverConfig||!this.config)return;this.container||(this.container=document.createElement("div"),this.container.id="voyage-widget-container",document.body.appendChild(this.container));let o=this.config.sdkKey;preact.render(preact.h(E,{config:this.serverConfig,visible:this.isWidgetVisible,defaultOpen:this.isModalOpen,onOpenChange:e=>{this.isModalOpen=e;},getMetadata:te,onSubmit:async e=>Z(o,e),onUpload:async e=>ee(o,e)}),this.container);}mergeConfig(o,e){return o||{...qe}}shouldDisplay(){if(!this.config)return false;let o=window.location.pathname,{include:e,exclude:n}=this.config;return e&&e.length>0?e.some(c=>this.matchPath(o,c)):n&&n.length>0?!n.some(c=>this.matchPath(o,c)):true}matchPath(o,e){if(e.endsWith("/*")){let n=e.slice(0,-2);return o.startsWith(n)}return o===e}},Ke=new O;var St=Ke;
41
- exports.Voyage=Ke;exports.default=St;//# sourceMappingURL=index.cjs.map
40
+ `,document.head.appendChild(r);};var T="https://rxflzurkkuqgopjkshjh.supabase.co/functions/v1",te="voyage_config";async function R(r){let o=ee(r);if(o)return o;try{let e=await fetch(`${T}/get-widget-config`,{method:"GET",headers:{"Content-Type":"application/json","x-sdk-key":r}});if(!e.ok)return console.error("[Voyage] Failed to fetch config:",e.status),null;let i=await e.json();return qe(r,i),i}catch(e){return console.error("[Voyage] Network error:",e),ee(r,true)}}async function oe(r,o){try{let e=await fetch(`${T}/submit-feedback`,{method:"POST",headers:{"Content-Type":"application/json","x-sdk-key":r},body:JSON.stringify({label:o.label,content:o.text,email:o.email,imageUrl:o.imageUrl,metadata:o.metadata})});if(!e.ok){let i=await e.json().catch(()=>({}));return console.error("[Voyage] Failed to submit feedback:",e.status,i),!1}return !0}catch(e){return console.error("[Voyage] Network error:",e),false}}async function re(r,o){if(!o.type.startsWith("image/"))return console.error("[Voyage] Only image files are allowed"),null;if(o.size>5*1024*1024)return console.error("[Voyage] Image must be under 5MB"),null;try{let e=new FormData;e.append("file",o);let i=await fetch(`${T}/upload-feedback-image`,{method:"POST",headers:{"x-sdk-key":r},body:e});if(!i.ok){let a=await i.json().catch(()=>({}));return console.error("[Voyage] Failed to upload image:",i.status,a),null}return (await i.json()).url}catch(e){return console.error("[Voyage] Network error:",e),null}}function ee(r,o=false){try{let e=localStorage.getItem(`${te}_${r}`);if(!e)return null;let i=JSON.parse(e);return Date.now()-i.timestamp>36e5&&!o?null:i.config}catch{return null}}function qe(r,o){try{let e={config:o,timestamp:Date.now()};localStorage.setItem(`${te}_${r}`,JSON.stringify(e));}catch{}}function ie(){return {url:window.location.href,pathname:window.location.pathname,browser:navigator.userAgent,viewport:`${window.innerWidth}x${window.innerHeight}`,title:document.title,timestamp:new Date().toISOString(),locale:navigator.language,referrer:document.referrer}}var O={projectId:"",formFields:{email:{enabled:true,required:false},category:{enabled:true,options:["bug","feature"]}},theme:{primaryColor:"#0ea5e9",position:"bottom-right"},i18n:{buttonLabel:"To : the Maker",placeholder:"Describe your ideas to improve our product",bugPlaceholder:"Please describe the bug in detail (e.g., clicked a button and it didn't work)",featurePlaceholder:"Describe your ideas to improve our product (e.g., I want to export TASK.md to Linear tickets)",submitLabel:"Send to the Maker",successMessage:"Thank you for your feedback!"}},$=class{constructor(){this.config=null;this.serverConfig=null;this.container=null;this.isWidgetVisible=false;this.isModalOpen=false;this.hasInitError=false;}async init(o){if(this.config=o,this.hasInitError=false,!o.sdkKey){console.error("[Voyage] SDK Key is required. Get your key from the dashboard."),this.hasInitError=true,V(),this.isWidgetVisible=true,this.serverConfig={...O},this.renderWidget();return}if(V(),!this.shouldDisplay()){console.log("[Voyage] Widget hidden by display rules");return}let e=await R(o.sdkKey);if(!e){console.error("[Voyage] Failed to fetch config. Check your SDK Key or network connection."),this.hasInitError=true,this.serverConfig={...O},this.isWidgetVisible=true,this.renderWidget();return}this.serverConfig=this.mergeConfig(e,o),this.isWidgetVisible=true,this.renderWidget(),console.log("[Voyage] Initialized");}show(){if(!this.config){console.warn("[Voyage] SDK not initialized");return}this.isWidgetVisible=true,this.renderWidget();}hide(){this.isWidgetVisible=false,this.renderWidget();}open(){if(!this.config){console.warn("[Voyage] SDK not initialized");return}this.isModalOpen=true,this.renderWidget();}close(){this.isModalOpen=false,this.renderWidget();}isOpen(){return this.isModalOpen}isVisible(){return this.isWidgetVisible}async refreshConfig(){if(!this.config)return;let o=await R(this.config.sdkKey);this.serverConfig=this.mergeConfig(o,this.config),this.renderWidget();}destroy(){this.container&&(preact.render(null,this.container),this.container.remove(),this.container=null),this.config=null,this.serverConfig=null,this.isWidgetVisible=false,this.isModalOpen=false;}renderWidget(){if(!this.serverConfig||!this.config)return;this.container||(this.container=document.createElement("div"),this.container.id="voyage-widget-container",document.body.appendChild(this.container));let o=this.config.sdkKey;preact.render(preact.h(z,{config:this.serverConfig,visible:this.isWidgetVisible,defaultOpen:this.isModalOpen,hasError:this.hasInitError,onOpenChange:e=>{this.isModalOpen=e;},getMetadata:ie,onSubmit:async e=>oe(o,e),onUpload:async e=>re(o,e)}),this.container);}mergeConfig(o,e){return o||{...O}}shouldDisplay(){if(!this.config)return false;let o=window.location.pathname,{include:e,exclude:i}=this.config;return e&&e.length>0?e.some(p=>this.matchPath(o,p)):i&&i.length>0?!i.some(p=>this.matchPath(o,p)):true}matchPath(o,e){if(e.endsWith("/*")){let i=e.slice(0,-2);return o.startsWith(i)}return o===e}},_e=new $;var St=_e;
41
+ exports.Voyage=_e;exports.default=St;//# sourceMappingURL=index.cjs.map
42
42
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Button.tsx","../src/components/Modal.tsx","../src/components/Widget.tsx","../src/styles.ts","../src/utils/api.ts","../src/utils/metadata.ts","../src/index.ts"],"names":["MessageIcon","jsx","Button","onClick","label","position","primaryColor","isHovered","setIsHovered","useState","isPressed","setIsPressed","positionStyle","getTransform","jsxs","size","BugIcon","LightbulbIcon","ImageIcon","CloseIcon","CheckIcon","colors","Modal","config","metadata","onClose","onSubmit","onUpload","setLabel","text","setText","email","setEmail","imageUrl","setImageUrl","imagePreview","setImagePreview","isSubmitting","setIsSubmitting","isUploading","setIsUploading","error","setError","success","setSuccess","fileInputRef","useRef","i18n","formFields","theme","maxLength","currentPlaceholder","handleFileSelect","e","file","processedFile","processImage","reader","url","err","handleRemoveImage","handleSubmit","feedbackData","result","styles","primaryBgLight","active","disabled","successContainerStyle","successIconStyle","successTitleStyle","successTextStyle","headerLeftStyle","headerTitleStyle","closeButtonStyle","contentStyle","sectionStyle","labelStyle","typeButtonsStyle","typeIconStyle","descriptionRowStyle","descriptionColStyle","textareaWrapperStyle","textareaStyle","charCountStyle","uploadColStyle","imagePreviewContainerStyle","imagePreviewSquareStyle","removeImageButtonStyle","uploadingOverlayStyle","uploadButtonSquareStyle","inputStyle","errorStyle","spinnerContainerStyle","options","maxWidth","maxHeight","quality","resolve","reject","img","width","height","ratio","canvas","ctx","blob","timestamp","newFile","type","Widget","getMetadata","visible","defaultOpen","onOpenChange","isOpen","setIsOpen","useEffect","Fragment","injectStyles","style","API_BASE","CACHE_KEY","fetchProjectConfig","sdkKey","cached","getFromCache","response","saveToCache","submitFeedback","data","errorData","uploadImage","formData","ignoreExpiry","raw","captureMetadata","DEFAULT_CONFIG","VoyageSDK","fetchedConfig","render","h","open","server","_client","pathname","include","exclude","pattern","prefix","Voyage","index_default"],"mappings":"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","file":"index.cjs","sourcesContent":["import { h } from 'preact';\nimport { useState } from 'preact/hooks';\n\ninterface ButtonProps {\n onClick: () => void;\n label: string;\n position: 'bottom-right' | 'bottom-left';\n primaryColor: string;\n}\n\n// 말풍선 아이콘 SVG\nfunction MessageIcon() {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n );\n}\n\nexport function Button({ onClick, label, position, primaryColor }: ButtonProps) {\n const [isHovered, setIsHovered] = useState(false);\n const [isPressed, setIsPressed] = useState(false);\n\n const positionStyle = position === 'bottom-right'\n ? { right: '24px' }\n : { left: '24px' };\n\n // Jelly 효과 transform\n const getTransform = () => {\n if (isPressed) return 'scale(0.95)';\n if (isHovered) return 'scale(1.02) translateY(-2px)';\n return 'scale(1)';\n };\n\n return (\n <button\n onClick={onClick}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => { setIsHovered(false); setIsPressed(false); }}\n onMouseDown={() => setIsPressed(true)}\n onMouseUp={() => setIsPressed(false)}\n style={{\n position: 'fixed',\n bottom: '24px',\n ...positionStyle,\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n padding: '14px 24px',\n border: 'none',\n borderRadius: '50px',\n cursor: 'pointer',\n fontFamily: \"'Quicksand', 'Nunito', system-ui, sans-serif\",\n fontSize: '15px',\n fontWeight: 600,\n color: '#fff',\n zIndex: 9998,\n // primaryColor 적용\n backgroundColor: primaryColor,\n // 그림자 + glow 효과\n boxShadow: isHovered\n ? `0 8px 32px ${primaryColor}60, 0 0 20px ${primaryColor}40`\n : `0 4px 20px ${primaryColor}50, 0 0 10px ${primaryColor}30`,\n // Jelly 애니메이션\n transform: getTransform(),\n transition: 'all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1)',\n }}\n >\n <MessageIcon />\n <span>{label}</span>\n </button>\n );\n}\n","import { h } from 'preact';\nimport { useRef, useState } from 'preact/hooks';\n\nimport type { ProjectConfig, FeedbackData, FeedbackMetadata } from '../types';\n\ninterface ModalProps {\n config: ProjectConfig;\n metadata: FeedbackMetadata;\n onClose: () => void;\n onSubmit: (data: FeedbackData) => Promise<boolean>;\n onUpload: (file: File) => Promise<string | null>;\n}\n\n// 아이콘들\nfunction MessageIcon({ size = 24 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n );\n}\n\nfunction BugIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M8 2l1.88 1.88M14.12 3.88L16 2M9 7.13v-1a3.003 3.003 0 116 0v1\" />\n <path d=\"M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 014-4h4a4 4 0 014 4v3c0 3.3-2.7 6-6 6\" />\n <path d=\"M12 20v-9M6.53 9C4.6 8.8 3 7.1 3 5M6 13H2M6 17l-4 1M17.47 9c1.93-.2 3.53-1.9 3.53-4M18 13h4M18 17l4 1\" />\n </svg>\n );\n}\n\nfunction LightbulbIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 006 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\" />\n <path d=\"M9 18h6M10 22h4\" />\n </svg>\n );\n}\n\nfunction ImageIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" />\n <polyline points=\"21 15 16 10 5 21\" />\n </svg>\n );\n}\n\nfunction CloseIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n\nfunction CheckIcon() {\n return (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n );\n}\n\n// 라이트 테마 색상\nconst colors = {\n bg: '#FFFFFF',\n bgLight: '#F8FAFC',\n bgCard: 'rgba(255, 255, 255, 0.98)',\n border: 'rgba(0, 0, 0, 0.08)',\n borderLight: 'rgba(0, 0, 0, 0.12)',\n text: '#1F2937',\n textMuted: '#6B7280',\n error: '#EF4444',\n success: '#22C55E',\n};\n\nexport function Modal({ config, metadata, onClose, onSubmit, onUpload }: ModalProps) {\n const [label, setLabel] = useState<'bug' | 'feature' | null>(null);\n const [text, setText] = useState('');\n const [email, setEmail] = useState('');\n const [imageUrl, setImageUrl] = useState<string | null>(null);\n const [imagePreview, setImagePreview] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isUploading, setIsUploading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [success, setSuccess] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const { i18n, formFields, theme } = config;\n const primaryColor = theme.primaryColor || '#0ea5e9';\n const maxLength = 400;\n\n // 동적 placeholder\n const currentPlaceholder = label === 'bug'\n ? (i18n.bugPlaceholder || i18n.placeholder)\n : (i18n.featurePlaceholder || i18n.placeholder);\n\n const handleFileSelect = async (e: Event) => {\n const target = e.target as HTMLInputElement;\n const file = target.files?.[0];\n if (!file) return;\n\n if (!file.type.startsWith('image/')) {\n setError('Only image files are allowed');\n return;\n }\n if (file.size > 10 * 1024 * 1024) {\n setError('Image must be under 10MB');\n return;\n }\n\n setIsUploading(true);\n setError(null);\n\n try {\n // 이미지를 WebP로 변환 및 resize\n const processedFile = await processImage(file, {\n maxWidth: 1920,\n maxHeight: 1080,\n quality: 0.8,\n });\n\n // 프리뷰 생성\n const reader = new FileReader();\n reader.onload = () => setImagePreview(reader.result as string);\n reader.readAsDataURL(processedFile);\n\n const url = await onUpload(processedFile);\n setIsUploading(false);\n\n if (url) {\n setImageUrl(url);\n } else {\n setError('Failed to upload image');\n setImagePreview(null);\n }\n } catch (err) {\n console.error('[Voyage] Image processing error:', err);\n setIsUploading(false);\n setError('Failed to process image');\n }\n };\n\n const handleRemoveImage = () => {\n setImageUrl(null);\n setImagePreview(null);\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n };\n\n const handleSubmit = async () => {\n if (!label) {\n setError('Please select a type');\n return;\n }\n if (!text.trim()) {\n setError('Please enter your feedback');\n return;\n }\n if (formFields.email.required && !email.trim()) {\n setError('Please enter your email');\n return;\n }\n\n setIsSubmitting(true);\n setError(null);\n\n const feedbackData: FeedbackData = {\n label,\n text: text.trim(),\n email: email.trim() || undefined,\n imageUrl: imageUrl || undefined,\n metadata,\n };\n\n const result = await onSubmit(feedbackData);\n setIsSubmitting(false);\n\n if (result) {\n setSuccess(true);\n } else {\n setError('Failed to submit. Please try again.');\n }\n };\n\n // 스타일 함수 (primaryColor 적용)\n const getStyles = () => {\n const primaryBgLight = `${primaryColor}15`;\n\n return {\n overlay: {\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.4)',\n backdropFilter: 'blur(4px)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 9999,\n padding: '20px',\n } as h.JSX.CSSProperties,\n\n modal: {\n backgroundColor: colors.bgCard,\n backdropFilter: 'blur(20px)',\n borderRadius: '20px',\n width: '100%',\n maxWidth: '580px',\n maxHeight: '90vh',\n overflowY: 'auto',\n position: 'relative',\n fontFamily: \"'Quicksand', 'Nunito', system-ui, sans-serif\",\n border: `1px solid ${colors.border}`,\n boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.15)',\n } as h.JSX.CSSProperties,\n\n colorBar: {\n height: '4px',\n backgroundColor: primaryColor,\n } as h.JSX.CSSProperties,\n\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '14px 20px',\n borderBottom: `1px solid ${colors.border}`,\n backgroundColor: colors.bgLight,\n } as h.JSX.CSSProperties,\n\n headerIcon: {\n width: '32px',\n height: '32px',\n borderRadius: '10px',\n backgroundColor: primaryColor,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n } as h.JSX.CSSProperties,\n\n typeButton: (active: boolean) => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '6px',\n padding: '10px 12px',\n border: active ? `2px solid ${primaryColor}` : `1px solid ${colors.border}`,\n borderRadius: '10px',\n backgroundColor: active ? primaryBgLight : colors.bgLight,\n cursor: 'pointer',\n fontWeight: 600,\n fontSize: '13px',\n color: active ? colors.text : colors.textMuted,\n transition: 'all 0.2s',\n } as h.JSX.CSSProperties),\n\n submitButton: (disabled: boolean) => ({\n width: '100%',\n padding: '12px',\n backgroundColor: disabled ? colors.bgLight : primaryColor,\n color: disabled ? colors.textMuted : '#fff',\n border: 'none',\n borderRadius: '12px',\n fontSize: '15px',\n fontWeight: 700,\n cursor: disabled ? 'not-allowed' : 'pointer',\n fontFamily: 'inherit',\n transition: 'all 0.2s',\n boxShadow: disabled ? 'none' : `0 4px 15px ${primaryColor}40`,\n } as h.JSX.CSSProperties),\n\n primaryButton: {\n width: '100%',\n padding: '16px',\n backgroundColor: primaryColor,\n color: '#fff',\n border: 'none',\n borderRadius: '12px',\n fontSize: '15px',\n fontWeight: 700,\n cursor: 'pointer',\n fontFamily: 'inherit',\n marginTop: '8px',\n } as h.JSX.CSSProperties,\n };\n };\n\n const styles = getStyles();\n\n // 성공 화면\n if (success) {\n return (\n <div style={styles.overlay}>\n <div style={styles.modal}>\n <div style={successContainerStyle}>\n <div style={successIconStyle}>\n <CheckIcon />\n </div>\n <h3 style={successTitleStyle}>{i18n.successMessage}</h3>\n <p style={successTextStyle}>Your voice shapes what we build next.</p>\n <button onClick={onClose} style={styles.primaryButton}>\n Done\n </button>\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div style={styles.overlay} onClick={onClose}>\n <div style={styles.modal} onClick={(e) => e.stopPropagation()}>\n {/* 헤더 */}\n <div style={styles.header}>\n <div style={headerLeftStyle}>\n <div style={styles.headerIcon}>\n <MessageIcon size={20} />\n </div>\n <span style={headerTitleStyle}>Help Us Improve</span>\n </div>\n <button onClick={onClose} style={closeButtonStyle}>\n <CloseIcon />\n </button>\n </div>\n\n {/* 컬러 바 */}\n <div style={styles.colorBar} />\n\n {/* 컨텐츠 */}\n <div style={contentStyle}>\n {/* 이슈 타입 */}\n <div style={sectionStyle}>\n <label style={labelStyle}>Feedback Type</label>\n <div style={typeButtonsStyle}>\n <button\n onClick={() => setLabel('bug')}\n style={styles.typeButton(label === 'bug')}\n >\n <span style={typeIconStyle(label === 'bug', 'bug')}>\n <BugIcon />\n </span>\n <span>Bug</span>\n </button>\n <button\n onClick={() => setLabel('feature')}\n style={styles.typeButton(label === 'feature')}\n >\n <span style={typeIconStyle(label === 'feature', 'feature')}>\n <LightbulbIcon />\n </span>\n <span>Feature</span>\n </button>\n </div>\n </div>\n\n {/* 설명 + 이미지 (flex row) */}\n <div style={descriptionRowStyle}>\n {/* 텍스트 영역 */}\n <div style={descriptionColStyle}>\n <label style={labelStyle}>Description</label>\n <div style={textareaWrapperStyle}>\n <textarea\n placeholder={currentPlaceholder}\n value={text}\n maxLength={maxLength}\n onInput={(e) => setText((e.target as HTMLTextAreaElement).value)}\n style={textareaStyle}\n />\n <span style={charCountStyle}>{text.length}/{maxLength}</span>\n </div>\n </div>\n\n {/* 이미지 업로드 (정사각형) */}\n <div style={uploadColStyle}>\n <label style={labelStyle}>Screenshot</label>\n {imagePreview ? (\n <div style={imagePreviewContainerStyle}>\n <img src={imagePreview} alt=\"Preview\" style={imagePreviewSquareStyle} />\n <button onClick={handleRemoveImage} style={removeImageButtonStyle}>\n <CloseIcon />\n </button>\n {isUploading && <div style={uploadingOverlayStyle}>...</div>}\n </div>\n ) : (\n <button\n onClick={() => fileInputRef.current?.click()}\n style={uploadButtonSquareStyle}\n >\n <ImageIcon />\n <span style={{ fontSize: '11px' }}>Upload</span>\n </button>\n )}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileSelect}\n style={{ display: 'none' }}\n />\n </div>\n </div>\n\n {/* 이메일 */}\n {formFields.email.enabled && (\n <div style={sectionStyle}>\n <label style={labelStyle}>\n Email {formFields.email.required ? '' : '(optional)'}\n </label>\n <input\n type=\"email\"\n placeholder=\"your@email.com\"\n value={email}\n onInput={(e) => setEmail((e.target as HTMLInputElement).value)}\n style={inputStyle}\n />\n </div>\n )}\n\n {/* 에러 */}\n {error && <p style={errorStyle}>{error}</p>}\n\n {/* 제출 버튼 */}\n <button\n onClick={handleSubmit}\n disabled={isSubmitting || isUploading}\n style={styles.submitButton(isSubmitting || isUploading)}\n >\n {isSubmitting ? (\n <span style={spinnerContainerStyle}>\n <span className=\"voyage-spinner\" />\n Sending...\n </span>\n ) : (\n i18n.submitLabel\n )}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n// 이미지 처리 유틸: resize + WebP 변환\ninterface ProcessImageOptions {\n maxWidth: number;\n maxHeight: number;\n quality: number;\n}\n\nasync function processImage(file: File, options: ProcessImageOptions): Promise<File> {\n const { maxWidth, maxHeight, quality } = options;\n\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n // 비율 유지하면서 resize 계산\n let { width, height } = img;\n\n if (width > maxWidth || height > maxHeight) {\n const ratio = Math.min(maxWidth / width, maxHeight / height);\n width = Math.round(width * ratio);\n height = Math.round(height * ratio);\n }\n\n // Canvas에 그리기\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n reject(new Error('Failed to get canvas context'));\n return;\n }\n\n ctx.drawImage(img, 0, 0, width, height);\n\n // WebP로 변환\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new Error('Failed to convert image'));\n return;\n }\n\n // Blob을 File로 변환\n const timestamp = Date.now();\n const newFile = new File([blob], `image_${timestamp}.webp`, {\n type: 'image/webp',\n });\n\n resolve(newFile);\n },\n 'image/webp',\n quality\n );\n };\n\n img.onerror = () => reject(new Error('Failed to load image'));\n img.src = URL.createObjectURL(file);\n });\n}\n\n// 정적 스타일 정의 (라이트 테마)\nconst headerLeftStyle: h.JSX.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n};\n\nconst headerTitleStyle: h.JSX.CSSProperties = {\n fontSize: '16px',\n fontWeight: 700,\n color: colors.text,\n};\n\nconst closeButtonStyle: h.JSX.CSSProperties = {\n background: 'transparent',\n border: 'none',\n color: colors.textMuted,\n cursor: 'pointer',\n padding: '8px',\n borderRadius: '8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'all 0.2s',\n};\n\nconst contentStyle: h.JSX.CSSProperties = {\n padding: '16px 20px',\n};\n\nconst sectionStyle: h.JSX.CSSProperties = {\n marginBottom: '14px',\n};\n\nconst labelStyle: h.JSX.CSSProperties = {\n display: 'block',\n fontSize: '13px',\n fontWeight: 600,\n color: colors.text,\n marginBottom: '8px',\n};\n\nconst typeButtonsStyle: h.JSX.CSSProperties = {\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: '12px',\n};\n\nconst descriptionRowStyle: h.JSX.CSSProperties = {\n display: 'flex',\n gap: '14px',\n marginBottom: '14px',\n};\n\nconst descriptionColStyle: h.JSX.CSSProperties = {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n};\n\nconst uploadColStyle: h.JSX.CSSProperties = {\n width: '120px',\n flexShrink: 0,\n display: 'flex',\n flexDirection: 'column',\n};\n\nconst uploadButtonSquareStyle: h.JSX.CSSProperties = {\n width: '100%',\n aspectRatio: '1',\n border: `2px dashed ${colors.border}`,\n borderRadius: '10px',\n backgroundColor: 'transparent',\n cursor: 'pointer',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '4px',\n color: colors.textMuted,\n fontSize: '12px',\n transition: 'all 0.2s',\n};\n\nconst imagePreviewSquareStyle: h.JSX.CSSProperties = {\n width: '100%',\n aspectRatio: '1',\n objectFit: 'cover',\n borderRadius: '10px',\n};\n\nconst typeIconStyle = (active: boolean, type: 'bug' | 'feature'): h.JSX.CSSProperties => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: active\n ? (type === 'bug' ? colors.error : '#F59E0B')\n : colors.textMuted,\n});\n\nconst textareaWrapperStyle: h.JSX.CSSProperties = {\n position: 'relative',\n};\n\nconst textareaStyle: h.JSX.CSSProperties = {\n width: '100%',\n minHeight: '120px',\n padding: '14px',\n border: `1px solid ${colors.border}`,\n borderRadius: '12px',\n fontSize: '14px',\n resize: 'vertical',\n boxSizing: 'border-box',\n backgroundColor: colors.bgLight,\n color: colors.text,\n fontFamily: 'inherit',\n outline: 'none',\n};\n\nconst charCountStyle: h.JSX.CSSProperties = {\n position: 'absolute',\n bottom: '12px',\n right: '14px',\n fontSize: '12px',\n color: colors.textMuted,\n};\n\nconst inputStyle: h.JSX.CSSProperties = {\n width: '100%',\n padding: '10px 12px',\n border: `1px solid ${colors.border}`,\n borderRadius: '10px',\n fontSize: '13px',\n boxSizing: 'border-box',\n backgroundColor: colors.bgLight,\n color: colors.text,\n fontFamily: 'inherit',\n outline: 'none',\n};\n\nconst imagePreviewContainerStyle: h.JSX.CSSProperties = {\n position: 'relative',\n display: 'inline-block',\n borderRadius: '12px',\n overflow: 'hidden',\n};\n\nconst removeImageButtonStyle: h.JSX.CSSProperties = {\n position: 'absolute',\n top: '8px',\n right: '8px',\n width: '28px',\n height: '28px',\n borderRadius: '50%',\n backgroundColor: 'rgba(0, 0, 0, 0.7)',\n color: '#fff',\n border: 'none',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n};\n\nconst uploadingOverlayStyle: h.JSX.CSSProperties = {\n position: 'absolute',\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.7)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n fontSize: '14px',\n borderRadius: '12px',\n};\n\nconst errorStyle: h.JSX.CSSProperties = {\n color: colors.error,\n fontSize: '14px',\n marginBottom: '16px',\n padding: '12px',\n backgroundColor: 'rgba(239, 68, 68, 0.1)',\n borderRadius: '8px',\n border: `1px solid rgba(239, 68, 68, 0.3)`,\n};\n\nconst successContainerStyle: h.JSX.CSSProperties = {\n padding: '48px 24px',\n textAlign: 'center',\n};\n\nconst successIconStyle: h.JSX.CSSProperties = {\n width: '64px',\n height: '64px',\n borderRadius: '50%',\n backgroundColor: 'rgba(34, 197, 94, 0.15)',\n color: colors.success,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: '0 auto 20px',\n};\n\nconst successTitleStyle: h.JSX.CSSProperties = {\n fontSize: '20px',\n fontWeight: 700,\n color: colors.text,\n marginBottom: '8px',\n};\n\nconst successTextStyle: h.JSX.CSSProperties = {\n fontSize: '14px',\n color: colors.textMuted,\n marginBottom: '24px',\n};\n\nconst spinnerContainerStyle: h.JSX.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n};\n","import { h } from 'preact';\nimport { useState, useEffect } from 'preact/hooks';\nimport { Button } from './Button';\nimport { Modal } from './Modal';\nimport type { ProjectConfig, FeedbackData, FeedbackMetadata } from '../types';\n\ninterface WidgetProps {\n config: ProjectConfig;\n onSubmit: (data: FeedbackData) => Promise<boolean>;\n onUpload: (file: File) => Promise<string | null>;\n getMetadata: () => FeedbackMetadata;\n visible: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nexport function Widget({\n config,\n onSubmit,\n onUpload,\n getMetadata,\n visible,\n defaultOpen = false,\n onOpenChange,\n}: WidgetProps) {\n const [isOpen, setIsOpen] = useState(defaultOpen);\n\n useEffect(() => {\n onOpenChange?.(isOpen);\n }, [isOpen, onOpenChange]);\n\n if (!visible) {\n return null;\n }\n\n const { theme, i18n } = config;\n\n return (\n <>\n {!isOpen && (\n <Button\n onClick={() => setIsOpen(true)}\n label={i18n.buttonLabel}\n position={theme.position}\n primaryColor={theme.primaryColor}\n />\n )}\n\n {isOpen && (\n <Modal\n config={config}\n metadata={getMetadata()}\n onClose={() => setIsOpen(false)}\n onSubmit={onSubmit}\n onUpload={onUpload}\n />\n )}\n </>\n );\n}\n","// SDK 전용 CSS 스타일 (동적 주입)\nexport const injectStyles = () => {\n if (typeof document === 'undefined') return;\n if (document.getElementById('voyage-sdk-styles')) return;\n\n const style = document.createElement('style');\n style.id = 'voyage-sdk-styles';\n style.textContent = `\n /* Voyage SDK Styles */\n\n /* Spinner Animation */\n @keyframes voyage-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n #voyage-widget-container * {\n box-sizing: border-box;\n }\n\n #voyage-widget-container button {\n font-family: 'Quicksand', 'Nunito', system-ui, sans-serif;\n }\n\n #voyage-widget-container textarea:focus,\n #voyage-widget-container input:focus {\n border-color: rgba(124, 58, 237, 0.5);\n box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.1);\n }\n\n #voyage-widget-container button:focus {\n outline: none;\n }\n\n /* Spinner */\n .voyage-spinner {\n width: 16px;\n height: 16px;\n border: 2px solid rgba(255,255,255,0.3);\n border-top-color: #fff;\n border-radius: 50%;\n animation: voyage-spin 0.8s linear infinite;\n }\n\n /* Load Quicksand font if not present */\n @import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@400;500;600;700&display=swap');\n `;\n\n document.head.appendChild(style);\n};\n","import type { ProjectConfig, FeedbackData } from '../types';\n\n// Supabase Edge Functions URL\nconst API_BASE = 'https://rxflzurkkuqgopjkshjh.supabase.co/functions/v1';\n\nconst CACHE_KEY = 'voyage_config';\nconst CACHE_TTL = 60 * 60 * 1000; // 1시간\n\ninterface CachedConfig {\n config: ProjectConfig;\n timestamp: number;\n}\n\nexport async function fetchProjectConfig(sdkKey: string): Promise<ProjectConfig | null> {\n // 캐시 확인\n const cached = getFromCache(sdkKey);\n if (cached) {\n return cached;\n }\n\n try {\n const response = await fetch(`${API_BASE}/get-widget-config`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'x-sdk-key': sdkKey,\n },\n });\n\n if (!response.ok) {\n console.error('[Voyage] Failed to fetch config:', response.status);\n return null;\n }\n\n const config = await response.json() as ProjectConfig;\n saveToCache(sdkKey, config);\n return config;\n } catch (error) {\n console.error('[Voyage] Network error:', error);\n // 네트워크 실패 시 캐시 사용 (만료되어도)\n return getFromCache(sdkKey, true);\n }\n}\n\nexport async function submitFeedback(sdkKey: string, data: FeedbackData): Promise<boolean> {\n try {\n const response = await fetch(`${API_BASE}/submit-feedback`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-sdk-key': sdkKey,\n },\n body: JSON.stringify({\n label: data.label,\n content: data.text,\n email: data.email,\n imageUrl: data.imageUrl,\n metadata: data.metadata,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error('[Voyage] Failed to submit feedback:', response.status, errorData);\n return false;\n }\n\n return true;\n } catch (error) {\n console.error('[Voyage] Network error:', error);\n return false;\n }\n}\n\nexport async function uploadImage(sdkKey: string, file: File): Promise<string | null> {\n // 검증\n if (!file.type.startsWith('image/')) {\n console.error('[Voyage] Only image files are allowed');\n return null;\n }\n\n if (file.size > 5 * 1024 * 1024) {\n console.error('[Voyage] Image must be under 5MB');\n return null;\n }\n\n try {\n const formData = new FormData();\n formData.append('file', file);\n\n const response = await fetch(`${API_BASE}/upload-feedback-image`, {\n method: 'POST',\n headers: {\n 'x-sdk-key': sdkKey,\n },\n body: formData,\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error('[Voyage] Failed to upload image:', response.status, errorData);\n return null;\n }\n\n const result = await response.json();\n return result.url;\n } catch (error) {\n console.error('[Voyage] Network error:', error);\n return null;\n }\n}\n\nfunction getFromCache(sdkKey: string, ignoreExpiry = false): ProjectConfig | null {\n try {\n const raw = localStorage.getItem(`${CACHE_KEY}_${sdkKey}`);\n if (!raw) return null;\n\n const cached: CachedConfig = JSON.parse(raw);\n const isExpired = Date.now() - cached.timestamp > CACHE_TTL;\n\n if (isExpired && !ignoreExpiry) {\n return null;\n }\n\n return cached.config;\n } catch {\n return null;\n }\n}\n\nfunction saveToCache(sdkKey: string, config: ProjectConfig): void {\n try {\n const cached: CachedConfig = {\n config,\n timestamp: Date.now(),\n };\n localStorage.setItem(`${CACHE_KEY}_${sdkKey}`, JSON.stringify(cached));\n } catch {\n // localStorage 사용 불가 시 무시\n }\n}\n","import type { FeedbackMetadata } from '../types';\n\nexport function captureMetadata(): FeedbackMetadata {\n return {\n url: window.location.href,\n pathname: window.location.pathname,\n browser: navigator.userAgent,\n viewport: `${window.innerWidth}x${window.innerHeight}`,\n title: document.title,\n timestamp: new Date().toISOString(),\n locale: navigator.language,\n referrer: document.referrer,\n };\n}\n","// @voyage/sdk\n// Feedback Widget SDK for collecting user feedback\n\nimport { h, render } from 'preact';\n\nimport { Widget } from './components';\nimport { injectStyles } from './styles';\nimport { fetchProjectConfig, submitFeedback, uploadImage } from './utils/api';\nimport { captureMetadata } from './utils/metadata';\n\nimport type { VoyageConfig, ProjectConfig, FeedbackData } from './types';\n\nexport type { VoyageConfig, ProjectConfig, FeedbackData, FeedbackMetadata } from './types';\n\nconst DEFAULT_CONFIG: ProjectConfig = {\n projectId: '',\n formFields: {\n email: { enabled: true, required: false },\n category: { enabled: true, options: ['bug', 'feature'] },\n },\n theme: {\n primaryColor: '#0ea5e9',\n position: 'bottom-right',\n },\n i18n: {\n buttonLabel: 'To : the Maker',\n placeholder: 'Describe your ideas to improve our product',\n bugPlaceholder: 'Please describe the bug in detail (e.g., clicked a button and it didn\\'t work)',\n featurePlaceholder: 'Describe your ideas to improve our product (e.g., I want to export TASK.md to Linear tickets)',\n submitLabel: 'Send to the Maker',\n successMessage: 'Thank you for your feedback!',\n },\n};\n\nclass VoyageSDK {\n private config: VoyageConfig | null = null;\n private serverConfig: ProjectConfig | null = null;\n private container: HTMLElement | null = null;\n private isWidgetVisible = false;\n private isModalOpen = false;\n\n async init(config: VoyageConfig): Promise<void> {\n this.config = config;\n\n if (!config.sdkKey) {\n console.error('[Voyage] Invalid SDK Key');\n return;\n }\n\n // Inject SDK styles\n injectStyles();\n\n // Check display control\n if (!this.shouldDisplay()) {\n console.log('[Voyage] Widget hidden by display rules');\n return;\n }\n\n // Fetch server config\n const fetchedConfig = await fetchProjectConfig(config.sdkKey);\n this.serverConfig = this.mergeConfig(fetchedConfig, config);\n\n // Render widget\n this.isWidgetVisible = true;\n this.renderWidget();\n console.log('[Voyage] Initialized');\n }\n\n show(): void {\n if (!this.config) {\n console.warn('[Voyage] SDK not initialized');\n return;\n }\n this.isWidgetVisible = true;\n this.renderWidget();\n }\n\n hide(): void {\n this.isWidgetVisible = false;\n this.renderWidget();\n }\n\n open(): void {\n if (!this.config) {\n console.warn('[Voyage] SDK not initialized');\n return;\n }\n this.isModalOpen = true;\n this.renderWidget();\n }\n\n close(): void {\n this.isModalOpen = false;\n this.renderWidget();\n }\n\n isOpen(): boolean {\n return this.isModalOpen;\n }\n\n isVisible(): boolean {\n return this.isWidgetVisible;\n }\n\n async refreshConfig(): Promise<void> {\n if (!this.config) return;\n const fetchedConfig = await fetchProjectConfig(this.config.sdkKey);\n this.serverConfig = this.mergeConfig(fetchedConfig, this.config);\n this.renderWidget();\n }\n\n destroy(): void {\n if (this.container) {\n render(null, this.container);\n this.container.remove();\n this.container = null;\n }\n this.config = null;\n this.serverConfig = null;\n this.isWidgetVisible = false;\n this.isModalOpen = false;\n }\n\n private renderWidget(): void {\n if (!this.serverConfig || !this.config) return;\n\n // Create container if not exists\n if (!this.container) {\n this.container = document.createElement('div');\n this.container.id = 'voyage-widget-container';\n document.body.appendChild(this.container);\n }\n\n const sdkKey = this.config.sdkKey;\n\n render(\n h(Widget, {\n config: this.serverConfig,\n visible: this.isWidgetVisible,\n defaultOpen: this.isModalOpen,\n onOpenChange: (open: boolean) => {\n this.isModalOpen = open;\n },\n getMetadata: captureMetadata,\n onSubmit: async (data: FeedbackData) => {\n return submitFeedback(sdkKey, data);\n },\n onUpload: async (file: File) => {\n return uploadImage(sdkKey, file);\n },\n }),\n this.container\n );\n }\n\n private mergeConfig(server: ProjectConfig | null, _client: VoyageConfig): ProjectConfig {\n // Server config takes priority: use values set from dashboard\n // Client-side theme override disabled (to prevent config conflicts)\n return server || { ...DEFAULT_CONFIG };\n }\n\n private shouldDisplay(): boolean {\n if (!this.config) return false;\n\n const pathname = window.location.pathname;\n const { include, exclude } = this.config;\n\n // include takes priority over exclude\n if (include && include.length > 0) {\n return include.some((pattern) => this.matchPath(pathname, pattern));\n }\n\n if (exclude && exclude.length > 0) {\n return !exclude.some((pattern) => this.matchPath(pathname, pattern));\n }\n\n return true;\n }\n\n private matchPath(pathname: string, pattern: string): boolean {\n // Simple glob matching: /admin/* matches /admin/anything\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2);\n return pathname.startsWith(prefix);\n }\n return pathname === pattern;\n }\n}\n\n// Singleton instance\nconst Voyage = new VoyageSDK();\n\nexport { Voyage };\nexport default Voyage;\n"]}
1
+ {"version":3,"sources":["../src/components/Button.tsx","../src/components/Modal.tsx","../src/components/Widget.tsx","../src/styles.ts","../src/utils/api.ts","../src/utils/metadata.ts","../src/index.ts"],"names":["MessageIcon","jsx","Button","onClick","label","position","primaryColor","hasError","isHovered","setIsHovered","useState","isPressed","setIsPressed","positionStyle","getTransform","jsxs","size","BugIcon","LightbulbIcon","ImageIcon","CloseIcon","CheckIcon","colors","Modal","config","metadata","onClose","onSubmit","onUpload","setLabel","text","setText","email","setEmail","imageUrl","setImageUrl","imagePreview","setImagePreview","isSubmitting","setIsSubmitting","isUploading","setIsUploading","error","setError","success","setSuccess","fileInputRef","useRef","i18n","formFields","theme","maxLength","currentPlaceholder","handleFileSelect","e","file","processedFile","processImage","reader","url","err","handleRemoveImage","handleSubmit","feedbackData","result","styles","primaryBgLight","active","disabled","successContainerStyle","successIconStyle","successTitleStyle","successTextStyle","headerLeftStyle","headerTitleStyle","closeButtonStyle","contentStyle","sectionStyle","labelStyle","typeButtonsStyle","typeIconStyle","descriptionRowStyle","descriptionColStyle","textareaWrapperStyle","textareaStyle","charCountStyle","uploadColStyle","imagePreviewContainerStyle","imagePreviewSquareStyle","removeImageButtonStyle","uploadingOverlayStyle","uploadButtonSquareStyle","inputStyle","errorStyle","spinnerContainerStyle","options","maxWidth","maxHeight","quality","resolve","reject","img","width","height","ratio","canvas","ctx","blob","timestamp","newFile","type","Widget","getMetadata","visible","defaultOpen","onOpenChange","isOpen","setIsOpen","useEffect","Fragment","injectStyles","style","API_BASE","CACHE_KEY","fetchProjectConfig","sdkKey","cached","getFromCache","response","saveToCache","submitFeedback","data","errorData","uploadImage","formData","ignoreExpiry","raw","captureMetadata","DEFAULT_CONFIG","VoyageSDK","fetchedConfig","render","h","open","server","_client","pathname","include","exclude","pattern","prefix","Voyage","index_default"],"mappings":"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","file":"index.cjs","sourcesContent":["import { h } from 'preact';\nimport { useState } from 'preact/hooks';\n\ninterface ButtonProps {\n onClick: () => void;\n label: string;\n position: 'bottom-right' | 'bottom-left';\n primaryColor: string;\n hasError?: boolean;\n}\n\n// 말풍선 아이콘 SVG\nfunction MessageIcon() {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n );\n}\n\n// 에러 아이콘 (느낌표)\nfunction ErrorIcon() {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"#fff\"\n stroke=\"none\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"#EF4444\" />\n <text x=\"12\" y=\"17\" textAnchor=\"middle\" fill=\"#fff\" fontSize=\"14\" fontWeight=\"bold\">!</text>\n </svg>\n );\n}\n\nexport function Button({ onClick, label, position, primaryColor, hasError = false }: ButtonProps) {\n const [isHovered, setIsHovered] = useState(false);\n const [isPressed, setIsPressed] = useState(false);\n\n const positionStyle = position === 'bottom-right'\n ? { right: '24px' }\n : { left: '24px' };\n\n // Jelly 효과 transform\n const getTransform = () => {\n if (isPressed) return 'scale(0.95)';\n if (isHovered) return 'scale(1.02) translateY(-2px)';\n return 'scale(1)';\n };\n\n return (\n <div style={{ position: 'fixed', bottom: '24px', ...positionStyle, zIndex: 9998 }}>\n <button\n onClick={onClick}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => { setIsHovered(false); setIsPressed(false); }}\n onMouseDown={() => setIsPressed(true)}\n onMouseUp={() => setIsPressed(false)}\n style={{\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n padding: '14px 24px',\n border: 'none',\n borderRadius: '50px',\n cursor: 'pointer',\n fontFamily: \"'Quicksand', 'Nunito', system-ui, sans-serif\",\n fontSize: '15px',\n fontWeight: 600,\n color: '#fff',\n // primaryColor 적용\n backgroundColor: primaryColor,\n // 그림자 + glow 효과\n boxShadow: isHovered\n ? `0 8px 32px ${primaryColor}60, 0 0 20px ${primaryColor}40`\n : `0 4px 20px ${primaryColor}50, 0 0 10px ${primaryColor}30`,\n // Jelly 애니메이션\n transform: getTransform(),\n transition: 'all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1)',\n }}\n >\n <MessageIcon />\n <span>{label}</span>\n </button>\n {/* 에러 아이콘 - 우측 상단 */}\n {hasError && (\n <div\n style={{\n position: 'absolute',\n top: '-4px',\n right: '-4px',\n width: '18px',\n height: '18px',\n borderRadius: '50%',\n backgroundColor: '#EF4444',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n fontSize: '12px',\n fontWeight: 'bold',\n boxShadow: '0 2px 6px rgba(239, 68, 68, 0.5)',\n }}\n >\n !\n </div>\n )}\n </div>\n );\n}\n","import { h } from 'preact';\nimport { useRef, useState } from 'preact/hooks';\n\nimport type { ProjectConfig, FeedbackData, FeedbackMetadata } from '../types';\n\ninterface ModalProps {\n config: ProjectConfig;\n metadata: FeedbackMetadata;\n onClose: () => void;\n onSubmit: (data: FeedbackData) => Promise<boolean>;\n onUpload: (file: File) => Promise<string | null>;\n}\n\n// 아이콘들\nfunction MessageIcon({ size = 24 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n );\n}\n\nfunction BugIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M8 2l1.88 1.88M14.12 3.88L16 2M9 7.13v-1a3.003 3.003 0 116 0v1\" />\n <path d=\"M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 014-4h4a4 4 0 014 4v3c0 3.3-2.7 6-6 6\" />\n <path d=\"M12 20v-9M6.53 9C4.6 8.8 3 7.1 3 5M6 13H2M6 17l-4 1M17.47 9c1.93-.2 3.53-1.9 3.53-4M18 13h4M18 17l4 1\" />\n </svg>\n );\n}\n\nfunction LightbulbIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 006 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\" />\n <path d=\"M9 18h6M10 22h4\" />\n </svg>\n );\n}\n\nfunction ImageIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" />\n <polyline points=\"21 15 16 10 5 21\" />\n </svg>\n );\n}\n\nfunction CloseIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n\nfunction CheckIcon() {\n return (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n );\n}\n\n// 라이트 테마 색상\nconst colors = {\n bg: '#FFFFFF',\n bgLight: '#F8FAFC',\n bgCard: 'rgba(255, 255, 255, 0.98)',\n border: 'rgba(0, 0, 0, 0.08)',\n borderLight: 'rgba(0, 0, 0, 0.12)',\n text: '#1F2937',\n textMuted: '#6B7280',\n error: '#EF4444',\n success: '#22C55E',\n};\n\nexport function Modal({ config, metadata, onClose, onSubmit, onUpload }: ModalProps) {\n const [label, setLabel] = useState<'bug' | 'feature' | null>(null);\n const [text, setText] = useState('');\n const [email, setEmail] = useState('');\n const [imageUrl, setImageUrl] = useState<string | null>(null);\n const [imagePreview, setImagePreview] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isUploading, setIsUploading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [success, setSuccess] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const { i18n, formFields, theme } = config;\n const primaryColor = theme.primaryColor || '#0ea5e9';\n const maxLength = 400;\n\n // 동적 placeholder\n const currentPlaceholder = label === 'bug'\n ? (i18n.bugPlaceholder || i18n.placeholder)\n : (i18n.featurePlaceholder || i18n.placeholder);\n\n const handleFileSelect = async (e: Event) => {\n const target = e.target as HTMLInputElement;\n const file = target.files?.[0];\n if (!file) return;\n\n if (!file.type.startsWith('image/')) {\n setError('Only image files are allowed');\n return;\n }\n if (file.size > 10 * 1024 * 1024) {\n setError('Image must be under 10MB');\n return;\n }\n\n setIsUploading(true);\n setError(null);\n\n try {\n // 이미지를 WebP로 변환 및 resize\n const processedFile = await processImage(file, {\n maxWidth: 1920,\n maxHeight: 1080,\n quality: 0.8,\n });\n\n // 프리뷰 생성\n const reader = new FileReader();\n reader.onload = () => setImagePreview(reader.result as string);\n reader.readAsDataURL(processedFile);\n\n const url = await onUpload(processedFile);\n setIsUploading(false);\n\n if (url) {\n setImageUrl(url);\n } else {\n setError('Failed to upload image');\n setImagePreview(null);\n }\n } catch (err) {\n console.error('[Voyage] Image processing error:', err);\n setIsUploading(false);\n setError('Failed to process image');\n }\n };\n\n const handleRemoveImage = () => {\n setImageUrl(null);\n setImagePreview(null);\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n };\n\n const handleSubmit = async () => {\n if (!label) {\n setError('Please select a type');\n return;\n }\n if (!text.trim()) {\n setError('Please enter your feedback');\n return;\n }\n if (formFields.email.required && !email.trim()) {\n setError('Please enter your email');\n return;\n }\n\n setIsSubmitting(true);\n setError(null);\n\n const feedbackData: FeedbackData = {\n label,\n text: text.trim(),\n email: email.trim() || undefined,\n imageUrl: imageUrl || undefined,\n metadata,\n };\n\n const result = await onSubmit(feedbackData);\n setIsSubmitting(false);\n\n if (result) {\n setSuccess(true);\n } else {\n setError('Failed to submit. Please try again.');\n }\n };\n\n // 스타일 함수 (primaryColor 적용)\n const getStyles = () => {\n const primaryBgLight = `${primaryColor}15`;\n\n return {\n overlay: {\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.4)',\n backdropFilter: 'blur(4px)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 9999,\n padding: '20px',\n } as h.JSX.CSSProperties,\n\n modal: {\n backgroundColor: colors.bgCard,\n backdropFilter: 'blur(20px)',\n borderRadius: '20px',\n width: '100%',\n maxWidth: '580px',\n maxHeight: '90vh',\n overflowY: 'auto',\n position: 'relative',\n fontFamily: \"'Quicksand', 'Nunito', system-ui, sans-serif\",\n border: `1px solid ${colors.border}`,\n boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.15)',\n } as h.JSX.CSSProperties,\n\n colorBar: {\n height: '4px',\n backgroundColor: primaryColor,\n } as h.JSX.CSSProperties,\n\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '14px 20px',\n borderBottom: `1px solid ${colors.border}`,\n backgroundColor: colors.bgLight,\n } as h.JSX.CSSProperties,\n\n headerIcon: {\n width: '32px',\n height: '32px',\n borderRadius: '10px',\n backgroundColor: primaryColor,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n } as h.JSX.CSSProperties,\n\n typeButton: (active: boolean) => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '6px',\n padding: '10px 12px',\n border: active ? `2px solid ${primaryColor}` : `1px solid ${colors.border}`,\n borderRadius: '10px',\n backgroundColor: active ? primaryBgLight : colors.bgLight,\n cursor: 'pointer',\n fontWeight: 600,\n fontSize: '13px',\n color: active ? colors.text : colors.textMuted,\n transition: 'all 0.2s',\n } as h.JSX.CSSProperties),\n\n submitButton: (disabled: boolean) => ({\n width: '100%',\n padding: '12px',\n backgroundColor: disabled ? colors.bgLight : primaryColor,\n color: disabled ? colors.textMuted : '#fff',\n border: 'none',\n borderRadius: '12px',\n fontSize: '15px',\n fontWeight: 700,\n cursor: disabled ? 'not-allowed' : 'pointer',\n fontFamily: 'inherit',\n transition: 'all 0.2s',\n boxShadow: disabled ? 'none' : `0 4px 15px ${primaryColor}40`,\n } as h.JSX.CSSProperties),\n\n primaryButton: {\n width: '100%',\n padding: '16px',\n backgroundColor: primaryColor,\n color: '#fff',\n border: 'none',\n borderRadius: '12px',\n fontSize: '15px',\n fontWeight: 700,\n cursor: 'pointer',\n fontFamily: 'inherit',\n marginTop: '8px',\n } as h.JSX.CSSProperties,\n };\n };\n\n const styles = getStyles();\n\n // 성공 화면\n if (success) {\n return (\n <div style={styles.overlay}>\n <div style={styles.modal}>\n <div style={successContainerStyle}>\n <div style={successIconStyle}>\n <CheckIcon />\n </div>\n <h3 style={successTitleStyle}>{i18n.successMessage}</h3>\n <p style={successTextStyle}>Your voice shapes what we build next.</p>\n <button onClick={onClose} style={styles.primaryButton}>\n Done\n </button>\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div style={styles.overlay} onClick={onClose}>\n <div style={styles.modal} onClick={(e) => e.stopPropagation()}>\n {/* 헤더 */}\n <div style={styles.header}>\n <div style={headerLeftStyle}>\n <div style={styles.headerIcon}>\n <MessageIcon size={20} />\n </div>\n <span style={headerTitleStyle}>Help Us Improve</span>\n </div>\n <button onClick={onClose} style={closeButtonStyle}>\n <CloseIcon />\n </button>\n </div>\n\n {/* 컬러 바 */}\n <div style={styles.colorBar} />\n\n {/* 컨텐츠 */}\n <div style={contentStyle}>\n {/* 이슈 타입 */}\n <div style={sectionStyle}>\n <label style={labelStyle}>Feedback Type</label>\n <div style={typeButtonsStyle}>\n <button\n onClick={() => setLabel('bug')}\n style={styles.typeButton(label === 'bug')}\n >\n <span style={typeIconStyle(label === 'bug', 'bug')}>\n <BugIcon />\n </span>\n <span>Bug</span>\n </button>\n <button\n onClick={() => setLabel('feature')}\n style={styles.typeButton(label === 'feature')}\n >\n <span style={typeIconStyle(label === 'feature', 'feature')}>\n <LightbulbIcon />\n </span>\n <span>Feature</span>\n </button>\n </div>\n </div>\n\n {/* 설명 + 이미지 (flex row) */}\n <div style={descriptionRowStyle}>\n {/* 텍스트 영역 */}\n <div style={descriptionColStyle}>\n <label style={labelStyle}>Description</label>\n <div style={textareaWrapperStyle}>\n <textarea\n placeholder={currentPlaceholder}\n value={text}\n maxLength={maxLength}\n onInput={(e) => setText((e.target as HTMLTextAreaElement).value)}\n style={textareaStyle}\n />\n <span style={charCountStyle}>{text.length}/{maxLength}</span>\n </div>\n </div>\n\n {/* 이미지 업로드 (정사각형) */}\n <div style={uploadColStyle}>\n <label style={labelStyle}>Screenshot</label>\n {imagePreview ? (\n <div style={imagePreviewContainerStyle}>\n <img src={imagePreview} alt=\"Preview\" style={imagePreviewSquareStyle} />\n <button onClick={handleRemoveImage} style={removeImageButtonStyle}>\n <CloseIcon />\n </button>\n {isUploading && <div style={uploadingOverlayStyle}>...</div>}\n </div>\n ) : (\n <button\n onClick={() => fileInputRef.current?.click()}\n style={uploadButtonSquareStyle}\n >\n <ImageIcon />\n <span style={{ fontSize: '11px' }}>Upload</span>\n </button>\n )}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileSelect}\n style={{ display: 'none' }}\n />\n </div>\n </div>\n\n {/* 이메일 */}\n {formFields.email.enabled && (\n <div style={sectionStyle}>\n <label style={labelStyle}>\n Email {formFields.email.required ? '' : '(optional)'}\n </label>\n <input\n type=\"email\"\n placeholder=\"your@email.com\"\n value={email}\n onInput={(e) => setEmail((e.target as HTMLInputElement).value)}\n style={inputStyle}\n />\n </div>\n )}\n\n {/* 에러 */}\n {error && <p style={errorStyle}>{error}</p>}\n\n {/* 제출 버튼 */}\n <button\n onClick={handleSubmit}\n disabled={isSubmitting || isUploading}\n style={styles.submitButton(isSubmitting || isUploading)}\n >\n {isSubmitting ? (\n <span style={spinnerContainerStyle}>\n <span className=\"voyage-spinner\" />\n Sending...\n </span>\n ) : (\n i18n.submitLabel\n )}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n// 이미지 처리 유틸: resize + WebP 변환\ninterface ProcessImageOptions {\n maxWidth: number;\n maxHeight: number;\n quality: number;\n}\n\nasync function processImage(file: File, options: ProcessImageOptions): Promise<File> {\n const { maxWidth, maxHeight, quality } = options;\n\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n // 비율 유지하면서 resize 계산\n let { width, height } = img;\n\n if (width > maxWidth || height > maxHeight) {\n const ratio = Math.min(maxWidth / width, maxHeight / height);\n width = Math.round(width * ratio);\n height = Math.round(height * ratio);\n }\n\n // Canvas에 그리기\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n reject(new Error('Failed to get canvas context'));\n return;\n }\n\n ctx.drawImage(img, 0, 0, width, height);\n\n // WebP로 변환\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new Error('Failed to convert image'));\n return;\n }\n\n // Blob을 File로 변환\n const timestamp = Date.now();\n const newFile = new File([blob], `image_${timestamp}.webp`, {\n type: 'image/webp',\n });\n\n resolve(newFile);\n },\n 'image/webp',\n quality\n );\n };\n\n img.onerror = () => reject(new Error('Failed to load image'));\n img.src = URL.createObjectURL(file);\n });\n}\n\n// 정적 스타일 정의 (라이트 테마)\nconst headerLeftStyle: h.JSX.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n};\n\nconst headerTitleStyle: h.JSX.CSSProperties = {\n fontSize: '16px',\n fontWeight: 700,\n color: colors.text,\n};\n\nconst closeButtonStyle: h.JSX.CSSProperties = {\n background: 'transparent',\n border: 'none',\n color: colors.textMuted,\n cursor: 'pointer',\n padding: '8px',\n borderRadius: '8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'all 0.2s',\n};\n\nconst contentStyle: h.JSX.CSSProperties = {\n padding: '16px 20px',\n};\n\nconst sectionStyle: h.JSX.CSSProperties = {\n marginBottom: '14px',\n};\n\nconst labelStyle: h.JSX.CSSProperties = {\n display: 'block',\n fontSize: '13px',\n fontWeight: 600,\n color: colors.text,\n marginBottom: '8px',\n};\n\nconst typeButtonsStyle: h.JSX.CSSProperties = {\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: '12px',\n};\n\nconst descriptionRowStyle: h.JSX.CSSProperties = {\n display: 'flex',\n gap: '14px',\n marginBottom: '14px',\n};\n\nconst descriptionColStyle: h.JSX.CSSProperties = {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n};\n\nconst uploadColStyle: h.JSX.CSSProperties = {\n width: '120px',\n flexShrink: 0,\n display: 'flex',\n flexDirection: 'column',\n};\n\nconst uploadButtonSquareStyle: h.JSX.CSSProperties = {\n width: '100%',\n aspectRatio: '1',\n border: `2px dashed ${colors.border}`,\n borderRadius: '10px',\n backgroundColor: 'transparent',\n cursor: 'pointer',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '4px',\n color: colors.textMuted,\n fontSize: '12px',\n transition: 'all 0.2s',\n};\n\nconst imagePreviewSquareStyle: h.JSX.CSSProperties = {\n width: '100%',\n aspectRatio: '1',\n objectFit: 'cover',\n borderRadius: '10px',\n};\n\nconst typeIconStyle = (active: boolean, type: 'bug' | 'feature'): h.JSX.CSSProperties => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: active\n ? (type === 'bug' ? colors.error : '#F59E0B')\n : colors.textMuted,\n});\n\nconst textareaWrapperStyle: h.JSX.CSSProperties = {\n position: 'relative',\n};\n\nconst textareaStyle: h.JSX.CSSProperties = {\n width: '100%',\n minHeight: '120px',\n padding: '14px',\n border: `1px solid ${colors.border}`,\n borderRadius: '12px',\n fontSize: '14px',\n resize: 'vertical',\n boxSizing: 'border-box',\n backgroundColor: colors.bgLight,\n color: colors.text,\n fontFamily: 'inherit',\n outline: 'none',\n};\n\nconst charCountStyle: h.JSX.CSSProperties = {\n position: 'absolute',\n bottom: '12px',\n right: '14px',\n fontSize: '12px',\n color: colors.textMuted,\n};\n\nconst inputStyle: h.JSX.CSSProperties = {\n width: '100%',\n padding: '10px 12px',\n border: `1px solid ${colors.border}`,\n borderRadius: '10px',\n fontSize: '13px',\n boxSizing: 'border-box',\n backgroundColor: colors.bgLight,\n color: colors.text,\n fontFamily: 'inherit',\n outline: 'none',\n};\n\nconst imagePreviewContainerStyle: h.JSX.CSSProperties = {\n position: 'relative',\n display: 'inline-block',\n borderRadius: '12px',\n overflow: 'hidden',\n};\n\nconst removeImageButtonStyle: h.JSX.CSSProperties = {\n position: 'absolute',\n top: '8px',\n right: '8px',\n width: '28px',\n height: '28px',\n borderRadius: '50%',\n backgroundColor: 'rgba(0, 0, 0, 0.7)',\n color: '#fff',\n border: 'none',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n};\n\nconst uploadingOverlayStyle: h.JSX.CSSProperties = {\n position: 'absolute',\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.7)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n fontSize: '14px',\n borderRadius: '12px',\n};\n\nconst errorStyle: h.JSX.CSSProperties = {\n color: colors.error,\n fontSize: '14px',\n marginBottom: '16px',\n padding: '12px',\n backgroundColor: 'rgba(239, 68, 68, 0.1)',\n borderRadius: '8px',\n border: `1px solid rgba(239, 68, 68, 0.3)`,\n};\n\nconst successContainerStyle: h.JSX.CSSProperties = {\n padding: '48px 24px',\n textAlign: 'center',\n};\n\nconst successIconStyle: h.JSX.CSSProperties = {\n width: '64px',\n height: '64px',\n borderRadius: '50%',\n backgroundColor: 'rgba(34, 197, 94, 0.15)',\n color: colors.success,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: '0 auto 20px',\n};\n\nconst successTitleStyle: h.JSX.CSSProperties = {\n fontSize: '20px',\n fontWeight: 700,\n color: colors.text,\n marginBottom: '8px',\n};\n\nconst successTextStyle: h.JSX.CSSProperties = {\n fontSize: '14px',\n color: colors.textMuted,\n marginBottom: '24px',\n};\n\nconst spinnerContainerStyle: h.JSX.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n};\n","import { h } from 'preact';\nimport { useState, useEffect } from 'preact/hooks';\nimport { Button } from './Button';\nimport { Modal } from './Modal';\nimport type { ProjectConfig, FeedbackData, FeedbackMetadata } from '../types';\n\ninterface WidgetProps {\n config: ProjectConfig;\n onSubmit: (data: FeedbackData) => Promise<boolean>;\n onUpload: (file: File) => Promise<string | null>;\n getMetadata: () => FeedbackMetadata;\n visible: boolean;\n defaultOpen?: boolean;\n hasError?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nexport function Widget({\n config,\n onSubmit,\n onUpload,\n getMetadata,\n visible,\n defaultOpen = false,\n hasError = false,\n onOpenChange,\n}: WidgetProps) {\n const [isOpen, setIsOpen] = useState(defaultOpen);\n\n // SDK에서 open()/close() 호출 시 동기화\n useEffect(() => {\n setIsOpen(defaultOpen);\n }, [defaultOpen]);\n\n useEffect(() => {\n onOpenChange?.(isOpen);\n }, [isOpen, onOpenChange]);\n\n if (!visible) {\n return null;\n }\n\n const { theme, i18n } = config;\n\n return (\n <>\n {!isOpen && (\n <Button\n onClick={() => setIsOpen(true)}\n label={i18n.buttonLabel}\n position={theme.position}\n primaryColor={theme.primaryColor}\n hasError={hasError}\n />\n )}\n\n {isOpen && (\n <Modal\n config={config}\n metadata={getMetadata()}\n onClose={() => setIsOpen(false)}\n onSubmit={onSubmit}\n onUpload={onUpload}\n />\n )}\n </>\n );\n}\n","// SDK 전용 CSS 스타일 (동적 주입)\nexport const injectStyles = () => {\n if (typeof document === 'undefined') return;\n if (document.getElementById('voyage-sdk-styles')) return;\n\n const style = document.createElement('style');\n style.id = 'voyage-sdk-styles';\n style.textContent = `\n /* Voyage SDK Styles */\n\n /* Spinner Animation */\n @keyframes voyage-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n #voyage-widget-container * {\n box-sizing: border-box;\n }\n\n #voyage-widget-container button {\n font-family: 'Quicksand', 'Nunito', system-ui, sans-serif;\n }\n\n #voyage-widget-container textarea:focus,\n #voyage-widget-container input:focus {\n border-color: rgba(124, 58, 237, 0.5);\n box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.1);\n }\n\n #voyage-widget-container button:focus {\n outline: none;\n }\n\n /* Spinner */\n .voyage-spinner {\n width: 16px;\n height: 16px;\n border: 2px solid rgba(255,255,255,0.3);\n border-top-color: #fff;\n border-radius: 50%;\n animation: voyage-spin 0.8s linear infinite;\n }\n\n /* Load Quicksand font if not present */\n @import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@400;500;600;700&display=swap');\n `;\n\n document.head.appendChild(style);\n};\n","import type { ProjectConfig, FeedbackData } from '../types';\n\n// Supabase Edge Functions URL\nconst API_BASE = 'https://rxflzurkkuqgopjkshjh.supabase.co/functions/v1';\n\nconst CACHE_KEY = 'voyage_config';\nconst CACHE_TTL = 60 * 60 * 1000; // 1시간\n\ninterface CachedConfig {\n config: ProjectConfig;\n timestamp: number;\n}\n\nexport async function fetchProjectConfig(sdkKey: string): Promise<ProjectConfig | null> {\n // 캐시 확인\n const cached = getFromCache(sdkKey);\n if (cached) {\n return cached;\n }\n\n try {\n const response = await fetch(`${API_BASE}/get-widget-config`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'x-sdk-key': sdkKey,\n },\n });\n\n if (!response.ok) {\n console.error('[Voyage] Failed to fetch config:', response.status);\n return null;\n }\n\n const config = await response.json() as ProjectConfig;\n saveToCache(sdkKey, config);\n return config;\n } catch (error) {\n console.error('[Voyage] Network error:', error);\n // 네트워크 실패 시 캐시 사용 (만료되어도)\n return getFromCache(sdkKey, true);\n }\n}\n\nexport async function submitFeedback(sdkKey: string, data: FeedbackData): Promise<boolean> {\n try {\n const response = await fetch(`${API_BASE}/submit-feedback`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-sdk-key': sdkKey,\n },\n body: JSON.stringify({\n label: data.label,\n content: data.text,\n email: data.email,\n imageUrl: data.imageUrl,\n metadata: data.metadata,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error('[Voyage] Failed to submit feedback:', response.status, errorData);\n return false;\n }\n\n return true;\n } catch (error) {\n console.error('[Voyage] Network error:', error);\n return false;\n }\n}\n\nexport async function uploadImage(sdkKey: string, file: File): Promise<string | null> {\n // 검증\n if (!file.type.startsWith('image/')) {\n console.error('[Voyage] Only image files are allowed');\n return null;\n }\n\n if (file.size > 5 * 1024 * 1024) {\n console.error('[Voyage] Image must be under 5MB');\n return null;\n }\n\n try {\n const formData = new FormData();\n formData.append('file', file);\n\n const response = await fetch(`${API_BASE}/upload-feedback-image`, {\n method: 'POST',\n headers: {\n 'x-sdk-key': sdkKey,\n },\n body: formData,\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error('[Voyage] Failed to upload image:', response.status, errorData);\n return null;\n }\n\n const result = await response.json();\n return result.url;\n } catch (error) {\n console.error('[Voyage] Network error:', error);\n return null;\n }\n}\n\nfunction getFromCache(sdkKey: string, ignoreExpiry = false): ProjectConfig | null {\n try {\n const raw = localStorage.getItem(`${CACHE_KEY}_${sdkKey}`);\n if (!raw) return null;\n\n const cached: CachedConfig = JSON.parse(raw);\n const isExpired = Date.now() - cached.timestamp > CACHE_TTL;\n\n if (isExpired && !ignoreExpiry) {\n return null;\n }\n\n return cached.config;\n } catch {\n return null;\n }\n}\n\nfunction saveToCache(sdkKey: string, config: ProjectConfig): void {\n try {\n const cached: CachedConfig = {\n config,\n timestamp: Date.now(),\n };\n localStorage.setItem(`${CACHE_KEY}_${sdkKey}`, JSON.stringify(cached));\n } catch {\n // localStorage 사용 불가 시 무시\n }\n}\n","import type { FeedbackMetadata } from '../types';\n\nexport function captureMetadata(): FeedbackMetadata {\n return {\n url: window.location.href,\n pathname: window.location.pathname,\n browser: navigator.userAgent,\n viewport: `${window.innerWidth}x${window.innerHeight}`,\n title: document.title,\n timestamp: new Date().toISOString(),\n locale: navigator.language,\n referrer: document.referrer,\n };\n}\n","// @voyage/sdk\n// Feedback Widget SDK for collecting user feedback\n\nimport { h, render } from 'preact';\n\nimport { Widget } from './components';\nimport { injectStyles } from './styles';\nimport { fetchProjectConfig, submitFeedback, uploadImage } from './utils/api';\nimport { captureMetadata } from './utils/metadata';\n\nimport type { VoyageConfig, ProjectConfig, FeedbackData } from './types';\n\nexport type { VoyageConfig, ProjectConfig, FeedbackData, FeedbackMetadata } from './types';\n\nconst DEFAULT_CONFIG: ProjectConfig = {\n projectId: '',\n formFields: {\n email: { enabled: true, required: false },\n category: { enabled: true, options: ['bug', 'feature'] },\n },\n theme: {\n primaryColor: '#0ea5e9',\n position: 'bottom-right',\n },\n i18n: {\n buttonLabel: 'To : the Maker',\n placeholder: 'Describe your ideas to improve our product',\n bugPlaceholder: 'Please describe the bug in detail (e.g., clicked a button and it didn\\'t work)',\n featurePlaceholder: 'Describe your ideas to improve our product (e.g., I want to export TASK.md to Linear tickets)',\n submitLabel: 'Send to the Maker',\n successMessage: 'Thank you for your feedback!',\n },\n};\n\nclass VoyageSDK {\n private config: VoyageConfig | null = null;\n private serverConfig: ProjectConfig | null = null;\n private container: HTMLElement | null = null;\n private isWidgetVisible = false;\n private isModalOpen = false;\n private hasInitError = false;\n\n async init(config: VoyageConfig): Promise<void> {\n this.config = config;\n this.hasInitError = false;\n\n if (!config.sdkKey) {\n console.error('[Voyage] SDK Key is required. Get your key from the dashboard.');\n this.hasInitError = true;\n injectStyles();\n this.isWidgetVisible = true;\n this.serverConfig = { ...DEFAULT_CONFIG };\n this.renderWidget();\n return;\n }\n\n // Inject SDK styles\n injectStyles();\n\n // Check display control\n if (!this.shouldDisplay()) {\n console.log('[Voyage] Widget hidden by display rules');\n return;\n }\n\n // Fetch server config\n const fetchedConfig = await fetchProjectConfig(config.sdkKey);\n\n if (!fetchedConfig) {\n console.error('[Voyage] Failed to fetch config. Check your SDK Key or network connection.');\n this.hasInitError = true;\n this.serverConfig = { ...DEFAULT_CONFIG };\n this.isWidgetVisible = true;\n this.renderWidget();\n return;\n }\n\n this.serverConfig = this.mergeConfig(fetchedConfig, config);\n\n // Render widget\n this.isWidgetVisible = true;\n this.renderWidget();\n console.log('[Voyage] Initialized');\n }\n\n show(): void {\n if (!this.config) {\n console.warn('[Voyage] SDK not initialized');\n return;\n }\n this.isWidgetVisible = true;\n this.renderWidget();\n }\n\n hide(): void {\n this.isWidgetVisible = false;\n this.renderWidget();\n }\n\n open(): void {\n if (!this.config) {\n console.warn('[Voyage] SDK not initialized');\n return;\n }\n this.isModalOpen = true;\n this.renderWidget();\n }\n\n close(): void {\n this.isModalOpen = false;\n this.renderWidget();\n }\n\n isOpen(): boolean {\n return this.isModalOpen;\n }\n\n isVisible(): boolean {\n return this.isWidgetVisible;\n }\n\n async refreshConfig(): Promise<void> {\n if (!this.config) return;\n const fetchedConfig = await fetchProjectConfig(this.config.sdkKey);\n this.serverConfig = this.mergeConfig(fetchedConfig, this.config);\n this.renderWidget();\n }\n\n destroy(): void {\n if (this.container) {\n render(null, this.container);\n this.container.remove();\n this.container = null;\n }\n this.config = null;\n this.serverConfig = null;\n this.isWidgetVisible = false;\n this.isModalOpen = false;\n }\n\n private renderWidget(): void {\n if (!this.serverConfig || !this.config) return;\n\n // Create container if not exists\n if (!this.container) {\n this.container = document.createElement('div');\n this.container.id = 'voyage-widget-container';\n document.body.appendChild(this.container);\n }\n\n const sdkKey = this.config.sdkKey;\n\n render(\n h(Widget, {\n config: this.serverConfig,\n visible: this.isWidgetVisible,\n defaultOpen: this.isModalOpen,\n hasError: this.hasInitError,\n onOpenChange: (open: boolean) => {\n this.isModalOpen = open;\n },\n getMetadata: captureMetadata,\n onSubmit: async (data: FeedbackData) => {\n return submitFeedback(sdkKey, data);\n },\n onUpload: async (file: File) => {\n return uploadImage(sdkKey, file);\n },\n }),\n this.container\n );\n }\n\n private mergeConfig(server: ProjectConfig | null, _client: VoyageConfig): ProjectConfig {\n // Server config takes priority: use values set from dashboard\n // Client-side theme override disabled (to prevent config conflicts)\n return server || { ...DEFAULT_CONFIG };\n }\n\n private shouldDisplay(): boolean {\n if (!this.config) return false;\n\n const pathname = window.location.pathname;\n const { include, exclude } = this.config;\n\n // include takes priority over exclude\n if (include && include.length > 0) {\n return include.some((pattern) => this.matchPath(pathname, pattern));\n }\n\n if (exclude && exclude.length > 0) {\n return !exclude.some((pattern) => this.matchPath(pathname, pattern));\n }\n\n return true;\n }\n\n private matchPath(pathname: string, pattern: string): boolean {\n // Simple glob matching: /admin/* matches /admin/anything\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2);\n return pathname.startsWith(prefix);\n }\n return pathname === pattern;\n }\n}\n\n// Singleton instance\nconst Voyage = new VoyageSDK();\n\nexport { Voyage };\nexport default Voyage;\n"]}
package/dist/index.d.cts CHANGED
@@ -54,6 +54,7 @@ declare class VoyageSDK {
54
54
  private container;
55
55
  private isWidgetVisible;
56
56
  private isModalOpen;
57
+ private hasInitError;
57
58
  init(config: VoyageConfig): Promise<void>;
58
59
  show(): void;
59
60
  hide(): void;
package/dist/index.d.ts CHANGED
@@ -54,6 +54,7 @@ declare class VoyageSDK {
54
54
  private container;
55
55
  private isWidgetVisible;
56
56
  private isModalOpen;
57
+ private hasInitError;
57
58
  init(config: VoyageConfig): Promise<void>;
58
59
  show(): void;
59
60
  hide(): void;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import {render,h}from'preact';import {useState,useEffect,useRef}from'preact/hooks';import {jsxs,Fragment,jsx}from'preact/jsx-runtime';function ce(){return jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsx("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"})})}function X({onClick:r,label:o,position:e,primaryColor:n}){let[c,l]=useState(false),[u,s]=useState(false),p=e==="bottom-right"?{right:"24px"}:{left:"24px"},d=()=>u?"scale(0.95)":c?"scale(1.02) translateY(-2px)":"scale(1)";return jsxs("button",{onClick:r,onMouseEnter:()=>l(true),onMouseLeave:()=>{l(false),s(false);},onMouseDown:()=>s(true),onMouseUp:()=>s(false),style:{position:"fixed",bottom:"24px",...p,display:"flex",alignItems:"center",gap:"10px",padding:"14px 24px",border:"none",borderRadius:"50px",cursor:"pointer",fontFamily:"'Quicksand', 'Nunito', system-ui, sans-serif",fontSize:"15px",fontWeight:600,color:"#fff",zIndex:9998,backgroundColor:n,boxShadow:c?`0 8px 32px ${n}60, 0 0 20px ${n}40`:`0 4px 20px ${n}50, 0 0 10px ${n}30`,transform:d(),transition:"all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1)"},children:[jsx(ce,{}),jsx("span",{children:o})]})}function ge({size:r=24}){return jsx("svg",{width:r,height:r,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsx("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"})})}function fe(){return jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("path",{d:"M8 2l1.88 1.88M14.12 3.88L16 2M9 7.13v-1a3.003 3.003 0 116 0v1"}),jsx("path",{d:"M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 014-4h4a4 4 0 014 4v3c0 3.3-2.7 6-6 6"}),jsx("path",{d:"M12 20v-9M6.53 9C4.6 8.8 3 7.1 3 5M6 13H2M6 17l-4 1M17.47 9c1.93-.2 3.53-1.9 3.53-4M18 13h4M18 17l4 1"})]})}function he(){return jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("path",{d:"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 006 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"}),jsx("path",{d:"M9 18h6M10 22h4"})]})}function me(){return jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),jsx("circle",{cx:"8.5",cy:"8.5",r:"1.5"}),jsx("polyline",{points:"21 15 16 10 5 21"})]})}function N(){return jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})}function be(){return jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsx("polyline",{points:"20 6 9 17 4 12"})})}var i={bgLight:"#F8FAFC",bgCard:"rgba(255, 255, 255, 0.98)",border:"rgba(0, 0, 0, 0.08)",text:"#1F2937",textMuted:"#6B7280",error:"#EF4444",success:"#22C55E"};function z({config:r,metadata:o,onClose:e,onSubmit:n,onUpload:c}){let[l,u]=useState(null),[s,p]=useState(""),[d,y]=useState(""),[k,x]=useState(null),[w,v]=useState(null),[j,R]=useState(false),[W,B]=useState(false),[$,m]=useState(null),[re,ne]=useState(false),P=useRef(null),{i18n:C,formFields:J,theme:ie}=r,S=ie.primaryColor||"#0ea5e9",H=400,ae=l==="bug"?C.bugPlaceholder||C.placeholder:C.featurePlaceholder||C.placeholder,se=async f=>{let F=f.target.files?.[0];if(F){if(!F.type.startsWith("image/")){m("Only image files are allowed");return}if(F.size>10*1024*1024){m("Image must be under 10MB");return}B(true),m(null);try{let M=await ye(F,{maxWidth:1920,maxHeight:1080,quality:.8}),D=new FileReader;D.onload=()=>v(D.result),D.readAsDataURL(M);let U=await c(M);B(!1),U?x(U):(m("Failed to upload image"),v(null));}catch(M){console.error("[Voyage] Image processing error:",M),B(false),m("Failed to process image");}}},le=()=>{x(null),v(null),P.current&&(P.current.value="");},de=async()=>{if(!l){m("Please select a type");return}if(!s.trim()){m("Please enter your feedback");return}if(J.email.required&&!d.trim()){m("Please enter your email");return}R(true),m(null);let f={label:l,text:s.trim(),email:d.trim()||void 0,imageUrl:k||void 0,metadata:o},h=await n(f);R(false),h?ne(true):m("Failed to submit. Please try again.");},g=(()=>{let f=`${S}15`;return {overlay:{position:"fixed",top:0,left:0,right:0,bottom:0,backgroundColor:"rgba(0, 0, 0, 0.4)",backdropFilter:"blur(4px)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999,padding:"20px"},modal:{backgroundColor:i.bgCard,backdropFilter:"blur(20px)",borderRadius:"20px",width:"100%",maxWidth:"580px",maxHeight:"90vh",overflowY:"auto",position:"relative",fontFamily:"'Quicksand', 'Nunito', system-ui, sans-serif",border:`1px solid ${i.border}`,boxShadow:"0 25px 50px -12px rgba(0, 0, 0, 0.15)"},colorBar:{height:"4px",backgroundColor:S},header:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"14px 20px",borderBottom:`1px solid ${i.border}`,backgroundColor:i.bgLight},headerIcon:{width:"32px",height:"32px",borderRadius:"10px",backgroundColor:S,display:"flex",alignItems:"center",justifyContent:"center",color:"#fff"},typeButton:h=>({display:"flex",alignItems:"center",justifyContent:"center",gap:"6px",padding:"10px 12px",border:h?`2px solid ${S}`:`1px solid ${i.border}`,borderRadius:"10px",backgroundColor:h?f:i.bgLight,cursor:"pointer",fontWeight:600,fontSize:"13px",color:h?i.text:i.textMuted,transition:"all 0.2s"}),submitButton:h=>({width:"100%",padding:"12px",backgroundColor:h?i.bgLight:S,color:h?i.textMuted:"#fff",border:"none",borderRadius:"12px",fontSize:"15px",fontWeight:700,cursor:h?"not-allowed":"pointer",fontFamily:"inherit",transition:"all 0.2s",boxShadow:h?"none":`0 4px 15px ${S}40`}),primaryButton:{width:"100%",padding:"16px",backgroundColor:S,color:"#fff",border:"none",borderRadius:"12px",fontSize:"15px",fontWeight:700,cursor:"pointer",fontFamily:"inherit",marginTop:"8px"}}})();return re?jsx("div",{style:g.overlay,children:jsx("div",{style:g.modal,children:jsxs("div",{style:Ee,children:[jsx("div",{style:Ve,children:jsx(be,{})}),jsx("h3",{style:Te,children:C.successMessage}),jsx("p",{style:Oe,children:"Your voice shapes what we build next."}),jsx("button",{onClick:e,style:g.primaryButton,children:"Done"})]})})}):jsx("div",{style:g.overlay,onClick:e,children:jsxs("div",{style:g.modal,onClick:f=>f.stopPropagation(),children:[jsxs("div",{style:g.header,children:[jsxs("div",{style:xe,children:[jsx("div",{style:g.headerIcon,children:jsx(ge,{size:20})}),jsx("span",{style:Se,children:"Help Us Improve"})]}),jsx("button",{onClick:e,style:Ce,children:jsx(N,{})})]}),jsx("div",{style:g.colorBar}),jsxs("div",{style:ve,children:[jsxs("div",{style:_,children:[jsx("label",{style:L,children:"Feedback Type"}),jsxs("div",{style:ke,children:[jsxs("button",{onClick:()=>u("bug"),style:g.typeButton(l==="bug"),children:[jsx("span",{style:q(l==="bug","bug"),children:jsx(fe,{})}),jsx("span",{children:"Bug"})]}),jsxs("button",{onClick:()=>u("feature"),style:g.typeButton(l==="feature"),children:[jsx("span",{style:q(l==="feature","feature"),children:jsx(he,{})}),jsx("span",{children:"Feature"})]})]})]}),jsxs("div",{style:we,children:[jsxs("div",{style:Pe,children:[jsx("label",{style:L,children:"Description"}),jsxs("div",{style:Le,children:[jsx("textarea",{placeholder:ae,value:s,maxLength:H,onInput:f=>p(f.target.value),style:je}),jsxs("span",{style:We,children:[s.length,"/",H]})]})]}),jsxs("div",{style:Fe,children:[jsx("label",{style:L,children:"Screenshot"}),w?jsxs("div",{style:Je,children:[jsx("img",{src:w,alt:"Preview",style:Ie}),jsx("button",{onClick:le,style:De,children:jsx(N,{})}),W&&jsx("div",{style:Xe,children:"..."})]}):jsxs("button",{onClick:()=>P.current?.click(),style:Me,children:[jsx(me,{}),jsx("span",{style:{fontSize:"11px"},children:"Upload"})]}),jsx("input",{ref:P,type:"file",accept:"image/*",onChange:se,style:{display:"none"}})]})]}),J.email.enabled&&jsxs("div",{style:_,children:[jsxs("label",{style:L,children:["Email ",J.email.required?"":"(optional)"]}),jsx("input",{type:"email",placeholder:"your@email.com",value:d,onInput:f=>y(f.target.value),style:Be})]}),$&&jsx("p",{style:ze,children:$}),jsx("button",{onClick:de,disabled:j||W,style:g.submitButton(j||W),children:j?jsxs("span",{style:Re,children:[jsx("span",{className:"voyage-spinner"}),"Sending..."]}):C.submitLabel})]})]})})}async function ye(r,o){let{maxWidth:e,maxHeight:n,quality:c}=o;return new Promise((l,u)=>{let s=new Image;s.onload=()=>{let{width:p,height:d}=s;if(p>e||d>n){let x=Math.min(e/p,n/d);p=Math.round(p*x),d=Math.round(d*x);}let y=document.createElement("canvas");y.width=p,y.height=d;let k=y.getContext("2d");if(!k){u(new Error("Failed to get canvas context"));return}k.drawImage(s,0,0,p,d),y.toBlob(x=>{if(!x){u(new Error("Failed to convert image"));return}let w=Date.now(),v=new File([x],`image_${w}.webp`,{type:"image/webp"});l(v);},"image/webp",c);},s.onerror=()=>u(new Error("Failed to load image")),s.src=URL.createObjectURL(r);})}var xe={display:"flex",alignItems:"center",gap:"12px"},Se={fontSize:"16px",fontWeight:700,color:i.text},Ce={background:"transparent",border:"none",color:i.textMuted,cursor:"pointer",padding:"8px",borderRadius:"8px",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s"},ve={padding:"16px 20px"},_={marginBottom:"14px"},L={display:"block",fontSize:"13px",fontWeight:600,color:i.text,marginBottom:"8px"},ke={display:"grid",gridTemplateColumns:"1fr 1fr",gap:"12px"},we={display:"flex",gap:"14px",marginBottom:"14px"},Pe={flex:1,display:"flex",flexDirection:"column"},Fe={width:"120px",flexShrink:0,display:"flex",flexDirection:"column"},Me={width:"100%",aspectRatio:"1",border:`2px dashed ${i.border}`,borderRadius:"10px",backgroundColor:"transparent",cursor:"pointer",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:"4px",color:i.textMuted,fontSize:"12px",transition:"all 0.2s"},Ie={width:"100%",aspectRatio:"1",objectFit:"cover",borderRadius:"10px"},q=(r,o)=>({display:"flex",alignItems:"center",justifyContent:"center",color:r?o==="bug"?i.error:"#F59E0B":i.textMuted}),Le={position:"relative"},je={width:"100%",minHeight:"120px",padding:"14px",border:`1px solid ${i.border}`,borderRadius:"12px",fontSize:"14px",resize:"vertical",boxSizing:"border-box",backgroundColor:i.bgLight,color:i.text,fontFamily:"inherit",outline:"none"},We={position:"absolute",bottom:"12px",right:"14px",fontSize:"12px",color:i.textMuted},Be={width:"100%",padding:"10px 12px",border:`1px solid ${i.border}`,borderRadius:"10px",fontSize:"13px",boxSizing:"border-box",backgroundColor:i.bgLight,color:i.text,fontFamily:"inherit",outline:"none"},Je={position:"relative",display:"inline-block",borderRadius:"12px",overflow:"hidden"},De={position:"absolute",top:"8px",right:"8px",width:"28px",height:"28px",borderRadius:"50%",backgroundColor:"rgba(0, 0, 0, 0.7)",color:"#fff",border:"none",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center"},Xe={position:"absolute",inset:0,backgroundColor:"rgba(0, 0, 0, 0.7)",display:"flex",alignItems:"center",justifyContent:"center",color:"#fff",fontSize:"14px",borderRadius:"12px"},ze={color:i.error,fontSize:"14px",marginBottom:"16px",padding:"12px",backgroundColor:"rgba(239, 68, 68, 0.1)",borderRadius:"8px",border:"1px solid rgba(239, 68, 68, 0.3)"},Ee={padding:"48px 24px",textAlign:"center"},Ve={width:"64px",height:"64px",borderRadius:"50%",backgroundColor:"rgba(34, 197, 94, 0.15)",color:i.success,display:"flex",alignItems:"center",justifyContent:"center",margin:"0 auto 20px"},Te={fontSize:"20px",fontWeight:700,color:i.text,marginBottom:"8px"},Oe={fontSize:"14px",color:i.textMuted,marginBottom:"24px"},Re={display:"flex",alignItems:"center",justifyContent:"center",gap:"8px"};function E({config:r,onSubmit:o,onUpload:e,getMetadata:n,visible:c,defaultOpen:l=false,onOpenChange:u}){let[s,p]=useState(l);if(useEffect(()=>{u?.(s);},[s,u]),!c)return null;let{theme:d,i18n:y}=r;return jsxs(Fragment,{children:[!s&&jsx(X,{onClick:()=>p(true),label:y.buttonLabel,position:d.position,primaryColor:d.primaryColor}),s&&jsx(z,{config:r,metadata:n(),onClose:()=>p(false),onSubmit:o,onUpload:e})]})}var Q=()=>{if(typeof document>"u"||document.getElementById("voyage-sdk-styles"))return;let r=document.createElement("style");r.id="voyage-sdk-styles",r.textContent=`
1
+ import {render,h}from'preact';import {useState,useEffect,useRef}from'preact/hooks';import {jsxs,Fragment,jsx}from'preact/jsx-runtime';function ge(){return jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsx("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"})})}function D({onClick:r,label:o,position:e,primaryColor:i,hasError:p=false}){let[a,u]=useState(false),[c,l]=useState(false),d=e==="bottom-right"?{right:"24px"}:{left:"24px"},g=()=>c?"scale(0.95)":a?"scale(1.02) translateY(-2px)":"scale(1)";return jsxs("div",{style:{position:"fixed",bottom:"24px",...d,zIndex:9998},children:[jsxs("button",{onClick:r,onMouseEnter:()=>u(true),onMouseLeave:()=>{u(false),l(false);},onMouseDown:()=>l(true),onMouseUp:()=>l(false),style:{position:"relative",display:"flex",alignItems:"center",gap:"10px",padding:"14px 24px",border:"none",borderRadius:"50px",cursor:"pointer",fontFamily:"'Quicksand', 'Nunito', system-ui, sans-serif",fontSize:"15px",fontWeight:600,color:"#fff",backgroundColor:i,boxShadow:a?`0 8px 32px ${i}60, 0 0 20px ${i}40`:`0 4px 20px ${i}50, 0 0 10px ${i}30`,transform:g(),transition:"all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1)"},children:[jsx(ge,{}),jsx("span",{children:o})]}),p&&jsx("div",{style:{position:"absolute",top:"-4px",right:"-4px",width:"18px",height:"18px",borderRadius:"50%",backgroundColor:"#EF4444",display:"flex",alignItems:"center",justifyContent:"center",color:"#fff",fontSize:"12px",fontWeight:"bold",boxShadow:"0 2px 6px rgba(239, 68, 68, 0.5)"},children:"!"})]})}function he({size:r=24}){return jsx("svg",{width:r,height:r,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsx("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"})})}function me(){return jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("path",{d:"M8 2l1.88 1.88M14.12 3.88L16 2M9 7.13v-1a3.003 3.003 0 116 0v1"}),jsx("path",{d:"M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 014-4h4a4 4 0 014 4v3c0 3.3-2.7 6-6 6"}),jsx("path",{d:"M12 20v-9M6.53 9C4.6 8.8 3 7.1 3 5M6 13H2M6 17l-4 1M17.47 9c1.93-.2 3.53-1.9 3.53-4M18 13h4M18 17l4 1"})]})}function be(){return jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("path",{d:"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 006 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"}),jsx("path",{d:"M9 18h6M10 22h4"})]})}function ye(){return jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),jsx("circle",{cx:"8.5",cy:"8.5",r:"1.5"}),jsx("polyline",{points:"21 15 16 10 5 21"})]})}function _(){return jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})}function xe(){return jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsx("polyline",{points:"20 6 9 17 4 12"})})}var n={bgLight:"#F8FAFC",bgCard:"rgba(255, 255, 255, 0.98)",border:"rgba(0, 0, 0, 0.08)",text:"#1F2937",textMuted:"#6B7280",error:"#EF4444",success:"#22C55E"};function X({config:r,metadata:o,onClose:e,onSubmit:i,onUpload:p}){let[a,u]=useState(null),[c,l]=useState(""),[d,g]=useState(""),[v,x]=useState(null),[P,k]=useState(null),[L,H]=useState(false),[j,B]=useState(false),[U,b]=useState(null),[se,ae]=useState(false),F=useRef(null),{i18n:C,formFields:E,theme:le}=r,S=le.primaryColor||"#0ea5e9",A=400,de=a==="bug"?C.bugPlaceholder||C.placeholder:C.featurePlaceholder||C.placeholder,ce=async h=>{let I=h.target.files?.[0];if(I){if(!I.type.startsWith("image/")){b("Only image files are allowed");return}if(I.size>10*1024*1024){b("Image must be under 10MB");return}B(true),b(null);try{let M=await Se(I,{maxWidth:1920,maxHeight:1080,quality:.8}),J=new FileReader;J.onload=()=>k(J.result),J.readAsDataURL(M);let N=await p(M);B(!1),N?x(N):(b("Failed to upload image"),k(null));}catch(M){console.error("[Voyage] Image processing error:",M),B(false),b("Failed to process image");}}},pe=()=>{x(null),k(null),F.current&&(F.current.value="");},ue=async()=>{if(!a){b("Please select a type");return}if(!c.trim()){b("Please enter your feedback");return}if(E.email.required&&!d.trim()){b("Please enter your email");return}H(true),b(null);let h={label:a,text:c.trim(),email:d.trim()||void 0,imageUrl:v||void 0,metadata:o},m=await i(h);H(false),m?ae(true):b("Failed to submit. Please try again.");},f=(()=>{let h=`${S}15`;return {overlay:{position:"fixed",top:0,left:0,right:0,bottom:0,backgroundColor:"rgba(0, 0, 0, 0.4)",backdropFilter:"blur(4px)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999,padding:"20px"},modal:{backgroundColor:n.bgCard,backdropFilter:"blur(20px)",borderRadius:"20px",width:"100%",maxWidth:"580px",maxHeight:"90vh",overflowY:"auto",position:"relative",fontFamily:"'Quicksand', 'Nunito', system-ui, sans-serif",border:`1px solid ${n.border}`,boxShadow:"0 25px 50px -12px rgba(0, 0, 0, 0.15)"},colorBar:{height:"4px",backgroundColor:S},header:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"14px 20px",borderBottom:`1px solid ${n.border}`,backgroundColor:n.bgLight},headerIcon:{width:"32px",height:"32px",borderRadius:"10px",backgroundColor:S,display:"flex",alignItems:"center",justifyContent:"center",color:"#fff"},typeButton:m=>({display:"flex",alignItems:"center",justifyContent:"center",gap:"6px",padding:"10px 12px",border:m?`2px solid ${S}`:`1px solid ${n.border}`,borderRadius:"10px",backgroundColor:m?h:n.bgLight,cursor:"pointer",fontWeight:600,fontSize:"13px",color:m?n.text:n.textMuted,transition:"all 0.2s"}),submitButton:m=>({width:"100%",padding:"12px",backgroundColor:m?n.bgLight:S,color:m?n.textMuted:"#fff",border:"none",borderRadius:"12px",fontSize:"15px",fontWeight:700,cursor:m?"not-allowed":"pointer",fontFamily:"inherit",transition:"all 0.2s",boxShadow:m?"none":`0 4px 15px ${S}40`}),primaryButton:{width:"100%",padding:"16px",backgroundColor:S,color:"#fff",border:"none",borderRadius:"12px",fontSize:"15px",fontWeight:700,cursor:"pointer",fontFamily:"inherit",marginTop:"8px"}}})();return se?jsx("div",{style:f.overlay,children:jsx("div",{style:f.modal,children:jsxs("div",{style:Te,children:[jsx("div",{style:Re,children:jsx(xe,{})}),jsx("h3",{style:Oe,children:C.successMessage}),jsx("p",{style:$e,children:"Your voice shapes what we build next."}),jsx("button",{onClick:e,style:f.primaryButton,children:"Done"})]})})}):jsx("div",{style:f.overlay,onClick:e,children:jsxs("div",{style:f.modal,onClick:h=>h.stopPropagation(),children:[jsxs("div",{style:f.header,children:[jsxs("div",{style:ve,children:[jsx("div",{style:f.headerIcon,children:jsx(he,{size:20})}),jsx("span",{style:Ce,children:"Help Us Improve"})]}),jsx("button",{onClick:e,style:ke,children:jsx(_,{})})]}),jsx("div",{style:f.colorBar}),jsxs("div",{style:we,children:[jsxs("div",{style:Q,children:[jsx("label",{style:W,children:"Feedback Type"}),jsxs("div",{style:Pe,children:[jsxs("button",{onClick:()=>u("bug"),style:f.typeButton(a==="bug"),children:[jsx("span",{style:Y(a==="bug","bug"),children:jsx(me,{})}),jsx("span",{children:"Bug"})]}),jsxs("button",{onClick:()=>u("feature"),style:f.typeButton(a==="feature"),children:[jsx("span",{style:Y(a==="feature","feature"),children:jsx(be,{})}),jsx("span",{children:"Feature"})]})]})]}),jsxs("div",{style:Fe,children:[jsxs("div",{style:Ie,children:[jsx("label",{style:W,children:"Description"}),jsxs("div",{style:je,children:[jsx("textarea",{placeholder:de,value:c,maxLength:A,onInput:h=>l(h.target.value),style:Be}),jsxs("span",{style:Ee,children:[c.length,"/",A]})]})]}),jsxs("div",{style:Me,children:[jsx("label",{style:W,children:"Screenshot"}),P?jsxs("div",{style:De,children:[jsx("img",{src:P,alt:"Preview",style:Le}),jsx("button",{onClick:pe,style:Xe,children:jsx(_,{})}),j&&jsx("div",{style:ze,children:"..."})]}):jsxs("button",{onClick:()=>F.current?.click(),style:We,children:[jsx(ye,{}),jsx("span",{style:{fontSize:"11px"},children:"Upload"})]}),jsx("input",{ref:F,type:"file",accept:"image/*",onChange:ce,style:{display:"none"}})]})]}),E.email.enabled&&jsxs("div",{style:Q,children:[jsxs("label",{style:W,children:["Email ",E.email.required?"":"(optional)"]}),jsx("input",{type:"email",placeholder:"your@email.com",value:d,onInput:h=>g(h.target.value),style:Je})]}),U&&jsx("p",{style:Ve,children:U}),jsx("button",{onClick:ue,disabled:L||j,style:f.submitButton(L||j),children:L?jsxs("span",{style:He,children:[jsx("span",{className:"voyage-spinner"}),"Sending..."]}):C.submitLabel})]})]})})}async function Se(r,o){let{maxWidth:e,maxHeight:i,quality:p}=o;return new Promise((a,u)=>{let c=new Image;c.onload=()=>{let{width:l,height:d}=c;if(l>e||d>i){let x=Math.min(e/l,i/d);l=Math.round(l*x),d=Math.round(d*x);}let g=document.createElement("canvas");g.width=l,g.height=d;let v=g.getContext("2d");if(!v){u(new Error("Failed to get canvas context"));return}v.drawImage(c,0,0,l,d),g.toBlob(x=>{if(!x){u(new Error("Failed to convert image"));return}let P=Date.now(),k=new File([x],`image_${P}.webp`,{type:"image/webp"});a(k);},"image/webp",p);},c.onerror=()=>u(new Error("Failed to load image")),c.src=URL.createObjectURL(r);})}var ve={display:"flex",alignItems:"center",gap:"12px"},Ce={fontSize:"16px",fontWeight:700,color:n.text},ke={background:"transparent",border:"none",color:n.textMuted,cursor:"pointer",padding:"8px",borderRadius:"8px",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s"},we={padding:"16px 20px"},Q={marginBottom:"14px"},W={display:"block",fontSize:"13px",fontWeight:600,color:n.text,marginBottom:"8px"},Pe={display:"grid",gridTemplateColumns:"1fr 1fr",gap:"12px"},Fe={display:"flex",gap:"14px",marginBottom:"14px"},Ie={flex:1,display:"flex",flexDirection:"column"},Me={width:"120px",flexShrink:0,display:"flex",flexDirection:"column"},We={width:"100%",aspectRatio:"1",border:`2px dashed ${n.border}`,borderRadius:"10px",backgroundColor:"transparent",cursor:"pointer",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:"4px",color:n.textMuted,fontSize:"12px",transition:"all 0.2s"},Le={width:"100%",aspectRatio:"1",objectFit:"cover",borderRadius:"10px"},Y=(r,o)=>({display:"flex",alignItems:"center",justifyContent:"center",color:r?o==="bug"?n.error:"#F59E0B":n.textMuted}),je={position:"relative"},Be={width:"100%",minHeight:"120px",padding:"14px",border:`1px solid ${n.border}`,borderRadius:"12px",fontSize:"14px",resize:"vertical",boxSizing:"border-box",backgroundColor:n.bgLight,color:n.text,fontFamily:"inherit",outline:"none"},Ee={position:"absolute",bottom:"12px",right:"14px",fontSize:"12px",color:n.textMuted},Je={width:"100%",padding:"10px 12px",border:`1px solid ${n.border}`,borderRadius:"10px",fontSize:"13px",boxSizing:"border-box",backgroundColor:n.bgLight,color:n.text,fontFamily:"inherit",outline:"none"},De={position:"relative",display:"inline-block",borderRadius:"12px",overflow:"hidden"},Xe={position:"absolute",top:"8px",right:"8px",width:"28px",height:"28px",borderRadius:"50%",backgroundColor:"rgba(0, 0, 0, 0.7)",color:"#fff",border:"none",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center"},ze={position:"absolute",inset:0,backgroundColor:"rgba(0, 0, 0, 0.7)",display:"flex",alignItems:"center",justifyContent:"center",color:"#fff",fontSize:"14px",borderRadius:"12px"},Ve={color:n.error,fontSize:"14px",marginBottom:"16px",padding:"12px",backgroundColor:"rgba(239, 68, 68, 0.1)",borderRadius:"8px",border:"1px solid rgba(239, 68, 68, 0.3)"},Te={padding:"48px 24px",textAlign:"center"},Re={width:"64px",height:"64px",borderRadius:"50%",backgroundColor:"rgba(34, 197, 94, 0.15)",color:n.success,display:"flex",alignItems:"center",justifyContent:"center",margin:"0 auto 20px"},Oe={fontSize:"20px",fontWeight:700,color:n.text,marginBottom:"8px"},$e={fontSize:"14px",color:n.textMuted,marginBottom:"24px"},He={display:"flex",alignItems:"center",justifyContent:"center",gap:"8px"};function z({config:r,onSubmit:o,onUpload:e,getMetadata:i,visible:p,defaultOpen:a=false,hasError:u=false,onOpenChange:c}){let[l,d]=useState(a);if(useEffect(()=>{d(a);},[a]),useEffect(()=>{c?.(l);},[l,c]),!p)return null;let{theme:g,i18n:v}=r;return jsxs(Fragment,{children:[!l&&jsx(D,{onClick:()=>d(true),label:v.buttonLabel,position:g.position,primaryColor:g.primaryColor,hasError:u}),l&&jsx(X,{config:r,metadata:i(),onClose:()=>d(false),onSubmit:o,onUpload:e})]})}var V=()=>{if(typeof document>"u"||document.getElementById("voyage-sdk-styles"))return;let r=document.createElement("style");r.id="voyage-sdk-styles",r.textContent=`
2
2
  /* Voyage SDK Styles */
3
3
 
4
4
  /* Spinner Animation */
@@ -37,6 +37,6 @@ import {render,h}from'preact';import {useState,useEffect,useRef}from'preact/hook
37
37
 
38
38
  /* Load Quicksand font if not present */
39
39
  @import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@400;500;600;700&display=swap');
40
- `,document.head.appendChild(r);};var V="https://rxflzurkkuqgopjkshjh.supabase.co/functions/v1",G="voyage_config";async function T(r){let o=Y(r);if(o)return o;try{let e=await fetch(`${V}/get-widget-config`,{method:"GET",headers:{"Content-Type":"application/json","x-sdk-key":r}});if(!e.ok)return console.error("[Voyage] Failed to fetch config:",e.status),null;let n=await e.json();return Ne(r,n),n}catch(e){return console.error("[Voyage] Network error:",e),Y(r,true)}}async function Z(r,o){try{let e=await fetch(`${V}/submit-feedback`,{method:"POST",headers:{"Content-Type":"application/json","x-sdk-key":r},body:JSON.stringify({label:o.label,content:o.text,email:o.email,imageUrl:o.imageUrl,metadata:o.metadata})});if(!e.ok){let n=await e.json().catch(()=>({}));return console.error("[Voyage] Failed to submit feedback:",e.status,n),!1}return !0}catch(e){return console.error("[Voyage] Network error:",e),false}}async function ee(r,o){if(!o.type.startsWith("image/"))return console.error("[Voyage] Only image files are allowed"),null;if(o.size>5*1024*1024)return console.error("[Voyage] Image must be under 5MB"),null;try{let e=new FormData;e.append("file",o);let n=await fetch(`${V}/upload-feedback-image`,{method:"POST",headers:{"x-sdk-key":r},body:e});if(!n.ok){let l=await n.json().catch(()=>({}));return console.error("[Voyage] Failed to upload image:",n.status,l),null}return (await n.json()).url}catch(e){return console.error("[Voyage] Network error:",e),null}}function Y(r,o=false){try{let e=localStorage.getItem(`${G}_${r}`);if(!e)return null;let n=JSON.parse(e);return Date.now()-n.timestamp>36e5&&!o?null:n.config}catch{return null}}function Ne(r,o){try{let e={config:o,timestamp:Date.now()};localStorage.setItem(`${G}_${r}`,JSON.stringify(e));}catch{}}function te(){return {url:window.location.href,pathname:window.location.pathname,browser:navigator.userAgent,viewport:`${window.innerWidth}x${window.innerHeight}`,title:document.title,timestamp:new Date().toISOString(),locale:navigator.language,referrer:document.referrer}}var qe={projectId:"",formFields:{email:{enabled:true,required:false},category:{enabled:true,options:["bug","feature"]}},theme:{primaryColor:"#0ea5e9",position:"bottom-right"},i18n:{buttonLabel:"To : the Maker",placeholder:"Describe your ideas to improve our product",bugPlaceholder:"Please describe the bug in detail (e.g., clicked a button and it didn't work)",featurePlaceholder:"Describe your ideas to improve our product (e.g., I want to export TASK.md to Linear tickets)",submitLabel:"Send to the Maker",successMessage:"Thank you for your feedback!"}},O=class{constructor(){this.config=null;this.serverConfig=null;this.container=null;this.isWidgetVisible=false;this.isModalOpen=false;}async init(o){if(this.config=o,!o.sdkKey){console.error("[Voyage] Invalid SDK Key");return}if(Q(),!this.shouldDisplay()){console.log("[Voyage] Widget hidden by display rules");return}let e=await T(o.sdkKey);this.serverConfig=this.mergeConfig(e,o),this.isWidgetVisible=true,this.renderWidget(),console.log("[Voyage] Initialized");}show(){if(!this.config){console.warn("[Voyage] SDK not initialized");return}this.isWidgetVisible=true,this.renderWidget();}hide(){this.isWidgetVisible=false,this.renderWidget();}open(){if(!this.config){console.warn("[Voyage] SDK not initialized");return}this.isModalOpen=true,this.renderWidget();}close(){this.isModalOpen=false,this.renderWidget();}isOpen(){return this.isModalOpen}isVisible(){return this.isWidgetVisible}async refreshConfig(){if(!this.config)return;let o=await T(this.config.sdkKey);this.serverConfig=this.mergeConfig(o,this.config),this.renderWidget();}destroy(){this.container&&(render(null,this.container),this.container.remove(),this.container=null),this.config=null,this.serverConfig=null,this.isWidgetVisible=false,this.isModalOpen=false;}renderWidget(){if(!this.serverConfig||!this.config)return;this.container||(this.container=document.createElement("div"),this.container.id="voyage-widget-container",document.body.appendChild(this.container));let o=this.config.sdkKey;render(h(E,{config:this.serverConfig,visible:this.isWidgetVisible,defaultOpen:this.isModalOpen,onOpenChange:e=>{this.isModalOpen=e;},getMetadata:te,onSubmit:async e=>Z(o,e),onUpload:async e=>ee(o,e)}),this.container);}mergeConfig(o,e){return o||{...qe}}shouldDisplay(){if(!this.config)return false;let o=window.location.pathname,{include:e,exclude:n}=this.config;return e&&e.length>0?e.some(c=>this.matchPath(o,c)):n&&n.length>0?!n.some(c=>this.matchPath(o,c)):true}matchPath(o,e){if(e.endsWith("/*")){let n=e.slice(0,-2);return o.startsWith(n)}return o===e}},Ke=new O;var St=Ke;
41
- export{Ke as Voyage,St as default};//# sourceMappingURL=index.js.map
40
+ `,document.head.appendChild(r);};var T="https://rxflzurkkuqgopjkshjh.supabase.co/functions/v1",te="voyage_config";async function R(r){let o=ee(r);if(o)return o;try{let e=await fetch(`${T}/get-widget-config`,{method:"GET",headers:{"Content-Type":"application/json","x-sdk-key":r}});if(!e.ok)return console.error("[Voyage] Failed to fetch config:",e.status),null;let i=await e.json();return qe(r,i),i}catch(e){return console.error("[Voyage] Network error:",e),ee(r,true)}}async function oe(r,o){try{let e=await fetch(`${T}/submit-feedback`,{method:"POST",headers:{"Content-Type":"application/json","x-sdk-key":r},body:JSON.stringify({label:o.label,content:o.text,email:o.email,imageUrl:o.imageUrl,metadata:o.metadata})});if(!e.ok){let i=await e.json().catch(()=>({}));return console.error("[Voyage] Failed to submit feedback:",e.status,i),!1}return !0}catch(e){return console.error("[Voyage] Network error:",e),false}}async function re(r,o){if(!o.type.startsWith("image/"))return console.error("[Voyage] Only image files are allowed"),null;if(o.size>5*1024*1024)return console.error("[Voyage] Image must be under 5MB"),null;try{let e=new FormData;e.append("file",o);let i=await fetch(`${T}/upload-feedback-image`,{method:"POST",headers:{"x-sdk-key":r},body:e});if(!i.ok){let a=await i.json().catch(()=>({}));return console.error("[Voyage] Failed to upload image:",i.status,a),null}return (await i.json()).url}catch(e){return console.error("[Voyage] Network error:",e),null}}function ee(r,o=false){try{let e=localStorage.getItem(`${te}_${r}`);if(!e)return null;let i=JSON.parse(e);return Date.now()-i.timestamp>36e5&&!o?null:i.config}catch{return null}}function qe(r,o){try{let e={config:o,timestamp:Date.now()};localStorage.setItem(`${te}_${r}`,JSON.stringify(e));}catch{}}function ie(){return {url:window.location.href,pathname:window.location.pathname,browser:navigator.userAgent,viewport:`${window.innerWidth}x${window.innerHeight}`,title:document.title,timestamp:new Date().toISOString(),locale:navigator.language,referrer:document.referrer}}var O={projectId:"",formFields:{email:{enabled:true,required:false},category:{enabled:true,options:["bug","feature"]}},theme:{primaryColor:"#0ea5e9",position:"bottom-right"},i18n:{buttonLabel:"To : the Maker",placeholder:"Describe your ideas to improve our product",bugPlaceholder:"Please describe the bug in detail (e.g., clicked a button and it didn't work)",featurePlaceholder:"Describe your ideas to improve our product (e.g., I want to export TASK.md to Linear tickets)",submitLabel:"Send to the Maker",successMessage:"Thank you for your feedback!"}},$=class{constructor(){this.config=null;this.serverConfig=null;this.container=null;this.isWidgetVisible=false;this.isModalOpen=false;this.hasInitError=false;}async init(o){if(this.config=o,this.hasInitError=false,!o.sdkKey){console.error("[Voyage] SDK Key is required. Get your key from the dashboard."),this.hasInitError=true,V(),this.isWidgetVisible=true,this.serverConfig={...O},this.renderWidget();return}if(V(),!this.shouldDisplay()){console.log("[Voyage] Widget hidden by display rules");return}let e=await R(o.sdkKey);if(!e){console.error("[Voyage] Failed to fetch config. Check your SDK Key or network connection."),this.hasInitError=true,this.serverConfig={...O},this.isWidgetVisible=true,this.renderWidget();return}this.serverConfig=this.mergeConfig(e,o),this.isWidgetVisible=true,this.renderWidget(),console.log("[Voyage] Initialized");}show(){if(!this.config){console.warn("[Voyage] SDK not initialized");return}this.isWidgetVisible=true,this.renderWidget();}hide(){this.isWidgetVisible=false,this.renderWidget();}open(){if(!this.config){console.warn("[Voyage] SDK not initialized");return}this.isModalOpen=true,this.renderWidget();}close(){this.isModalOpen=false,this.renderWidget();}isOpen(){return this.isModalOpen}isVisible(){return this.isWidgetVisible}async refreshConfig(){if(!this.config)return;let o=await R(this.config.sdkKey);this.serverConfig=this.mergeConfig(o,this.config),this.renderWidget();}destroy(){this.container&&(render(null,this.container),this.container.remove(),this.container=null),this.config=null,this.serverConfig=null,this.isWidgetVisible=false,this.isModalOpen=false;}renderWidget(){if(!this.serverConfig||!this.config)return;this.container||(this.container=document.createElement("div"),this.container.id="voyage-widget-container",document.body.appendChild(this.container));let o=this.config.sdkKey;render(h(z,{config:this.serverConfig,visible:this.isWidgetVisible,defaultOpen:this.isModalOpen,hasError:this.hasInitError,onOpenChange:e=>{this.isModalOpen=e;},getMetadata:ie,onSubmit:async e=>oe(o,e),onUpload:async e=>re(o,e)}),this.container);}mergeConfig(o,e){return o||{...O}}shouldDisplay(){if(!this.config)return false;let o=window.location.pathname,{include:e,exclude:i}=this.config;return e&&e.length>0?e.some(p=>this.matchPath(o,p)):i&&i.length>0?!i.some(p=>this.matchPath(o,p)):true}matchPath(o,e){if(e.endsWith("/*")){let i=e.slice(0,-2);return o.startsWith(i)}return o===e}},_e=new $;var St=_e;
41
+ export{_e as Voyage,St as default};//# sourceMappingURL=index.js.map
42
42
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Button.tsx","../src/components/Modal.tsx","../src/components/Widget.tsx","../src/styles.ts","../src/utils/api.ts","../src/utils/metadata.ts","../src/index.ts"],"names":["MessageIcon","jsx","Button","onClick","label","position","primaryColor","isHovered","setIsHovered","useState","isPressed","setIsPressed","positionStyle","getTransform","jsxs","size","BugIcon","LightbulbIcon","ImageIcon","CloseIcon","CheckIcon","colors","Modal","config","metadata","onClose","onSubmit","onUpload","setLabel","text","setText","email","setEmail","imageUrl","setImageUrl","imagePreview","setImagePreview","isSubmitting","setIsSubmitting","isUploading","setIsUploading","error","setError","success","setSuccess","fileInputRef","useRef","i18n","formFields","theme","maxLength","currentPlaceholder","handleFileSelect","e","file","processedFile","processImage","reader","url","err","handleRemoveImage","handleSubmit","feedbackData","result","styles","primaryBgLight","active","disabled","successContainerStyle","successIconStyle","successTitleStyle","successTextStyle","headerLeftStyle","headerTitleStyle","closeButtonStyle","contentStyle","sectionStyle","labelStyle","typeButtonsStyle","typeIconStyle","descriptionRowStyle","descriptionColStyle","textareaWrapperStyle","textareaStyle","charCountStyle","uploadColStyle","imagePreviewContainerStyle","imagePreviewSquareStyle","removeImageButtonStyle","uploadingOverlayStyle","uploadButtonSquareStyle","inputStyle","errorStyle","spinnerContainerStyle","options","maxWidth","maxHeight","quality","resolve","reject","img","width","height","ratio","canvas","ctx","blob","timestamp","newFile","type","Widget","getMetadata","visible","defaultOpen","onOpenChange","isOpen","setIsOpen","useEffect","Fragment","injectStyles","style","API_BASE","CACHE_KEY","fetchProjectConfig","sdkKey","cached","getFromCache","response","saveToCache","submitFeedback","data","errorData","uploadImage","formData","ignoreExpiry","raw","captureMetadata","DEFAULT_CONFIG","VoyageSDK","fetchedConfig","render","h","open","server","_client","pathname","include","exclude","pattern","prefix","Voyage","index_default"],"mappings":"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","file":"index.js","sourcesContent":["import { h } from 'preact';\nimport { useState } from 'preact/hooks';\n\ninterface ButtonProps {\n onClick: () => void;\n label: string;\n position: 'bottom-right' | 'bottom-left';\n primaryColor: string;\n}\n\n// 말풍선 아이콘 SVG\nfunction MessageIcon() {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n );\n}\n\nexport function Button({ onClick, label, position, primaryColor }: ButtonProps) {\n const [isHovered, setIsHovered] = useState(false);\n const [isPressed, setIsPressed] = useState(false);\n\n const positionStyle = position === 'bottom-right'\n ? { right: '24px' }\n : { left: '24px' };\n\n // Jelly 효과 transform\n const getTransform = () => {\n if (isPressed) return 'scale(0.95)';\n if (isHovered) return 'scale(1.02) translateY(-2px)';\n return 'scale(1)';\n };\n\n return (\n <button\n onClick={onClick}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => { setIsHovered(false); setIsPressed(false); }}\n onMouseDown={() => setIsPressed(true)}\n onMouseUp={() => setIsPressed(false)}\n style={{\n position: 'fixed',\n bottom: '24px',\n ...positionStyle,\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n padding: '14px 24px',\n border: 'none',\n borderRadius: '50px',\n cursor: 'pointer',\n fontFamily: \"'Quicksand', 'Nunito', system-ui, sans-serif\",\n fontSize: '15px',\n fontWeight: 600,\n color: '#fff',\n zIndex: 9998,\n // primaryColor 적용\n backgroundColor: primaryColor,\n // 그림자 + glow 효과\n boxShadow: isHovered\n ? `0 8px 32px ${primaryColor}60, 0 0 20px ${primaryColor}40`\n : `0 4px 20px ${primaryColor}50, 0 0 10px ${primaryColor}30`,\n // Jelly 애니메이션\n transform: getTransform(),\n transition: 'all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1)',\n }}\n >\n <MessageIcon />\n <span>{label}</span>\n </button>\n );\n}\n","import { h } from 'preact';\nimport { useRef, useState } from 'preact/hooks';\n\nimport type { ProjectConfig, FeedbackData, FeedbackMetadata } from '../types';\n\ninterface ModalProps {\n config: ProjectConfig;\n metadata: FeedbackMetadata;\n onClose: () => void;\n onSubmit: (data: FeedbackData) => Promise<boolean>;\n onUpload: (file: File) => Promise<string | null>;\n}\n\n// 아이콘들\nfunction MessageIcon({ size = 24 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n );\n}\n\nfunction BugIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M8 2l1.88 1.88M14.12 3.88L16 2M9 7.13v-1a3.003 3.003 0 116 0v1\" />\n <path d=\"M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 014-4h4a4 4 0 014 4v3c0 3.3-2.7 6-6 6\" />\n <path d=\"M12 20v-9M6.53 9C4.6 8.8 3 7.1 3 5M6 13H2M6 17l-4 1M17.47 9c1.93-.2 3.53-1.9 3.53-4M18 13h4M18 17l4 1\" />\n </svg>\n );\n}\n\nfunction LightbulbIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 006 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\" />\n <path d=\"M9 18h6M10 22h4\" />\n </svg>\n );\n}\n\nfunction ImageIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" />\n <polyline points=\"21 15 16 10 5 21\" />\n </svg>\n );\n}\n\nfunction CloseIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n\nfunction CheckIcon() {\n return (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n );\n}\n\n// 라이트 테마 색상\nconst colors = {\n bg: '#FFFFFF',\n bgLight: '#F8FAFC',\n bgCard: 'rgba(255, 255, 255, 0.98)',\n border: 'rgba(0, 0, 0, 0.08)',\n borderLight: 'rgba(0, 0, 0, 0.12)',\n text: '#1F2937',\n textMuted: '#6B7280',\n error: '#EF4444',\n success: '#22C55E',\n};\n\nexport function Modal({ config, metadata, onClose, onSubmit, onUpload }: ModalProps) {\n const [label, setLabel] = useState<'bug' | 'feature' | null>(null);\n const [text, setText] = useState('');\n const [email, setEmail] = useState('');\n const [imageUrl, setImageUrl] = useState<string | null>(null);\n const [imagePreview, setImagePreview] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isUploading, setIsUploading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [success, setSuccess] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const { i18n, formFields, theme } = config;\n const primaryColor = theme.primaryColor || '#0ea5e9';\n const maxLength = 400;\n\n // 동적 placeholder\n const currentPlaceholder = label === 'bug'\n ? (i18n.bugPlaceholder || i18n.placeholder)\n : (i18n.featurePlaceholder || i18n.placeholder);\n\n const handleFileSelect = async (e: Event) => {\n const target = e.target as HTMLInputElement;\n const file = target.files?.[0];\n if (!file) return;\n\n if (!file.type.startsWith('image/')) {\n setError('Only image files are allowed');\n return;\n }\n if (file.size > 10 * 1024 * 1024) {\n setError('Image must be under 10MB');\n return;\n }\n\n setIsUploading(true);\n setError(null);\n\n try {\n // 이미지를 WebP로 변환 및 resize\n const processedFile = await processImage(file, {\n maxWidth: 1920,\n maxHeight: 1080,\n quality: 0.8,\n });\n\n // 프리뷰 생성\n const reader = new FileReader();\n reader.onload = () => setImagePreview(reader.result as string);\n reader.readAsDataURL(processedFile);\n\n const url = await onUpload(processedFile);\n setIsUploading(false);\n\n if (url) {\n setImageUrl(url);\n } else {\n setError('Failed to upload image');\n setImagePreview(null);\n }\n } catch (err) {\n console.error('[Voyage] Image processing error:', err);\n setIsUploading(false);\n setError('Failed to process image');\n }\n };\n\n const handleRemoveImage = () => {\n setImageUrl(null);\n setImagePreview(null);\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n };\n\n const handleSubmit = async () => {\n if (!label) {\n setError('Please select a type');\n return;\n }\n if (!text.trim()) {\n setError('Please enter your feedback');\n return;\n }\n if (formFields.email.required && !email.trim()) {\n setError('Please enter your email');\n return;\n }\n\n setIsSubmitting(true);\n setError(null);\n\n const feedbackData: FeedbackData = {\n label,\n text: text.trim(),\n email: email.trim() || undefined,\n imageUrl: imageUrl || undefined,\n metadata,\n };\n\n const result = await onSubmit(feedbackData);\n setIsSubmitting(false);\n\n if (result) {\n setSuccess(true);\n } else {\n setError('Failed to submit. Please try again.');\n }\n };\n\n // 스타일 함수 (primaryColor 적용)\n const getStyles = () => {\n const primaryBgLight = `${primaryColor}15`;\n\n return {\n overlay: {\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.4)',\n backdropFilter: 'blur(4px)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 9999,\n padding: '20px',\n } as h.JSX.CSSProperties,\n\n modal: {\n backgroundColor: colors.bgCard,\n backdropFilter: 'blur(20px)',\n borderRadius: '20px',\n width: '100%',\n maxWidth: '580px',\n maxHeight: '90vh',\n overflowY: 'auto',\n position: 'relative',\n fontFamily: \"'Quicksand', 'Nunito', system-ui, sans-serif\",\n border: `1px solid ${colors.border}`,\n boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.15)',\n } as h.JSX.CSSProperties,\n\n colorBar: {\n height: '4px',\n backgroundColor: primaryColor,\n } as h.JSX.CSSProperties,\n\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '14px 20px',\n borderBottom: `1px solid ${colors.border}`,\n backgroundColor: colors.bgLight,\n } as h.JSX.CSSProperties,\n\n headerIcon: {\n width: '32px',\n height: '32px',\n borderRadius: '10px',\n backgroundColor: primaryColor,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n } as h.JSX.CSSProperties,\n\n typeButton: (active: boolean) => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '6px',\n padding: '10px 12px',\n border: active ? `2px solid ${primaryColor}` : `1px solid ${colors.border}`,\n borderRadius: '10px',\n backgroundColor: active ? primaryBgLight : colors.bgLight,\n cursor: 'pointer',\n fontWeight: 600,\n fontSize: '13px',\n color: active ? colors.text : colors.textMuted,\n transition: 'all 0.2s',\n } as h.JSX.CSSProperties),\n\n submitButton: (disabled: boolean) => ({\n width: '100%',\n padding: '12px',\n backgroundColor: disabled ? colors.bgLight : primaryColor,\n color: disabled ? colors.textMuted : '#fff',\n border: 'none',\n borderRadius: '12px',\n fontSize: '15px',\n fontWeight: 700,\n cursor: disabled ? 'not-allowed' : 'pointer',\n fontFamily: 'inherit',\n transition: 'all 0.2s',\n boxShadow: disabled ? 'none' : `0 4px 15px ${primaryColor}40`,\n } as h.JSX.CSSProperties),\n\n primaryButton: {\n width: '100%',\n padding: '16px',\n backgroundColor: primaryColor,\n color: '#fff',\n border: 'none',\n borderRadius: '12px',\n fontSize: '15px',\n fontWeight: 700,\n cursor: 'pointer',\n fontFamily: 'inherit',\n marginTop: '8px',\n } as h.JSX.CSSProperties,\n };\n };\n\n const styles = getStyles();\n\n // 성공 화면\n if (success) {\n return (\n <div style={styles.overlay}>\n <div style={styles.modal}>\n <div style={successContainerStyle}>\n <div style={successIconStyle}>\n <CheckIcon />\n </div>\n <h3 style={successTitleStyle}>{i18n.successMessage}</h3>\n <p style={successTextStyle}>Your voice shapes what we build next.</p>\n <button onClick={onClose} style={styles.primaryButton}>\n Done\n </button>\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div style={styles.overlay} onClick={onClose}>\n <div style={styles.modal} onClick={(e) => e.stopPropagation()}>\n {/* 헤더 */}\n <div style={styles.header}>\n <div style={headerLeftStyle}>\n <div style={styles.headerIcon}>\n <MessageIcon size={20} />\n </div>\n <span style={headerTitleStyle}>Help Us Improve</span>\n </div>\n <button onClick={onClose} style={closeButtonStyle}>\n <CloseIcon />\n </button>\n </div>\n\n {/* 컬러 바 */}\n <div style={styles.colorBar} />\n\n {/* 컨텐츠 */}\n <div style={contentStyle}>\n {/* 이슈 타입 */}\n <div style={sectionStyle}>\n <label style={labelStyle}>Feedback Type</label>\n <div style={typeButtonsStyle}>\n <button\n onClick={() => setLabel('bug')}\n style={styles.typeButton(label === 'bug')}\n >\n <span style={typeIconStyle(label === 'bug', 'bug')}>\n <BugIcon />\n </span>\n <span>Bug</span>\n </button>\n <button\n onClick={() => setLabel('feature')}\n style={styles.typeButton(label === 'feature')}\n >\n <span style={typeIconStyle(label === 'feature', 'feature')}>\n <LightbulbIcon />\n </span>\n <span>Feature</span>\n </button>\n </div>\n </div>\n\n {/* 설명 + 이미지 (flex row) */}\n <div style={descriptionRowStyle}>\n {/* 텍스트 영역 */}\n <div style={descriptionColStyle}>\n <label style={labelStyle}>Description</label>\n <div style={textareaWrapperStyle}>\n <textarea\n placeholder={currentPlaceholder}\n value={text}\n maxLength={maxLength}\n onInput={(e) => setText((e.target as HTMLTextAreaElement).value)}\n style={textareaStyle}\n />\n <span style={charCountStyle}>{text.length}/{maxLength}</span>\n </div>\n </div>\n\n {/* 이미지 업로드 (정사각형) */}\n <div style={uploadColStyle}>\n <label style={labelStyle}>Screenshot</label>\n {imagePreview ? (\n <div style={imagePreviewContainerStyle}>\n <img src={imagePreview} alt=\"Preview\" style={imagePreviewSquareStyle} />\n <button onClick={handleRemoveImage} style={removeImageButtonStyle}>\n <CloseIcon />\n </button>\n {isUploading && <div style={uploadingOverlayStyle}>...</div>}\n </div>\n ) : (\n <button\n onClick={() => fileInputRef.current?.click()}\n style={uploadButtonSquareStyle}\n >\n <ImageIcon />\n <span style={{ fontSize: '11px' }}>Upload</span>\n </button>\n )}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileSelect}\n style={{ display: 'none' }}\n />\n </div>\n </div>\n\n {/* 이메일 */}\n {formFields.email.enabled && (\n <div style={sectionStyle}>\n <label style={labelStyle}>\n Email {formFields.email.required ? '' : '(optional)'}\n </label>\n <input\n type=\"email\"\n placeholder=\"your@email.com\"\n value={email}\n onInput={(e) => setEmail((e.target as HTMLInputElement).value)}\n style={inputStyle}\n />\n </div>\n )}\n\n {/* 에러 */}\n {error && <p style={errorStyle}>{error}</p>}\n\n {/* 제출 버튼 */}\n <button\n onClick={handleSubmit}\n disabled={isSubmitting || isUploading}\n style={styles.submitButton(isSubmitting || isUploading)}\n >\n {isSubmitting ? (\n <span style={spinnerContainerStyle}>\n <span className=\"voyage-spinner\" />\n Sending...\n </span>\n ) : (\n i18n.submitLabel\n )}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n// 이미지 처리 유틸: resize + WebP 변환\ninterface ProcessImageOptions {\n maxWidth: number;\n maxHeight: number;\n quality: number;\n}\n\nasync function processImage(file: File, options: ProcessImageOptions): Promise<File> {\n const { maxWidth, maxHeight, quality } = options;\n\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n // 비율 유지하면서 resize 계산\n let { width, height } = img;\n\n if (width > maxWidth || height > maxHeight) {\n const ratio = Math.min(maxWidth / width, maxHeight / height);\n width = Math.round(width * ratio);\n height = Math.round(height * ratio);\n }\n\n // Canvas에 그리기\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n reject(new Error('Failed to get canvas context'));\n return;\n }\n\n ctx.drawImage(img, 0, 0, width, height);\n\n // WebP로 변환\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new Error('Failed to convert image'));\n return;\n }\n\n // Blob을 File로 변환\n const timestamp = Date.now();\n const newFile = new File([blob], `image_${timestamp}.webp`, {\n type: 'image/webp',\n });\n\n resolve(newFile);\n },\n 'image/webp',\n quality\n );\n };\n\n img.onerror = () => reject(new Error('Failed to load image'));\n img.src = URL.createObjectURL(file);\n });\n}\n\n// 정적 스타일 정의 (라이트 테마)\nconst headerLeftStyle: h.JSX.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n};\n\nconst headerTitleStyle: h.JSX.CSSProperties = {\n fontSize: '16px',\n fontWeight: 700,\n color: colors.text,\n};\n\nconst closeButtonStyle: h.JSX.CSSProperties = {\n background: 'transparent',\n border: 'none',\n color: colors.textMuted,\n cursor: 'pointer',\n padding: '8px',\n borderRadius: '8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'all 0.2s',\n};\n\nconst contentStyle: h.JSX.CSSProperties = {\n padding: '16px 20px',\n};\n\nconst sectionStyle: h.JSX.CSSProperties = {\n marginBottom: '14px',\n};\n\nconst labelStyle: h.JSX.CSSProperties = {\n display: 'block',\n fontSize: '13px',\n fontWeight: 600,\n color: colors.text,\n marginBottom: '8px',\n};\n\nconst typeButtonsStyle: h.JSX.CSSProperties = {\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: '12px',\n};\n\nconst descriptionRowStyle: h.JSX.CSSProperties = {\n display: 'flex',\n gap: '14px',\n marginBottom: '14px',\n};\n\nconst descriptionColStyle: h.JSX.CSSProperties = {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n};\n\nconst uploadColStyle: h.JSX.CSSProperties = {\n width: '120px',\n flexShrink: 0,\n display: 'flex',\n flexDirection: 'column',\n};\n\nconst uploadButtonSquareStyle: h.JSX.CSSProperties = {\n width: '100%',\n aspectRatio: '1',\n border: `2px dashed ${colors.border}`,\n borderRadius: '10px',\n backgroundColor: 'transparent',\n cursor: 'pointer',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '4px',\n color: colors.textMuted,\n fontSize: '12px',\n transition: 'all 0.2s',\n};\n\nconst imagePreviewSquareStyle: h.JSX.CSSProperties = {\n width: '100%',\n aspectRatio: '1',\n objectFit: 'cover',\n borderRadius: '10px',\n};\n\nconst typeIconStyle = (active: boolean, type: 'bug' | 'feature'): h.JSX.CSSProperties => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: active\n ? (type === 'bug' ? colors.error : '#F59E0B')\n : colors.textMuted,\n});\n\nconst textareaWrapperStyle: h.JSX.CSSProperties = {\n position: 'relative',\n};\n\nconst textareaStyle: h.JSX.CSSProperties = {\n width: '100%',\n minHeight: '120px',\n padding: '14px',\n border: `1px solid ${colors.border}`,\n borderRadius: '12px',\n fontSize: '14px',\n resize: 'vertical',\n boxSizing: 'border-box',\n backgroundColor: colors.bgLight,\n color: colors.text,\n fontFamily: 'inherit',\n outline: 'none',\n};\n\nconst charCountStyle: h.JSX.CSSProperties = {\n position: 'absolute',\n bottom: '12px',\n right: '14px',\n fontSize: '12px',\n color: colors.textMuted,\n};\n\nconst inputStyle: h.JSX.CSSProperties = {\n width: '100%',\n padding: '10px 12px',\n border: `1px solid ${colors.border}`,\n borderRadius: '10px',\n fontSize: '13px',\n boxSizing: 'border-box',\n backgroundColor: colors.bgLight,\n color: colors.text,\n fontFamily: 'inherit',\n outline: 'none',\n};\n\nconst imagePreviewContainerStyle: h.JSX.CSSProperties = {\n position: 'relative',\n display: 'inline-block',\n borderRadius: '12px',\n overflow: 'hidden',\n};\n\nconst removeImageButtonStyle: h.JSX.CSSProperties = {\n position: 'absolute',\n top: '8px',\n right: '8px',\n width: '28px',\n height: '28px',\n borderRadius: '50%',\n backgroundColor: 'rgba(0, 0, 0, 0.7)',\n color: '#fff',\n border: 'none',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n};\n\nconst uploadingOverlayStyle: h.JSX.CSSProperties = {\n position: 'absolute',\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.7)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n fontSize: '14px',\n borderRadius: '12px',\n};\n\nconst errorStyle: h.JSX.CSSProperties = {\n color: colors.error,\n fontSize: '14px',\n marginBottom: '16px',\n padding: '12px',\n backgroundColor: 'rgba(239, 68, 68, 0.1)',\n borderRadius: '8px',\n border: `1px solid rgba(239, 68, 68, 0.3)`,\n};\n\nconst successContainerStyle: h.JSX.CSSProperties = {\n padding: '48px 24px',\n textAlign: 'center',\n};\n\nconst successIconStyle: h.JSX.CSSProperties = {\n width: '64px',\n height: '64px',\n borderRadius: '50%',\n backgroundColor: 'rgba(34, 197, 94, 0.15)',\n color: colors.success,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: '0 auto 20px',\n};\n\nconst successTitleStyle: h.JSX.CSSProperties = {\n fontSize: '20px',\n fontWeight: 700,\n color: colors.text,\n marginBottom: '8px',\n};\n\nconst successTextStyle: h.JSX.CSSProperties = {\n fontSize: '14px',\n color: colors.textMuted,\n marginBottom: '24px',\n};\n\nconst spinnerContainerStyle: h.JSX.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n};\n","import { h } from 'preact';\nimport { useState, useEffect } from 'preact/hooks';\nimport { Button } from './Button';\nimport { Modal } from './Modal';\nimport type { ProjectConfig, FeedbackData, FeedbackMetadata } from '../types';\n\ninterface WidgetProps {\n config: ProjectConfig;\n onSubmit: (data: FeedbackData) => Promise<boolean>;\n onUpload: (file: File) => Promise<string | null>;\n getMetadata: () => FeedbackMetadata;\n visible: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nexport function Widget({\n config,\n onSubmit,\n onUpload,\n getMetadata,\n visible,\n defaultOpen = false,\n onOpenChange,\n}: WidgetProps) {\n const [isOpen, setIsOpen] = useState(defaultOpen);\n\n useEffect(() => {\n onOpenChange?.(isOpen);\n }, [isOpen, onOpenChange]);\n\n if (!visible) {\n return null;\n }\n\n const { theme, i18n } = config;\n\n return (\n <>\n {!isOpen && (\n <Button\n onClick={() => setIsOpen(true)}\n label={i18n.buttonLabel}\n position={theme.position}\n primaryColor={theme.primaryColor}\n />\n )}\n\n {isOpen && (\n <Modal\n config={config}\n metadata={getMetadata()}\n onClose={() => setIsOpen(false)}\n onSubmit={onSubmit}\n onUpload={onUpload}\n />\n )}\n </>\n );\n}\n","// SDK 전용 CSS 스타일 (동적 주입)\nexport const injectStyles = () => {\n if (typeof document === 'undefined') return;\n if (document.getElementById('voyage-sdk-styles')) return;\n\n const style = document.createElement('style');\n style.id = 'voyage-sdk-styles';\n style.textContent = `\n /* Voyage SDK Styles */\n\n /* Spinner Animation */\n @keyframes voyage-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n #voyage-widget-container * {\n box-sizing: border-box;\n }\n\n #voyage-widget-container button {\n font-family: 'Quicksand', 'Nunito', system-ui, sans-serif;\n }\n\n #voyage-widget-container textarea:focus,\n #voyage-widget-container input:focus {\n border-color: rgba(124, 58, 237, 0.5);\n box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.1);\n }\n\n #voyage-widget-container button:focus {\n outline: none;\n }\n\n /* Spinner */\n .voyage-spinner {\n width: 16px;\n height: 16px;\n border: 2px solid rgba(255,255,255,0.3);\n border-top-color: #fff;\n border-radius: 50%;\n animation: voyage-spin 0.8s linear infinite;\n }\n\n /* Load Quicksand font if not present */\n @import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@400;500;600;700&display=swap');\n `;\n\n document.head.appendChild(style);\n};\n","import type { ProjectConfig, FeedbackData } from '../types';\n\n// Supabase Edge Functions URL\nconst API_BASE = 'https://rxflzurkkuqgopjkshjh.supabase.co/functions/v1';\n\nconst CACHE_KEY = 'voyage_config';\nconst CACHE_TTL = 60 * 60 * 1000; // 1시간\n\ninterface CachedConfig {\n config: ProjectConfig;\n timestamp: number;\n}\n\nexport async function fetchProjectConfig(sdkKey: string): Promise<ProjectConfig | null> {\n // 캐시 확인\n const cached = getFromCache(sdkKey);\n if (cached) {\n return cached;\n }\n\n try {\n const response = await fetch(`${API_BASE}/get-widget-config`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'x-sdk-key': sdkKey,\n },\n });\n\n if (!response.ok) {\n console.error('[Voyage] Failed to fetch config:', response.status);\n return null;\n }\n\n const config = await response.json() as ProjectConfig;\n saveToCache(sdkKey, config);\n return config;\n } catch (error) {\n console.error('[Voyage] Network error:', error);\n // 네트워크 실패 시 캐시 사용 (만료되어도)\n return getFromCache(sdkKey, true);\n }\n}\n\nexport async function submitFeedback(sdkKey: string, data: FeedbackData): Promise<boolean> {\n try {\n const response = await fetch(`${API_BASE}/submit-feedback`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-sdk-key': sdkKey,\n },\n body: JSON.stringify({\n label: data.label,\n content: data.text,\n email: data.email,\n imageUrl: data.imageUrl,\n metadata: data.metadata,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error('[Voyage] Failed to submit feedback:', response.status, errorData);\n return false;\n }\n\n return true;\n } catch (error) {\n console.error('[Voyage] Network error:', error);\n return false;\n }\n}\n\nexport async function uploadImage(sdkKey: string, file: File): Promise<string | null> {\n // 검증\n if (!file.type.startsWith('image/')) {\n console.error('[Voyage] Only image files are allowed');\n return null;\n }\n\n if (file.size > 5 * 1024 * 1024) {\n console.error('[Voyage] Image must be under 5MB');\n return null;\n }\n\n try {\n const formData = new FormData();\n formData.append('file', file);\n\n const response = await fetch(`${API_BASE}/upload-feedback-image`, {\n method: 'POST',\n headers: {\n 'x-sdk-key': sdkKey,\n },\n body: formData,\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error('[Voyage] Failed to upload image:', response.status, errorData);\n return null;\n }\n\n const result = await response.json();\n return result.url;\n } catch (error) {\n console.error('[Voyage] Network error:', error);\n return null;\n }\n}\n\nfunction getFromCache(sdkKey: string, ignoreExpiry = false): ProjectConfig | null {\n try {\n const raw = localStorage.getItem(`${CACHE_KEY}_${sdkKey}`);\n if (!raw) return null;\n\n const cached: CachedConfig = JSON.parse(raw);\n const isExpired = Date.now() - cached.timestamp > CACHE_TTL;\n\n if (isExpired && !ignoreExpiry) {\n return null;\n }\n\n return cached.config;\n } catch {\n return null;\n }\n}\n\nfunction saveToCache(sdkKey: string, config: ProjectConfig): void {\n try {\n const cached: CachedConfig = {\n config,\n timestamp: Date.now(),\n };\n localStorage.setItem(`${CACHE_KEY}_${sdkKey}`, JSON.stringify(cached));\n } catch {\n // localStorage 사용 불가 시 무시\n }\n}\n","import type { FeedbackMetadata } from '../types';\n\nexport function captureMetadata(): FeedbackMetadata {\n return {\n url: window.location.href,\n pathname: window.location.pathname,\n browser: navigator.userAgent,\n viewport: `${window.innerWidth}x${window.innerHeight}`,\n title: document.title,\n timestamp: new Date().toISOString(),\n locale: navigator.language,\n referrer: document.referrer,\n };\n}\n","// @voyage/sdk\n// Feedback Widget SDK for collecting user feedback\n\nimport { h, render } from 'preact';\n\nimport { Widget } from './components';\nimport { injectStyles } from './styles';\nimport { fetchProjectConfig, submitFeedback, uploadImage } from './utils/api';\nimport { captureMetadata } from './utils/metadata';\n\nimport type { VoyageConfig, ProjectConfig, FeedbackData } from './types';\n\nexport type { VoyageConfig, ProjectConfig, FeedbackData, FeedbackMetadata } from './types';\n\nconst DEFAULT_CONFIG: ProjectConfig = {\n projectId: '',\n formFields: {\n email: { enabled: true, required: false },\n category: { enabled: true, options: ['bug', 'feature'] },\n },\n theme: {\n primaryColor: '#0ea5e9',\n position: 'bottom-right',\n },\n i18n: {\n buttonLabel: 'To : the Maker',\n placeholder: 'Describe your ideas to improve our product',\n bugPlaceholder: 'Please describe the bug in detail (e.g., clicked a button and it didn\\'t work)',\n featurePlaceholder: 'Describe your ideas to improve our product (e.g., I want to export TASK.md to Linear tickets)',\n submitLabel: 'Send to the Maker',\n successMessage: 'Thank you for your feedback!',\n },\n};\n\nclass VoyageSDK {\n private config: VoyageConfig | null = null;\n private serverConfig: ProjectConfig | null = null;\n private container: HTMLElement | null = null;\n private isWidgetVisible = false;\n private isModalOpen = false;\n\n async init(config: VoyageConfig): Promise<void> {\n this.config = config;\n\n if (!config.sdkKey) {\n console.error('[Voyage] Invalid SDK Key');\n return;\n }\n\n // Inject SDK styles\n injectStyles();\n\n // Check display control\n if (!this.shouldDisplay()) {\n console.log('[Voyage] Widget hidden by display rules');\n return;\n }\n\n // Fetch server config\n const fetchedConfig = await fetchProjectConfig(config.sdkKey);\n this.serverConfig = this.mergeConfig(fetchedConfig, config);\n\n // Render widget\n this.isWidgetVisible = true;\n this.renderWidget();\n console.log('[Voyage] Initialized');\n }\n\n show(): void {\n if (!this.config) {\n console.warn('[Voyage] SDK not initialized');\n return;\n }\n this.isWidgetVisible = true;\n this.renderWidget();\n }\n\n hide(): void {\n this.isWidgetVisible = false;\n this.renderWidget();\n }\n\n open(): void {\n if (!this.config) {\n console.warn('[Voyage] SDK not initialized');\n return;\n }\n this.isModalOpen = true;\n this.renderWidget();\n }\n\n close(): void {\n this.isModalOpen = false;\n this.renderWidget();\n }\n\n isOpen(): boolean {\n return this.isModalOpen;\n }\n\n isVisible(): boolean {\n return this.isWidgetVisible;\n }\n\n async refreshConfig(): Promise<void> {\n if (!this.config) return;\n const fetchedConfig = await fetchProjectConfig(this.config.sdkKey);\n this.serverConfig = this.mergeConfig(fetchedConfig, this.config);\n this.renderWidget();\n }\n\n destroy(): void {\n if (this.container) {\n render(null, this.container);\n this.container.remove();\n this.container = null;\n }\n this.config = null;\n this.serverConfig = null;\n this.isWidgetVisible = false;\n this.isModalOpen = false;\n }\n\n private renderWidget(): void {\n if (!this.serverConfig || !this.config) return;\n\n // Create container if not exists\n if (!this.container) {\n this.container = document.createElement('div');\n this.container.id = 'voyage-widget-container';\n document.body.appendChild(this.container);\n }\n\n const sdkKey = this.config.sdkKey;\n\n render(\n h(Widget, {\n config: this.serverConfig,\n visible: this.isWidgetVisible,\n defaultOpen: this.isModalOpen,\n onOpenChange: (open: boolean) => {\n this.isModalOpen = open;\n },\n getMetadata: captureMetadata,\n onSubmit: async (data: FeedbackData) => {\n return submitFeedback(sdkKey, data);\n },\n onUpload: async (file: File) => {\n return uploadImage(sdkKey, file);\n },\n }),\n this.container\n );\n }\n\n private mergeConfig(server: ProjectConfig | null, _client: VoyageConfig): ProjectConfig {\n // Server config takes priority: use values set from dashboard\n // Client-side theme override disabled (to prevent config conflicts)\n return server || { ...DEFAULT_CONFIG };\n }\n\n private shouldDisplay(): boolean {\n if (!this.config) return false;\n\n const pathname = window.location.pathname;\n const { include, exclude } = this.config;\n\n // include takes priority over exclude\n if (include && include.length > 0) {\n return include.some((pattern) => this.matchPath(pathname, pattern));\n }\n\n if (exclude && exclude.length > 0) {\n return !exclude.some((pattern) => this.matchPath(pathname, pattern));\n }\n\n return true;\n }\n\n private matchPath(pathname: string, pattern: string): boolean {\n // Simple glob matching: /admin/* matches /admin/anything\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2);\n return pathname.startsWith(prefix);\n }\n return pathname === pattern;\n }\n}\n\n// Singleton instance\nconst Voyage = new VoyageSDK();\n\nexport { Voyage };\nexport default Voyage;\n"]}
1
+ {"version":3,"sources":["../src/components/Button.tsx","../src/components/Modal.tsx","../src/components/Widget.tsx","../src/styles.ts","../src/utils/api.ts","../src/utils/metadata.ts","../src/index.ts"],"names":["MessageIcon","jsx","Button","onClick","label","position","primaryColor","hasError","isHovered","setIsHovered","useState","isPressed","setIsPressed","positionStyle","getTransform","jsxs","size","BugIcon","LightbulbIcon","ImageIcon","CloseIcon","CheckIcon","colors","Modal","config","metadata","onClose","onSubmit","onUpload","setLabel","text","setText","email","setEmail","imageUrl","setImageUrl","imagePreview","setImagePreview","isSubmitting","setIsSubmitting","isUploading","setIsUploading","error","setError","success","setSuccess","fileInputRef","useRef","i18n","formFields","theme","maxLength","currentPlaceholder","handleFileSelect","e","file","processedFile","processImage","reader","url","err","handleRemoveImage","handleSubmit","feedbackData","result","styles","primaryBgLight","active","disabled","successContainerStyle","successIconStyle","successTitleStyle","successTextStyle","headerLeftStyle","headerTitleStyle","closeButtonStyle","contentStyle","sectionStyle","labelStyle","typeButtonsStyle","typeIconStyle","descriptionRowStyle","descriptionColStyle","textareaWrapperStyle","textareaStyle","charCountStyle","uploadColStyle","imagePreviewContainerStyle","imagePreviewSquareStyle","removeImageButtonStyle","uploadingOverlayStyle","uploadButtonSquareStyle","inputStyle","errorStyle","spinnerContainerStyle","options","maxWidth","maxHeight","quality","resolve","reject","img","width","height","ratio","canvas","ctx","blob","timestamp","newFile","type","Widget","getMetadata","visible","defaultOpen","onOpenChange","isOpen","setIsOpen","useEffect","Fragment","injectStyles","style","API_BASE","CACHE_KEY","fetchProjectConfig","sdkKey","cached","getFromCache","response","saveToCache","submitFeedback","data","errorData","uploadImage","formData","ignoreExpiry","raw","captureMetadata","DEFAULT_CONFIG","VoyageSDK","fetchedConfig","render","h","open","server","_client","pathname","include","exclude","pattern","prefix","Voyage","index_default"],"mappings":"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","file":"index.js","sourcesContent":["import { h } from 'preact';\nimport { useState } from 'preact/hooks';\n\ninterface ButtonProps {\n onClick: () => void;\n label: string;\n position: 'bottom-right' | 'bottom-left';\n primaryColor: string;\n hasError?: boolean;\n}\n\n// 말풍선 아이콘 SVG\nfunction MessageIcon() {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n );\n}\n\n// 에러 아이콘 (느낌표)\nfunction ErrorIcon() {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"#fff\"\n stroke=\"none\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"#EF4444\" />\n <text x=\"12\" y=\"17\" textAnchor=\"middle\" fill=\"#fff\" fontSize=\"14\" fontWeight=\"bold\">!</text>\n </svg>\n );\n}\n\nexport function Button({ onClick, label, position, primaryColor, hasError = false }: ButtonProps) {\n const [isHovered, setIsHovered] = useState(false);\n const [isPressed, setIsPressed] = useState(false);\n\n const positionStyle = position === 'bottom-right'\n ? { right: '24px' }\n : { left: '24px' };\n\n // Jelly 효과 transform\n const getTransform = () => {\n if (isPressed) return 'scale(0.95)';\n if (isHovered) return 'scale(1.02) translateY(-2px)';\n return 'scale(1)';\n };\n\n return (\n <div style={{ position: 'fixed', bottom: '24px', ...positionStyle, zIndex: 9998 }}>\n <button\n onClick={onClick}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => { setIsHovered(false); setIsPressed(false); }}\n onMouseDown={() => setIsPressed(true)}\n onMouseUp={() => setIsPressed(false)}\n style={{\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n padding: '14px 24px',\n border: 'none',\n borderRadius: '50px',\n cursor: 'pointer',\n fontFamily: \"'Quicksand', 'Nunito', system-ui, sans-serif\",\n fontSize: '15px',\n fontWeight: 600,\n color: '#fff',\n // primaryColor 적용\n backgroundColor: primaryColor,\n // 그림자 + glow 효과\n boxShadow: isHovered\n ? `0 8px 32px ${primaryColor}60, 0 0 20px ${primaryColor}40`\n : `0 4px 20px ${primaryColor}50, 0 0 10px ${primaryColor}30`,\n // Jelly 애니메이션\n transform: getTransform(),\n transition: 'all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1)',\n }}\n >\n <MessageIcon />\n <span>{label}</span>\n </button>\n {/* 에러 아이콘 - 우측 상단 */}\n {hasError && (\n <div\n style={{\n position: 'absolute',\n top: '-4px',\n right: '-4px',\n width: '18px',\n height: '18px',\n borderRadius: '50%',\n backgroundColor: '#EF4444',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n fontSize: '12px',\n fontWeight: 'bold',\n boxShadow: '0 2px 6px rgba(239, 68, 68, 0.5)',\n }}\n >\n !\n </div>\n )}\n </div>\n );\n}\n","import { h } from 'preact';\nimport { useRef, useState } from 'preact/hooks';\n\nimport type { ProjectConfig, FeedbackData, FeedbackMetadata } from '../types';\n\ninterface ModalProps {\n config: ProjectConfig;\n metadata: FeedbackMetadata;\n onClose: () => void;\n onSubmit: (data: FeedbackData) => Promise<boolean>;\n onUpload: (file: File) => Promise<string | null>;\n}\n\n// 아이콘들\nfunction MessageIcon({ size = 24 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n );\n}\n\nfunction BugIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M8 2l1.88 1.88M14.12 3.88L16 2M9 7.13v-1a3.003 3.003 0 116 0v1\" />\n <path d=\"M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 014-4h4a4 4 0 014 4v3c0 3.3-2.7 6-6 6\" />\n <path d=\"M12 20v-9M6.53 9C4.6 8.8 3 7.1 3 5M6 13H2M6 17l-4 1M17.47 9c1.93-.2 3.53-1.9 3.53-4M18 13h4M18 17l4 1\" />\n </svg>\n );\n}\n\nfunction LightbulbIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 006 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\" />\n <path d=\"M9 18h6M10 22h4\" />\n </svg>\n );\n}\n\nfunction ImageIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" />\n <polyline points=\"21 15 16 10 5 21\" />\n </svg>\n );\n}\n\nfunction CloseIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n\nfunction CheckIcon() {\n return (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n );\n}\n\n// 라이트 테마 색상\nconst colors = {\n bg: '#FFFFFF',\n bgLight: '#F8FAFC',\n bgCard: 'rgba(255, 255, 255, 0.98)',\n border: 'rgba(0, 0, 0, 0.08)',\n borderLight: 'rgba(0, 0, 0, 0.12)',\n text: '#1F2937',\n textMuted: '#6B7280',\n error: '#EF4444',\n success: '#22C55E',\n};\n\nexport function Modal({ config, metadata, onClose, onSubmit, onUpload }: ModalProps) {\n const [label, setLabel] = useState<'bug' | 'feature' | null>(null);\n const [text, setText] = useState('');\n const [email, setEmail] = useState('');\n const [imageUrl, setImageUrl] = useState<string | null>(null);\n const [imagePreview, setImagePreview] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isUploading, setIsUploading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [success, setSuccess] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const { i18n, formFields, theme } = config;\n const primaryColor = theme.primaryColor || '#0ea5e9';\n const maxLength = 400;\n\n // 동적 placeholder\n const currentPlaceholder = label === 'bug'\n ? (i18n.bugPlaceholder || i18n.placeholder)\n : (i18n.featurePlaceholder || i18n.placeholder);\n\n const handleFileSelect = async (e: Event) => {\n const target = e.target as HTMLInputElement;\n const file = target.files?.[0];\n if (!file) return;\n\n if (!file.type.startsWith('image/')) {\n setError('Only image files are allowed');\n return;\n }\n if (file.size > 10 * 1024 * 1024) {\n setError('Image must be under 10MB');\n return;\n }\n\n setIsUploading(true);\n setError(null);\n\n try {\n // 이미지를 WebP로 변환 및 resize\n const processedFile = await processImage(file, {\n maxWidth: 1920,\n maxHeight: 1080,\n quality: 0.8,\n });\n\n // 프리뷰 생성\n const reader = new FileReader();\n reader.onload = () => setImagePreview(reader.result as string);\n reader.readAsDataURL(processedFile);\n\n const url = await onUpload(processedFile);\n setIsUploading(false);\n\n if (url) {\n setImageUrl(url);\n } else {\n setError('Failed to upload image');\n setImagePreview(null);\n }\n } catch (err) {\n console.error('[Voyage] Image processing error:', err);\n setIsUploading(false);\n setError('Failed to process image');\n }\n };\n\n const handleRemoveImage = () => {\n setImageUrl(null);\n setImagePreview(null);\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n };\n\n const handleSubmit = async () => {\n if (!label) {\n setError('Please select a type');\n return;\n }\n if (!text.trim()) {\n setError('Please enter your feedback');\n return;\n }\n if (formFields.email.required && !email.trim()) {\n setError('Please enter your email');\n return;\n }\n\n setIsSubmitting(true);\n setError(null);\n\n const feedbackData: FeedbackData = {\n label,\n text: text.trim(),\n email: email.trim() || undefined,\n imageUrl: imageUrl || undefined,\n metadata,\n };\n\n const result = await onSubmit(feedbackData);\n setIsSubmitting(false);\n\n if (result) {\n setSuccess(true);\n } else {\n setError('Failed to submit. Please try again.');\n }\n };\n\n // 스타일 함수 (primaryColor 적용)\n const getStyles = () => {\n const primaryBgLight = `${primaryColor}15`;\n\n return {\n overlay: {\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.4)',\n backdropFilter: 'blur(4px)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 9999,\n padding: '20px',\n } as h.JSX.CSSProperties,\n\n modal: {\n backgroundColor: colors.bgCard,\n backdropFilter: 'blur(20px)',\n borderRadius: '20px',\n width: '100%',\n maxWidth: '580px',\n maxHeight: '90vh',\n overflowY: 'auto',\n position: 'relative',\n fontFamily: \"'Quicksand', 'Nunito', system-ui, sans-serif\",\n border: `1px solid ${colors.border}`,\n boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.15)',\n } as h.JSX.CSSProperties,\n\n colorBar: {\n height: '4px',\n backgroundColor: primaryColor,\n } as h.JSX.CSSProperties,\n\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '14px 20px',\n borderBottom: `1px solid ${colors.border}`,\n backgroundColor: colors.bgLight,\n } as h.JSX.CSSProperties,\n\n headerIcon: {\n width: '32px',\n height: '32px',\n borderRadius: '10px',\n backgroundColor: primaryColor,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n } as h.JSX.CSSProperties,\n\n typeButton: (active: boolean) => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '6px',\n padding: '10px 12px',\n border: active ? `2px solid ${primaryColor}` : `1px solid ${colors.border}`,\n borderRadius: '10px',\n backgroundColor: active ? primaryBgLight : colors.bgLight,\n cursor: 'pointer',\n fontWeight: 600,\n fontSize: '13px',\n color: active ? colors.text : colors.textMuted,\n transition: 'all 0.2s',\n } as h.JSX.CSSProperties),\n\n submitButton: (disabled: boolean) => ({\n width: '100%',\n padding: '12px',\n backgroundColor: disabled ? colors.bgLight : primaryColor,\n color: disabled ? colors.textMuted : '#fff',\n border: 'none',\n borderRadius: '12px',\n fontSize: '15px',\n fontWeight: 700,\n cursor: disabled ? 'not-allowed' : 'pointer',\n fontFamily: 'inherit',\n transition: 'all 0.2s',\n boxShadow: disabled ? 'none' : `0 4px 15px ${primaryColor}40`,\n } as h.JSX.CSSProperties),\n\n primaryButton: {\n width: '100%',\n padding: '16px',\n backgroundColor: primaryColor,\n color: '#fff',\n border: 'none',\n borderRadius: '12px',\n fontSize: '15px',\n fontWeight: 700,\n cursor: 'pointer',\n fontFamily: 'inherit',\n marginTop: '8px',\n } as h.JSX.CSSProperties,\n };\n };\n\n const styles = getStyles();\n\n // 성공 화면\n if (success) {\n return (\n <div style={styles.overlay}>\n <div style={styles.modal}>\n <div style={successContainerStyle}>\n <div style={successIconStyle}>\n <CheckIcon />\n </div>\n <h3 style={successTitleStyle}>{i18n.successMessage}</h3>\n <p style={successTextStyle}>Your voice shapes what we build next.</p>\n <button onClick={onClose} style={styles.primaryButton}>\n Done\n </button>\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div style={styles.overlay} onClick={onClose}>\n <div style={styles.modal} onClick={(e) => e.stopPropagation()}>\n {/* 헤더 */}\n <div style={styles.header}>\n <div style={headerLeftStyle}>\n <div style={styles.headerIcon}>\n <MessageIcon size={20} />\n </div>\n <span style={headerTitleStyle}>Help Us Improve</span>\n </div>\n <button onClick={onClose} style={closeButtonStyle}>\n <CloseIcon />\n </button>\n </div>\n\n {/* 컬러 바 */}\n <div style={styles.colorBar} />\n\n {/* 컨텐츠 */}\n <div style={contentStyle}>\n {/* 이슈 타입 */}\n <div style={sectionStyle}>\n <label style={labelStyle}>Feedback Type</label>\n <div style={typeButtonsStyle}>\n <button\n onClick={() => setLabel('bug')}\n style={styles.typeButton(label === 'bug')}\n >\n <span style={typeIconStyle(label === 'bug', 'bug')}>\n <BugIcon />\n </span>\n <span>Bug</span>\n </button>\n <button\n onClick={() => setLabel('feature')}\n style={styles.typeButton(label === 'feature')}\n >\n <span style={typeIconStyle(label === 'feature', 'feature')}>\n <LightbulbIcon />\n </span>\n <span>Feature</span>\n </button>\n </div>\n </div>\n\n {/* 설명 + 이미지 (flex row) */}\n <div style={descriptionRowStyle}>\n {/* 텍스트 영역 */}\n <div style={descriptionColStyle}>\n <label style={labelStyle}>Description</label>\n <div style={textareaWrapperStyle}>\n <textarea\n placeholder={currentPlaceholder}\n value={text}\n maxLength={maxLength}\n onInput={(e) => setText((e.target as HTMLTextAreaElement).value)}\n style={textareaStyle}\n />\n <span style={charCountStyle}>{text.length}/{maxLength}</span>\n </div>\n </div>\n\n {/* 이미지 업로드 (정사각형) */}\n <div style={uploadColStyle}>\n <label style={labelStyle}>Screenshot</label>\n {imagePreview ? (\n <div style={imagePreviewContainerStyle}>\n <img src={imagePreview} alt=\"Preview\" style={imagePreviewSquareStyle} />\n <button onClick={handleRemoveImage} style={removeImageButtonStyle}>\n <CloseIcon />\n </button>\n {isUploading && <div style={uploadingOverlayStyle}>...</div>}\n </div>\n ) : (\n <button\n onClick={() => fileInputRef.current?.click()}\n style={uploadButtonSquareStyle}\n >\n <ImageIcon />\n <span style={{ fontSize: '11px' }}>Upload</span>\n </button>\n )}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileSelect}\n style={{ display: 'none' }}\n />\n </div>\n </div>\n\n {/* 이메일 */}\n {formFields.email.enabled && (\n <div style={sectionStyle}>\n <label style={labelStyle}>\n Email {formFields.email.required ? '' : '(optional)'}\n </label>\n <input\n type=\"email\"\n placeholder=\"your@email.com\"\n value={email}\n onInput={(e) => setEmail((e.target as HTMLInputElement).value)}\n style={inputStyle}\n />\n </div>\n )}\n\n {/* 에러 */}\n {error && <p style={errorStyle}>{error}</p>}\n\n {/* 제출 버튼 */}\n <button\n onClick={handleSubmit}\n disabled={isSubmitting || isUploading}\n style={styles.submitButton(isSubmitting || isUploading)}\n >\n {isSubmitting ? (\n <span style={spinnerContainerStyle}>\n <span className=\"voyage-spinner\" />\n Sending...\n </span>\n ) : (\n i18n.submitLabel\n )}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n// 이미지 처리 유틸: resize + WebP 변환\ninterface ProcessImageOptions {\n maxWidth: number;\n maxHeight: number;\n quality: number;\n}\n\nasync function processImage(file: File, options: ProcessImageOptions): Promise<File> {\n const { maxWidth, maxHeight, quality } = options;\n\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n // 비율 유지하면서 resize 계산\n let { width, height } = img;\n\n if (width > maxWidth || height > maxHeight) {\n const ratio = Math.min(maxWidth / width, maxHeight / height);\n width = Math.round(width * ratio);\n height = Math.round(height * ratio);\n }\n\n // Canvas에 그리기\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n reject(new Error('Failed to get canvas context'));\n return;\n }\n\n ctx.drawImage(img, 0, 0, width, height);\n\n // WebP로 변환\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new Error('Failed to convert image'));\n return;\n }\n\n // Blob을 File로 변환\n const timestamp = Date.now();\n const newFile = new File([blob], `image_${timestamp}.webp`, {\n type: 'image/webp',\n });\n\n resolve(newFile);\n },\n 'image/webp',\n quality\n );\n };\n\n img.onerror = () => reject(new Error('Failed to load image'));\n img.src = URL.createObjectURL(file);\n });\n}\n\n// 정적 스타일 정의 (라이트 테마)\nconst headerLeftStyle: h.JSX.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n};\n\nconst headerTitleStyle: h.JSX.CSSProperties = {\n fontSize: '16px',\n fontWeight: 700,\n color: colors.text,\n};\n\nconst closeButtonStyle: h.JSX.CSSProperties = {\n background: 'transparent',\n border: 'none',\n color: colors.textMuted,\n cursor: 'pointer',\n padding: '8px',\n borderRadius: '8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'all 0.2s',\n};\n\nconst contentStyle: h.JSX.CSSProperties = {\n padding: '16px 20px',\n};\n\nconst sectionStyle: h.JSX.CSSProperties = {\n marginBottom: '14px',\n};\n\nconst labelStyle: h.JSX.CSSProperties = {\n display: 'block',\n fontSize: '13px',\n fontWeight: 600,\n color: colors.text,\n marginBottom: '8px',\n};\n\nconst typeButtonsStyle: h.JSX.CSSProperties = {\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: '12px',\n};\n\nconst descriptionRowStyle: h.JSX.CSSProperties = {\n display: 'flex',\n gap: '14px',\n marginBottom: '14px',\n};\n\nconst descriptionColStyle: h.JSX.CSSProperties = {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n};\n\nconst uploadColStyle: h.JSX.CSSProperties = {\n width: '120px',\n flexShrink: 0,\n display: 'flex',\n flexDirection: 'column',\n};\n\nconst uploadButtonSquareStyle: h.JSX.CSSProperties = {\n width: '100%',\n aspectRatio: '1',\n border: `2px dashed ${colors.border}`,\n borderRadius: '10px',\n backgroundColor: 'transparent',\n cursor: 'pointer',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '4px',\n color: colors.textMuted,\n fontSize: '12px',\n transition: 'all 0.2s',\n};\n\nconst imagePreviewSquareStyle: h.JSX.CSSProperties = {\n width: '100%',\n aspectRatio: '1',\n objectFit: 'cover',\n borderRadius: '10px',\n};\n\nconst typeIconStyle = (active: boolean, type: 'bug' | 'feature'): h.JSX.CSSProperties => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: active\n ? (type === 'bug' ? colors.error : '#F59E0B')\n : colors.textMuted,\n});\n\nconst textareaWrapperStyle: h.JSX.CSSProperties = {\n position: 'relative',\n};\n\nconst textareaStyle: h.JSX.CSSProperties = {\n width: '100%',\n minHeight: '120px',\n padding: '14px',\n border: `1px solid ${colors.border}`,\n borderRadius: '12px',\n fontSize: '14px',\n resize: 'vertical',\n boxSizing: 'border-box',\n backgroundColor: colors.bgLight,\n color: colors.text,\n fontFamily: 'inherit',\n outline: 'none',\n};\n\nconst charCountStyle: h.JSX.CSSProperties = {\n position: 'absolute',\n bottom: '12px',\n right: '14px',\n fontSize: '12px',\n color: colors.textMuted,\n};\n\nconst inputStyle: h.JSX.CSSProperties = {\n width: '100%',\n padding: '10px 12px',\n border: `1px solid ${colors.border}`,\n borderRadius: '10px',\n fontSize: '13px',\n boxSizing: 'border-box',\n backgroundColor: colors.bgLight,\n color: colors.text,\n fontFamily: 'inherit',\n outline: 'none',\n};\n\nconst imagePreviewContainerStyle: h.JSX.CSSProperties = {\n position: 'relative',\n display: 'inline-block',\n borderRadius: '12px',\n overflow: 'hidden',\n};\n\nconst removeImageButtonStyle: h.JSX.CSSProperties = {\n position: 'absolute',\n top: '8px',\n right: '8px',\n width: '28px',\n height: '28px',\n borderRadius: '50%',\n backgroundColor: 'rgba(0, 0, 0, 0.7)',\n color: '#fff',\n border: 'none',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n};\n\nconst uploadingOverlayStyle: h.JSX.CSSProperties = {\n position: 'absolute',\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.7)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n fontSize: '14px',\n borderRadius: '12px',\n};\n\nconst errorStyle: h.JSX.CSSProperties = {\n color: colors.error,\n fontSize: '14px',\n marginBottom: '16px',\n padding: '12px',\n backgroundColor: 'rgba(239, 68, 68, 0.1)',\n borderRadius: '8px',\n border: `1px solid rgba(239, 68, 68, 0.3)`,\n};\n\nconst successContainerStyle: h.JSX.CSSProperties = {\n padding: '48px 24px',\n textAlign: 'center',\n};\n\nconst successIconStyle: h.JSX.CSSProperties = {\n width: '64px',\n height: '64px',\n borderRadius: '50%',\n backgroundColor: 'rgba(34, 197, 94, 0.15)',\n color: colors.success,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: '0 auto 20px',\n};\n\nconst successTitleStyle: h.JSX.CSSProperties = {\n fontSize: '20px',\n fontWeight: 700,\n color: colors.text,\n marginBottom: '8px',\n};\n\nconst successTextStyle: h.JSX.CSSProperties = {\n fontSize: '14px',\n color: colors.textMuted,\n marginBottom: '24px',\n};\n\nconst spinnerContainerStyle: h.JSX.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n};\n","import { h } from 'preact';\nimport { useState, useEffect } from 'preact/hooks';\nimport { Button } from './Button';\nimport { Modal } from './Modal';\nimport type { ProjectConfig, FeedbackData, FeedbackMetadata } from '../types';\n\ninterface WidgetProps {\n config: ProjectConfig;\n onSubmit: (data: FeedbackData) => Promise<boolean>;\n onUpload: (file: File) => Promise<string | null>;\n getMetadata: () => FeedbackMetadata;\n visible: boolean;\n defaultOpen?: boolean;\n hasError?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nexport function Widget({\n config,\n onSubmit,\n onUpload,\n getMetadata,\n visible,\n defaultOpen = false,\n hasError = false,\n onOpenChange,\n}: WidgetProps) {\n const [isOpen, setIsOpen] = useState(defaultOpen);\n\n // SDK에서 open()/close() 호출 시 동기화\n useEffect(() => {\n setIsOpen(defaultOpen);\n }, [defaultOpen]);\n\n useEffect(() => {\n onOpenChange?.(isOpen);\n }, [isOpen, onOpenChange]);\n\n if (!visible) {\n return null;\n }\n\n const { theme, i18n } = config;\n\n return (\n <>\n {!isOpen && (\n <Button\n onClick={() => setIsOpen(true)}\n label={i18n.buttonLabel}\n position={theme.position}\n primaryColor={theme.primaryColor}\n hasError={hasError}\n />\n )}\n\n {isOpen && (\n <Modal\n config={config}\n metadata={getMetadata()}\n onClose={() => setIsOpen(false)}\n onSubmit={onSubmit}\n onUpload={onUpload}\n />\n )}\n </>\n );\n}\n","// SDK 전용 CSS 스타일 (동적 주입)\nexport const injectStyles = () => {\n if (typeof document === 'undefined') return;\n if (document.getElementById('voyage-sdk-styles')) return;\n\n const style = document.createElement('style');\n style.id = 'voyage-sdk-styles';\n style.textContent = `\n /* Voyage SDK Styles */\n\n /* Spinner Animation */\n @keyframes voyage-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n #voyage-widget-container * {\n box-sizing: border-box;\n }\n\n #voyage-widget-container button {\n font-family: 'Quicksand', 'Nunito', system-ui, sans-serif;\n }\n\n #voyage-widget-container textarea:focus,\n #voyage-widget-container input:focus {\n border-color: rgba(124, 58, 237, 0.5);\n box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.1);\n }\n\n #voyage-widget-container button:focus {\n outline: none;\n }\n\n /* Spinner */\n .voyage-spinner {\n width: 16px;\n height: 16px;\n border: 2px solid rgba(255,255,255,0.3);\n border-top-color: #fff;\n border-radius: 50%;\n animation: voyage-spin 0.8s linear infinite;\n }\n\n /* Load Quicksand font if not present */\n @import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@400;500;600;700&display=swap');\n `;\n\n document.head.appendChild(style);\n};\n","import type { ProjectConfig, FeedbackData } from '../types';\n\n// Supabase Edge Functions URL\nconst API_BASE = 'https://rxflzurkkuqgopjkshjh.supabase.co/functions/v1';\n\nconst CACHE_KEY = 'voyage_config';\nconst CACHE_TTL = 60 * 60 * 1000; // 1시간\n\ninterface CachedConfig {\n config: ProjectConfig;\n timestamp: number;\n}\n\nexport async function fetchProjectConfig(sdkKey: string): Promise<ProjectConfig | null> {\n // 캐시 확인\n const cached = getFromCache(sdkKey);\n if (cached) {\n return cached;\n }\n\n try {\n const response = await fetch(`${API_BASE}/get-widget-config`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'x-sdk-key': sdkKey,\n },\n });\n\n if (!response.ok) {\n console.error('[Voyage] Failed to fetch config:', response.status);\n return null;\n }\n\n const config = await response.json() as ProjectConfig;\n saveToCache(sdkKey, config);\n return config;\n } catch (error) {\n console.error('[Voyage] Network error:', error);\n // 네트워크 실패 시 캐시 사용 (만료되어도)\n return getFromCache(sdkKey, true);\n }\n}\n\nexport async function submitFeedback(sdkKey: string, data: FeedbackData): Promise<boolean> {\n try {\n const response = await fetch(`${API_BASE}/submit-feedback`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-sdk-key': sdkKey,\n },\n body: JSON.stringify({\n label: data.label,\n content: data.text,\n email: data.email,\n imageUrl: data.imageUrl,\n metadata: data.metadata,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error('[Voyage] Failed to submit feedback:', response.status, errorData);\n return false;\n }\n\n return true;\n } catch (error) {\n console.error('[Voyage] Network error:', error);\n return false;\n }\n}\n\nexport async function uploadImage(sdkKey: string, file: File): Promise<string | null> {\n // 검증\n if (!file.type.startsWith('image/')) {\n console.error('[Voyage] Only image files are allowed');\n return null;\n }\n\n if (file.size > 5 * 1024 * 1024) {\n console.error('[Voyage] Image must be under 5MB');\n return null;\n }\n\n try {\n const formData = new FormData();\n formData.append('file', file);\n\n const response = await fetch(`${API_BASE}/upload-feedback-image`, {\n method: 'POST',\n headers: {\n 'x-sdk-key': sdkKey,\n },\n body: formData,\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error('[Voyage] Failed to upload image:', response.status, errorData);\n return null;\n }\n\n const result = await response.json();\n return result.url;\n } catch (error) {\n console.error('[Voyage] Network error:', error);\n return null;\n }\n}\n\nfunction getFromCache(sdkKey: string, ignoreExpiry = false): ProjectConfig | null {\n try {\n const raw = localStorage.getItem(`${CACHE_KEY}_${sdkKey}`);\n if (!raw) return null;\n\n const cached: CachedConfig = JSON.parse(raw);\n const isExpired = Date.now() - cached.timestamp > CACHE_TTL;\n\n if (isExpired && !ignoreExpiry) {\n return null;\n }\n\n return cached.config;\n } catch {\n return null;\n }\n}\n\nfunction saveToCache(sdkKey: string, config: ProjectConfig): void {\n try {\n const cached: CachedConfig = {\n config,\n timestamp: Date.now(),\n };\n localStorage.setItem(`${CACHE_KEY}_${sdkKey}`, JSON.stringify(cached));\n } catch {\n // localStorage 사용 불가 시 무시\n }\n}\n","import type { FeedbackMetadata } from '../types';\n\nexport function captureMetadata(): FeedbackMetadata {\n return {\n url: window.location.href,\n pathname: window.location.pathname,\n browser: navigator.userAgent,\n viewport: `${window.innerWidth}x${window.innerHeight}`,\n title: document.title,\n timestamp: new Date().toISOString(),\n locale: navigator.language,\n referrer: document.referrer,\n };\n}\n","// @voyage/sdk\n// Feedback Widget SDK for collecting user feedback\n\nimport { h, render } from 'preact';\n\nimport { Widget } from './components';\nimport { injectStyles } from './styles';\nimport { fetchProjectConfig, submitFeedback, uploadImage } from './utils/api';\nimport { captureMetadata } from './utils/metadata';\n\nimport type { VoyageConfig, ProjectConfig, FeedbackData } from './types';\n\nexport type { VoyageConfig, ProjectConfig, FeedbackData, FeedbackMetadata } from './types';\n\nconst DEFAULT_CONFIG: ProjectConfig = {\n projectId: '',\n formFields: {\n email: { enabled: true, required: false },\n category: { enabled: true, options: ['bug', 'feature'] },\n },\n theme: {\n primaryColor: '#0ea5e9',\n position: 'bottom-right',\n },\n i18n: {\n buttonLabel: 'To : the Maker',\n placeholder: 'Describe your ideas to improve our product',\n bugPlaceholder: 'Please describe the bug in detail (e.g., clicked a button and it didn\\'t work)',\n featurePlaceholder: 'Describe your ideas to improve our product (e.g., I want to export TASK.md to Linear tickets)',\n submitLabel: 'Send to the Maker',\n successMessage: 'Thank you for your feedback!',\n },\n};\n\nclass VoyageSDK {\n private config: VoyageConfig | null = null;\n private serverConfig: ProjectConfig | null = null;\n private container: HTMLElement | null = null;\n private isWidgetVisible = false;\n private isModalOpen = false;\n private hasInitError = false;\n\n async init(config: VoyageConfig): Promise<void> {\n this.config = config;\n this.hasInitError = false;\n\n if (!config.sdkKey) {\n console.error('[Voyage] SDK Key is required. Get your key from the dashboard.');\n this.hasInitError = true;\n injectStyles();\n this.isWidgetVisible = true;\n this.serverConfig = { ...DEFAULT_CONFIG };\n this.renderWidget();\n return;\n }\n\n // Inject SDK styles\n injectStyles();\n\n // Check display control\n if (!this.shouldDisplay()) {\n console.log('[Voyage] Widget hidden by display rules');\n return;\n }\n\n // Fetch server config\n const fetchedConfig = await fetchProjectConfig(config.sdkKey);\n\n if (!fetchedConfig) {\n console.error('[Voyage] Failed to fetch config. Check your SDK Key or network connection.');\n this.hasInitError = true;\n this.serverConfig = { ...DEFAULT_CONFIG };\n this.isWidgetVisible = true;\n this.renderWidget();\n return;\n }\n\n this.serverConfig = this.mergeConfig(fetchedConfig, config);\n\n // Render widget\n this.isWidgetVisible = true;\n this.renderWidget();\n console.log('[Voyage] Initialized');\n }\n\n show(): void {\n if (!this.config) {\n console.warn('[Voyage] SDK not initialized');\n return;\n }\n this.isWidgetVisible = true;\n this.renderWidget();\n }\n\n hide(): void {\n this.isWidgetVisible = false;\n this.renderWidget();\n }\n\n open(): void {\n if (!this.config) {\n console.warn('[Voyage] SDK not initialized');\n return;\n }\n this.isModalOpen = true;\n this.renderWidget();\n }\n\n close(): void {\n this.isModalOpen = false;\n this.renderWidget();\n }\n\n isOpen(): boolean {\n return this.isModalOpen;\n }\n\n isVisible(): boolean {\n return this.isWidgetVisible;\n }\n\n async refreshConfig(): Promise<void> {\n if (!this.config) return;\n const fetchedConfig = await fetchProjectConfig(this.config.sdkKey);\n this.serverConfig = this.mergeConfig(fetchedConfig, this.config);\n this.renderWidget();\n }\n\n destroy(): void {\n if (this.container) {\n render(null, this.container);\n this.container.remove();\n this.container = null;\n }\n this.config = null;\n this.serverConfig = null;\n this.isWidgetVisible = false;\n this.isModalOpen = false;\n }\n\n private renderWidget(): void {\n if (!this.serverConfig || !this.config) return;\n\n // Create container if not exists\n if (!this.container) {\n this.container = document.createElement('div');\n this.container.id = 'voyage-widget-container';\n document.body.appendChild(this.container);\n }\n\n const sdkKey = this.config.sdkKey;\n\n render(\n h(Widget, {\n config: this.serverConfig,\n visible: this.isWidgetVisible,\n defaultOpen: this.isModalOpen,\n hasError: this.hasInitError,\n onOpenChange: (open: boolean) => {\n this.isModalOpen = open;\n },\n getMetadata: captureMetadata,\n onSubmit: async (data: FeedbackData) => {\n return submitFeedback(sdkKey, data);\n },\n onUpload: async (file: File) => {\n return uploadImage(sdkKey, file);\n },\n }),\n this.container\n );\n }\n\n private mergeConfig(server: ProjectConfig | null, _client: VoyageConfig): ProjectConfig {\n // Server config takes priority: use values set from dashboard\n // Client-side theme override disabled (to prevent config conflicts)\n return server || { ...DEFAULT_CONFIG };\n }\n\n private shouldDisplay(): boolean {\n if (!this.config) return false;\n\n const pathname = window.location.pathname;\n const { include, exclude } = this.config;\n\n // include takes priority over exclude\n if (include && include.length > 0) {\n return include.some((pattern) => this.matchPath(pathname, pattern));\n }\n\n if (exclude && exclude.length > 0) {\n return !exclude.some((pattern) => this.matchPath(pathname, pattern));\n }\n\n return true;\n }\n\n private matchPath(pathname: string, pattern: string): boolean {\n // Simple glob matching: /admin/* matches /admin/anything\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2);\n return pathname.startsWith(prefix);\n }\n return pathname === pattern;\n }\n}\n\n// Singleton instance\nconst Voyage = new VoyageSDK();\n\nexport { Voyage };\nexport default Voyage;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyage-sdk/core",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Voyage Feedback Widget SDK - Collect user feedback with ease",
5
5
  "author": "Voyage",
6
6
  "homepage": "https://voyagefeedback.com",