@pitangent/feedback-system 1.0.2 → 1.0.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.js CHANGED
@@ -54,4 +54,4 @@
54
54
  transform: ${a} !important;
55
55
  }
56
56
  `)});let A=document.createElement("style");A.id="temp-fixed-style",A.innerHTML=V.join(`
57
- `),document.head.appendChild(A);try{let s=document.documentElement;N=await(0,$e.toPng)(s,{width:window.innerWidth,height:window.innerHeight,canvasWidth:window.innerWidth,canvasHeight:window.innerHeight,pixelRatio:window.devicePixelRatio,filter:U=>{if(U instanceof HTMLElement||U&&"classList"in U){let z=U;if(z.classList&&z.classList.contains("feedback-no-capture"))return!1}return!0},style:{transform:`translate(-${u}px, -${D}px)`,transformOrigin:"top left",width:`${s.scrollWidth}px`,height:`${s.scrollHeight}px`}})}catch(s){console.warn("html2canvas direct capture failed, falling back to display media stream:",s);let U;try{U=await navigator.mediaDevices.getDisplayMedia({video:{displaySurface:"browser"},audio:!1,preferCurrentTab:!0,selfBrowserSurface:"include"})}catch(d){let a=d;if(a?.name==="NotAllowedError"||a?.name==="AbortError")throw a;U=await navigator.mediaDevices.getDisplayMedia({video:!0})}let z=document.createElement("video");z.srcObject=U,z.muted=!0,z.playsInline=!0,await new Promise(d=>{z.onloadedmetadata=()=>{z.play().then(()=>d()).catch(()=>d())},setTimeout(d,1e3)}),await new Promise(d=>setTimeout(d,150));let Z=document.createElement("canvas");Z.width=z.videoWidth||window.innerWidth,Z.height=z.videoHeight||window.innerHeight;let ie=Z.getContext("2d");ie&&(ie.drawImage(z,0,0,Z.width,Z.height),N=Z.toDataURL("image/png")),U.getTracks().forEach(d=>d.stop())}finally{A.remove(),W.forEach(s=>{s.removeAttribute("data-fixed-id")})}if(N)M(N),v(!0);else throw new Error("Could not generate screen capture data.")}catch(N){console.error("Failed to capture screenshot:",N);let W=N;if(W?.name==="NotAllowedError"||W?.name==="AbortError"){t(C.current||"general");return}be.toast.error("Capture Failed",{description:"Could not capture screenshot. Please try again."}),t(C.current||"general")}},F=async()=>{C.current=e,t(null),l(!1),Q(!0),O.current=[],await new Promise(N=>setTimeout(N,300));try{I.current=(0,He.record)({emit(N){O.current.push(N)},sampling:{mousemove:!0},blockClass:"feedback-no-capture",recordCanvas:!0}),console.log("[RRWeb Recorder] Recording started. Viewport:",{innerWidth:window.innerWidth,innerHeight:window.innerHeight,devicePixelRatio:window.devicePixelRatio})}catch(N){console.error("Failed to start rrweb recording:",N),be.toast.error("Failed to start session recording."),Q(!1),t(C.current||"general")}},X=()=>{if(I.current){try{I.current()}catch(N){console.error("Error stopping rrweb recording:",N)}I.current=void 0}if(Q(!1),O.current.length>0){let N=new Blob([JSON.stringify(O.current)],{type:"application/json"});b(N),m(URL.createObjectURL(N)),be.toast.success("Session recorded successfully!")}else be.toast.error("No events recorded during session.");t(C.current||"general")},S=()=>{r(null),b(null),H&&URL.revokeObjectURL(H),m(null),re(null),M(null),v(!1)};return{screenshotData:g,setScreenshotData:r,recordingBlob:y,setRecordingBlob:b,recordingUrl:H,setRecordingUrl:m,externalFile:w,setExternalFile:re,capturedImg:G,setCapturedImg:M,editorOpen:j,setEditorOpen:v,isRecording:$,prevActiveModal:C,recordingEvents:O.current,handleFileChange:R,captureScreenshot:ee,startRecording:F,stopRecording:X,clearAllMedia:S}};var Ce=Ke(require("axios")),Oe=async(e,t,l)=>{try{let g=l?.apiUrl,r="feedback";t==="bug"?r="bug-report":t==="feature"&&(r="feature-request");let y=`${g}/${r}`,b={};return l?.authToken&&(b.Authorization=`Bearer ${l.authToken}`),l?.tenantId&&(b["X-Tenant-ID"]=l.tenantId),l?.apiKey&&(b["x-api-key"]=l?.apiKey),(await Ce.default.post(y,e,{headers:b})).data}catch(g){throw console.error(`Error creating ${t} feedback:`,g),g}},Be=async e=>{try{let l=`${e?.apiUrl}/tickets/priorities`;return(await Ce.default.get(l)).data}catch(t){throw console.error("Error fetching ticket priorities:",t),t}};var pe=require("react/jsx-runtime"),at=(e,t)=>{let l=e.split(","),g=l[0].match(/:(.*?);/)?.[1]||"image/png",r=atob(l[1]),y=r.length,b=new Uint8Array(y);for(;y--;)b[y]=r.charCodeAt(y);return new File([b],t,{type:g})},Ue=({isAuthenticated:e,user:t,apiUrl:l,apiKey:g,getAuthToken:r,getTenantId:y})=>{let[b,H]=(0,ne.useState)(!1),[m,w]=(0,ne.useState)(null),[re,G]=(0,ne.useState)(!1),[M,j]=(0,ne.useState)(!1),[v,C]=(0,ne.useState)(0),[I,O]=(0,ne.useState)(0),[$,Q]=(0,ne.useState)(""),[R,ee]=(0,ne.useState)(""),[F,X]=(0,ne.useState)({}),[S,N]=(0,ne.useState)([]),[W,V]=(0,ne.useState)(""),u=(0,ne.useRef)(null),D=(0,ne.useRef)(null),A=(0,ne.useRef)(null),s=We({activeModal:m,setActiveModal:w,setPanelOpen:H});(0,ne.useEffect)(()=>{m==="bug"&&(async()=>{try{let f=r?await r():null,k=y?y():null,L=await Be({apiUrl:l,apiKey:g,authToken:f,tenantId:k});if(L&&L.data){N(L.data);let o=L.data.find(i=>i.name.toLowerCase()==="low");o?V(o.id):L.data.length>0&&V(L.data[0].id)}}catch(f){console.error("Failed to fetch priorities:",f)}})()},[m,l,r,y]),(0,ne.useEffect)(()=>{let a=f=>{u.current&&!u.current.contains(f.target)&&D.current&&!D.current.contains(f.target)&&H(!1)};return b&&document.addEventListener("mousedown",a),()=>{document.removeEventListener("mousedown",a)}},[b]);let U=a=>{w(a),H(!1),C(0),O(0),Q(""),ee(""),V(""),s.clearAllMedia(),A.current&&(A.current.value=""),X({})},z=()=>{w(null),C(0),O(0),Q(""),ee(""),V(""),s.clearAllMedia(),A.current&&(A.current.value=""),X({})},Z=()=>{let a={};return m==="general"?(v===0&&(a.rating="Please select a rating"),R.trim()?R.trim().length<5&&(a.description="Please enter at least 5 characters"):a.description="Please enter your feedback"):(m==="bug"||m==="feature")&&($.trim()?$.length>100&&(a.title="Title must be 100 characters or less"):a.title="Please enter a title",R.trim()?R.trim().length<10&&(a.description="Please enter at least 10 characters"):a.description="Please enter details",m==="bug"&&!W&&(a.priority="Please select a priority")),X(a),Object.keys(a).length===0},ie=async a=>{if(a.preventDefault(),!(!Z()||!m)){G(!0);try{let f=r?await r():null,k=y?y():null,L=new FormData;if(L.append("user_id",String(t?.id??"")),L.append("user_email",t?.email_id||""),m==="general"&&v>0&&L.append("ratting",String(v)),$&&L.append("title",$),R&&L.append("description",R),m==="bug"&&W&&L.append("ticketPriorityId",W),s.screenshotData)try{let c=at(s.screenshotData,"screenshot.png");L.append("screenshot",c)}catch(c){console.error("Failed to convert screenshot to file",c)}s.recordingEvents&&s.recordingEvents.length>0&&L.append("events",JSON.stringify(s.recordingEvents)),s.externalFile&&L.append("attachement",s.externalFile);let o=await Oe(L,m,{apiUrl:l,authToken:f,tenantId:k});console.log("res",o);let i="Thank you for your feedback!";m==="bug"?i="Thank you! The bug report has been submitted.":m==="feature"&&(i="Thank you! The feature request has been submitted."),ke.toast.success("Success",{description:i}),z()}catch(f){console.error("API submission error:",f),ke.toast.error("Submission Failed",{description:"An error occurred while submitting your feedback. Please try again."})}finally{G(!1)}}},d=a=>{F[a]&&X(f=>({...f,[a]:void 0}))};return e?(0,pe.jsxs)(pe.Fragment,{children:[(0,pe.jsx)(Ee,{buttonRef:D,onClick:()=>H(!b)}),(0,pe.jsx)(Me,{panelRef:u,isOpen:b,onClose:()=>H(!1),onOpenModal:U}),(0,pe.jsx)(Pe,{activeModal:m,onClose:z,onSubmit:ie,userEmail:t?.email_id||"",submitting:re,rating:v,setRating:C,hoverRating:I,setHoverRating:O,title:$,setTitle:Q,description:R,setDescription:ee,screenshotData:s.screenshotData,setScreenshotData:s.setScreenshotData,recordingBlob:s.recordingBlob,onRemoveRecording:()=>{s.setRecordingBlob(null),s.setRecordingUrl(null)},onPreviewRecording:()=>setTimeout(()=>j(!0),100),externalFile:s.externalFile,setExternalFile:s.setExternalFile,fileInputRef:A,handleFileChange:s.handleFileChange,onCaptureScreenshot:s.captureScreenshot,onStartRecording:s.startRecording,errors:F,onClearError:d,priorities:S,selectedPriorityId:W,setSelectedPriorityId:V}),(0,pe.jsx)(Ae,{isRecording:s.isRecording,onStopRecording:s.stopRecording}),(0,pe.jsx)(Le,{isOpen:s.editorOpen,capturedImg:s.capturedImg||"",onClose:()=>{s.setEditorOpen(!1),w(s.prevActiveModal.current||"general")},onSave:a=>{s.setScreenshotData(a),s.setEditorOpen(!1),w(s.prevActiveModal.current||"general"),ke.toast.success("Screenshot attached successfully!")}}),(0,pe.jsx)(ve,{isOpen:M,onClose:()=>j(!1),events:s.recordingEvents})]}):null};0&&(module.exports={FeedbackWidget,RRWebPlayerModal,SessionRecordingPreview});
57
+ `),document.head.appendChild(A);try{let s=document.documentElement;N=await(0,$e.toPng)(s,{width:window.innerWidth,height:window.innerHeight,canvasWidth:window.innerWidth,canvasHeight:window.innerHeight,pixelRatio:window.devicePixelRatio,filter:U=>{if(U instanceof HTMLElement||U&&"classList"in U){let z=U;if(z.classList&&z.classList.contains("feedback-no-capture"))return!1}return!0},style:{transform:`translate(-${u}px, -${D}px)`,transformOrigin:"top left",width:`${s.scrollWidth}px`,height:`${s.scrollHeight}px`}})}catch(s){console.warn("html2canvas direct capture failed, falling back to display media stream:",s);let U;try{U=await navigator.mediaDevices.getDisplayMedia({video:{displaySurface:"browser"},audio:!1,preferCurrentTab:!0,selfBrowserSurface:"include"})}catch(d){let a=d;if(a?.name==="NotAllowedError"||a?.name==="AbortError")throw a;U=await navigator.mediaDevices.getDisplayMedia({video:!0})}let z=document.createElement("video");z.srcObject=U,z.muted=!0,z.playsInline=!0,await new Promise(d=>{z.onloadedmetadata=()=>{z.play().then(()=>d()).catch(()=>d())},setTimeout(d,1e3)}),await new Promise(d=>setTimeout(d,150));let Z=document.createElement("canvas");Z.width=z.videoWidth||window.innerWidth,Z.height=z.videoHeight||window.innerHeight;let ie=Z.getContext("2d");ie&&(ie.drawImage(z,0,0,Z.width,Z.height),N=Z.toDataURL("image/png")),U.getTracks().forEach(d=>d.stop())}finally{A.remove(),W.forEach(s=>{s.removeAttribute("data-fixed-id")})}if(N)M(N),v(!0);else throw new Error("Could not generate screen capture data.")}catch(N){console.error("Failed to capture screenshot:",N);let W=N;if(W?.name==="NotAllowedError"||W?.name==="AbortError"){t(C.current||"general");return}be.toast.error("Capture Failed",{description:"Could not capture screenshot. Please try again."}),t(C.current||"general")}},F=async()=>{C.current=e,t(null),l(!1),Q(!0),O.current=[],await new Promise(N=>setTimeout(N,300));try{I.current=(0,He.record)({emit(N){O.current.push(N)},sampling:{mousemove:!0},blockClass:"feedback-no-capture",recordCanvas:!0}),console.log("[RRWeb Recorder] Recording started. Viewport:",{innerWidth:window.innerWidth,innerHeight:window.innerHeight,devicePixelRatio:window.devicePixelRatio})}catch(N){console.error("Failed to start rrweb recording:",N),be.toast.error("Failed to start session recording."),Q(!1),t(C.current||"general")}},X=()=>{if(I.current){try{I.current()}catch(N){console.error("Error stopping rrweb recording:",N)}I.current=void 0}if(Q(!1),O.current.length>0){let N=new Blob([JSON.stringify(O.current)],{type:"application/json"});b(N),m(URL.createObjectURL(N)),be.toast.success("Session recorded successfully!")}else be.toast.error("No events recorded during session.");t(C.current||"general")},S=()=>{r(null),b(null),H&&URL.revokeObjectURL(H),m(null),re(null),M(null),v(!1)};return{screenshotData:g,setScreenshotData:r,recordingBlob:y,setRecordingBlob:b,recordingUrl:H,setRecordingUrl:m,externalFile:w,setExternalFile:re,capturedImg:G,setCapturedImg:M,editorOpen:j,setEditorOpen:v,isRecording:$,prevActiveModal:C,recordingEvents:O.current,handleFileChange:R,captureScreenshot:ee,startRecording:F,stopRecording:X,clearAllMedia:S}};var Ce=Ke(require("axios")),Oe=async(e,t,l)=>{try{let g=l?.apiUrl,r="feedback";t==="bug"?r="bug-report":t==="feature"&&(r="feature-request");let y=`${g}/${r}`,b={};return l?.authToken&&(b.Authorization=`Bearer ${l.authToken}`),l?.tenantId&&(b["X-Tenant-ID"]=l.tenantId),l?.apiKey&&(b["x-api-key"]=l?.apiKey),(await Ce.default.post(y,e,{headers:b})).data}catch(g){throw console.error(`Error creating ${t} feedback:`,g),g}},Be=async e=>{try{let l=`${e?.apiUrl}/tickets/priorities`;return(await Ce.default.get(l)).data}catch(t){throw console.error("Error fetching ticket priorities:",t),t}};var pe=require("react/jsx-runtime"),at=(e,t)=>{let l=e.split(","),g=l[0].match(/:(.*?);/)?.[1]||"image/png",r=atob(l[1]),y=r.length,b=new Uint8Array(y);for(;y--;)b[y]=r.charCodeAt(y);return new File([b],t,{type:g})},Ue=({isAuthenticated:e,user:t,apiUrl:l,apiKey:g,getAuthToken:r,getTenantId:y})=>{let[b,H]=(0,ne.useState)(!1),[m,w]=(0,ne.useState)(null),[re,G]=(0,ne.useState)(!1),[M,j]=(0,ne.useState)(!1),[v,C]=(0,ne.useState)(0),[I,O]=(0,ne.useState)(0),[$,Q]=(0,ne.useState)(""),[R,ee]=(0,ne.useState)(""),[F,X]=(0,ne.useState)({}),[S,N]=(0,ne.useState)([]),[W,V]=(0,ne.useState)(""),u=(0,ne.useRef)(null),D=(0,ne.useRef)(null),A=(0,ne.useRef)(null),s=We({activeModal:m,setActiveModal:w,setPanelOpen:H});(0,ne.useEffect)(()=>{m==="bug"&&(async()=>{try{let f=r?await r():null,k=y?y():null,L=await Be({apiUrl:l,authToken:f,tenantId:k});if(L&&L.data){N(L.data);let o=L.data.find(i=>i.name.toLowerCase()==="low");o?V(o.id):L.data.length>0&&V(L.data[0].id)}}catch(f){console.error("Failed to fetch priorities:",f)}})()},[m,l,r,y]),(0,ne.useEffect)(()=>{let a=f=>{u.current&&!u.current.contains(f.target)&&D.current&&!D.current.contains(f.target)&&H(!1)};return b&&document.addEventListener("mousedown",a),()=>{document.removeEventListener("mousedown",a)}},[b]);let U=a=>{w(a),H(!1),C(0),O(0),Q(""),ee(""),V(""),s.clearAllMedia(),A.current&&(A.current.value=""),X({})},z=()=>{w(null),C(0),O(0),Q(""),ee(""),V(""),s.clearAllMedia(),A.current&&(A.current.value=""),X({})},Z=()=>{let a={};return m==="general"?(v===0&&(a.rating="Please select a rating"),R.trim()?R.trim().length<5&&(a.description="Please enter at least 5 characters"):a.description="Please enter your feedback"):(m==="bug"||m==="feature")&&($.trim()?$.length>100&&(a.title="Title must be 100 characters or less"):a.title="Please enter a title",R.trim()?R.trim().length<10&&(a.description="Please enter at least 10 characters"):a.description="Please enter details",m==="bug"&&!W&&(a.priority="Please select a priority")),X(a),Object.keys(a).length===0},ie=async a=>{if(a.preventDefault(),!(!Z()||!m)){G(!0);try{let f=r?await r():null,k=y?y():null,L=new FormData;if(L.append("user_id",String(t?.id??"")),L.append("user_email",t?.email_id||""),m==="general"&&v>0&&L.append("ratting",String(v)),$&&L.append("title",$),R&&L.append("description",R),m==="bug"&&W&&L.append("ticketPriorityId",W),s.screenshotData)try{let c=at(s.screenshotData,"screenshot.png");L.append("screenshot",c)}catch(c){console.error("Failed to convert screenshot to file",c)}s.recordingEvents&&s.recordingEvents.length>0&&L.append("events",JSON.stringify(s.recordingEvents)),s.externalFile&&L.append("attachement",s.externalFile);let o=await Oe(L,m,{apiUrl:l,apiKey:g,authToken:f,tenantId:k});console.log("res",o);let i="Thank you for your feedback!";m==="bug"?i="Thank you! The bug report has been submitted.":m==="feature"&&(i="Thank you! The feature request has been submitted."),ke.toast.success("Success",{description:i}),z()}catch(f){console.error("API submission error:",f),ke.toast.error("Submission Failed",{description:"An error occurred while submitting your feedback. Please try again."})}finally{G(!1)}}},d=a=>{F[a]&&X(f=>({...f,[a]:void 0}))};return e?(0,pe.jsxs)(pe.Fragment,{children:[(0,pe.jsx)(Ee,{buttonRef:D,onClick:()=>H(!b)}),(0,pe.jsx)(Me,{panelRef:u,isOpen:b,onClose:()=>H(!1),onOpenModal:U}),(0,pe.jsx)(Pe,{activeModal:m,onClose:z,onSubmit:ie,userEmail:t?.email_id||"",submitting:re,rating:v,setRating:C,hoverRating:I,setHoverRating:O,title:$,setTitle:Q,description:R,setDescription:ee,screenshotData:s.screenshotData,setScreenshotData:s.setScreenshotData,recordingBlob:s.recordingBlob,onRemoveRecording:()=>{s.setRecordingBlob(null),s.setRecordingUrl(null)},onPreviewRecording:()=>setTimeout(()=>j(!0),100),externalFile:s.externalFile,setExternalFile:s.setExternalFile,fileInputRef:A,handleFileChange:s.handleFileChange,onCaptureScreenshot:s.captureScreenshot,onStartRecording:s.startRecording,errors:F,onClearError:d,priorities:S,selectedPriorityId:W,setSelectedPriorityId:V}),(0,pe.jsx)(Ae,{isRecording:s.isRecording,onStopRecording:s.stopRecording}),(0,pe.jsx)(Le,{isOpen:s.editorOpen,capturedImg:s.capturedImg||"",onClose:()=>{s.setEditorOpen(!1),w(s.prevActiveModal.current||"general")},onSave:a=>{s.setScreenshotData(a),s.setEditorOpen(!1),w(s.prevActiveModal.current||"general"),ke.toast.success("Screenshot attached successfully!")}}),(0,pe.jsx)(ve,{isOpen:M,onClose:()=>j(!1),events:s.recordingEvents})]}):null};0&&(module.exports={FeedbackWidget,RRWebPlayerModal,SessionRecordingPreview});
package/dist/index.mjs CHANGED
@@ -54,4 +54,4 @@ import{useEffect as Ze,useRef as Fe,useState as ie}from"react";import{MessageSqu
54
54
  transform: ${r} !important;
55
55
  }
