@pitangent/feedback-system 1.0.1

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/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # @wellnesspro/feedback
2
+
3
+ A drop-in React feedback widget with screenshot capture and rrweb session
4
+ recording/playback.
5
+
6
+ ## Exports
7
+
8
+ ```ts
9
+ import {
10
+ FeedbackWidget, // the full feedback widget (trigger + panel + modal)
11
+ RRWebPlayerModal, // standalone session-recording preview player
12
+ SessionRecordingPreview // friendly alias for RRWebPlayerModal
13
+ } from '@wellnesspro/feedback';
14
+ import type { RRWebPlayerModalProps } from '@wellnesspro/feedback';
15
+ ```
16
+
17
+ ### Peer dependencies
18
+
19
+ Consumers must have these installed (they are **not** bundled):
20
+
21
+ - `react` `^18 || ^19`
22
+ - `react-dom` `^18 || ^19`
23
+ - `lucide-react` `^0.525.0`
24
+ - `sonner` `^2.0.0`
25
+
26
+ ---
27
+
28
+ ## Publishing to npm — step by step
29
+
30
+ > This is a **scoped** package (`@wellnesspro/...`). On the public npm registry,
31
+ > scoped packages are **private by default**, so you must pass `--access public`
32
+ > the first time (or set `publishConfig.access` — see below).
33
+
34
+ ### One-time setup
35
+
36
+ 1. **Create / verify the npm org.** The `@wellnesspro` scope must be an npm
37
+ organization (or user) you belong to. Create it at
38
+ <https://www.npmjs.com/org/create> (name: `wellnesspro`), or change the
39
+ package name in `package.json`.
40
+
41
+ 2. **Recommended `package.json` additions** so publishes are safe and repeatable:
42
+
43
+ ```jsonc
44
+ {
45
+ "files": ["dist"], // ship only the build output
46
+ "publishConfig": { "access": "public" },
47
+ "scripts": {
48
+ "prepublishOnly": "npm run build" // always build fresh dist before publish
49
+ }
50
+ }
51
+ ```
52
+
53
+ ### Every release
54
+
55
+ ```bash
56
+ cd packages
57
+
58
+ # 1. Log in (once per machine)
59
+ npm login
60
+ npm whoami # confirm you're logged in
61
+
62
+ # 2. Bump the version (npm rejects re-publishing an existing version)
63
+ npm version patch # bug fix: 1.0.0 -> 1.0.1
64
+ # npm version minor # new feature: 1.0.0 -> 1.1.0
65
+ # npm version major # breaking: 1.0.0 -> 2.0.0
66
+
67
+ # 3. Build the distributable (skip if you added prepublishOnly above)
68
+ npm run build
69
+
70
+ # 4. Dry run — inspect exactly what will be shipped (should be dist/* + package.json)
71
+ npm publish --dry-run --access public
72
+
73
+ # 5. Publish
74
+ npm publish --access public
75
+
76
+ # 6. Verify
77
+ npm view @wellnesspro/feedback
78
+ ```
79
+
80
+ ---
81
+
82
+ ## Free account now, paid/private later — what you can and can't do
83
+
84
+ **You can publish this on a free npm account today**, and move to a paid/private
85
+ plan later **without renaming the package**.
86
+
87
+ | Plan | What you can publish |
88
+ | --- | --- |
89
+ | **Free account** | Unlimited **public** packages, including scoped public ones (`@wellnesspro/feedback` with `--access public`). |
90
+ | **Paid plan** (paid user or paid org) | Everything above **plus private packages**. |
91
+
92
+ ### Now (free): publish as public
93
+
94
+ ```bash
95
+ npm publish --access public
96
+ ```
97
+
98
+ ### Later (paid): switch the same package to private
99
+
100
+ Once you upgrade to a paid plan, flip the existing package's visibility — no
101
+ rename, no republish needed:
102
+
103
+ ```bash
104
+ npm access restricted @wellnesspro/feedback # public -> private
105
+ # npm access public @wellnesspro/feedback # private -> public (reverse)
106
+ ```
107
+
108
+ After that, only members of the org (or people you grant access) can install it.
109
+
110
+ > ⚠️ **Caveat:** any version you published while it was public was already
111
+ > downloadable, so making the package private only restricts **future** installs
112
+ > — it does not retract copies people already have. If the code must never be
113
+ > public, start on a paid/private plan from the first publish instead.
114
+
115
+ ### Private install requires auth
116
+
117
+ Once private, consumers (and CI) need an auth token in their `.npmrc`:
118
+
119
+ ```ini
120
+ //registry.npmjs.org/:_authToken=${NPM_TOKEN}
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Using a private GitLab registry instead
126
+
127
+ Your repo lives on GitLab (`gitlab.pitangent.net`). If you'd rather host this in
128
+ GitLab's package registry instead of npmjs.com, add a project-level `.npmrc`:
129
+
130
+ ```ini
131
+ @wellnesspro:registry=https://gitlab.pitangent.net/api/v4/projects/<PROJECT_ID>/packages/npm/
132
+ //gitlab.pitangent.net/api/v4/projects/<PROJECT_ID>/packages/npm/:_authToken=${CI_JOB_TOKEN}
133
+ ```
134
+
135
+ Then `npm publish` (no `--access` flag needed). This keeps the package private to
136
+ your GitLab group at no extra npm cost.
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+
3
+ declare const FeedbackWidget: React.FC<{
4
+ isAuthenticated: boolean;
5
+ user: {
6
+ id: string;
7
+ email_id: string;
8
+ } | null;
9
+ apiUrl: string;
10
+ apiKey: string;
11
+ getAuthToken?: () => Promise<string | null> | string | null;
12
+ getTenantId?: () => string | null;
13
+ }>;
14
+
15
+ interface RRWebPlayerModalProps {
16
+ isOpen: boolean;
17
+ onClose: () => void;
18
+ events: unknown[];
19
+ }
20
+ declare const RRWebPlayerModal: React.FC<RRWebPlayerModalProps>;
21
+
22
+ export { FeedbackWidget, RRWebPlayerModal, type RRWebPlayerModalProps, RRWebPlayerModal as SessionRecordingPreview };
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+
3
+ declare const FeedbackWidget: React.FC<{
4
+ isAuthenticated: boolean;
5
+ user: {
6
+ id: string;
7
+ email_id: string;
8
+ } | null;
9
+ apiUrl: string;
10
+ apiKey: string;
11
+ getAuthToken?: () => Promise<string | null> | string | null;
12
+ getTenantId?: () => string | null;
13
+ }>;
14
+
15
+ interface RRWebPlayerModalProps {
16
+ isOpen: boolean;
17
+ onClose: () => void;
18
+ events: unknown[];
19
+ }
20
+ declare const RRWebPlayerModal: React.FC<RRWebPlayerModalProps>;
21
+
22
+ export { FeedbackWidget, RRWebPlayerModal, type RRWebPlayerModalProps, RRWebPlayerModal as SessionRecordingPreview };
package/dist/index.js ADDED
@@ -0,0 +1,57 @@
1
+ "use strict";var je=Object.create;var we=Object.defineProperty;var ze=Object.getOwnPropertyDescriptor;var Xe=Object.getOwnPropertyNames;var Ye=Object.getPrototypeOf,_e=Object.prototype.hasOwnProperty;var qe=(e,t)=>{for(var l in t)we(e,l,{get:t[l],enumerable:!0})},Re=(e,t,l,g)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Xe(t))!_e.call(e,r)&&r!==l&&we(e,r,{get:()=>t[r],enumerable:!(g=ze(t,r))||g.enumerable});return e};var Ke=(e,t,l)=>(l=e!=null?je(Ye(e)):{},Re(t||!e||!e.__esModule?we(l,"default",{value:e,enumerable:!0}):l,e)),Ve=e=>Re(we({},"__esModule",{value:!0}),e);var ot={};qe(ot,{FeedbackWidget:()=>Ue,RRWebPlayerModal:()=>ve,SessionRecordingPreview:()=>ve});module.exports=Ve(ot);var ne=require("react");var K=require("lucide-react");var ge=require("react/jsx-runtime"),Se=({priorities:e,selectedPriorityId:t,onChange:l,error:g})=>(0,ge.jsxs)("div",{className:"space-y-2",children:[(0,ge.jsxs)("label",{className:"block text-sm font-semibold text-gray-700",children:["Priority Level ",(0,ge.jsx)("span",{className:"text-red-500",children:"*"})]}),(0,ge.jsx)("div",{className:"flex gap-2.5",children:e.map(r=>{let y=t===r.id,b=r.name.toLowerCase(),H="border-gray-200 text-gray-600 bg-white hover:bg-gray-50 hover:border-gray-300";return y&&(b==="low"?H="border-emerald-500 bg-emerald-50/70 text-emerald-700 ring-2 ring-emerald-500/10":b==="medium"?H="border-amber-500 bg-amber-50/70 text-amber-700 ring-2 ring-amber-500/10":b==="high"||b==="critical"?H="border-rose-500 bg-rose-50/70 text-rose-700 ring-2 ring-rose-500/10":H="border-[#3A5659] bg-[#3A5659]/5 text-[#3A5659] ring-2 ring-[#3A5659]/10"),(0,ge.jsx)("button",{type:"button",onClick:()=>l(r.id),className:`flex-1 py-2.5 px-4 text-xs font-bold border rounded-xl transition-all duration-200 text-center capitalize shadow-sm cursor-pointer ${H}`,children:r.name},r.id)})}),g&&(0,ge.jsx)("p",{className:"text-xs text-red-500 font-semibold mt-1.5",children:g})]});var n=require("react/jsx-runtime"),Pe=({activeModal:e,onClose:t,onSubmit:l,userEmail:g,submitting:r,rating:y,setRating:b,hoverRating:H,setHoverRating:m,title:w,setTitle:re,description:G,setDescription:M,screenshotData:j,setScreenshotData:v,recordingBlob:C,onRemoveRecording:I,onPreviewRecording:O,externalFile:$,setExternalFile:Q,fileInputRef:R,handleFileChange:ee,onCaptureScreenshot:F,onStartRecording:X,errors:S,onClearError:N,priorities:W,selectedPriorityId:V,setSelectedPriorityId:u})=>{let A=(()=>{switch(e){case"general":return{title:"General Feedback",icon:(0,n.jsx)(K.MessageSquare,{className:"w-5 h-5 text-sky-600"}),bgColor:"bg-sky-100",description:"Share your overall experience or thoughts about WellnessPro."};case"bug":return{title:"Report a Bug",icon:(0,n.jsx)(K.Bug,{className:"w-5 h-5 text-orange-600"}),bgColor:"bg-orange-100",description:"Help us improve by describing the issue you encountered."};case"feature":return{title:"Suggest a Feature",icon:(0,n.jsx)(K.Lightbulb,{className:"w-5 h-5 text-purple-600"}),bgColor:"bg-purple-100",description:"Tell us about a feature you would love to see in the system."};default:return{title:"",icon:null,bgColor:"bg-gray-100",description:""}}})();return e===null?null:(0,n.jsx)("div",{className:"feedback-no-capture fixed inset-0 bg-black/40 backdrop-blur-sm z-[100] flex items-center justify-center p-4",onClick:t,children:(0,n.jsxs)("div",{className:"relative bg-white rounded-2xl shadow-2xl w-full max-w-lg overflow-hidden flex flex-col max-h-[90vh] transition-all",onClick:s=>s.stopPropagation(),children:[(0,n.jsxs)("div",{className:"flex items-center justify-between p-5 border-b border-gray-100",children:[(0,n.jsxs)("div",{className:"flex items-center gap-3.5",children:[(0,n.jsx)("div",{className:`w-10 h-10 rounded-xl ${A.bgColor} flex items-center justify-center shrink-0`,children:A.icon}),(0,n.jsxs)("div",{children:[(0,n.jsx)("h2",{className:"text-base font-bold text-gray-900",children:A.title}),(0,n.jsx)("p",{className:"text-[11px] text-gray-400 mt-0.5 font-normal leading-normal",children:A.description})]})]}),(0,n.jsx)("button",{onClick:t,className:"p-1.5 hover:bg-gray-100 rounded-full transition-colors","aria-label":"Close modal",children:(0,n.jsx)(K.X,{className:"w-5 h-5 text-gray-400"})})]}),(0,n.jsxs)("form",{onSubmit:l,className:"flex-1 overflow-y-auto p-6 space-y-4",children:[(0,n.jsxs)("div",{className:"space-y-1.5",children:[(0,n.jsx)("label",{className:"block text-sm font-medium text-gray-700",children:"Email Address"}),(0,n.jsx)("input",{type:"email",value:g,readOnly:!0,className:"w-full px-3.5 py-2.5 text-sm bg-gray-50 border border-gray-200 rounded-xl text-gray-500 focus:outline-none cursor-not-allowed"})]}),e==="general"&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)("div",{className:"space-y-2",children:[(0,n.jsxs)("label",{className:"block text-sm font-medium text-gray-700",children:["How would you rate your experience?"," ",(0,n.jsx)("span",{className:"text-red-500",children:"*"})]}),(0,n.jsx)("div",{className:"flex items-center gap-1.5 py-1",children:[1,2,3,4,5].map(s=>(0,n.jsx)("button",{type:"button",onClick:()=>{b(s),N("rating")},onMouseEnter:()=>m(s),onMouseLeave:()=>m(0),className:"focus:outline-none transition-transform hover:scale-110",children:(0,n.jsx)(K.Star,{className:`w-8 h-8 ${(H||y)>=s?"fill-amber-400 text-amber-400":"text-gray-200"}`,strokeWidth:1.5})},s))}),S.rating&&(0,n.jsx)("p",{className:"text-xs text-red-500 font-medium",children:S.rating})]}),(0,n.jsxs)("div",{className:"space-y-1.5",children:[(0,n.jsxs)("label",{className:"block text-sm font-medium text-gray-700",children:["Feedback Details ",(0,n.jsx)("span",{className:"text-red-500",children:"*"})]}),(0,n.jsx)("textarea",{rows:4,value:G,onChange:s=>{M(s.target.value),N("description")},placeholder:"Tell us what you like or what can be improved...",maxLength:1e3,className:`w-full px-3.5 py-2.5 text-sm bg-gray-50 border rounded-xl focus:outline-none focus:ring-2 focus:ring-[#3A5659]/20 focus:border-[#3A5659] transition-all resize-none ${S.description?"border-red-500":"border-gray-200"}`}),(0,n.jsxs)("div",{className:"flex justify-between items-center text-[11px] text-gray-400 mt-1",children:[S.description?(0,n.jsx)("span",{className:"text-red-500 font-medium",children:S.description}):(0,n.jsx)("span",{children:"Please enter at least 5 characters"}),(0,n.jsxs)("span",{children:[G.length,"/1000"]})]})]})]}),e==="bug"&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)("div",{className:"space-y-1.5",children:[(0,n.jsxs)("label",{className:"block text-sm font-medium text-gray-700",children:["Issue Title ",(0,n.jsx)("span",{className:"text-red-500",children:"*"})]}),(0,n.jsx)("input",{type:"text",value:w,onChange:s=>{re(s.target.value),N("title")},placeholder:"Describe the issue briefly (e.g. 'Dashboard chart is not rendering')",maxLength:100,className:`w-full px-3.5 py-2.5 text-sm bg-gray-50 border rounded-xl focus:outline-none focus:ring-2 focus:ring-[#3A5659]/20 focus:border-[#3A5659] transition-all ${S.title?"border-red-500":"border-gray-200"}`}),S.title&&(0,n.jsx)("p",{className:"text-xs text-red-500 font-medium mt-1",children:S.title})]}),W&&W.length>0&&(0,n.jsx)(Se,{priorities:W,selectedPriorityId:V,onChange:s=>{u(s),N("priority")},error:S.priority}),(0,n.jsxs)("div",{className:"space-y-1.5",children:[(0,n.jsxs)("label",{className:"block text-sm font-medium text-gray-700",children:["Bug Details & Steps to Reproduce"," ",(0,n.jsx)("span",{className:"text-red-500",children:"*"})]}),(0,n.jsx)("textarea",{rows:4,value:G,onChange:s=>{M(s.target.value),N("description")},placeholder:"What did you expect to happen? What actually happened? Provide steps to reproduce if possible.",maxLength:2e3,className:`w-full px-3.5 py-2.5 text-sm bg-gray-50 border rounded-xl focus:outline-none focus:ring-2 focus:ring-[#3A5659]/20 focus:border-[#3A5659] transition-all resize-none ${S.description?"border-red-500":"border-gray-200"}`}),(0,n.jsxs)("div",{className:"flex justify-between items-center text-[11px] text-gray-400 mt-1",children:[S.description?(0,n.jsx)("span",{className:"text-red-500 font-medium",children:S.description}):(0,n.jsx)("span",{children:"Please enter at least 10 characters"}),(0,n.jsxs)("span",{children:[G.length,"/2000"]})]})]})]}),e==="feature"&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)("div",{className:"space-y-1.5",children:[(0,n.jsxs)("label",{className:"block text-sm font-medium text-gray-700",children:["Feature Request Title ",(0,n.jsx)("span",{className:"text-red-500",children:"*"})]}),(0,n.jsx)("input",{type:"text",value:w,onChange:s=>{re(s.target.value),N("title")},placeholder:"Give your suggestion a clear title (e.g. 'Add exporting to CSV option')",maxLength:100,className:`w-full px-3.5 py-2.5 text-sm bg-gray-50 border rounded-xl focus:outline-none focus:ring-2 focus:ring-[#3A5659]/20 focus:border-[#3A5659] transition-all ${S.title?"border-red-500":"border-gray-200"}`}),S.title&&(0,n.jsx)("p",{className:"text-xs text-red-500 font-medium mt-1",children:S.title})]}),(0,n.jsxs)("div",{className:"space-y-1.5",children:[(0,n.jsxs)("label",{className:"block text-sm font-medium text-gray-700",children:["Describe the Feature ",(0,n.jsx)("span",{className:"text-red-500",children:"*"})]}),(0,n.jsx)("textarea",{rows:4,value:G,onChange:s=>{M(s.target.value),N("description")},placeholder:"What problem does this feature solve? How should it work? Who would benefit from it?",maxLength:2e3,className:`w-full px-3.5 py-2.5 text-sm bg-gray-50 border rounded-xl focus:outline-none focus:ring-2 focus:ring-[#3A5659]/20 focus:border-[#3A5659] transition-all resize-none ${S.description?"border-red-500":"border-gray-200"}`}),(0,n.jsxs)("div",{className:"flex justify-between items-center text-[11px] text-gray-400 mt-1",children:[S.description?(0,n.jsx)("span",{className:"text-red-500 font-medium",children:S.description}):(0,n.jsx)("span",{children:"Please enter at least 10 characters"}),(0,n.jsxs)("span",{children:[G.length,"/2000"]})]})]})]}),j&&(0,n.jsxs)("div",{className:"space-y-1.5 pt-2",children:[(0,n.jsx)("label",{className:"block text-xs font-semibold text-gray-500 uppercase tracking-wider",children:"Attached Screenshot"}),(0,n.jsxs)("div",{className:"relative inline-block border border-gray-200 rounded-xl overflow-hidden shadow-sm group",children:[(0,n.jsx)("img",{src:j,alt:"Screenshot attachment",className:"h-20 w-auto object-cover max-w-full"}),(0,n.jsx)("button",{type:"button",onClick:()=>v(null),className:"absolute top-1.5 right-1.5 p-1 bg-red-500 hover:bg-red-600 text-white rounded-full transition-colors shadow-md",title:"Remove screenshot",children:(0,n.jsx)(K.X,{className:"w-3 h-3"})})]})]}),C&&(0,n.jsxs)("div",{className:"space-y-1.5 pt-2",children:[(0,n.jsx)("label",{className:"block text-xs font-semibold text-gray-500 uppercase tracking-wider",children:"Attached Session Recording"}),(0,n.jsxs)("div",{onClick:O,className:"flex items-center justify-between p-2.5 bg-gray-50 border border-gray-200 hover:bg-gray-100 hover:border-gray-300 rounded-xl max-w-full cursor-pointer transition-all group/preview",title:"Click to preview session recording",children:[(0,n.jsxs)("div",{className:"flex items-center gap-2 overflow-hidden mr-4",children:[(0,n.jsx)(K.Video,{className:"w-4.5 h-4.5 text-[#3A5659] shrink-0 group-hover/preview:scale-105 transition-transform"}),(0,n.jsx)("span",{className:"text-xs font-semibold text-gray-700 truncate group-hover/preview:text-[#2d4346] transition-colors",children:"session-recording"}),(0,n.jsxs)("span",{className:"text-[10px] text-gray-400 shrink-0",children:["(",(C.size/1024).toFixed(1)," KB)"]})]}),(0,n.jsx)("button",{type:"button",onClick:s=>{s.stopPropagation(),I()},className:"p-1 hover:bg-gray-200 text-gray-500 hover:text-red-500 rounded-full transition-colors",title:"Remove session recording",children:(0,n.jsx)(K.X,{className:"w-4 h-4"})})]})]}),$&&(0,n.jsxs)("div",{className:"space-y-1.5 pt-2",children:[(0,n.jsx)("label",{className:"block text-xs font-semibold text-gray-500 uppercase tracking-wider",children:"Attached File"}),(0,n.jsxs)("div",{className:"flex items-center justify-between p-2.5 bg-gray-50 border border-gray-200 rounded-xl max-w-full",children:[(0,n.jsxs)("div",{className:"flex items-center gap-2 overflow-hidden mr-4",children:[(0,n.jsx)(K.Paperclip,{className:"w-4.5 h-4.5 text-gray-400 shrink-0"}),(0,n.jsx)("span",{className:"text-xs font-medium text-gray-700 truncate",title:$.name,children:$.name}),(0,n.jsxs)("span",{className:"text-[10px] text-gray-400 shrink-0",children:["(",($.size/1024).toFixed(1)," KB)"]})]}),(0,n.jsx)("button",{type:"button",onClick:()=>Q(null),className:"p-1 hover:bg-gray-200 text-gray-500 hover:text-red-500 rounded-full transition-colors",title:"Remove file",children:(0,n.jsx)(K.X,{className:"w-4 h-4"})})]})]}),(0,n.jsx)("button",{type:"submit",className:"hidden"})]}),(0,n.jsxs)("div",{className:"relative z-10 flex items-center justify-between p-4 bg-gray-50 border-t border-gray-100 shrink-0",children:[(0,n.jsxs)("div",{className:"flex items-center gap-2",children:[(0,n.jsxs)("div",{className:"relative group",children:[(0,n.jsx)("button",{type:"button",className:"w-9 h-9 rounded-full flex items-center justify-center bg-white border border-gray-200 text-gray-500 hover:text-[#3A5659] hover:border-[#3A5659] transition-all hover:bg-sky-50/50 shadow-sm",onClick:F,children:(0,n.jsx)(K.Camera,{className:"w-4.5 h-4.5"})}),(0,n.jsx)("span",{className:"absolute bottom-full left-0 mb-2 px-2 py-1 text-[10px] text-white bg-gray-800 rounded opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap pointer-events-none z-50 shadow-md",children:"Capture & Annotate Screenshot"})]}),(0,n.jsxs)("div",{className:"relative group",children:[(0,n.jsx)("button",{type:"button",className:"w-9 h-9 rounded-full flex items-center justify-center bg-white border border-gray-200 text-gray-500 hover:text-red-500 hover:border-red-300 transition-all hover:bg-red-50/50 shadow-sm",onClick:X,children:(0,n.jsx)(K.Video,{className:"w-4.5 h-4.5"})}),(0,n.jsx)("span",{className:"absolute bottom-full left-0 mb-2 px-2 py-1 text-[10px] text-white bg-gray-800 rounded opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap pointer-events-none z-50 shadow-md",children:"Record Screen with Live Drawing (Max 60s)"})]}),(0,n.jsxs)("div",{className:"relative group",children:[(0,n.jsx)("button",{type:"button",className:"w-9 h-9 rounded-full flex items-center justify-center bg-white border border-gray-200 text-gray-500 hover:text-emerald-600 hover:border-emerald-300 transition-all hover:bg-emerald-50/50 shadow-sm",onClick:()=>R.current?.click(),children:(0,n.jsx)(K.Paperclip,{className:"w-4.5 h-4.5"})}),(0,n.jsx)("input",{type:"file",ref:R,onChange:ee,className:"hidden"}),(0,n.jsx)("span",{className:"absolute bottom-full left-0 mb-2 px-2 py-1 text-[10px] text-white bg-gray-800 rounded opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap pointer-events-none z-50 shadow-md",children:"Attach External File"})]})]}),(0,n.jsxs)("div",{className:"flex items-center gap-2.5",children:[(0,n.jsx)("button",{type:"button",onClick:t,className:"px-4 py-2 text-sm font-medium text-gray-600 hover:bg-gray-100 rounded-xl transition-colors",children:"Cancel"}),(0,n.jsxs)("button",{type:"button",onClick:l,disabled:r,className:"px-5 py-2 text-sm font-semibold text-white bg-[#3A5659] hover:bg-[#31494c] rounded-xl transition-all flex items-center gap-1.5 disabled:opacity-70 disabled:cursor-not-allowed shadow-sm shadow-[#3A5659]/10",children:[r&&(0,n.jsx)(K.Loader2,{className:"w-4 h-4 animate-spin"}),(0,n.jsx)("span",{children:"Submit"})]})]})]})]})})};var he=require("lucide-react"),Y=require("react/jsx-runtime"),Me=({panelRef:e,isOpen:t,onClose:l,onOpenModal:g})=>(0,Y.jsxs)("div",{ref:e,className:"feedback-no-capture fixed top-1/2 -translate-y-1/2 z-50 w-72 bg-white rounded-l-2xl border border-gray-100 shadow-2xl p-5 flex flex-col transition-all duration-300",style:{right:t?"0":"-320px"},children:[(0,Y.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,Y.jsx)("h3",{className:"font-bold text-gray-900 text-base",children:"Share Feedback"}),(0,Y.jsx)("button",{onClick:l,className:"p-1 hover:bg-gray-100 rounded-full transition-colors","aria-label":"Close panel",children:(0,Y.jsx)(he.X,{className:"w-4 h-4 text-gray-400"})})]}),(0,Y.jsx)("p",{className:"text-xs text-gray-500 mb-5 leading-relaxed",children:"What kind of feedback would you like to submit?"}),(0,Y.jsxs)("button",{onClick:()=>g("general"),className:"flex items-center gap-4 p-3.5 border border-gray-100 rounded-xl cursor-pointer bg-gray-50 hover:bg-sky-50 hover:border-sky-200 transition-all duration-200 text-left w-full group mb-3",children:[(0,Y.jsx)("div",{className:"w-9 h-9 rounded-full bg-sky-100 flex items-center justify-center shrink-0 group-hover:bg-sky-200 transition-colors",children:(0,Y.jsx)(he.MessageSquare,{className:"w-4 h-4 text-sky-600"})}),(0,Y.jsxs)("div",{children:[(0,Y.jsx)("span",{className:"block font-semibold text-gray-800 text-sm",children:"General Feedback"}),(0,Y.jsx)("span",{className:"block text-[11px] text-gray-400 mt-0.5",children:"Share your general thoughts"})]})]}),(0,Y.jsxs)("button",{onClick:()=>g("bug"),className:"flex items-center gap-4 p-3.5 border border-gray-100 rounded-xl cursor-pointer bg-gray-50 hover:bg-orange-50 hover:border-orange-200 transition-all duration-200 text-left w-full group mb-3",children:[(0,Y.jsx)("div",{className:"w-9 h-9 rounded-full bg-orange-100 flex items-center justify-center shrink-0 group-hover:bg-orange-200 transition-colors",children:(0,Y.jsx)(he.Bug,{className:"w-4 h-4 text-orange-600"})}),(0,Y.jsxs)("div",{children:[(0,Y.jsx)("span",{className:"block font-semibold text-gray-800 text-sm",children:"Bug Report"}),(0,Y.jsx)("span",{className:"block text-[11px] text-gray-400 mt-0.5",children:"Report a problem or error"})]})]}),(0,Y.jsxs)("button",{onClick:()=>g("feature"),className:"flex items-center gap-4 p-3.5 border border-gray-100 rounded-xl cursor-pointer bg-gray-50 hover:bg-purple-50 hover:border-purple-200 transition-all duration-200 text-left w-full group",children:[(0,Y.jsx)("div",{className:"w-9 h-9 rounded-full bg-purple-100 flex items-center justify-center shrink-0 group-hover:bg-purple-200 transition-colors",children:(0,Y.jsx)(he.Lightbulb,{className:"w-4 h-4 text-purple-600"})}),(0,Y.jsxs)("div",{children:[(0,Y.jsx)("span",{className:"block font-semibold text-gray-800 text-sm",children:"Feature Request"}),(0,Y.jsx)("span",{className:"block text-[11px] text-gray-400 mt-0.5",children:"Suggest a new improvement"})]})]})]});var Te=require("lucide-react"),xe=require("react/jsx-runtime"),Ee=({buttonRef:e,onClick:t})=>(0,xe.jsx)("div",{ref:e,className:"feedback-no-capture fixed right-0 top-1/2 -translate-y-1/2 z-50 text-white px-3 py-4 cursor-pointer shadow-xl flex flex-col items-center gap-2 font-semibold tracking-wider select-none transition-all duration-200 hover:pr-4 hover:scale-105 rounded-l-xl bg-[#3A5659]",style:{writingMode:"vertical-rl",textOrientation:"mixed"},onClick:t,children:(0,xe.jsxs)("div",{className:"flex items-center gap-2",children:[(0,xe.jsx)(Te.MessageSquare,{className:"w-4 h-4 rotate-90"}),(0,xe.jsx)("span",{children:"Feedback"})]})});var te=require("react"),ue=require("lucide-react"),Fe=require("@rrweb/all"),ft=require("@rrweb/all/dist/style.css"),E=require("react/jsx-runtime"),ve=({isOpen:e,onClose:t,events:l})=>{let g=(0,te.useRef)(null),r=(0,te.useRef)(null),y=(0,te.useRef)(null),b=(0,te.useRef)(null),H=(0,te.useRef)(null),[m,w]=(0,te.useState)(!1),[re,G]=(0,te.useState)(1),[M,j]=(0,te.useState)(1),[v,C]=(0,te.useState)(!1),[I,O]=(0,te.useState)(0),[$,Q]=(0,te.useState)(0),R=(0,te.useRef)(0);(0,te.useEffect)(()=>{R.current=$},[$]);let ee=l.find(u=>u.type===4),F=ee?.data?.width||1024,X=ee?.data?.height||576;if((0,te.useEffect)(()=>{if(!e||!r.current){C(!1);return}let u=new ResizeObserver(D=>{for(let A of D){let{width:s,height:U}=A.contentRect;s>0&&U>0&&C(!0)}});return u.observe(r.current),()=>{u.disconnect()}},[e]),(0,te.useEffect)(()=>{if(!e||!v||l.length===0||!g.current||!r.current)return;g.current.innerHTML="",console.log("[RRWeb Replayer] Initializing Replayer..."),console.log("[RRWeb Replayer] containerRef clientWidth:",r.current.clientWidth),console.log("[RRWeb Replayer] containerRef clientHeight:",r.current.clientHeight),console.log("[RRWeb Replayer] containerRef getBoundingClientRect:",r.current.getBoundingClientRect());let u=null;try{u=new Fe.Replayer(l.slice(),{root:g.current,unpackFn:void 0,mouseTail:!1,blockClass:"feedback-no-capture",UNSAFE_replayCanvas:!0,insertStyleRules:[".replayer-mouse { display: none !important; }",".replayer-mouse-tail { display: none !important; }",".feedback-no-capture { display: none !important; }"]}),y.current=u;let s=u.getMetaData();Q(s.totalTime),O(0),u.on("start",()=>w(!0)),u.on("pause",()=>w(!1)),u.on("finish",()=>{w(!1),O(s.totalTime)}),u.pause(0),O(0);let U=()=>{if(y.current===u)try{u?.play(0),w(!0)}catch(z){console.error("Failed to start rrweb playback:",z)}};b.current=requestAnimationFrame(()=>{H.current=window.setTimeout(U,200)})}catch(s){console.error("Failed to initialize rrweb replayer:",s)}let D=()=>{if(!r.current)return;let s=r.current.clientWidth-48,U=r.current.clientHeight-48,z=s/F,Z=U/X,ie=Math.min(z,Z,1);console.log("[RRWeb Replayer] Viewport comparison:",{recorded:{width:F,height:X},replayerContainer:{width:s,height:U},scaleX:z,scaleY:Z,appliedScale:ie}),j(ie)};D();let A=new ResizeObserver(()=>{D()});return A.observe(r.current),()=>{if(A.disconnect(),b.current!==null&&(cancelAnimationFrame(b.current),b.current=null),H.current!==null&&(clearTimeout(H.current),H.current=null),y.current){try{y.current.destroy()}catch(s){console.error(s)}y.current=null}}},[e,v,l]),(0,te.useEffect)(()=>{let u,D=()=>{if(y.current&&m)try{let A=y.current.getCurrentTime();O(Math.min(A,R.current))}catch{}u=requestAnimationFrame(D)};return m&&(u=requestAnimationFrame(D)),()=>{cancelAnimationFrame(u)}},[m]),!e)return null;let S=()=>{let u=y.current;u&&(m?(u.pause(),w(!1)):(u.play(),w(!0)))},N=()=>{let u=y.current;u&&(u.play(0),O(0),w(!0))},W=()=>{let u=y.current;if(!u)return;let D=1;re===1?D=2:re===2?D=4:D=1,G(D),u.setConfig({speed:D})},V=u=>{let D=Math.floor(u/1e3),A=Math.floor(D/60),s=D%60;return`${A.toString().padStart(2,"0")}:${s.toString().padStart(2,"0")}`};return(0,E.jsxs)(E.Fragment,{children:[(0,E.jsx)("style",{children:`
2
+ .replayer-mouse, .replayer-mouse-tail, .feedback-no-capture {
3
+ display: none !important;
4
+ }
5
+ /*
6
+ * Constrain rrweb's generated wrapper/iframe to the recorded viewport.
7
+ * For pages taller than the viewport (scrollable, > 100vh), rrweb sizes
8
+ * the wrapper to the full document height, which makes the whole long
9
+ * page render and spill/shrink instead of showing just the viewport and
10
+ * replaying scroll within it. Pinning to the recorded viewport + clipping
11
+ * overflow keeps the preview matching what was actually on screen.
12
+ */
13
+ .rrweb-replayer-wrapper .replayer-wrapper {
14
+ position: relative !important;
15
+ top: 0 !important;
16
+ left: 0 !important;
17
+ margin: 0 !important;
18
+ width: ${F}px !important;
19
+ height: ${X}px !important;
20
+ overflow: hidden !important;
21
+ }
22
+ .rrweb-replayer-wrapper .replayer-wrapper iframe {
23
+ width: ${F}px !important;
24
+ height: ${X}px !important;
25
+ border: none !important;
26
+ }
27
+ .custom-player-slider::-webkit-slider-thumb {
28
+ -webkit-appearance: none;
29
+ appearance: none;
30
+ width: 12px;
31
+ height: 12px;
32
+ border-radius: 50%;
33
+ background: #3A5659;
34
+ cursor: pointer;
35
+ transition: transform 0.1s ease;
36
+ }
37
+ .custom-player-slider::-webkit-slider-thumb:hover {
38
+ transform: scale(1.3);
39
+ }
40
+ .custom-player-slider::-moz-range-thumb {
41
+ width: 12px;
42
+ height: 12px;
43
+ border-radius: 50%;
44
+ background: #3A5659;
45
+ cursor: pointer;
46
+ border: none;
47
+ transition: transform 0.1s ease;
48
+ }
49
+ .custom-player-slider::-moz-range-thumb:hover {
50
+ transform: scale(1.3);
51
+ }
52
+ `}),(0,E.jsx)("div",{className:"fixed inset-0 z-[10000] bg-black/80 backdrop-blur-md flex items-center justify-center p-4",onClick:t,children:(0,E.jsxs)("div",{className:"relative bg-slate-900 border border-slate-800 rounded-2xl shadow-2xl w-full max-w-[90vw] overflow-hidden flex flex-col max-h-[90vh]",onClick:u=>u.stopPropagation(),children:[(0,E.jsxs)("div",{className:"flex items-center justify-between px-5 py-4 border-b border-slate-800 shrink-0",children:[(0,E.jsxs)("div",{children:[(0,E.jsx)("h3",{className:"text-sm font-bold text-white",children:"Session Recording Preview"}),(0,E.jsx)("p",{className:"text-[10px] text-slate-400 mt-0.5",children:"Replaying user actions & annotations"})]}),(0,E.jsx)("button",{onClick:t,className:"p-1.5 hover:bg-slate-850 rounded-full text-slate-400 hover:text-white transition-colors",children:(0,E.jsx)(ue.X,{className:"w-5 h-5"})})]}),(0,E.jsxs)("div",{ref:r,onClick:S,className:"flex-1 min-h-[300px] h-[55vh] bg-slate-950 flex items-center justify-center overflow-hidden p-6 relative cursor-pointer group",children:[!m&&(0,E.jsx)("div",{className:"absolute inset-0 bg-black/40 flex items-center justify-center z-10 transition-opacity",children:(0,E.jsx)("div",{className:"w-16 h-16 rounded-full bg-white/20 backdrop-blur-sm border border-white/30 flex items-center justify-center text-white shadow-2xl hover:scale-110 hover:bg-white/30 transition-all",children:(0,E.jsx)(ue.Play,{className:"w-8 h-8 fill-current translate-x-0.5"})})}),(0,E.jsx)("div",{className:"shadow-2xl rounded border border-slate-800 bg-white overflow-hidden shrink-0",style:{width:`${F*M}px`,height:`${X*M}px`},onClick:u=>u.stopPropagation(),children:(0,E.jsx)("div",{ref:g,className:"rrweb-replayer-wrapper w-full h-full",style:{width:`${F}px`,height:`${X}px`,transform:`scale(${M})`,transformOrigin:"top left"}})})]}),(0,E.jsxs)("div",{className:"px-6 py-4 bg-slate-900 border-t border-slate-800 flex items-center justify-between shrink-0 gap-5",children:[(0,E.jsxs)("div",{className:"flex items-center gap-3 shrink-0",children:[(0,E.jsx)("button",{type:"button",onClick:S,className:"p-2.5 bg-[#3A5659] hover:bg-[#31494c] text-white rounded-full shadow transition-all hover:scale-105",title:m?"Pause":"Play",children:m?(0,E.jsx)(ue.Pause,{className:"w-4.5 h-4.5"}):(0,E.jsx)(ue.Play,{className:"w-4.5 h-4.5 fill-current"})}),(0,E.jsx)("button",{type:"button",onClick:N,className:"p-2 bg-slate-800 hover:bg-slate-700 text-slate-300 hover:text-white rounded-full transition-colors",title:"Restart Playback",children:(0,E.jsx)(ue.RotateCcw,{className:"w-4.5 h-4.5"})})]}),(0,E.jsxs)("div",{className:"flex-1 flex items-center gap-3 min-w-0",onClick:u=>u.stopPropagation(),children:[(0,E.jsx)("span",{className:"text-[10px] font-semibold font-mono text-slate-400 shrink-0",children:V(I)}),(0,E.jsx)("input",{type:"range",min:"0",max:$||100,value:I,onChange:u=>{let D=Number(u.target.value);O(D),y.current?.play(D)},className:"custom-player-slider flex-1 h-1 bg-slate-800 rounded-lg appearance-none cursor-pointer accent-[#3A5659] focus:outline-none"}),(0,E.jsx)("span",{className:"text-[10px] font-semibold font-mono text-slate-400 shrink-0",children:V($)})]}),(0,E.jsx)("div",{className:"flex items-center gap-2 shrink-0",children:(0,E.jsxs)("button",{type:"button",onClick:W,className:"px-3 py-1.5 bg-slate-800 hover:bg-slate-700 text-xs font-bold font-mono text-slate-300 hover:text-white rounded-lg flex items-center gap-1 transition-colors",title:"Change Speed",children:[(0,E.jsx)(ue.FastForward,{className:"w-3.5 h-3.5"}),(0,E.jsxs)("span",{children:[re,"x"]})]})})]})]})})]})};var _=require("react"),ae=require("lucide-react"),P=require("react/jsx-runtime");function Je(e,t,l,g){e.strokeStyle=g,e.fillStyle=g,e.lineWidth=4,e.lineCap="round",e.beginPath(),e.moveTo(t.x,t.y),e.lineTo(l.x,l.y),e.stroke();let r=Math.atan2(l.y-t.y,l.x-t.x);e.beginPath(),e.moveTo(l.x,l.y),e.lineTo(l.x-15*Math.cos(r-Math.PI/6),l.y-15*Math.sin(r-Math.PI/6)),e.lineTo(l.x-15*Math.cos(r+Math.PI/6),l.y-15*Math.sin(r+Math.PI/6)),e.closePath(),e.fill()}function Ge(e,t,l,g){e.strokeStyle=g,e.lineWidth=4,e.strokeRect(t.x,t.y,l.x-t.x,l.y-t.y)}function Qe(e,t,l){if(!(t.length<2)){e.strokeStyle=l,e.lineWidth=4,e.lineCap="round",e.lineJoin="round",e.beginPath(),e.moveTo(t[0].x,t[0].y);for(let g=1;g<t.length;g++)e.lineTo(t[g].x,t[g].y);e.stroke()}}function Ze(e,t,l,g){e.fillStyle=g,e.font="bold 20px sans-serif",e.fillText(l,t.x,t.y)}function De(e,t){t.type==="pencil"?Qe(e,t.points,t.color):t.type==="arrow"?Je(e,t.start,t.end,t.color):t.type==="rect"?Ge(e,t.start,t.end,t.color):t.type==="text"&&Ze(e,t.position,t.text,t.color)}var Ae=({isRecording:e,onStopRecording:t})=>{let[l,g]=(0,_.useState)(60),[r,y]=(0,_.useState)("pencil"),[b,H]=(0,_.useState)("#EF4444"),[m,w]=(0,_.useState)([]),[re,G]=(0,_.useState)(!1),[M,j]=(0,_.useState)(null),[v,C]=(0,_.useState)(null),[I,O]=(0,_.useState)(null),[$,Q]=(0,_.useState)(null),[R,ee]=(0,_.useState)([]),[F,X]=(0,_.useState)(null),[S,N]=(0,_.useState)(""),W=(0,_.useRef)(null),V=(0,_.useRef)(null);(0,_.useEffect)(()=>{F&&V.current&&V.current.focus()},[F]);let u=(0,_.useCallback)((d,a)=>{let f=W.current;if(!f)return;let k=f.getContext("2d");if(!k)return;let L=window.devicePixelRatio||1;k.setTransform(1,0,0,1,0,0),k.clearRect(0,0,f.width,f.height),k.scale(L,L),(a||m).filter((c,p)=>p!==I).forEach(c=>{De(k,c)}),d&&De(k,d);let i=a||m;if(r==="select"&&v!==null&&i[v]){let c=i[v],p=0,T=0,h=0,ce=0;c.type==="text"?(p=c.position.x-6,T=c.position.x+c.text.length*12+6,h=c.position.y-22,ce=c.position.y+6):(c.type==="rect"||c.type==="arrow")&&(p=Math.min(c.start.x,c.end.x)-6,T=Math.max(c.start.x,c.end.x)+6,h=Math.min(c.start.y,c.end.y)-6,ce=Math.max(c.start.y,c.end.y)+6),(p!==0||T!==0)&&(k.strokeStyle="#38BDF8",k.lineWidth=1.5,k.setLineDash([4,4]),k.strokeRect(p,h,T-p,ce-h),k.setLineDash([]))}},[m,r,v,I]);(0,_.useEffect)(()=>{let d;return e&&l>0&&(d=setInterval(()=>{g(a=>a<=1?(t(),0):a-1)},1e3)),()=>clearInterval(d)},[e,l,t]),(0,_.useEffect)(()=>{if(e){let d=()=>{let a=W.current;if(a){let f=window.devicePixelRatio||1,k=window.innerWidth,L=window.innerHeight;a.width=k*f,a.height=L*f,a.style.width=`${k}px`,a.style.height=`${L}px`,u()}};return d(),window.addEventListener("resize",d),()=>window.removeEventListener("resize",d)}},[e,u]),(0,_.useEffect)(()=>{e&&u()},[e,u]),(0,_.useEffect)(()=>{e||(w([]),j(null),C(null),O(null),X(null),N(""),y("pencil"),g(60))},[e]);let D=(d,a)=>{if(a.type==="text"){let f=a.position.x-10,k=a.position.x+a.text.length*12+10,L=a.position.y-24,o=a.position.y+10;return d.x>=f&&d.x<=k&&d.y>=L&&d.y<=o}if(a.type==="rect"||a.type==="arrow"){let f=Math.min(a.start.x,a.end.x)-10,k=Math.max(a.start.x,a.end.x)+10,L=Math.min(a.start.y,a.end.y)-10,o=Math.max(a.start.y,a.end.y)+10;return d.x>=f&&d.x<=k&&d.y>=L&&d.y<=o}return!1},A=d=>{let a=W.current;if(!a)return{x:0,y:0};let f=a.getBoundingClientRect();return{x:d.clientX-f.left,y:d.clientY-f.top}},s=(0,_.useCallback)(()=>{if(I!==null)S.trim()?w(d=>{let a=[...d];return a[I]&&a[I].type==="text"&&(a[I]={...a[I],text:S.trim()}),a}):w(d=>d.filter((a,f)=>f!==I)),O(null);else if(F&&S.trim()){let d={type:"text",position:{x:F.canvasX,y:F.canvasY},text:S.trim(),color:b};w(a=>[...a,d])}X(null),N("")},[I,F,S,b]);(0,_.useEffect)(()=>{let d=a=>{a.target instanceof HTMLInputElement||a.target instanceof HTMLTextAreaElement||(a.key==="Delete"||a.key==="Backspace")&&r==="select"&&v!==null&&(w(f=>f.filter((k,L)=>L!==v)),C(null))};return window.addEventListener("keydown",d),()=>window.removeEventListener("keydown",d)},[r,v]);let U=d=>{if(r==="interact")return;let a=A(d);if(F){s();return}if(r==="select"){let f=-1;for(let k=m.length-1;k>=0;k--)if(D(a,m[k])){f=k;break}f!==-1?(C(f),Q(a),ee(JSON.parse(JSON.stringify(m)))):C(null);return}if(r==="text"){X({clientX:d.clientX,clientY:d.clientY,canvasX:a.x,canvasY:a.y}),N(""),O(null);return}G(!0),r==="pencil"?j({type:"pencil",points:[a],color:b}):r==="arrow"?j({type:"arrow",start:a,end:a,color:b}):r==="rect"&&j({type:"rect",start:a,end:a,color:b})},z=d=>{let a=A(d);if(r==="select"&&$&&v!==null){let f=a.x-$.x,k=a.y-$.y,o=R[v];if(!o)return;w(i=>{let c=[...i],p={...o};return p.type==="text"&&o.type==="text"?p.position={x:o.position.x+f,y:o.position.y+k}:(p.type==="rect"||p.type==="arrow")&&(o.type==="rect"||o.type==="arrow")&&(p.start={x:o.start.x+f,y:o.start.y+k},p.end={x:o.end.x+f,y:o.end.y+k}),c[v]=p,u(void 0,c),c});return}if(!(!re||!M)){if(M.type==="pencil"){let f={...M,points:[...M.points,a]};j(f),u(f)}else if(M.type==="arrow"||M.type==="rect"){let f={...M,end:a};j(f),u(f)}}},Z=()=>{if(r==="select"){Q(null),ee([]);return}re&&M&&(w(d=>[...d,M]),j(null),G(!1),u())},ie=d=>{if(r!=="select")return;let a=A(d),f=-1;for(let k=m.length-1;k>=0;k--)if(D(a,m[k])){f=k;break}if(f!==-1&&m[f].type==="text"){let k=m[f];k.type==="text"&&(O(f),X({clientX:d.clientX,clientY:d.clientY,canvasX:k.position.x,canvasY:k.position.y}),N(k.text),C(null))}};return e?(0,P.jsxs)("div",{className:`fixed inset-0 z-[9999] flex flex-col justify-between ${r!=="interact"?"pointer-events-auto":"pointer-events-none"}`,children:[(0,P.jsx)("canvas",{ref:W,className:`absolute inset-0 w-full h-full bg-transparent ${r!=="interact"?"pointer-events-auto":"pointer-events-none"} ${r==="select"||r==="interact"?"cursor-default":"cursor-crosshair"}`,onMouseDown:U,onMouseMove:z,onMouseUp:Z,onDoubleClick:ie}),F&&(0,P.jsx)("input",{ref:V,type:"text",autoFocus:!0,value:S,onChange:d=>N(d.target.value),onKeyDown:d=>{d.key==="Enter"?s():d.key==="Escape"&&(X(null),N(""),O(null))},onBlur:s,onMouseDown:d=>d.stopPropagation(),onMouseUp:d=>d.stopPropagation(),onClick:d=>d.stopPropagation(),className:"feedback-no-capture pointer-events-auto absolute z-[10000] px-2 py-1 text-sm font-bold bg-slate-900/95 text-white border border-dashed rounded shadow-lg focus:outline-none placeholder-slate-500",style:{left:`${F.clientX}px`,top:`${F.clientY-16}px`,color:b,font:"bold 20px sans-serif",borderColor:b,caretColor:b,width:`${Math.max(150,S.length*12)}px`,pointerEvents:"auto"},placeholder:"Type text..."}),(0,P.jsx)("div",{className:"feedback-no-capture absolute top-0 inset-x-0 h-1.5 bg-red-500 animate-pulse pointer-events-none"}),(0,P.jsxs)("div",{className:"feedback-no-capture absolute bottom-6 right-6 pointer-events-auto flex items-center gap-4 bg-slate-900/95 border border-slate-800 rounded-2xl shadow-2xl p-3 text-white",children:[(0,P.jsxs)("div",{className:"flex items-center gap-2 px-1",children:[(0,P.jsx)("span",{className:"w-2.5 h-2.5 rounded-full bg-red-500 animate-pulse"}),(0,P.jsxs)("span",{className:"text-xs font-bold font-mono",children:[Math.floor((60-l)/60).toString().padStart(2,"0"),":",((60-l)%60).toString().padStart(2,"0")," / 01:00"]})]}),(0,P.jsx)("div",{className:"w-px h-5 bg-slate-800"}),(0,P.jsxs)("div",{className:"flex items-center gap-1",children:[(0,P.jsx)("button",{type:"button",onClick:()=>{y("interact"),C(null)},className:`p-2 rounded-xl transition-all ${r==="interact"?"bg-[#3A5659] text-white font-bold":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Interact Mode (Click elements on the screen)",children:(0,P.jsx)(ae.Navigation,{className:"w-4.5 h-4.5 rotate-45"})}),(0,P.jsx)("button",{type:"button",onClick:()=>{y("select")},className:`p-2 rounded-xl transition-all ${r==="select"?"bg-[#3A5659] text-white font-bold":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Select & Move Annotations",children:(0,P.jsx)(ae.MousePointer,{className:"w-4.5 h-4.5"})}),(0,P.jsx)("button",{type:"button",onClick:()=>{y("pencil"),C(null)},className:`p-2 rounded-xl transition-all ${r==="pencil"?"bg-[#3A5659] text-white font-bold":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Pencil / Draw Lines",children:(0,P.jsx)(ae.Pencil,{className:"w-4.5 h-4.5"})}),(0,P.jsx)("button",{type:"button",onClick:()=>{y("arrow"),C(null)},className:`p-2 rounded-xl transition-all ${r==="arrow"?"bg-[#3A5659] text-white font-bold":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Arrow",children:(0,P.jsx)(ae.ArrowRight,{className:"w-4.5 h-4.5"})}),(0,P.jsx)("button",{type:"button",onClick:()=>{y("rect"),C(null)},className:`p-2 rounded-xl transition-all ${r==="rect"?"bg-[#3A5659] text-white font-bold":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Rectangle / Highlight",children:(0,P.jsx)(ae.Square,{className:"w-4.5 h-4.5"})})]}),(0,P.jsx)("div",{className:"w-px h-5 bg-slate-800"}),r!=="interact"&&(0,P.jsx)("div",{className:"flex items-center gap-1.5",children:[{value:"#EF4444",label:"Red"},{value:"#F59E0B",label:"Yellow"},{value:"#3B82F6",label:"Blue"},{value:"#10B981",label:"Green"}].map(d=>(0,P.jsx)("button",{type:"button",onClick:()=>{if(H(d.value),r==="select"&&v!==null&&m[v]){let a=[...m];a[v]={...a[v],color:d.value},w(a)}},className:`w-5.5 h-5.5 rounded-full transition-transform hover:scale-110 ${b===d.value?"ring-2 ring-white ring-offset-2 ring-offset-slate-900 scale-105":""}`,style:{backgroundColor:d.value},title:d.label},d.value))}),(0,P.jsx)("div",{className:"w-px h-5 bg-slate-800"}),(0,P.jsxs)("div",{className:"flex items-center gap-1",children:[v!==null&&(0,P.jsx)("button",{type:"button",onClick:()=>{v!==null&&(w(d=>d.filter((a,f)=>f!==v)),C(null))},className:"p-2 text-red-400 hover:text-red-300 hover:bg-red-500/10 rounded-xl transition-all",title:"Delete selected shape",children:(0,P.jsx)(ae.Trash2,{className:"w-4.5 h-4.5"})}),(0,P.jsx)("button",{type:"button",onClick:()=>{w(d=>d.slice(0,-1)),C(null)},disabled:m.length===0,className:"p-2 text-slate-400 hover:text-white disabled:text-slate-600 rounded-xl hover:bg-slate-800 transition-all",title:"Undo last annotation",children:(0,P.jsx)(ae.Undo,{className:"w-4.5 h-4.5"})}),(0,P.jsx)("button",{type:"button",onClick:()=>{w([]),C(null)},disabled:m.length===0,className:"p-2 text-slate-400 hover:text-white disabled:text-slate-600 rounded-xl hover:bg-slate-800 transition-all",title:"Clear all annotations",children:(0,P.jsx)(ae.Trash2,{className:"w-4.5 h-4.5"})})]}),(0,P.jsx)("div",{className:"w-px h-5 bg-slate-800"}),(0,P.jsxs)("button",{type:"button",onClick:t,className:"flex items-center gap-1.5 px-3 py-1.5 bg-red-600 hover:bg-red-700 text-white rounded-xl font-semibold text-xs transition-all shadow-md shadow-red-950/20",title:"Stop recording",children:[(0,P.jsx)(ae.StopCircle,{className:"w-4 h-4"}),(0,P.jsx)("span",{children:"Stop"})]})]})]}):null};var q=require("react"),J=require("lucide-react"),Ie=require("sonner"),x=require("react/jsx-runtime");function et(e,t,l,g){e.strokeStyle=g,e.fillStyle=g,e.lineWidth=3,e.lineCap="round",e.beginPath(),e.moveTo(t.x,t.y),e.lineTo(l.x,l.y),e.stroke();let r=Math.atan2(l.y-t.y,l.x-t.x);e.beginPath(),e.moveTo(l.x,l.y),e.lineTo(l.x-15*Math.cos(r-Math.PI/6),l.y-15*Math.sin(r-Math.PI/6)),e.lineTo(l.x-15*Math.cos(r+Math.PI/6),l.y-15*Math.sin(r+Math.PI/6)),e.closePath(),e.fill()}function tt(e,t,l,g){e.strokeStyle=g,e.lineWidth=3,e.strokeRect(t.x,t.y,l.x-t.x,l.y-t.y)}function nt(e,t,l){if(!(t.length<2)){e.strokeStyle=l,e.lineWidth=3,e.lineCap="round",e.lineJoin="round",e.beginPath(),e.moveTo(t[0].x,t[0].y);for(let g=1;g<t.length;g++)e.lineTo(t[g].x,t[g].y);e.stroke()}}function rt(e,t,l,g){e.fillStyle=g,e.font="bold 18px sans-serif",e.fillText(l,t.x,t.y)}function Ne(e,t){t.type==="pencil"?nt(e,t.points,t.color):t.type==="arrow"?et(e,t.start,t.end,t.color):t.type==="rect"?tt(e,t.start,t.end,t.color):t.type==="text"&&rt(e,t.position,t.text,t.color)}var Le=({isOpen:e,capturedImg:t,onClose:l,onSave:g})=>{let[r,y]=(0,q.useState)("crop"),[b,H]=(0,q.useState)("#EF4444"),[m,w]=(0,q.useState)([]),[re,G]=(0,q.useState)(!1),[M,j]=(0,q.useState)(null),[v,C]=(0,q.useState)(null),[I,O]=(0,q.useState)(null),[$,Q]=(0,q.useState)(""),[R,ee]=(0,q.useState)(null),[F,X]=(0,q.useState)(null),[S,N]=(0,q.useState)(null),[W,V]=(0,q.useState)([]),u=(0,q.useRef)(null),D=(0,q.useRef)(null),A=(0,q.useRef)(null);(0,q.useEffect)(()=>{if(e&&t){let o=new Image;o.src=t,o.onload=()=>{A.current=o;let i=u.current;if(i){i.width=o.width,i.height=o.height;let c=i.getContext("2d");c&&c.drawImage(o,0,0),w([]),j(null),C(null),ee(null),X(null),y("crop")}}}},[e,t]);let s=(0,q.useCallback)((o,i,c)=>{let p=u.current,T=A.current;if(!p||!T)return;let h=p.getContext("2d");if(!h)return;h.clearRect(0,0,p.width,p.height),h.drawImage(T,0,0),(c||m).filter((B,se)=>se!==F).forEach(B=>{Ne(h,B)}),o&&Ne(h,o);let oe=i||v;if(r==="crop"&&oe){h.strokeStyle="#3A5659",h.lineWidth=2,h.setLineDash([6,4]);let B=Math.min(oe.start.x,oe.end.x),se=Math.min(oe.start.y,oe.end.y),me=Math.abs(oe.start.x-oe.end.x),de=Math.abs(oe.start.y-oe.end.y);h.fillStyle="rgba(0, 0, 0, 0.4)",h.fillRect(0,0,p.width,se),h.fillRect(0,se+de,p.width,p.height-(se+de)),h.fillRect(0,se,B,de),h.fillRect(B+me,se,p.width-(B+me),de),h.strokeRect(B,se,me,de),h.setLineDash([])}let fe=c||m;if(r==="select"&&R!==null&&fe[R]){let B=fe[R],se=0,me=0,de=0,ye=0;B.type==="text"?(se=B.position.x-6,me=B.position.x+B.text.length*11+6,de=B.position.y-20,ye=B.position.y+6):(B.type==="rect"||B.type==="arrow")&&(se=Math.min(B.start.x,B.end.x)-6,me=Math.max(B.start.x,B.end.x)+6,de=Math.min(B.start.y,B.end.y)-6,ye=Math.max(B.start.y,B.end.y)+6),(se!==0||me!==0)&&(h.strokeStyle="#38BDF8",h.lineWidth=1.5,h.setLineDash([4,4]),h.strokeRect(se,de,me-se,ye-de),h.setLineDash([]))}},[m,r,v,R,F]);(0,q.useEffect)(()=>{e&&s()},[e,s]),(0,q.useEffect)(()=>{let o=i=>{i.target instanceof HTMLInputElement||i.target instanceof HTMLTextAreaElement||(i.key==="Delete"||i.key==="Backspace")&&r==="select"&&R!==null&&(w(c=>c.filter((p,T)=>T!==R)),ee(null))};return window.addEventListener("keydown",o),()=>window.removeEventListener("keydown",o)},[r,R]);let U=o=>{let i=u.current;if(!i)return{x:0,y:0};let c=i.getBoundingClientRect(),p=i.width/c.width,T=i.height/c.height;return{x:(o.clientX-c.left)*p,y:(o.clientY-c.top)*T}},z=(0,q.useCallback)(()=>{if(F!==null)$.trim()?w(o=>{let i=[...o];return i[F]&&i[F].type==="text"&&(i[F]={...i[F],text:$.trim()}),i}):w(o=>o.filter((i,c)=>c!==F)),X(null);else if(I&&$.trim()){let o={type:"text",position:{x:I.canvasX,y:I.canvasY},text:$.trim(),color:b};w(i=>[...i,o])}O(null),Q("")},[F,I,$,b]),Z=(o,i)=>{if(i.type==="text"){let c=i.position.x-10,p=i.position.x+i.text.length*11+10,T=i.position.y-22,h=i.position.y+10;return o.x>=c&&o.x<=p&&o.y>=T&&o.y<=h}if(i.type==="rect"||i.type==="arrow"){let c=Math.min(i.start.x,i.end.x)-10,p=Math.max(i.start.x,i.end.x)+10,T=Math.min(i.start.y,i.end.y)-10,h=Math.max(i.start.y,i.end.y)+10;return o.x>=c&&o.x<=p&&o.y>=T&&o.y<=h}return!1},ie=o=>{if(r!=="select")return;let i=U(o),c=-1;for(let p=m.length-1;p>=0;p--)if(Z(i,m[p])){c=p;break}if(c!==-1){let p=m[c];if(p.type==="text"){let T=u.current,h=D.current;if(T&&h){let ce=h.getBoundingClientRect(),oe=T.getBoundingClientRect(),fe=oe.left-ce.left,B=oe.top-ce.top,se=oe.width/T.width,me=oe.height/T.height,de=fe+p.position.x*se,ye=B+p.position.y*me;X(c),Q(p.text),O({clientX:de,clientY:ye,canvasX:p.position.x,canvasY:p.position.y})}}}},d=o=>{let i=U(o);if(G(!0),r==="select"){let c=-1;for(let p=m.length-1;p>=0;p--)if(Z(i,m[p])){c=p;break}c!==-1?(ee(c),N(i),V([...m])):(ee(null),N(null),V([]))}else r==="pencil"?j({type:"pencil",points:[i],color:b}):r==="arrow"?j({type:"arrow",start:i,end:i,color:b}):r==="rect"?j({type:"rect",start:i,end:i,color:b}):r==="crop"?C({start:i,end:i}):r==="text"&&G(!1)},a=o=>{if(!re)return;let i=U(o);if(r==="select"&&R!==null&&S&&W[R]){let c=i.x-S.x,p=i.y-S.y,T=[...W],h=W[R];h.type==="text"?T[R]={...h,position:{x:h.position.x+c,y:h.position.y+p}}:(h.type==="rect"||h.type==="arrow")&&(T[R]={...h,start:{x:h.start.x+c,y:h.start.y+p},end:{x:h.end.x+c,y:h.end.y+p}}),w(T),s(void 0,null,T);return}if(r==="pencil"&&M&&M.type==="pencil"){let c={...M,points:[...M.points,i]};j(c),s(c)}else if(r==="arrow"&&M&&M.type==="arrow"){let c={...M,end:i};j(c),s(c)}else if(r==="rect"&&M&&M.type==="rect"){let c={...M,end:i};j(c),s(c)}else if(r==="crop"){let c=v?{start:v.start,end:i}:null;c&&(C(c),s(void 0,c))}},f=o=>{if(G(!1),r==="select")N(null),V([]);else if(r==="crop")s();else if(r==="text"){let i=U(o);if(I&&$.trim()){let T={type:"text",position:{x:I.canvasX,y:I.canvasY},text:$,color:b};w(h=>[...h,T])}let c=u.current,p=D.current;if(c&&p){let T=p.getBoundingClientRect(),h=o.clientX-T.left,ce=o.clientY-T.top;O({clientX:h,clientY:ce,canvasX:i.x,canvasY:i.y}),Q("")}}else M&&(w(i=>[...i,M]),j(null))},k=()=>{if(!v)return;let o=u.current;if(!o)return;let i=Math.min(v.start.x,v.end.x),c=Math.min(v.start.y,v.end.y),p=Math.abs(v.start.x-v.end.x),T=Math.abs(v.start.y-v.end.y);if(p<10||T<10){Ie.toast.warning("Crop area is too small.");return}let h=document.createElement("canvas");h.width=p,h.height=T;let ce=h.getContext("2d");if(!ce)return;ce.drawImage(o,i,c,p,T,0,0,p,T);let oe=h.toDataURL("image/png"),fe=new Image;fe.src=oe,fe.onload=()=>{A.current=fe,o.width=p,o.height=T;let B=o.getContext("2d");B&&B.drawImage(fe,0,0),w([]),j(null),C(null),y("pencil")}},L=()=>{let o=u.current;if(!o)return;let i=o.getContext("2d");i&&A.current&&(i.clearRect(0,0,o.width,o.height),i.drawImage(A.current,0,0),m.forEach(p=>{Ne(i,p)}));let c=o.toDataURL("image/png");g(c)};return e?(0,x.jsxs)("div",{className:"fixed inset-0 z-[200] bg-slate-950 flex flex-col text-slate-200",children:[(0,x.jsxs)("div",{className:"flex items-center justify-between px-6 py-4 border-b border-slate-800 bg-slate-900 shrink-0",children:[(0,x.jsxs)("div",{className:"flex items-center gap-3",children:[(0,x.jsx)("div",{className:"w-8 h-8 rounded-lg bg-sky-500/10 flex items-center justify-center text-sky-400",children:(0,x.jsx)(J.Crop,{className:"w-4 h-4"})}),(0,x.jsxs)("div",{children:[(0,x.jsx)("h3",{className:"font-bold text-sm",children:"Crop & Annotate Screenshot"}),(0,x.jsx)("p",{className:"text-[10px] text-slate-400",children:"Add lines, arrows, text, or crop the captured area"})]})]}),(0,x.jsxs)("div",{className:"flex items-center gap-2",children:[(0,x.jsx)("button",{type:"button",onClick:l,className:"px-3.5 py-1.5 text-xs font-semibold text-slate-400 hover:text-white hover:bg-slate-800 rounded-xl transition-all",children:"Cancel"}),r==="crop"&&v&&(0,x.jsxs)("button",{type:"button",onClick:k,className:"px-4 py-1.5 text-xs font-semibold bg-[#3A5659] text-white hover:bg-[#31494c] rounded-xl transition-all flex items-center gap-1 shadow-sm",children:[(0,x.jsx)(J.Crop,{className:"w-3.5 h-3.5"}),(0,x.jsx)("span",{children:"Apply Crop"})]}),(0,x.jsxs)("button",{type:"button",onClick:L,className:"px-4 py-1.5 text-xs font-semibold bg-emerald-600 text-white hover:bg-emerald-700 rounded-xl transition-all flex items-center gap-1 shadow-sm",children:[(0,x.jsx)(J.Check,{className:"w-3.5 h-3.5"}),(0,x.jsx)("span",{children:"Attach to Feedback"})]})]})]}),(0,x.jsx)("div",{className:"flex-1 overflow-auto flex items-center justify-center p-8 bg-slate-950",children:(0,x.jsxs)("div",{ref:D,className:"relative border border-slate-800 rounded-xl overflow-hidden shadow-2xl bg-slate-900/50 max-w-[90vw] max-h-[70vh]",children:[(0,x.jsx)("canvas",{ref:u,className:`block max-w-full max-h-[70vh] object-contain ${r==="select"?"cursor-default":"cursor-crosshair"}`,onMouseDown:d,onMouseMove:a,onMouseUp:f,onDoubleClick:ie}),I&&(0,x.jsx)("input",{type:"text",autoFocus:!0,value:$,onChange:o=>Q(o.target.value),onKeyDown:o=>{o.key==="Enter"?z():o.key==="Escape"&&(O(null),Q(""),X(null))},onBlur:z,onMouseDown:o=>o.stopPropagation(),onMouseUp:o=>o.stopPropagation(),onClick:o=>o.stopPropagation(),className:"absolute z-50 px-2 py-1 text-sm font-bold bg-slate-900/95 text-white border border-dashed rounded shadow-lg focus:outline-none placeholder-slate-500",style:{left:`${I.clientX}px`,top:`${I.clientY-16}px`,color:b,font:"bold 18px sans-serif",borderColor:b,caretColor:b,width:`${Math.max(150,$.length*11)}px`},placeholder:"Type text..."})]})}),(0,x.jsxs)("div",{className:"px-6 py-4 border-t border-slate-800 bg-slate-900 flex items-center justify-between shrink-0",children:[(0,x.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,x.jsx)("button",{type:"button",onClick:()=>{y("pencil"),C(null)},className:`p-2 rounded-xl transition-all ${r==="pencil"?"bg-[#3A5659] text-white":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Pencil / Draw Lines",children:(0,x.jsx)(J.Pencil,{className:"w-5 h-5"})}),(0,x.jsx)("button",{type:"button",onClick:()=>{y("arrow"),C(null)},className:`p-2 rounded-xl transition-all ${r==="arrow"?"bg-[#3A5659] text-white":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Arrow",children:(0,x.jsx)(J.ArrowRight,{className:"w-5 h-5"})}),(0,x.jsx)("button",{type:"button",onClick:()=>{y("rect"),C(null)},className:`p-2 rounded-xl transition-all ${r==="rect"?"bg-[#3A5659] text-white":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Rectangle / Highlight",children:(0,x.jsx)(J.Square,{className:"w-5 h-5"})}),(0,x.jsx)("button",{type:"button",onClick:()=>{y("text"),C(null)},className:`p-2 rounded-xl transition-all ${r==="text"?"bg-[#3A5659] text-white":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Add Text",children:(0,x.jsx)(J.Type,{className:"w-5 h-5"})}),(0,x.jsx)("button",{type:"button",onClick:()=>{y("crop"),C(null)},className:`p-2 rounded-xl transition-all ${r==="crop"?"bg-[#3A5659] text-white":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Crop Screenshot",children:(0,x.jsx)(J.Crop,{className:"w-5 h-5"})}),(0,x.jsx)("button",{type:"button",onClick:()=>{y("select"),C(null)},className:`p-2 rounded-xl transition-all ${r==="select"?"bg-[#3A5659] text-white":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Select & Move Shapes",children:(0,x.jsx)(J.MousePointer,{className:"w-5 h-5"})})]}),r!=="crop"&&(0,x.jsxs)("div",{className:"flex items-center gap-2",children:[(0,x.jsx)("span",{className:"text-xs text-slate-400 mr-1",children:"Color:"}),[{value:"#EF4444",label:"Red"},{value:"#F59E0B",label:"Yellow"},{value:"#3B82F6",label:"Blue"},{value:"#10B981",label:"Green"}].map(o=>(0,x.jsx)("button",{type:"button",onClick:()=>{if(H(o.value),r==="select"&&R!==null&&m[R]){let i=[...m];i[R]={...i[R],color:o.value},w(i)}},className:`w-6 h-6 rounded-full transition-transform hover:scale-110 ${b===o.value?"ring-2 ring-white ring-offset-2 ring-offset-slate-900 scale-105":""}`,style:{backgroundColor:o.value},title:o.label},o.value))]}),(0,x.jsxs)("div",{className:"flex items-center gap-2",children:[R!==null&&(0,x.jsxs)("button",{type:"button",onClick:()=>{R!==null&&(w(o=>o.filter((i,c)=>c!==R)),ee(null))},className:"px-3 py-1.5 text-xs font-semibold text-red-400 hover:text-red-300 rounded-xl hover:bg-red-500/10 transition-all flex items-center gap-1",title:"Delete selected shape",children:[(0,x.jsx)(J.Trash2,{className:"w-3.5 h-3.5"}),(0,x.jsx)("span",{children:"Delete Selected"})]}),(0,x.jsxs)("button",{type:"button",onClick:()=>{w(o=>o.slice(0,-1))},disabled:m.length===0,className:"px-3 py-1.5 text-xs font-semibold text-slate-400 hover:text-white disabled:text-slate-600 disabled:hover:text-slate-600 rounded-xl hover:bg-slate-800/50 transition-all flex items-center gap-1",title:"Undo last stroke",children:[(0,x.jsx)(J.Undo,{className:"w-3.5 h-3.5"}),(0,x.jsx)("span",{children:"Undo"})]}),(0,x.jsxs)("button",{type:"button",onClick:()=>{w([]),C(null)},disabled:m.length===0,className:"px-3 py-1.5 text-xs font-semibold text-slate-400 hover:text-white disabled:text-slate-600 disabled:hover:text-slate-600 rounded-xl hover:bg-slate-800/50 transition-all flex items-center gap-1",title:"Clear all drawings",children:[(0,x.jsx)(J.Trash2,{className:"w-3.5 h-3.5"}),(0,x.jsx)("span",{children:"Clear All"})]})]})]})]}):null};var ke=require("sonner");var le=require("react"),$e=require("html-to-image"),be=require("sonner"),He=require("@rrweb/all"),We=({activeModal:e,setActiveModal:t,setPanelOpen:l})=>{let[g,r]=(0,le.useState)(null),[y,b]=(0,le.useState)(null),[H,m]=(0,le.useState)(null),[w,re]=(0,le.useState)(null),[G,M]=(0,le.useState)(null),[j,v]=(0,le.useState)(!1),C=(0,le.useRef)(null),I=(0,le.useRef)(void 0),O=(0,le.useRef)([]),[$,Q]=(0,le.useState)(!1);(0,le.useEffect)(()=>()=>{H&&URL.revokeObjectURL(H)},[H]);let R=N=>{let W=N.target.files?.[0];if(W){if(W.size>10*1024*1024){be.toast.error("File size cannot exceed 10MB.");return}re(W),be.toast.success(`Attached file: ${W.name}`)}},ee=async()=>{try{C.current=e,t(null),l(!1),await new Promise(s=>setTimeout(s,300));let N="",W=Array.from(document.querySelectorAll("*")).filter(s=>window.getComputedStyle(s).position==="fixed"),V=[],u=window.scrollX||window.pageXOffset,D=window.scrollY||window.pageYOffset;W.forEach((s,U)=>{let z=`fixed-el-${U}`;s.setAttribute("data-fixed-id",z);let Z=window.getComputedStyle(s),ie=Z.transform&&Z.transform!=="none"?Z.transform:"",d=`translate(${u}px, ${D}px)`,a=ie?`${ie} ${d}`:d;V.push(`
53
+ foreignObject [data-fixed-id="${z}"] {
54
+ transform: ${a} !important;
55
+ }
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});
package/dist/index.mjs ADDED
@@ -0,0 +1,57 @@
1
+ import{useEffect as Ze,useRef as Fe,useState as ie}from"react";import{MessageSquare as et,Bug as tt,Lightbulb as nt,X as we,Star as rt,Camera as at,Video as Le,Paperclip as $e,Loader2 as ot}from"lucide-react";import{jsx as ve,jsxs as Ae}from"react/jsx-runtime";var Ie=({priorities:e,selectedPriorityId:t,onChange:c,error:g})=>Ae("div",{className:"space-y-2",children:[Ae("label",{className:"block text-sm font-semibold text-gray-700",children:["Priority Level ",ve("span",{className:"text-red-500",children:"*"})]}),ve("div",{className:"flex gap-2.5",children:e.map(n=>{let x=t===n.id,b=n.name.toLowerCase(),$="border-gray-200 text-gray-600 bg-white hover:bg-gray-50 hover:border-gray-300";return x&&(b==="low"?$="border-emerald-500 bg-emerald-50/70 text-emerald-700 ring-2 ring-emerald-500/10":b==="medium"?$="border-amber-500 bg-amber-50/70 text-amber-700 ring-2 ring-amber-500/10":b==="high"||b==="critical"?$="border-rose-500 bg-rose-50/70 text-rose-700 ring-2 ring-rose-500/10":$="border-[#3A5659] bg-[#3A5659]/5 text-[#3A5659] ring-2 ring-[#3A5659]/10"),ve("button",{type:"button",onClick:()=>c(n.id),className:`flex-1 py-2.5 px-4 text-xs font-bold border rounded-xl transition-all duration-200 text-center capitalize shadow-sm cursor-pointer ${$}`,children:n.name},n.id)})}),g&&ve("p",{className:"text-xs text-red-500 font-semibold mt-1.5",children:g})]});import{Fragment as Ce,jsx as p,jsxs as k}from"react/jsx-runtime";var He=({activeModal:e,onClose:t,onSubmit:c,userEmail:g,submitting:n,rating:x,setRating:b,hoverRating:$,setHoverRating:m,title:v,setTitle:G,description:q,setDescription:P,screenshotData:j,setScreenshotData:y,recordingBlob:C,onRemoveRecording:D,onPreviewRecording:W,externalFile:L,setExternalFile:K,fileInputRef:R,handleFileChange:J,onCaptureScreenshot:T,onStartRecording:X,errors:S,onClearError:N,priorities:H,selectedPriorityId:Y,setSelectedPriorityId:d})=>{let F=(()=>{switch(e){case"general":return{title:"General Feedback",icon:p(et,{className:"w-5 h-5 text-sky-600"}),bgColor:"bg-sky-100",description:"Share your overall experience or thoughts about WellnessPro."};case"bug":return{title:"Report a Bug",icon:p(tt,{className:"w-5 h-5 text-orange-600"}),bgColor:"bg-orange-100",description:"Help us improve by describing the issue you encountered."};case"feature":return{title:"Suggest a Feature",icon:p(nt,{className:"w-5 h-5 text-purple-600"}),bgColor:"bg-purple-100",description:"Tell us about a feature you would love to see in the system."};default:return{title:"",icon:null,bgColor:"bg-gray-100",description:""}}})();return e===null?null:p("div",{className:"feedback-no-capture fixed inset-0 bg-black/40 backdrop-blur-sm z-[100] flex items-center justify-center p-4",onClick:t,children:k("div",{className:"relative bg-white rounded-2xl shadow-2xl w-full max-w-lg overflow-hidden flex flex-col max-h-[90vh] transition-all",onClick:o=>o.stopPropagation(),children:[k("div",{className:"flex items-center justify-between p-5 border-b border-gray-100",children:[k("div",{className:"flex items-center gap-3.5",children:[p("div",{className:`w-10 h-10 rounded-xl ${F.bgColor} flex items-center justify-center shrink-0`,children:F.icon}),k("div",{children:[p("h2",{className:"text-base font-bold text-gray-900",children:F.title}),p("p",{className:"text-[11px] text-gray-400 mt-0.5 font-normal leading-normal",children:F.description})]})]}),p("button",{onClick:t,className:"p-1.5 hover:bg-gray-100 rounded-full transition-colors","aria-label":"Close modal",children:p(we,{className:"w-5 h-5 text-gray-400"})})]}),k("form",{onSubmit:c,className:"flex-1 overflow-y-auto p-6 space-y-4",children:[k("div",{className:"space-y-1.5",children:[p("label",{className:"block text-sm font-medium text-gray-700",children:"Email Address"}),p("input",{type:"email",value:g,readOnly:!0,className:"w-full px-3.5 py-2.5 text-sm bg-gray-50 border border-gray-200 rounded-xl text-gray-500 focus:outline-none cursor-not-allowed"})]}),e==="general"&&k(Ce,{children:[k("div",{className:"space-y-2",children:[k("label",{className:"block text-sm font-medium text-gray-700",children:["How would you rate your experience?"," ",p("span",{className:"text-red-500",children:"*"})]}),p("div",{className:"flex items-center gap-1.5 py-1",children:[1,2,3,4,5].map(o=>p("button",{type:"button",onClick:()=>{b(o),N("rating")},onMouseEnter:()=>m(o),onMouseLeave:()=>m(0),className:"focus:outline-none transition-transform hover:scale-110",children:p(rt,{className:`w-8 h-8 ${($||x)>=o?"fill-amber-400 text-amber-400":"text-gray-200"}`,strokeWidth:1.5})},o))}),S.rating&&p("p",{className:"text-xs text-red-500 font-medium",children:S.rating})]}),k("div",{className:"space-y-1.5",children:[k("label",{className:"block text-sm font-medium text-gray-700",children:["Feedback Details ",p("span",{className:"text-red-500",children:"*"})]}),p("textarea",{rows:4,value:q,onChange:o=>{P(o.target.value),N("description")},placeholder:"Tell us what you like or what can be improved...",maxLength:1e3,className:`w-full px-3.5 py-2.5 text-sm bg-gray-50 border rounded-xl focus:outline-none focus:ring-2 focus:ring-[#3A5659]/20 focus:border-[#3A5659] transition-all resize-none ${S.description?"border-red-500":"border-gray-200"}`}),k("div",{className:"flex justify-between items-center text-[11px] text-gray-400 mt-1",children:[S.description?p("span",{className:"text-red-500 font-medium",children:S.description}):p("span",{children:"Please enter at least 5 characters"}),k("span",{children:[q.length,"/1000"]})]})]})]}),e==="bug"&&k(Ce,{children:[k("div",{className:"space-y-1.5",children:[k("label",{className:"block text-sm font-medium text-gray-700",children:["Issue Title ",p("span",{className:"text-red-500",children:"*"})]}),p("input",{type:"text",value:v,onChange:o=>{G(o.target.value),N("title")},placeholder:"Describe the issue briefly (e.g. 'Dashboard chart is not rendering')",maxLength:100,className:`w-full px-3.5 py-2.5 text-sm bg-gray-50 border rounded-xl focus:outline-none focus:ring-2 focus:ring-[#3A5659]/20 focus:border-[#3A5659] transition-all ${S.title?"border-red-500":"border-gray-200"}`}),S.title&&p("p",{className:"text-xs text-red-500 font-medium mt-1",children:S.title})]}),H&&H.length>0&&p(Ie,{priorities:H,selectedPriorityId:Y,onChange:o=>{d(o),N("priority")},error:S.priority}),k("div",{className:"space-y-1.5",children:[k("label",{className:"block text-sm font-medium text-gray-700",children:["Bug Details & Steps to Reproduce"," ",p("span",{className:"text-red-500",children:"*"})]}),p("textarea",{rows:4,value:q,onChange:o=>{P(o.target.value),N("description")},placeholder:"What did you expect to happen? What actually happened? Provide steps to reproduce if possible.",maxLength:2e3,className:`w-full px-3.5 py-2.5 text-sm bg-gray-50 border rounded-xl focus:outline-none focus:ring-2 focus:ring-[#3A5659]/20 focus:border-[#3A5659] transition-all resize-none ${S.description?"border-red-500":"border-gray-200"}`}),k("div",{className:"flex justify-between items-center text-[11px] text-gray-400 mt-1",children:[S.description?p("span",{className:"text-red-500 font-medium",children:S.description}):p("span",{children:"Please enter at least 10 characters"}),k("span",{children:[q.length,"/2000"]})]})]})]}),e==="feature"&&k(Ce,{children:[k("div",{className:"space-y-1.5",children:[k("label",{className:"block text-sm font-medium text-gray-700",children:["Feature Request Title ",p("span",{className:"text-red-500",children:"*"})]}),p("input",{type:"text",value:v,onChange:o=>{G(o.target.value),N("title")},placeholder:"Give your suggestion a clear title (e.g. 'Add exporting to CSV option')",maxLength:100,className:`w-full px-3.5 py-2.5 text-sm bg-gray-50 border rounded-xl focus:outline-none focus:ring-2 focus:ring-[#3A5659]/20 focus:border-[#3A5659] transition-all ${S.title?"border-red-500":"border-gray-200"}`}),S.title&&p("p",{className:"text-xs text-red-500 font-medium mt-1",children:S.title})]}),k("div",{className:"space-y-1.5",children:[k("label",{className:"block text-sm font-medium text-gray-700",children:["Describe the Feature ",p("span",{className:"text-red-500",children:"*"})]}),p("textarea",{rows:4,value:q,onChange:o=>{P(o.target.value),N("description")},placeholder:"What problem does this feature solve? How should it work? Who would benefit from it?",maxLength:2e3,className:`w-full px-3.5 py-2.5 text-sm bg-gray-50 border rounded-xl focus:outline-none focus:ring-2 focus:ring-[#3A5659]/20 focus:border-[#3A5659] transition-all resize-none ${S.description?"border-red-500":"border-gray-200"}`}),k("div",{className:"flex justify-between items-center text-[11px] text-gray-400 mt-1",children:[S.description?p("span",{className:"text-red-500 font-medium",children:S.description}):p("span",{children:"Please enter at least 10 characters"}),k("span",{children:[q.length,"/2000"]})]})]})]}),j&&k("div",{className:"space-y-1.5 pt-2",children:[p("label",{className:"block text-xs font-semibold text-gray-500 uppercase tracking-wider",children:"Attached Screenshot"}),k("div",{className:"relative inline-block border border-gray-200 rounded-xl overflow-hidden shadow-sm group",children:[p("img",{src:j,alt:"Screenshot attachment",className:"h-20 w-auto object-cover max-w-full"}),p("button",{type:"button",onClick:()=>y(null),className:"absolute top-1.5 right-1.5 p-1 bg-red-500 hover:bg-red-600 text-white rounded-full transition-colors shadow-md",title:"Remove screenshot",children:p(we,{className:"w-3 h-3"})})]})]}),C&&k("div",{className:"space-y-1.5 pt-2",children:[p("label",{className:"block text-xs font-semibold text-gray-500 uppercase tracking-wider",children:"Attached Session Recording"}),k("div",{onClick:W,className:"flex items-center justify-between p-2.5 bg-gray-50 border border-gray-200 hover:bg-gray-100 hover:border-gray-300 rounded-xl max-w-full cursor-pointer transition-all group/preview",title:"Click to preview session recording",children:[k("div",{className:"flex items-center gap-2 overflow-hidden mr-4",children:[p(Le,{className:"w-4.5 h-4.5 text-[#3A5659] shrink-0 group-hover/preview:scale-105 transition-transform"}),p("span",{className:"text-xs font-semibold text-gray-700 truncate group-hover/preview:text-[#2d4346] transition-colors",children:"session-recording"}),k("span",{className:"text-[10px] text-gray-400 shrink-0",children:["(",(C.size/1024).toFixed(1)," KB)"]})]}),p("button",{type:"button",onClick:o=>{o.stopPropagation(),D()},className:"p-1 hover:bg-gray-200 text-gray-500 hover:text-red-500 rounded-full transition-colors",title:"Remove session recording",children:p(we,{className:"w-4 h-4"})})]})]}),L&&k("div",{className:"space-y-1.5 pt-2",children:[p("label",{className:"block text-xs font-semibold text-gray-500 uppercase tracking-wider",children:"Attached File"}),k("div",{className:"flex items-center justify-between p-2.5 bg-gray-50 border border-gray-200 rounded-xl max-w-full",children:[k("div",{className:"flex items-center gap-2 overflow-hidden mr-4",children:[p($e,{className:"w-4.5 h-4.5 text-gray-400 shrink-0"}),p("span",{className:"text-xs font-medium text-gray-700 truncate",title:L.name,children:L.name}),k("span",{className:"text-[10px] text-gray-400 shrink-0",children:["(",(L.size/1024).toFixed(1)," KB)"]})]}),p("button",{type:"button",onClick:()=>K(null),className:"p-1 hover:bg-gray-200 text-gray-500 hover:text-red-500 rounded-full transition-colors",title:"Remove file",children:p(we,{className:"w-4 h-4"})})]})]}),p("button",{type:"submit",className:"hidden"})]}),k("div",{className:"relative z-10 flex items-center justify-between p-4 bg-gray-50 border-t border-gray-100 shrink-0",children:[k("div",{className:"flex items-center gap-2",children:[k("div",{className:"relative group",children:[p("button",{type:"button",className:"w-9 h-9 rounded-full flex items-center justify-center bg-white border border-gray-200 text-gray-500 hover:text-[#3A5659] hover:border-[#3A5659] transition-all hover:bg-sky-50/50 shadow-sm",onClick:T,children:p(at,{className:"w-4.5 h-4.5"})}),p("span",{className:"absolute bottom-full left-0 mb-2 px-2 py-1 text-[10px] text-white bg-gray-800 rounded opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap pointer-events-none z-50 shadow-md",children:"Capture & Annotate Screenshot"})]}),k("div",{className:"relative group",children:[p("button",{type:"button",className:"w-9 h-9 rounded-full flex items-center justify-center bg-white border border-gray-200 text-gray-500 hover:text-red-500 hover:border-red-300 transition-all hover:bg-red-50/50 shadow-sm",onClick:X,children:p(Le,{className:"w-4.5 h-4.5"})}),p("span",{className:"absolute bottom-full left-0 mb-2 px-2 py-1 text-[10px] text-white bg-gray-800 rounded opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap pointer-events-none z-50 shadow-md",children:"Record Screen with Live Drawing (Max 60s)"})]}),k("div",{className:"relative group",children:[p("button",{type:"button",className:"w-9 h-9 rounded-full flex items-center justify-center bg-white border border-gray-200 text-gray-500 hover:text-emerald-600 hover:border-emerald-300 transition-all hover:bg-emerald-50/50 shadow-sm",onClick:()=>R.current?.click(),children:p($e,{className:"w-4.5 h-4.5"})}),p("input",{type:"file",ref:R,onChange:J,className:"hidden"}),p("span",{className:"absolute bottom-full left-0 mb-2 px-2 py-1 text-[10px] text-white bg-gray-800 rounded opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap pointer-events-none z-50 shadow-md",children:"Attach External File"})]})]}),k("div",{className:"flex items-center gap-2.5",children:[p("button",{type:"button",onClick:t,className:"px-4 py-2 text-sm font-medium text-gray-600 hover:bg-gray-100 rounded-xl transition-colors",children:"Cancel"}),k("button",{type:"button",onClick:c,disabled:n,className:"px-5 py-2 text-sm font-semibold text-white bg-[#3A5659] hover:bg-[#31494c] rounded-xl transition-all flex items-center gap-1.5 disabled:opacity-70 disabled:cursor-not-allowed shadow-sm shadow-[#3A5659]/10",children:[n&&p(ot,{className:"w-4 h-4 animate-spin"}),p("span",{children:"Submit"})]})]})]})]})})};import{X as st,MessageSquare as it,Bug as lt,Lightbulb as ct}from"lucide-react";import{jsx as ee,jsxs as ue}from"react/jsx-runtime";var We=({panelRef:e,isOpen:t,onClose:c,onOpenModal:g})=>ue("div",{ref:e,className:"feedback-no-capture fixed top-1/2 -translate-y-1/2 z-50 w-72 bg-white rounded-l-2xl border border-gray-100 shadow-2xl p-5 flex flex-col transition-all duration-300",style:{right:t?"0":"-320px"},children:[ue("div",{className:"flex items-center justify-between mb-2",children:[ee("h3",{className:"font-bold text-gray-900 text-base",children:"Share Feedback"}),ee("button",{onClick:c,className:"p-1 hover:bg-gray-100 rounded-full transition-colors","aria-label":"Close panel",children:ee(st,{className:"w-4 h-4 text-gray-400"})})]}),ee("p",{className:"text-xs text-gray-500 mb-5 leading-relaxed",children:"What kind of feedback would you like to submit?"}),ue("button",{onClick:()=>g("general"),className:"flex items-center gap-4 p-3.5 border border-gray-100 rounded-xl cursor-pointer bg-gray-50 hover:bg-sky-50 hover:border-sky-200 transition-all duration-200 text-left w-full group mb-3",children:[ee("div",{className:"w-9 h-9 rounded-full bg-sky-100 flex items-center justify-center shrink-0 group-hover:bg-sky-200 transition-colors",children:ee(it,{className:"w-4 h-4 text-sky-600"})}),ue("div",{children:[ee("span",{className:"block font-semibold text-gray-800 text-sm",children:"General Feedback"}),ee("span",{className:"block text-[11px] text-gray-400 mt-0.5",children:"Share your general thoughts"})]})]}),ue("button",{onClick:()=>g("bug"),className:"flex items-center gap-4 p-3.5 border border-gray-100 rounded-xl cursor-pointer bg-gray-50 hover:bg-orange-50 hover:border-orange-200 transition-all duration-200 text-left w-full group mb-3",children:[ee("div",{className:"w-9 h-9 rounded-full bg-orange-100 flex items-center justify-center shrink-0 group-hover:bg-orange-200 transition-colors",children:ee(lt,{className:"w-4 h-4 text-orange-600"})}),ue("div",{children:[ee("span",{className:"block font-semibold text-gray-800 text-sm",children:"Bug Report"}),ee("span",{className:"block text-[11px] text-gray-400 mt-0.5",children:"Report a problem or error"})]})]}),ue("button",{onClick:()=>g("feature"),className:"flex items-center gap-4 p-3.5 border border-gray-100 rounded-xl cursor-pointer bg-gray-50 hover:bg-purple-50 hover:border-purple-200 transition-all duration-200 text-left w-full group",children:[ee("div",{className:"w-9 h-9 rounded-full bg-purple-100 flex items-center justify-center shrink-0 group-hover:bg-purple-200 transition-colors",children:ee(ct,{className:"w-4 h-4 text-purple-600"})}),ue("div",{children:[ee("span",{className:"block font-semibold text-gray-800 text-sm",children:"Feature Request"}),ee("span",{className:"block text-[11px] text-gray-400 mt-0.5",children:"Suggest a new improvement"})]})]})]});import{MessageSquare as dt}from"lucide-react";import{jsx as Re,jsxs as ut}from"react/jsx-runtime";var Oe=({buttonRef:e,onClick:t})=>Re("div",{ref:e,className:"feedback-no-capture fixed right-0 top-1/2 -translate-y-1/2 z-50 text-white px-3 py-4 cursor-pointer shadow-xl flex flex-col items-center gap-2 font-semibold tracking-wider select-none transition-all duration-200 hover:pr-4 hover:scale-105 rounded-l-xl bg-[#3A5659]",style:{writingMode:"vertical-rl",textOrientation:"mixed"},onClick:t,children:ut("div",{className:"flex items-center gap-2",children:[Re(dt,{className:"w-4 h-4 rotate-90"}),Re("span",{children:"Feedback"})]})});import{useEffect as ke,useRef as fe,useState as ge}from"react";import{Play as Be,Pause as pt,RotateCcw as mt,X as ft,FastForward as gt}from"lucide-react";import{Replayer as ht}from"@rrweb/all";import"@rrweb/all/dist/style.css";import{Fragment as bt,jsx as _,jsxs as ce}from"react/jsx-runtime";var Ne=({isOpen:e,onClose:t,events:c})=>{let g=fe(null),n=fe(null),x=fe(null),b=fe(null),$=fe(null),[m,v]=ge(!1),[G,q]=ge(1),[P,j]=ge(1),[y,C]=ge(!1),[D,W]=ge(0),[L,K]=ge(0),R=fe(0);ke(()=>{R.current=L},[L]);let J=c.find(d=>d.type===4),T=J?.data?.width||1024,X=J?.data?.height||576;if(ke(()=>{if(!e||!n.current){C(!1);return}let d=new ResizeObserver(E=>{for(let F of E){let{width:o,height:B}=F.contentRect;o>0&&B>0&&C(!0)}});return d.observe(n.current),()=>{d.disconnect()}},[e]),ke(()=>{if(!e||!y||c.length===0||!g.current||!n.current)return;g.current.innerHTML="",console.log("[RRWeb Replayer] Initializing Replayer..."),console.log("[RRWeb Replayer] containerRef clientWidth:",n.current.clientWidth),console.log("[RRWeb Replayer] containerRef clientHeight:",n.current.clientHeight),console.log("[RRWeb Replayer] containerRef getBoundingClientRect:",n.current.getBoundingClientRect());let d=null;try{d=new ht(c.slice(),{root:g.current,unpackFn:void 0,mouseTail:!1,blockClass:"feedback-no-capture",UNSAFE_replayCanvas:!0,insertStyleRules:[".replayer-mouse { display: none !important; }",".replayer-mouse-tail { display: none !important; }",".feedback-no-capture { display: none !important; }"]}),x.current=d;let o=d.getMetaData();K(o.totalTime),W(0),d.on("start",()=>v(!0)),d.on("pause",()=>v(!1)),d.on("finish",()=>{v(!1),W(o.totalTime)}),d.pause(0),W(0);let B=()=>{if(x.current===d)try{d?.play(0),v(!0)}catch(z){console.error("Failed to start rrweb playback:",z)}};b.current=requestAnimationFrame(()=>{$.current=window.setTimeout(B,200)})}catch(o){console.error("Failed to initialize rrweb replayer:",o)}let E=()=>{if(!n.current)return;let o=n.current.clientWidth-48,B=n.current.clientHeight-48,z=o/T,V=B/X,ne=Math.min(z,V,1);console.log("[RRWeb Replayer] Viewport comparison:",{recorded:{width:T,height:X},replayerContainer:{width:o,height:B},scaleX:z,scaleY:V,appliedScale:ne}),j(ne)};E();let F=new ResizeObserver(()=>{E()});return F.observe(n.current),()=>{if(F.disconnect(),b.current!==null&&(cancelAnimationFrame(b.current),b.current=null),$.current!==null&&(clearTimeout($.current),$.current=null),x.current){try{x.current.destroy()}catch(o){console.error(o)}x.current=null}}},[e,y,c]),ke(()=>{let d,E=()=>{if(x.current&&m)try{let F=x.current.getCurrentTime();W(Math.min(F,R.current))}catch{}d=requestAnimationFrame(E)};return m&&(d=requestAnimationFrame(E)),()=>{cancelAnimationFrame(d)}},[m]),!e)return null;let S=()=>{let d=x.current;d&&(m?(d.pause(),v(!1)):(d.play(),v(!0)))},N=()=>{let d=x.current;d&&(d.play(0),W(0),v(!0))},H=()=>{let d=x.current;if(!d)return;let E=1;G===1?E=2:G===2?E=4:E=1,q(E),d.setConfig({speed:E})},Y=d=>{let E=Math.floor(d/1e3),F=Math.floor(E/60),o=E%60;return`${F.toString().padStart(2,"0")}:${o.toString().padStart(2,"0")}`};return ce(bt,{children:[_("style",{children:`
2
+ .replayer-mouse, .replayer-mouse-tail, .feedback-no-capture {
3
+ display: none !important;
4
+ }
5
+ /*
6
+ * Constrain rrweb's generated wrapper/iframe to the recorded viewport.
7
+ * For pages taller than the viewport (scrollable, > 100vh), rrweb sizes
8
+ * the wrapper to the full document height, which makes the whole long
9
+ * page render and spill/shrink instead of showing just the viewport and
10
+ * replaying scroll within it. Pinning to the recorded viewport + clipping
11
+ * overflow keeps the preview matching what was actually on screen.
12
+ */
13
+ .rrweb-replayer-wrapper .replayer-wrapper {
14
+ position: relative !important;
15
+ top: 0 !important;
16
+ left: 0 !important;
17
+ margin: 0 !important;
18
+ width: ${T}px !important;
19
+ height: ${X}px !important;
20
+ overflow: hidden !important;
21
+ }
22
+ .rrweb-replayer-wrapper .replayer-wrapper iframe {
23
+ width: ${T}px !important;
24
+ height: ${X}px !important;
25
+ border: none !important;
26
+ }
27
+ .custom-player-slider::-webkit-slider-thumb {
28
+ -webkit-appearance: none;
29
+ appearance: none;
30
+ width: 12px;
31
+ height: 12px;
32
+ border-radius: 50%;
33
+ background: #3A5659;
34
+ cursor: pointer;
35
+ transition: transform 0.1s ease;
36
+ }
37
+ .custom-player-slider::-webkit-slider-thumb:hover {
38
+ transform: scale(1.3);
39
+ }
40
+ .custom-player-slider::-moz-range-thumb {
41
+ width: 12px;
42
+ height: 12px;
43
+ border-radius: 50%;
44
+ background: #3A5659;
45
+ cursor: pointer;
46
+ border: none;
47
+ transition: transform 0.1s ease;
48
+ }
49
+ .custom-player-slider::-moz-range-thumb:hover {
50
+ transform: scale(1.3);
51
+ }
52
+ `}),_("div",{className:"fixed inset-0 z-[10000] bg-black/80 backdrop-blur-md flex items-center justify-center p-4",onClick:t,children:ce("div",{className:"relative bg-slate-900 border border-slate-800 rounded-2xl shadow-2xl w-full max-w-[90vw] overflow-hidden flex flex-col max-h-[90vh]",onClick:d=>d.stopPropagation(),children:[ce("div",{className:"flex items-center justify-between px-5 py-4 border-b border-slate-800 shrink-0",children:[ce("div",{children:[_("h3",{className:"text-sm font-bold text-white",children:"Session Recording Preview"}),_("p",{className:"text-[10px] text-slate-400 mt-0.5",children:"Replaying user actions & annotations"})]}),_("button",{onClick:t,className:"p-1.5 hover:bg-slate-850 rounded-full text-slate-400 hover:text-white transition-colors",children:_(ft,{className:"w-5 h-5"})})]}),ce("div",{ref:n,onClick:S,className:"flex-1 min-h-[300px] h-[55vh] bg-slate-950 flex items-center justify-center overflow-hidden p-6 relative cursor-pointer group",children:[!m&&_("div",{className:"absolute inset-0 bg-black/40 flex items-center justify-center z-10 transition-opacity",children:_("div",{className:"w-16 h-16 rounded-full bg-white/20 backdrop-blur-sm border border-white/30 flex items-center justify-center text-white shadow-2xl hover:scale-110 hover:bg-white/30 transition-all",children:_(Be,{className:"w-8 h-8 fill-current translate-x-0.5"})})}),_("div",{className:"shadow-2xl rounded border border-slate-800 bg-white overflow-hidden shrink-0",style:{width:`${T*P}px`,height:`${X*P}px`},onClick:d=>d.stopPropagation(),children:_("div",{ref:g,className:"rrweb-replayer-wrapper w-full h-full",style:{width:`${T}px`,height:`${X}px`,transform:`scale(${P})`,transformOrigin:"top left"}})})]}),ce("div",{className:"px-6 py-4 bg-slate-900 border-t border-slate-800 flex items-center justify-between shrink-0 gap-5",children:[ce("div",{className:"flex items-center gap-3 shrink-0",children:[_("button",{type:"button",onClick:S,className:"p-2.5 bg-[#3A5659] hover:bg-[#31494c] text-white rounded-full shadow transition-all hover:scale-105",title:m?"Pause":"Play",children:m?_(pt,{className:"w-4.5 h-4.5"}):_(Be,{className:"w-4.5 h-4.5 fill-current"})}),_("button",{type:"button",onClick:N,className:"p-2 bg-slate-800 hover:bg-slate-700 text-slate-300 hover:text-white rounded-full transition-colors",title:"Restart Playback",children:_(mt,{className:"w-4.5 h-4.5"})})]}),ce("div",{className:"flex-1 flex items-center gap-3 min-w-0",onClick:d=>d.stopPropagation(),children:[_("span",{className:"text-[10px] font-semibold font-mono text-slate-400 shrink-0",children:Y(D)}),_("input",{type:"range",min:"0",max:L||100,value:D,onChange:d=>{let E=Number(d.target.value);W(E),x.current?.play(E)},className:"custom-player-slider flex-1 h-1 bg-slate-800 rounded-lg appearance-none cursor-pointer accent-[#3A5659] focus:outline-none"}),_("span",{className:"text-[10px] font-semibold font-mono text-slate-400 shrink-0",children:Y(L)})]}),_("div",{className:"flex items-center gap-2 shrink-0",children:ce("button",{type:"button",onClick:H,className:"px-3 py-1.5 bg-slate-800 hover:bg-slate-700 text-xs font-bold font-mono text-slate-300 hover:text-white rounded-lg flex items-center gap-1 transition-colors",title:"Change Speed",children:[_(gt,{className:"w-3.5 h-3.5"}),ce("span",{children:[G,"x"]})]})})]})]})})]})};import{useState as oe,useEffect as he,useRef as Ue,useCallback as je}from"react";import{MousePointer as xt,Pencil as yt,ArrowRight as vt,Square as wt,Trash2 as ze,StopCircle as kt,Undo as Nt,Navigation as Ct}from"lucide-react";import{jsx as U,jsxs as pe}from"react/jsx-runtime";function Rt(e,t,c,g){e.strokeStyle=g,e.fillStyle=g,e.lineWidth=4,e.lineCap="round",e.beginPath(),e.moveTo(t.x,t.y),e.lineTo(c.x,c.y),e.stroke();let n=Math.atan2(c.y-t.y,c.x-t.x);e.beginPath(),e.moveTo(c.x,c.y),e.lineTo(c.x-15*Math.cos(n-Math.PI/6),c.y-15*Math.sin(n-Math.PI/6)),e.lineTo(c.x-15*Math.cos(n+Math.PI/6),c.y-15*Math.sin(n+Math.PI/6)),e.closePath(),e.fill()}function St(e,t,c,g){e.strokeStyle=g,e.lineWidth=4,e.strokeRect(t.x,t.y,c.x-t.x,c.y-t.y)}function Pt(e,t,c){if(!(t.length<2)){e.strokeStyle=c,e.lineWidth=4,e.lineCap="round",e.lineJoin="round",e.beginPath(),e.moveTo(t[0].x,t[0].y);for(let g=1;g<t.length;g++)e.lineTo(t[g].x,t[g].y);e.stroke()}}function Mt(e,t,c,g){e.fillStyle=g,e.font="bold 20px sans-serif",e.fillText(c,t.x,t.y)}function Xe(e,t){t.type==="pencil"?Pt(e,t.points,t.color):t.type==="arrow"?Rt(e,t.start,t.end,t.color):t.type==="rect"?St(e,t.start,t.end,t.color):t.type==="text"&&Mt(e,t.position,t.text,t.color)}var Ye=({isRecording:e,onStopRecording:t})=>{let[c,g]=oe(60),[n,x]=oe("pencil"),[b,$]=oe("#EF4444"),[m,v]=oe([]),[G,q]=oe(!1),[P,j]=oe(null),[y,C]=oe(null),[D,W]=oe(null),[L,K]=oe(null),[R,J]=oe([]),[T,X]=oe(null),[S,N]=oe(""),H=Ue(null),Y=Ue(null);he(()=>{T&&Y.current&&Y.current.focus()},[T]);let d=je((l,r)=>{let f=H.current;if(!f)return;let w=f.getContext("2d");if(!w)return;let A=window.devicePixelRatio||1;w.setTransform(1,0,0,1,0,0),w.clearRect(0,0,f.width,f.height),w.scale(A,A),(r||m).filter((i,u)=>u!==D).forEach(i=>{Xe(w,i)}),l&&Xe(w,l);let s=r||m;if(n==="select"&&y!==null&&s[y]){let i=s[y],u=0,M=0,h=0,re=0;i.type==="text"?(u=i.position.x-6,M=i.position.x+i.text.length*12+6,h=i.position.y-22,re=i.position.y+6):(i.type==="rect"||i.type==="arrow")&&(u=Math.min(i.start.x,i.end.x)-6,M=Math.max(i.start.x,i.end.x)+6,h=Math.min(i.start.y,i.end.y)-6,re=Math.max(i.start.y,i.end.y)+6),(u!==0||M!==0)&&(w.strokeStyle="#38BDF8",w.lineWidth=1.5,w.setLineDash([4,4]),w.strokeRect(u,h,M-u,re-h),w.setLineDash([]))}},[m,n,y,D]);he(()=>{let l;return e&&c>0&&(l=setInterval(()=>{g(r=>r<=1?(t(),0):r-1)},1e3)),()=>clearInterval(l)},[e,c,t]),he(()=>{if(e){let l=()=>{let r=H.current;if(r){let f=window.devicePixelRatio||1,w=window.innerWidth,A=window.innerHeight;r.width=w*f,r.height=A*f,r.style.width=`${w}px`,r.style.height=`${A}px`,d()}};return l(),window.addEventListener("resize",l),()=>window.removeEventListener("resize",l)}},[e,d]),he(()=>{e&&d()},[e,d]),he(()=>{e||(v([]),j(null),C(null),W(null),X(null),N(""),x("pencil"),g(60))},[e]);let E=(l,r)=>{if(r.type==="text"){let f=r.position.x-10,w=r.position.x+r.text.length*12+10,A=r.position.y-24,a=r.position.y+10;return l.x>=f&&l.x<=w&&l.y>=A&&l.y<=a}if(r.type==="rect"||r.type==="arrow"){let f=Math.min(r.start.x,r.end.x)-10,w=Math.max(r.start.x,r.end.x)+10,A=Math.min(r.start.y,r.end.y)-10,a=Math.max(r.start.y,r.end.y)+10;return l.x>=f&&l.x<=w&&l.y>=A&&l.y<=a}return!1},F=l=>{let r=H.current;if(!r)return{x:0,y:0};let f=r.getBoundingClientRect();return{x:l.clientX-f.left,y:l.clientY-f.top}},o=je(()=>{if(D!==null)S.trim()?v(l=>{let r=[...l];return r[D]&&r[D].type==="text"&&(r[D]={...r[D],text:S.trim()}),r}):v(l=>l.filter((r,f)=>f!==D)),W(null);else if(T&&S.trim()){let l={type:"text",position:{x:T.canvasX,y:T.canvasY},text:S.trim(),color:b};v(r=>[...r,l])}X(null),N("")},[D,T,S,b]);he(()=>{let l=r=>{r.target instanceof HTMLInputElement||r.target instanceof HTMLTextAreaElement||(r.key==="Delete"||r.key==="Backspace")&&n==="select"&&y!==null&&(v(f=>f.filter((w,A)=>A!==y)),C(null))};return window.addEventListener("keydown",l),()=>window.removeEventListener("keydown",l)},[n,y]);let B=l=>{if(n==="interact")return;let r=F(l);if(T){o();return}if(n==="select"){let f=-1;for(let w=m.length-1;w>=0;w--)if(E(r,m[w])){f=w;break}f!==-1?(C(f),K(r),J(JSON.parse(JSON.stringify(m)))):C(null);return}if(n==="text"){X({clientX:l.clientX,clientY:l.clientY,canvasX:r.x,canvasY:r.y}),N(""),W(null);return}q(!0),n==="pencil"?j({type:"pencil",points:[r],color:b}):n==="arrow"?j({type:"arrow",start:r,end:r,color:b}):n==="rect"&&j({type:"rect",start:r,end:r,color:b})},z=l=>{let r=F(l);if(n==="select"&&L&&y!==null){let f=r.x-L.x,w=r.y-L.y,a=R[y];if(!a)return;v(s=>{let i=[...s],u={...a};return u.type==="text"&&a.type==="text"?u.position={x:a.position.x+f,y:a.position.y+w}:(u.type==="rect"||u.type==="arrow")&&(a.type==="rect"||a.type==="arrow")&&(u.start={x:a.start.x+f,y:a.start.y+w},u.end={x:a.end.x+f,y:a.end.y+w}),i[y]=u,d(void 0,i),i});return}if(!(!G||!P)){if(P.type==="pencil"){let f={...P,points:[...P.points,r]};j(f),d(f)}else if(P.type==="arrow"||P.type==="rect"){let f={...P,end:r};j(f),d(f)}}},V=()=>{if(n==="select"){K(null),J([]);return}G&&P&&(v(l=>[...l,P]),j(null),q(!1),d())},ne=l=>{if(n!=="select")return;let r=F(l),f=-1;for(let w=m.length-1;w>=0;w--)if(E(r,m[w])){f=w;break}if(f!==-1&&m[f].type==="text"){let w=m[f];w.type==="text"&&(W(f),X({clientX:l.clientX,clientY:l.clientY,canvasX:w.position.x,canvasY:w.position.y}),N(w.text),C(null))}};return e?pe("div",{className:`fixed inset-0 z-[9999] flex flex-col justify-between ${n!=="interact"?"pointer-events-auto":"pointer-events-none"}`,children:[U("canvas",{ref:H,className:`absolute inset-0 w-full h-full bg-transparent ${n!=="interact"?"pointer-events-auto":"pointer-events-none"} ${n==="select"||n==="interact"?"cursor-default":"cursor-crosshair"}`,onMouseDown:B,onMouseMove:z,onMouseUp:V,onDoubleClick:ne}),T&&U("input",{ref:Y,type:"text",autoFocus:!0,value:S,onChange:l=>N(l.target.value),onKeyDown:l=>{l.key==="Enter"?o():l.key==="Escape"&&(X(null),N(""),W(null))},onBlur:o,onMouseDown:l=>l.stopPropagation(),onMouseUp:l=>l.stopPropagation(),onClick:l=>l.stopPropagation(),className:"feedback-no-capture pointer-events-auto absolute z-[10000] px-2 py-1 text-sm font-bold bg-slate-900/95 text-white border border-dashed rounded shadow-lg focus:outline-none placeholder-slate-500",style:{left:`${T.clientX}px`,top:`${T.clientY-16}px`,color:b,font:"bold 20px sans-serif",borderColor:b,caretColor:b,width:`${Math.max(150,S.length*12)}px`,pointerEvents:"auto"},placeholder:"Type text..."}),U("div",{className:"feedback-no-capture absolute top-0 inset-x-0 h-1.5 bg-red-500 animate-pulse pointer-events-none"}),pe("div",{className:"feedback-no-capture absolute bottom-6 right-6 pointer-events-auto flex items-center gap-4 bg-slate-900/95 border border-slate-800 rounded-2xl shadow-2xl p-3 text-white",children:[pe("div",{className:"flex items-center gap-2 px-1",children:[U("span",{className:"w-2.5 h-2.5 rounded-full bg-red-500 animate-pulse"}),pe("span",{className:"text-xs font-bold font-mono",children:[Math.floor((60-c)/60).toString().padStart(2,"0"),":",((60-c)%60).toString().padStart(2,"0")," / 01:00"]})]}),U("div",{className:"w-px h-5 bg-slate-800"}),pe("div",{className:"flex items-center gap-1",children:[U("button",{type:"button",onClick:()=>{x("interact"),C(null)},className:`p-2 rounded-xl transition-all ${n==="interact"?"bg-[#3A5659] text-white font-bold":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Interact Mode (Click elements on the screen)",children:U(Ct,{className:"w-4.5 h-4.5 rotate-45"})}),U("button",{type:"button",onClick:()=>{x("select")},className:`p-2 rounded-xl transition-all ${n==="select"?"bg-[#3A5659] text-white font-bold":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Select & Move Annotations",children:U(xt,{className:"w-4.5 h-4.5"})}),U("button",{type:"button",onClick:()=>{x("pencil"),C(null)},className:`p-2 rounded-xl transition-all ${n==="pencil"?"bg-[#3A5659] text-white font-bold":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Pencil / Draw Lines",children:U(yt,{className:"w-4.5 h-4.5"})}),U("button",{type:"button",onClick:()=>{x("arrow"),C(null)},className:`p-2 rounded-xl transition-all ${n==="arrow"?"bg-[#3A5659] text-white font-bold":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Arrow",children:U(vt,{className:"w-4.5 h-4.5"})}),U("button",{type:"button",onClick:()=>{x("rect"),C(null)},className:`p-2 rounded-xl transition-all ${n==="rect"?"bg-[#3A5659] text-white font-bold":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Rectangle / Highlight",children:U(wt,{className:"w-4.5 h-4.5"})})]}),U("div",{className:"w-px h-5 bg-slate-800"}),n!=="interact"&&U("div",{className:"flex items-center gap-1.5",children:[{value:"#EF4444",label:"Red"},{value:"#F59E0B",label:"Yellow"},{value:"#3B82F6",label:"Blue"},{value:"#10B981",label:"Green"}].map(l=>U("button",{type:"button",onClick:()=>{if($(l.value),n==="select"&&y!==null&&m[y]){let r=[...m];r[y]={...r[y],color:l.value},v(r)}},className:`w-5.5 h-5.5 rounded-full transition-transform hover:scale-110 ${b===l.value?"ring-2 ring-white ring-offset-2 ring-offset-slate-900 scale-105":""}`,style:{backgroundColor:l.value},title:l.label},l.value))}),U("div",{className:"w-px h-5 bg-slate-800"}),pe("div",{className:"flex items-center gap-1",children:[y!==null&&U("button",{type:"button",onClick:()=>{y!==null&&(v(l=>l.filter((r,f)=>f!==y)),C(null))},className:"p-2 text-red-400 hover:text-red-300 hover:bg-red-500/10 rounded-xl transition-all",title:"Delete selected shape",children:U(ze,{className:"w-4.5 h-4.5"})}),U("button",{type:"button",onClick:()=>{v(l=>l.slice(0,-1)),C(null)},disabled:m.length===0,className:"p-2 text-slate-400 hover:text-white disabled:text-slate-600 rounded-xl hover:bg-slate-800 transition-all",title:"Undo last annotation",children:U(Nt,{className:"w-4.5 h-4.5"})}),U("button",{type:"button",onClick:()=>{v([]),C(null)},disabled:m.length===0,className:"p-2 text-slate-400 hover:text-white disabled:text-slate-600 rounded-xl hover:bg-slate-800 transition-all",title:"Clear all annotations",children:U(ze,{className:"w-4.5 h-4.5"})})]}),U("div",{className:"w-px h-5 bg-slate-800"}),pe("button",{type:"button",onClick:t,className:"flex items-center gap-1.5 px-3 py-1.5 bg-red-600 hover:bg-red-700 text-white rounded-xl font-semibold text-xs transition-all shadow-md shadow-red-950/20",title:"Stop recording",children:[U(kt,{className:"w-4 h-4"}),U("span",{children:"Stop"})]})]})]}):null};import{useState as se,useEffect as Se,useRef as Pe,useCallback as _e}from"react";import{Pencil as Tt,ArrowRight as Et,Square as Ft,Type as Dt,Crop as Me,Check as At,Undo as It,Trash2 as qe,MousePointer as Lt}from"lucide-react";import{toast as $t}from"sonner";import{jsx as I,jsxs as te}from"react/jsx-runtime";function Ht(e,t,c,g){e.strokeStyle=g,e.fillStyle=g,e.lineWidth=3,e.lineCap="round",e.beginPath(),e.moveTo(t.x,t.y),e.lineTo(c.x,c.y),e.stroke();let n=Math.atan2(c.y-t.y,c.x-t.x);e.beginPath(),e.moveTo(c.x,c.y),e.lineTo(c.x-15*Math.cos(n-Math.PI/6),c.y-15*Math.sin(n-Math.PI/6)),e.lineTo(c.x-15*Math.cos(n+Math.PI/6),c.y-15*Math.sin(n+Math.PI/6)),e.closePath(),e.fill()}function Wt(e,t,c,g){e.strokeStyle=g,e.lineWidth=3,e.strokeRect(t.x,t.y,c.x-t.x,c.y-t.y)}function Ot(e,t,c){if(!(t.length<2)){e.strokeStyle=c,e.lineWidth=3,e.lineCap="round",e.lineJoin="round",e.beginPath(),e.moveTo(t[0].x,t[0].y);for(let g=1;g<t.length;g++)e.lineTo(t[g].x,t[g].y);e.stroke()}}function Bt(e,t,c,g){e.fillStyle=g,e.font="bold 18px sans-serif",e.fillText(c,t.x,t.y)}function Te(e,t){t.type==="pencil"?Ot(e,t.points,t.color):t.type==="arrow"?Ht(e,t.start,t.end,t.color):t.type==="rect"?Wt(e,t.start,t.end,t.color):t.type==="text"&&Bt(e,t.position,t.text,t.color)}var Ke=({isOpen:e,capturedImg:t,onClose:c,onSave:g})=>{let[n,x]=se("crop"),[b,$]=se("#EF4444"),[m,v]=se([]),[G,q]=se(!1),[P,j]=se(null),[y,C]=se(null),[D,W]=se(null),[L,K]=se(""),[R,J]=se(null),[T,X]=se(null),[S,N]=se(null),[H,Y]=se([]),d=Pe(null),E=Pe(null),F=Pe(null);Se(()=>{if(e&&t){let a=new Image;a.src=t,a.onload=()=>{F.current=a;let s=d.current;if(s){s.width=a.width,s.height=a.height;let i=s.getContext("2d");i&&i.drawImage(a,0,0),v([]),j(null),C(null),J(null),X(null),x("crop")}}}},[e,t]);let o=_e((a,s,i)=>{let u=d.current,M=F.current;if(!u||!M)return;let h=u.getContext("2d");if(!h)return;h.clearRect(0,0,u.width,u.height),h.drawImage(M,0,0),(i||m).filter((O,Z)=>Z!==T).forEach(O=>{Te(h,O)}),a&&Te(h,a);let Q=s||y;if(n==="crop"&&Q){h.strokeStyle="#3A5659",h.lineWidth=2,h.setLineDash([6,4]);let O=Math.min(Q.start.x,Q.end.x),Z=Math.min(Q.start.y,Q.end.y),le=Math.abs(Q.start.x-Q.end.x),ae=Math.abs(Q.start.y-Q.end.y);h.fillStyle="rgba(0, 0, 0, 0.4)",h.fillRect(0,0,u.width,Z),h.fillRect(0,Z+ae,u.width,u.height-(Z+ae)),h.fillRect(0,Z,O,ae),h.fillRect(O+le,Z,u.width-(O+le),ae),h.strokeRect(O,Z,le,ae),h.setLineDash([])}let de=i||m;if(n==="select"&&R!==null&&de[R]){let O=de[R],Z=0,le=0,ae=0,ye=0;O.type==="text"?(Z=O.position.x-6,le=O.position.x+O.text.length*11+6,ae=O.position.y-20,ye=O.position.y+6):(O.type==="rect"||O.type==="arrow")&&(Z=Math.min(O.start.x,O.end.x)-6,le=Math.max(O.start.x,O.end.x)+6,ae=Math.min(O.start.y,O.end.y)-6,ye=Math.max(O.start.y,O.end.y)+6),(Z!==0||le!==0)&&(h.strokeStyle="#38BDF8",h.lineWidth=1.5,h.setLineDash([4,4]),h.strokeRect(Z,ae,le-Z,ye-ae),h.setLineDash([]))}},[m,n,y,R,T]);Se(()=>{e&&o()},[e,o]),Se(()=>{let a=s=>{s.target instanceof HTMLInputElement||s.target instanceof HTMLTextAreaElement||(s.key==="Delete"||s.key==="Backspace")&&n==="select"&&R!==null&&(v(i=>i.filter((u,M)=>M!==R)),J(null))};return window.addEventListener("keydown",a),()=>window.removeEventListener("keydown",a)},[n,R]);let B=a=>{let s=d.current;if(!s)return{x:0,y:0};let i=s.getBoundingClientRect(),u=s.width/i.width,M=s.height/i.height;return{x:(a.clientX-i.left)*u,y:(a.clientY-i.top)*M}},z=_e(()=>{if(T!==null)L.trim()?v(a=>{let s=[...a];return s[T]&&s[T].type==="text"&&(s[T]={...s[T],text:L.trim()}),s}):v(a=>a.filter((s,i)=>i!==T)),X(null);else if(D&&L.trim()){let a={type:"text",position:{x:D.canvasX,y:D.canvasY},text:L.trim(),color:b};v(s=>[...s,a])}W(null),K("")},[T,D,L,b]),V=(a,s)=>{if(s.type==="text"){let i=s.position.x-10,u=s.position.x+s.text.length*11+10,M=s.position.y-22,h=s.position.y+10;return a.x>=i&&a.x<=u&&a.y>=M&&a.y<=h}if(s.type==="rect"||s.type==="arrow"){let i=Math.min(s.start.x,s.end.x)-10,u=Math.max(s.start.x,s.end.x)+10,M=Math.min(s.start.y,s.end.y)-10,h=Math.max(s.start.y,s.end.y)+10;return a.x>=i&&a.x<=u&&a.y>=M&&a.y<=h}return!1},ne=a=>{if(n!=="select")return;let s=B(a),i=-1;for(let u=m.length-1;u>=0;u--)if(V(s,m[u])){i=u;break}if(i!==-1){let u=m[i];if(u.type==="text"){let M=d.current,h=E.current;if(M&&h){let re=h.getBoundingClientRect(),Q=M.getBoundingClientRect(),de=Q.left-re.left,O=Q.top-re.top,Z=Q.width/M.width,le=Q.height/M.height,ae=de+u.position.x*Z,ye=O+u.position.y*le;X(i),K(u.text),W({clientX:ae,clientY:ye,canvasX:u.position.x,canvasY:u.position.y})}}}},l=a=>{let s=B(a);if(q(!0),n==="select"){let i=-1;for(let u=m.length-1;u>=0;u--)if(V(s,m[u])){i=u;break}i!==-1?(J(i),N(s),Y([...m])):(J(null),N(null),Y([]))}else n==="pencil"?j({type:"pencil",points:[s],color:b}):n==="arrow"?j({type:"arrow",start:s,end:s,color:b}):n==="rect"?j({type:"rect",start:s,end:s,color:b}):n==="crop"?C({start:s,end:s}):n==="text"&&q(!1)},r=a=>{if(!G)return;let s=B(a);if(n==="select"&&R!==null&&S&&H[R]){let i=s.x-S.x,u=s.y-S.y,M=[...H],h=H[R];h.type==="text"?M[R]={...h,position:{x:h.position.x+i,y:h.position.y+u}}:(h.type==="rect"||h.type==="arrow")&&(M[R]={...h,start:{x:h.start.x+i,y:h.start.y+u},end:{x:h.end.x+i,y:h.end.y+u}}),v(M),o(void 0,null,M);return}if(n==="pencil"&&P&&P.type==="pencil"){let i={...P,points:[...P.points,s]};j(i),o(i)}else if(n==="arrow"&&P&&P.type==="arrow"){let i={...P,end:s};j(i),o(i)}else if(n==="rect"&&P&&P.type==="rect"){let i={...P,end:s};j(i),o(i)}else if(n==="crop"){let i=y?{start:y.start,end:s}:null;i&&(C(i),o(void 0,i))}},f=a=>{if(q(!1),n==="select")N(null),Y([]);else if(n==="crop")o();else if(n==="text"){let s=B(a);if(D&&L.trim()){let M={type:"text",position:{x:D.canvasX,y:D.canvasY},text:L,color:b};v(h=>[...h,M])}let i=d.current,u=E.current;if(i&&u){let M=u.getBoundingClientRect(),h=a.clientX-M.left,re=a.clientY-M.top;W({clientX:h,clientY:re,canvasX:s.x,canvasY:s.y}),K("")}}else P&&(v(s=>[...s,P]),j(null))},w=()=>{if(!y)return;let a=d.current;if(!a)return;let s=Math.min(y.start.x,y.end.x),i=Math.min(y.start.y,y.end.y),u=Math.abs(y.start.x-y.end.x),M=Math.abs(y.start.y-y.end.y);if(u<10||M<10){$t.warning("Crop area is too small.");return}let h=document.createElement("canvas");h.width=u,h.height=M;let re=h.getContext("2d");if(!re)return;re.drawImage(a,s,i,u,M,0,0,u,M);let Q=h.toDataURL("image/png"),de=new Image;de.src=Q,de.onload=()=>{F.current=de,a.width=u,a.height=M;let O=a.getContext("2d");O&&O.drawImage(de,0,0),v([]),j(null),C(null),x("pencil")}},A=()=>{let a=d.current;if(!a)return;let s=a.getContext("2d");s&&F.current&&(s.clearRect(0,0,a.width,a.height),s.drawImage(F.current,0,0),m.forEach(u=>{Te(s,u)}));let i=a.toDataURL("image/png");g(i)};return e?te("div",{className:"fixed inset-0 z-[200] bg-slate-950 flex flex-col text-slate-200",children:[te("div",{className:"flex items-center justify-between px-6 py-4 border-b border-slate-800 bg-slate-900 shrink-0",children:[te("div",{className:"flex items-center gap-3",children:[I("div",{className:"w-8 h-8 rounded-lg bg-sky-500/10 flex items-center justify-center text-sky-400",children:I(Me,{className:"w-4 h-4"})}),te("div",{children:[I("h3",{className:"font-bold text-sm",children:"Crop & Annotate Screenshot"}),I("p",{className:"text-[10px] text-slate-400",children:"Add lines, arrows, text, or crop the captured area"})]})]}),te("div",{className:"flex items-center gap-2",children:[I("button",{type:"button",onClick:c,className:"px-3.5 py-1.5 text-xs font-semibold text-slate-400 hover:text-white hover:bg-slate-800 rounded-xl transition-all",children:"Cancel"}),n==="crop"&&y&&te("button",{type:"button",onClick:w,className:"px-4 py-1.5 text-xs font-semibold bg-[#3A5659] text-white hover:bg-[#31494c] rounded-xl transition-all flex items-center gap-1 shadow-sm",children:[I(Me,{className:"w-3.5 h-3.5"}),I("span",{children:"Apply Crop"})]}),te("button",{type:"button",onClick:A,className:"px-4 py-1.5 text-xs font-semibold bg-emerald-600 text-white hover:bg-emerald-700 rounded-xl transition-all flex items-center gap-1 shadow-sm",children:[I(At,{className:"w-3.5 h-3.5"}),I("span",{children:"Attach to Feedback"})]})]})]}),I("div",{className:"flex-1 overflow-auto flex items-center justify-center p-8 bg-slate-950",children:te("div",{ref:E,className:"relative border border-slate-800 rounded-xl overflow-hidden shadow-2xl bg-slate-900/50 max-w-[90vw] max-h-[70vh]",children:[I("canvas",{ref:d,className:`block max-w-full max-h-[70vh] object-contain ${n==="select"?"cursor-default":"cursor-crosshair"}`,onMouseDown:l,onMouseMove:r,onMouseUp:f,onDoubleClick:ne}),D&&I("input",{type:"text",autoFocus:!0,value:L,onChange:a=>K(a.target.value),onKeyDown:a=>{a.key==="Enter"?z():a.key==="Escape"&&(W(null),K(""),X(null))},onBlur:z,onMouseDown:a=>a.stopPropagation(),onMouseUp:a=>a.stopPropagation(),onClick:a=>a.stopPropagation(),className:"absolute z-50 px-2 py-1 text-sm font-bold bg-slate-900/95 text-white border border-dashed rounded shadow-lg focus:outline-none placeholder-slate-500",style:{left:`${D.clientX}px`,top:`${D.clientY-16}px`,color:b,font:"bold 18px sans-serif",borderColor:b,caretColor:b,width:`${Math.max(150,L.length*11)}px`},placeholder:"Type text..."})]})}),te("div",{className:"px-6 py-4 border-t border-slate-800 bg-slate-900 flex items-center justify-between shrink-0",children:[te("div",{className:"flex items-center gap-1.5",children:[I("button",{type:"button",onClick:()=>{x("pencil"),C(null)},className:`p-2 rounded-xl transition-all ${n==="pencil"?"bg-[#3A5659] text-white":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Pencil / Draw Lines",children:I(Tt,{className:"w-5 h-5"})}),I("button",{type:"button",onClick:()=>{x("arrow"),C(null)},className:`p-2 rounded-xl transition-all ${n==="arrow"?"bg-[#3A5659] text-white":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Arrow",children:I(Et,{className:"w-5 h-5"})}),I("button",{type:"button",onClick:()=>{x("rect"),C(null)},className:`p-2 rounded-xl transition-all ${n==="rect"?"bg-[#3A5659] text-white":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Rectangle / Highlight",children:I(Ft,{className:"w-5 h-5"})}),I("button",{type:"button",onClick:()=>{x("text"),C(null)},className:`p-2 rounded-xl transition-all ${n==="text"?"bg-[#3A5659] text-white":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Add Text",children:I(Dt,{className:"w-5 h-5"})}),I("button",{type:"button",onClick:()=>{x("crop"),C(null)},className:`p-2 rounded-xl transition-all ${n==="crop"?"bg-[#3A5659] text-white":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Crop Screenshot",children:I(Me,{className:"w-5 h-5"})}),I("button",{type:"button",onClick:()=>{x("select"),C(null)},className:`p-2 rounded-xl transition-all ${n==="select"?"bg-[#3A5659] text-white":"text-slate-400 hover:text-white hover:bg-slate-800"}`,title:"Select & Move Shapes",children:I(Lt,{className:"w-5 h-5"})})]}),n!=="crop"&&te("div",{className:"flex items-center gap-2",children:[I("span",{className:"text-xs text-slate-400 mr-1",children:"Color:"}),[{value:"#EF4444",label:"Red"},{value:"#F59E0B",label:"Yellow"},{value:"#3B82F6",label:"Blue"},{value:"#10B981",label:"Green"}].map(a=>I("button",{type:"button",onClick:()=>{if($(a.value),n==="select"&&R!==null&&m[R]){let s=[...m];s[R]={...s[R],color:a.value},v(s)}},className:`w-6 h-6 rounded-full transition-transform hover:scale-110 ${b===a.value?"ring-2 ring-white ring-offset-2 ring-offset-slate-900 scale-105":""}`,style:{backgroundColor:a.value},title:a.label},a.value))]}),te("div",{className:"flex items-center gap-2",children:[R!==null&&te("button",{type:"button",onClick:()=>{R!==null&&(v(a=>a.filter((s,i)=>i!==R)),J(null))},className:"px-3 py-1.5 text-xs font-semibold text-red-400 hover:text-red-300 rounded-xl hover:bg-red-500/10 transition-all flex items-center gap-1",title:"Delete selected shape",children:[I(qe,{className:"w-3.5 h-3.5"}),I("span",{children:"Delete Selected"})]}),te("button",{type:"button",onClick:()=>{v(a=>a.slice(0,-1))},disabled:m.length===0,className:"px-3 py-1.5 text-xs font-semibold text-slate-400 hover:text-white disabled:text-slate-600 disabled:hover:text-slate-600 rounded-xl hover:bg-slate-800/50 transition-all flex items-center gap-1",title:"Undo last stroke",children:[I(It,{className:"w-3.5 h-3.5"}),I("span",{children:"Undo"})]}),te("button",{type:"button",onClick:()=>{v([]),C(null)},disabled:m.length===0,className:"px-3 py-1.5 text-xs font-semibold text-slate-400 hover:text-white disabled:text-slate-600 disabled:hover:text-slate-600 rounded-xl hover:bg-slate-800/50 transition-all flex items-center gap-1",title:"Clear all drawings",children:[I(qe,{className:"w-3.5 h-3.5"}),I("span",{children:"Clear All"})]})]})]})]}):null};import{toast as De}from"sonner";import{useState as me,useEffect as Ut,useRef as Ee}from"react";import{toPng as jt}from"html-to-image";import{toast as be}from"sonner";import{record as zt}from"@rrweb/all";var Ve=({activeModal:e,setActiveModal:t,setPanelOpen:c})=>{let[g,n]=me(null),[x,b]=me(null),[$,m]=me(null),[v,G]=me(null),[q,P]=me(null),[j,y]=me(!1),C=Ee(null),D=Ee(void 0),W=Ee([]),[L,K]=me(!1);Ut(()=>()=>{$&&URL.revokeObjectURL($)},[$]);let R=N=>{let H=N.target.files?.[0];if(H){if(H.size>10*1024*1024){be.error("File size cannot exceed 10MB.");return}G(H),be.success(`Attached file: ${H.name}`)}},J=async()=>{try{C.current=e,t(null),c(!1),await new Promise(o=>setTimeout(o,300));let N="",H=Array.from(document.querySelectorAll("*")).filter(o=>window.getComputedStyle(o).position==="fixed"),Y=[],d=window.scrollX||window.pageXOffset,E=window.scrollY||window.pageYOffset;H.forEach((o,B)=>{let z=`fixed-el-${B}`;o.setAttribute("data-fixed-id",z);let V=window.getComputedStyle(o),ne=V.transform&&V.transform!=="none"?V.transform:"",l=`translate(${d}px, ${E}px)`,r=ne?`${ne} ${l}`:l;Y.push(`
53
+ foreignObject [data-fixed-id="${z}"] {
54
+ transform: ${r} !important;
55
+ }
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};
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@pitangent/feedback-system",
3
+ "version": "1.0.1",
4
+ "main": "dist/index.js",
5
+ "module": "dist/index.mjs",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "scripts": {
21
+ "build": "tsup src/index.ts --format cjs,esm --dts --minify --external react,react-dom,sonner",
22
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch --external react,react-dom,sonner",
23
+ "prepublishOnly": "npm run build"
24
+ },
25
+ "dependencies": {
26
+ "@rrweb/all": "^2.0.0-alpha.11",
27
+ "axios": "^1.17.0",
28
+ "html-to-image": "^1.11.13"
29
+ },
30
+ "peerDependencies": {
31
+ "lucide-react": "^0.525.0",
32
+ "react": "^18.0.0 || ^19.0.0",
33
+ "react-dom": "^18.0.0 || ^19.0.0",
34
+ "sonner": "^2.0.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/react": "^19.0.0",
38
+ "@types/react-dom": "^19.0.0",
39
+ "tsup": "^8.0.0",
40
+ "typescript": "^5.0.0"
41
+ }
42
+ }