56
56
  `)});let F=document.createElement("style");F.id="temp-fixed-style",F.innerHTML=Y.join(`
57
- `),document.head.appendChild(F);try{let o=document.documentElement;N=await jt(o,{width:window.innerWidth,height:window.innerHeight,canvasWidth:window.innerWidth,canvasHeight:window.innerHeight,pixelRatio:window.devicePixelRatio,filter:B=>{if(B instanceof HTMLElement||B&&"classList"in B){let z=B;if(z.classList&&z.classList.contains("feedback-no-capture"))return!1}return!0},style:{transform:`translate(-${d}px, -${E}px)`,transformOrigin:"top left",width:`${o.scrollWidth}px`,height:`${o.scrollHeight}px`}})}catch(o){console.warn("html2canvas direct capture failed, falling back to display media stream:",o);let B;try{B=await navigator.mediaDevices.getDisplayMedia({video:{displaySurface:"browser"},audio:!1,preferCurrentTab:!0,selfBrowserSurface:"include"})}catch(l){let r=l;if(r?.name==="NotAllowedError"||r?.name==="AbortError")throw r;B=await navigator.mediaDevices.getDisplayMedia({video:!0})}let z=document.createElement("video");z.srcObject=B,z.muted=!0,z.playsInline=!0,await new Promise(l=>{z.onloadedmetadata=()=>{z.play().then(()=>l()).catch(()=>l())},setTimeout(l,1e3)}),await new Promise(l=>setTimeout(l,150));let V=document.createElement("canvas");V.width=z.videoWidth||window.innerWidth,V.height=z.videoHeight||window.innerHeight;let ne=V.getContext("2d");ne&&(ne.drawImage(z,0,0,V.width,V.height),N=V.toDataURL("image/png")),B.getTracks().forEach(l=>l.stop())}finally{F.remove(),H.forEach(o=>{o.removeAttribute("data-fixed-id")})}if(N)P(N),y(!0);else throw new Error("Could not generate screen capture data.")}catch(N){console.error("Failed to capture screenshot:",N);let H=N;if(H?.name==="NotAllowedError"||H?.name==="AbortError"){t(C.current||"general");return}be.error("Capture Failed",{description:"Could not capture screenshot. Please try again."}),t(C.current||"general")}},T=async()=>{C.current=e,t(null),c(!1),K(!0),W.current=[],await new Promise(N=>setTimeout(N,300));try{D.current=zt({emit(N){W.current.push(N)},sampling:{mousemove:!0},blockClass:"feedback-no-capture",recordCanvas:!0}),console.log("[RRWeb Recorder] Recording started. Viewport:",{innerWidth:window.innerWidth,innerHeight:window.innerHeight,devicePixelRatio:window.devicePixelRatio})}catch(N){console.error("Failed to start rrweb recording:",N),be.error("Failed to start session recording."),K(!1),t(C.current||"general")}},X=()=>{if(D.current){try{D.current()}catch(N){console.error("Error stopping rrweb recording:",N)}D.current=void 0}if(K(!1),W.current.length>0){let N=new Blob([JSON.stringify(W.current)],{type:"application/json"});b(N),m(URL.createObjectURL(N)),be.success("Session recorded successfully!")}else be.error("No events recorded during session.");t(C.current||"general")},S=()=>{n(null),b(null),$&&URL.revokeObjectURL($),m(null),G(null),P(null),y(!1)};return{screenshotData:g,setScreenshotData:n,recordingBlob:x,setRecordingBlob:b,recordingUrl:$,setRecordingUrl:m,externalFile:v,setExternalFile:G,capturedImg:q,setCapturedImg:P,editorOpen:j,setEditorOpen:y,isRecording:L,prevActiveModal:C,recordingEvents:W.current,handleFileChange:R,captureScreenshot:J,startRecording:T,stopRecording:X,clearAllMedia:S}};import Je from"axios";var Ge=async(e,t,c)=>{try{let g=c?.apiUrl,n="feedback";t==="bug"?n="bug-report":t==="feature"&&(n="feature-request");let x=`${g}/${n}`,b={};return c?.authToken&&(b.Authorization=`Bearer ${c.authToken}`),c?.tenantId&&(b["X-Tenant-ID"]=c.tenantId),c?.apiKey&&(b["x-api-key"]=c?.apiKey),(await Je.post(x,e,{headers:b})).data}catch(g){throw console.error(`Error creating ${t} feedback:`,g),g}},Qe=async e=>{try{let c=`${e?.apiUrl}/tickets/priorities`;return(await Je.get(c)).data}catch(t){throw console.error("Error fetching ticket priorities:",t),t}};import{Fragment as _t,jsx as xe,jsxs as qt}from"react/jsx-runtime";var Xt=(e,t)=>{let c=e.split(","),g=c[0].match(/:(.*?);/)?.[1]||"image/png",n=atob(c[1]),x=n.length,b=new Uint8Array(x);for(;x--;)b[x]=n.charCodeAt(x);return new File([b],t,{type:g})},Yt=({isAuthenticated:e,user:t,apiUrl:c,apiKey:g,getAuthToken:n,getTenantId:x})=>{let[b,$]=ie(!1),[m,v]=ie(null),[G,q]=ie(!1),[P,j]=ie(!1),[y,C]=ie(0),[D,W]=ie(0),[L,K]=ie(""),[R,J]=ie(""),[T,X]=ie({}),[S,N]=ie([]),[H,Y]=ie(""),d=Fe(null),E=Fe(null),F=Fe(null),o=Ve({activeModal:m,setActiveModal:v,setPanelOpen:$});Ze(()=>{m==="bug"&&(async()=>{try{let f=n?await n():null,w=x?x():null,A=await Qe({apiUrl:c,apiKey:g,authToken:f,tenantId:w});if(A&&A.data){N(A.data);let a=A.data.find(s=>s.name.toLowerCase()==="low");a?Y(a.id):A.data.length>0&&Y(A.data[0].id)}}catch(f){console.error("Failed to fetch priorities:",f)}})()},[m,c,n,x]),Ze(()=>{let r=f=>{d.current&&!d.current.contains(f.target)&&E.current&&!E.current.contains(f.target)&&$(!1)};return b&&document.addEventListener("mousedown",r),()=>{document.removeEventListener("mousedown",r)}},[b]);let B=r=>{v(r),$(!1),C(0),W(0),K(""),J(""),Y(""),o.clearAllMedia(),F.current&&(F.current.value=""),X({})},z=()=>{v(null),C(0),W(0),K(""),J(""),Y(""),o.clearAllMedia(),F.current&&(F.current.value=""),X({})},V=()=>{let r={};return m==="general"?(y===0&&(r.rating="Please select a rating"),R.trim()?R.trim().length<5&&(r.description="Please enter at least 5 characters"):r.description="Please enter your feedback"):(m==="bug"||m==="feature")&&(L.trim()?L.length>100&&(r.title="Title must be 100 characters or less"):r.title="Please enter a title",R.trim()?R.trim().length<10&&(r.description="Please enter at least 10 characters"):r.description="Please enter details",m==="bug"&&!H&&(r.priority="Please select a priority")),X(r),Object.keys(r).length===0},ne=async r=>{if(r.preventDefault(),!(!V()||!m)){q(!0);try{let f=n?await n():null,w=x?x():null,A=new FormData;if(A.append("user_id",String(t?.id??"")),A.append("user_email",t?.email_id||""),m==="general"&&y>0&&A.append("ratting",String(y)),L&&A.append("title",L),R&&A.append("description",R),m==="bug"&&H&&A.append("ticketPriorityId",H),o.screenshotData)try{let i=Xt(o.screenshotData,"screenshot.png");A.append("screenshot",i)}catch(i){console.error("Failed to convert screenshot to file",i)}o.recordingEvents&&o.recordingEvents.length>0&&A.append("events",JSON.stringify(o.recordingEvents)),o.externalFile&&A.append("attachement",o.externalFile);let a=await Ge(A,m,{apiUrl:c,authToken:f,tenantId:w});console.log("res",a);let s="Thank you for your feedback!";m==="bug"?s="Thank you! The bug report has been submitted.":m==="feature"&&(s="Thank you! The feature request has been submitted."),De.success("Success",{description:s}),z()}catch(f){console.error("API submission error:",f),De.error("Submission Failed",{description:"An error occurred while submitting your feedback. Please try again."})}finally{q(!1)}}},l=r=>{T[r]&&X(f=>({...f,[r]:void 0}))};return e?qt(_t,{children:[xe(Oe,{buttonRef:E,onClick:()=>$(!b)}),xe(We,{panelRef:d,isOpen:b,onClose:()=>$(!1),onOpenModal:B}),xe(He,{activeModal:m,onClose:z,onSubmit:ne,userEmail:t?.email_id||"",submitting:G,rating:y,setRating:C,hoverRating:D,setHoverRating:W,title:L,setTitle:K,description:R,setDescription:J,screenshotData:o.screenshotData,setScreenshotData:o.setScreenshotData,recordingBlob:o.recordingBlob,onRemoveRecording:()=>{o.setRecordingBlob(null),o.setRecordingUrl(null)},onPreviewRecording:()=>setTimeout(()=>j(!0),100),externalFile:o.externalFile,setExternalFile:o.setExternalFile,fileInputRef:F,handleFileChange:o.handleFileChange,onCaptureScreenshot:o.captureScreenshot,onStartRecording:o.startRecording,errors:T,onClearError:l,priorities:S,selectedPriorityId:H,setSelectedPriorityId:Y}),xe(Ye,{isRecording:o.isRecording,onStopRecording:o.stopRecording}),xe(Ke,{isOpen:o.editorOpen,capturedImg:o.capturedImg||"",onClose:()=>{o.setEditorOpen(!1),v(o.prevActiveModal.current||"general")},onSave:r=>{o.setScreenshotData(r),o.setEditorOpen(!1),v(o.prevActiveModal.current||"general"),De.success("Screenshot attached successfully!")}}),xe(Ne,{isOpen:P,onClose:()=>j(!1),events:o.recordingEvents})]}):null};export{Yt as FeedbackWidget,Ne as RRWebPlayerModal,Ne as SessionRecordingPreview};
57
+ `),document.head.appendChild(F);try{let o=document.documentElement;N=await jt(o,{width:window.innerWidth,height:window.innerHeight,canvasWidth:window.innerWidth,canvasHeight:window.innerHeight,pixelRatio:window.devicePixelRatio,filter:B=>{if(B instanceof HTMLElement||B&&"classList"in B){let z=B;if(z.classList&&z.classList.contains("feedback-no-capture"))return!1}return!0},style:{transform:`translate(-${d}px, -${E}px)`,transformOrigin:"top left",width:`${o.scrollWidth}px`,height:`${o.scrollHeight}px`}})}catch(o){console.warn("html2canvas direct capture failed, falling back to display media stream:",o);let B;try{B=await navigator.mediaDevices.getDisplayMedia({video:{displaySurface:"browser"},audio:!1,preferCurrentTab:!0,selfBrowserSurface:"include"})}catch(l){let r=l;if(r?.name==="NotAllowedError"||r?.name==="AbortError")throw r;B=await navigator.mediaDevices.getDisplayMedia({video:!0})}let z=document.createElement("video");z.srcObject=B,z.muted=!0,z.playsInline=!0,await new Promise(l=>{z.onloadedmetadata=()=>{z.play().then(()=>l()).catch(()=>l())},setTimeout(l,1e3)}),await new Promise(l=>setTimeout(l,150));let V=document.createElement("canvas");V.width=z.videoWidth||window.innerWidth,V.height=z.videoHeight||window.innerHeight;let ne=V.getContext("2d");ne&&(ne.drawImage(z,0,0,V.width,V.height),N=V.toDataURL("image/png")),B.getTracks().forEach(l=>l.stop())}finally{F.remove(),H.forEach(o=>{o.removeAttribute("data-fixed-id")})}if(N)P(N),y(!0);else throw new Error("Could not generate screen capture data.")}catch(N){console.error("Failed to capture screenshot:",N);let H=N;if(H?.name==="NotAllowedError"||H?.name==="AbortError"){t(C.current||"general");return}be.error("Capture Failed",{description:"Could not capture screenshot. Please try again."}),t(C.current||"general")}},T=async()=>{C.current=e,t(null),c(!1),K(!0),W.current=[],await new Promise(N=>setTimeout(N,300));try{D.current=zt({emit(N){W.current.push(N)},sampling:{mousemove:!0},blockClass:"feedback-no-capture",recordCanvas:!0}),console.log("[RRWeb Recorder] Recording started. Viewport:",{innerWidth:window.innerWidth,innerHeight:window.innerHeight,devicePixelRatio:window.devicePixelRatio})}catch(N){console.error("Failed to start rrweb recording:",N),be.error("Failed to start session recording."),K(!1),t(C.current||"general")}},X=()=>{if(D.current){try{D.current()}catch(N){console.error("Error stopping rrweb recording:",N)}D.current=void 0}if(K(!1),W.current.length>0){let N=new Blob([JSON.stringify(W.current)],{type:"application/json"});b(N),m(URL.createObjectURL(N)),be.success("Session recorded successfully!")}else be.error("No events recorded during session.");t(C.current||"general")},S=()=>{n(null),b(null),$&&URL.revokeObjectURL($),m(null),G(null),P(null),y(!1)};return{screenshotData:g,setScreenshotData:n,recordingBlob:x,setRecordingBlob:b,recordingUrl:$,setRecordingUrl:m,externalFile:v,setExternalFile:G,capturedImg:q,setCapturedImg:P,editorOpen:j,setEditorOpen:y,isRecording:L,prevActiveModal:C,recordingEvents:W.current,handleFileChange:R,captureScreenshot:J,startRecording:T,stopRecording:X,clearAllMedia:S}};import Je from"axios";var Ge=async(e,t,c)=>{try{let g=c?.apiUrl,n="feedback";t==="bug"?n="bug-report":t==="feature"&&(n="feature-request");let x=`${g}/${n}`,b={};return c?.authToken&&(b.Authorization=`Bearer ${c.authToken}`),c?.tenantId&&(b["X-Tenant-ID"]=c.tenantId),c?.apiKey&&(b["x-api-key"]=c?.apiKey),(await Je.post(x,e,{headers:b})).data}catch(g){throw console.error(`Error creating ${t} feedback:`,g),g}},Qe=async e=>{try{let c=`${e?.apiUrl}/tickets/priorities`;return(await Je.get(c)).data}catch(t){throw console.error("Error fetching ticket priorities:",t),t}};import{Fragment as _t,jsx as xe,jsxs as qt}from"react/jsx-runtime";var Xt=(e,t)=>{let c=e.split(","),g=c[0].match(/:(.*?);/)?.[1]||"image/png",n=atob(c[1]),x=n.length,b=new Uint8Array(x);for(;x--;)b[x]=n.charCodeAt(x);return new File([b],t,{type:g})},Yt=({isAuthenticated:e,user:t,apiUrl:c,apiKey:g,getAuthToken:n,getTenantId:x})=>{let[b,$]=ie(!1),[m,v]=ie(null),[G,q]=ie(!1),[P,j]=ie(!1),[y,C]=ie(0),[D,W]=ie(0),[L,K]=ie(""),[R,J]=ie(""),[T,X]=ie({}),[S,N]=ie([]),[H,Y]=ie(""),d=Fe(null),E=Fe(null),F=Fe(null),o=Ve({activeModal:m,setActiveModal:v,setPanelOpen:$});Ze(()=>{m==="bug"&&(async()=>{try{let f=n?await n():null,w=x?x():null,A=await Qe({apiUrl:c,authToken:f,tenantId:w});if(A&&A.data){N(A.data);let a=A.data.find(s=>s.name.toLowerCase()==="low");a?Y(a.id):A.data.length>0&&Y(A.data[0].id)}}catch(f){console.error("Failed to fetch priorities:",f)}})()},[m,c,n,x]),Ze(()=>{let r=f=>{d.current&&!d.current.contains(f.target)&&E.current&&!E.current.contains(f.target)&&$(!1)};return b&&document.addEventListener("mousedown",r),()=>{document.removeEventListener("mousedown",r)}},[b]);let B=r=>{v(r),$(!1),C(0),W(0),K(""),J(""),Y(""),o.clearAllMedia(),F.current&&(F.current.value=""),X({})},z=()=>{v(null),C(0),W(0),K(""),J(""),Y(""),o.clearAllMedia(),F.current&&(F.current.value=""),X({})},V=()=>{let r={};return m==="general"?(y===0&&(r.rating="Please select a rating"),R.trim()?R.trim().length<5&&(r.description="Please enter at least 5 characters"):r.description="Please enter your feedback"):(m==="bug"||m==="feature")&&(L.trim()?L.length>100&&(r.title="Title must be 100 characters or less"):r.title="Please enter a title",R.trim()?R.trim().length<10&&(r.description="Please enter at least 10 characters"):r.description="Please enter details",m==="bug"&&!H&&(r.priority="Please select a priority")),X(r),Object.keys(r).length===0},ne=async r=>{if(r.preventDefault(),!(!V()||!m)){q(!0);try{let f=n?await n():null,w=x?x():null,A=new FormData;if(A.append("user_id",String(t?.id??"")),A.append("user_email",t?.email_id||""),m==="general"&&y>0&&A.append("ratting",String(y)),L&&A.append("title",L),R&&A.append("description",R),m==="bug"&&H&&A.append("ticketPriorityId",H),o.screenshotData)try{let i=Xt(o.screenshotData,"screenshot.png");A.append("screenshot",i)}catch(i){console.error("Failed to convert screenshot to file",i)}o.recordingEvents&&o.recordingEvents.length>0&&A.append("events",JSON.stringify(o.recordingEvents)),o.externalFile&&A.append("attachement",o.externalFile);let a=await Ge(A,m,{apiUrl:c,apiKey:g,authToken:f,tenantId:w});console.log("res",a);let s="Thank you for your feedback!";m==="bug"?s="Thank you! The bug report has been submitted.":m==="feature"&&(s="Thank you! The feature request has been submitted."),De.success("Success",{description:s}),z()}catch(f){console.error("API submission error:",f),De.error("Submission Failed",{description:"An error occurred while submitting your feedback. Please try again."})}finally{q(!1)}}},l=r=>{T[r]&&X(f=>({...f,[r]:void 0}))};return e?qt(_t,{children:[xe(Oe,{buttonRef:E,onClick:()=>$(!b)}),xe(We,{panelRef:d,isOpen:b,onClose:()=>$(!1),onOpenModal:B}),xe(He,{activeModal:m,onClose:z,onSubmit:ne,userEmail:t?.email_id||"",submitting:G,rating:y,setRating:C,hoverRating:D,setHoverRating:W,title:L,setTitle:K,description:R,setDescription:J,screenshotData:o.screenshotData,setScreenshotData:o.setScreenshotData,recordingBlob:o.recordingBlob,onRemoveRecording:()=>{o.setRecordingBlob(null),o.setRecordingUrl(null)},onPreviewRecording:()=>setTimeout(()=>j(!0),100),externalFile:o.externalFile,setExternalFile:o.setExternalFile,fileInputRef:F,handleFileChange:o.handleFileChange,onCaptureScreenshot:o.captureScreenshot,onStartRecording:o.startRecording,errors:T,onClearError:l,priorities:S,selectedPriorityId:H,setSelectedPriorityId:Y}),xe(Ye,{isRecording:o.isRecording,onStopRecording:o.stopRecording}),xe(Ke,{isOpen:o.editorOpen,capturedImg:o.capturedImg||"",onClose:()=>{o.setEditorOpen(!1),v(o.prevActiveModal.current||"general")},onSave:r=>{o.setScreenshotData(r),o.setEditorOpen(!1),v(o.prevActiveModal.current||"general"),De.success("Screenshot attached successfully!")}}),xe(Ne,{isOpen:P,onClose:()=>j(!1),events:o.recordingEvents})]}):null};export{Yt as FeedbackWidget,Ne as RRWebPlayerModal,Ne as SessionRecordingPreview};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pitangent/feedback-system",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",