bug-widget-library 0.0.0-stage → 0.1.0
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 +176 -2
- package/dist/bug-widget-library.cjs +2 -0
- package/dist/bug-widget-library.cjs.map +1 -0
- package/dist/bug-widget-library.css +2 -0
- package/dist/bug-widget-library.js +1084 -0
- package/dist/bug-widget-library.js.map +1 -0
- package/dist/components/Form.d.ts +16 -0
- package/dist/components/Form.d.ts.map +1 -0
- package/dist/components/KonvaEditor.d.ts +10 -0
- package/dist/components/KonvaEditor.d.ts.map +1 -0
- package/dist/components/Widget.d.ts +4 -0
- package/dist/components/Widget.d.ts.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/types.d.ts +112 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +70 -4
package/README.md
CHANGED
|
@@ -1,3 +1,177 @@
|
|
|
1
|
-
#
|
|
1
|
+
# bug-widget-library
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Embeddable React bug-reporting widget with screenshot capture and Konva annotation.
|
|
4
|
+
|
|
5
|
+
You provide a **submit handler** (`onSubmit`) to decide where the report data is sent. The widget collects the form fields and screenshots, then calls your handler.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install bug-widget-library
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Peer dependencies** (must already be in your app):
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install react react-dom
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`react` and `react-dom` >= 18 are required.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Quick start
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import { Widget } from 'bug-widget-library';
|
|
29
|
+
import type { BugReportData } from 'bug-widget-library';
|
|
30
|
+
import 'bug-widget-library/style.css';
|
|
31
|
+
|
|
32
|
+
export function App() {
|
|
33
|
+
const handleSubmit = async (data: BugReportData) => {
|
|
34
|
+
const response = await fetch(data.projectUrl, {
|
|
35
|
+
method: 'POST',
|
|
36
|
+
headers: { 'Content-Type': 'application/json' },
|
|
37
|
+
body: JSON.stringify(data),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
if (!response.ok) {
|
|
41
|
+
throw new Error('Failed to submit bug report');
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<Widget
|
|
47
|
+
projectUrl="https://api.example.com/projects/abc123/bugs"
|
|
48
|
+
onSubmit={handleSubmit}
|
|
49
|
+
uiSettings={{
|
|
50
|
+
position: 'bottom-right',
|
|
51
|
+
primaryColor: '#2563eb',
|
|
52
|
+
buttonText: 'Report Bug',
|
|
53
|
+
}}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
> Always import the stylesheet: `import 'bug-widget-library/style.css'`.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## How it works
|
|
64
|
+
|
|
65
|
+
1. User opens the floating widget and fills in title + description.
|
|
66
|
+
2. Optionally captures and annotates up to 3 screenshots.
|
|
67
|
+
3. On submit, the widget builds a `BugReportData` object and calls your `onSubmit` handler.
|
|
68
|
+
4. You send that data to your backend (or any service).
|
|
69
|
+
5. If `onSubmit` throws / rejects, the form shows an error. If it resolves, the success screen is shown.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Props
|
|
74
|
+
|
|
75
|
+
### `Widget`
|
|
76
|
+
|
|
77
|
+
| Prop | Type | Required | Default | Description |
|
|
78
|
+
|------|------|----------|---------|-------------|
|
|
79
|
+
| `projectUrl` | `string` | Yes | — | Project URL included in the report payload (and shown as a label in the form). |
|
|
80
|
+
| `onSubmit` | `(data: BugReportData) => Promise<void> \| void` | Yes | — | **Submit handler.** Send the report wherever you want. Throw/reject to fail the submit. |
|
|
81
|
+
| `uiSettings` | `WidgetUiSettings` | No | `{}` | Appearance and placement options. |
|
|
82
|
+
| `onSuccess` | `(data: BugReportData) => void` | No | — | Called after `onSubmit` resolves. |
|
|
83
|
+
| `onError` | `(error: Error) => void` | No | — | Called when `onSubmit` throws or rejects. |
|
|
84
|
+
| `isOpen` | `boolean` | No | — | Controlled open state for the drawer. |
|
|
85
|
+
| `onToggle` | `(open: boolean) => void` | No | — | Fired when open state changes. |
|
|
86
|
+
| `className` | `string` | No | `''` | Extra class on the floating button wrapper. |
|
|
87
|
+
|
|
88
|
+
### `uiSettings` (`WidgetUiSettings`)
|
|
89
|
+
|
|
90
|
+
| Option | Type | Default | Description |
|
|
91
|
+
|--------|------|---------|-------------|
|
|
92
|
+
| `position` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left' \| 'right' \| 'left'` | `'bottom-right'` | Button position; form slides from the same side. |
|
|
93
|
+
| `primaryColor` | `string` | `'#2563eb'` | Accent color for button and actions. |
|
|
94
|
+
| `buttonSize` | `'sm' \| 'md' \| 'lg'` | `'md'` | Floating button size. |
|
|
95
|
+
| `buttonText` | `string` | — | Optional label next to the icon. |
|
|
96
|
+
| `buttonIcon` | `ReactNode` | Bug icon | Custom trigger icon. |
|
|
97
|
+
| `title` | `string` | `'Report a Bug'` | Form header title. |
|
|
98
|
+
| `subtitle` | `string` | `'Found an issue? ...'` | Form header subtitle. |
|
|
99
|
+
| `placeholderTitle` | `string` | — | Title input placeholder. |
|
|
100
|
+
| `placeholderDescription` | `string` | — | Description textarea placeholder. |
|
|
101
|
+
| `zIndex` | `number` | `99990` | Base z-index for overlays. |
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Submit payload (`BugReportData`)
|
|
106
|
+
|
|
107
|
+
Your `onSubmit` receives:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
{
|
|
111
|
+
projectUrl: string;
|
|
112
|
+
title: string;
|
|
113
|
+
description: string;
|
|
114
|
+
screenshots: Array<{
|
|
115
|
+
id: string;
|
|
116
|
+
dataUrl: string; // PNG data URL
|
|
117
|
+
createdAt: number;
|
|
118
|
+
}>;
|
|
119
|
+
timestamp: string; // ISO string
|
|
120
|
+
meta: {
|
|
121
|
+
url: string; // page URL where the report was filed
|
|
122
|
+
userAgent: string;
|
|
123
|
+
timestamp?: string;
|
|
124
|
+
screenSize: { width: number; height: number };
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Example: POST to your API
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
<Widget
|
|
133
|
+
projectUrl="https://api.example.com/bugs"
|
|
134
|
+
onSubmit={async (data) => {
|
|
135
|
+
await fetch('https://api.example.com/bugs', {
|
|
136
|
+
method: 'POST',
|
|
137
|
+
headers: { 'Content-Type': 'application/json' },
|
|
138
|
+
body: JSON.stringify(data),
|
|
139
|
+
}).then((res) => {
|
|
140
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
141
|
+
});
|
|
142
|
+
}}
|
|
143
|
+
onSuccess={() => console.log('Bug report sent')}
|
|
144
|
+
onError={(err) => console.error(err)}
|
|
145
|
+
/>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Exports
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
import { Widget } from 'bug-widget-library';
|
|
154
|
+
import type {
|
|
155
|
+
WidgetProps,
|
|
156
|
+
WidgetUiSettings,
|
|
157
|
+
WidgetPosition,
|
|
158
|
+
WidgetButtonSize,
|
|
159
|
+
BugReportData,
|
|
160
|
+
BugReportMetadata,
|
|
161
|
+
ScreenshotItem,
|
|
162
|
+
} from 'bug-widget-library';
|
|
163
|
+
import 'bug-widget-library/style.css';
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Only `Widget` and the types above are public. Form UI and the annotation editor are internal.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Local development (this repo)
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
npm install
|
|
174
|
+
npm run typecheck
|
|
175
|
+
npm run lint
|
|
176
|
+
npm run build
|
|
177
|
+
```
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,s)=>(s=n==null?{}:e(i(n)),o(r||!n||!n.__esModule||!a.call(n,`default`)?t(s,`default`,{value:n,enumerable:!0}):s,n));let c=require("react");c=s(c,1);let l=require("html2canvas");l=s(l,1);let u=require("lucide-react"),d=require("react/jsx-runtime"),f=require("react-konva");function p(e){try{return new URL(e).hostname}catch{return`project`}}var m=({projectUrl:e,isOpen:t,onClose:n,uiSettings:r={},screenshots:i,onTriggerScreenshot:a,onEditScreenshot:o,onDeleteScreenshot:s,onSubmitReport:l})=>{let{position:f=`bottom-right`,primaryColor:m=`#2563eb`,title:h=`Report a Bug`,subtitle:g=`Found an issue? Let us know with details and screenshots.`,placeholderTitle:_=`e.g. Broken checkout button on cart page`,placeholderDescription:v=`Describe what happened, steps to reproduce, and expected result...`}=r,y=(e=>e===`bottom-left`||e===`top-left`||e===`left`)(f),[b,x]=(0,c.useState)(``),[S,C]=(0,c.useState)(``),[w,T]=(0,c.useState)(!1),[E,D]=(0,c.useState)(!1),[O,k]=(0,c.useState)(null),[A,j]=(0,c.useState)({}),[M,N]=(0,c.useState)(null),P=p(e),F=()=>{let e={};return b.trim()||(e.title=`Title / bug name is required.`),S.trim()||(e.description=`Description is required.`),j(e),Object.keys(e).length===0};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(`div`,{"data-bugdrop-widget":`true`,onClick:n,className:`fixed inset-0 z-[99990] bg-slate-900/40 backdrop-blur-sm transition-opacity duration-300 ${t?`opacity-100 pointer-events-auto`:`opacity-0 pointer-events-none`}`}),(0,d.jsxs)(`aside`,{"data-bugdrop-widget":`true`,className:`fixed top-0 z-[99995] flex h-full w-full max-w-md flex-col bg-white shadow-2xl transition-all duration-300 ease-out sm:max-w-lg ${y?`left-0 border-r border-slate-200`:`right-0 border-l border-slate-200`} ${y?t?`translate-x-0 opacity-100 pointer-events-auto`:`-translate-x-full opacity-0 pointer-events-none`:t?`translate-x-0 opacity-100 pointer-events-auto`:`translate-x-full opacity-0 pointer-events-none`}`,role:`dialog`,"aria-modal":`true`,"aria-label":h,children:[(0,d.jsxs)(`div`,{className:`flex shrink-0 items-center justify-between border-b border-slate-100 px-6 py-5`,children:[(0,d.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,d.jsx)(`div`,{className:`flex h-10 w-10 items-center justify-center rounded-xl text-white shadow-md font-bold`,style:{backgroundColor:m},children:(0,d.jsx)(u.Sparkles,{className:`h-5 w-5`})}),(0,d.jsxs)(`div`,{children:[(0,d.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,d.jsx)(`h2`,{className:`text-lg font-bold text-slate-800`,children:h}),(0,d.jsx)(`span`,{className:`rounded-md bg-slate-100 px-2 py-0.5 text-[11px] font-semibold tracking-wider text-slate-500`,title:e,children:P})]}),(0,d.jsx)(`p`,{className:`mt-0.5 text-xs text-slate-500`,children:g})]})]}),(0,d.jsx)(`button`,{type:`button`,onClick:n,className:`flex h-8 w-8 items-center justify-center rounded-lg text-slate-400 transition hover:bg-slate-100 hover:text-slate-600`,children:(0,d.jsx)(u.X,{className:`h-5 w-5`})})]}),(0,d.jsx)(`div`,{className:`flex-1 overflow-y-auto px-6 py-5`,children:E?(0,d.jsxs)(`div`,{className:`flex h-full flex-col items-center justify-center text-center py-10 animate-fadeIn`,children:[(0,d.jsx)(`div`,{className:`flex h-16 w-16 items-center justify-center rounded-full text-white shadow-lg mb-4`,style:{backgroundColor:m},children:(0,d.jsx)(u.CheckCircle2,{className:`h-9 w-9`})}),(0,d.jsx)(`h3`,{className:`text-xl font-bold text-slate-800`,children:`Bug Report Submitted!`}),(0,d.jsxs)(`p`,{className:`mt-2 text-sm text-slate-500 max-w-xs`,children:[`Thank you! Your bug report with `,i.length,` screenshot`,i.length===1?``:`s`,` has been captured and logged.`]}),(0,d.jsxs)(`div`,{className:`mt-8 flex flex-col sm:flex-row gap-3 w-full`,children:[(0,d.jsx)(`button`,{type:`button`,onClick:()=>{x(``),C(``),j({}),k(null),D(!1)},className:`flex-1 rounded-xl border border-slate-200 bg-white py-2.5 text-sm font-semibold text-slate-700 shadow-sm transition hover:bg-slate-50`,children:`Report Another Bug`}),(0,d.jsx)(`button`,{type:`button`,onClick:n,style:{backgroundColor:m},className:`flex-1 rounded-xl py-2.5 text-sm font-semibold text-white shadow-md transition hover:brightness-110`,children:`Close`})]})]}):(0,d.jsxs)(`form`,{onSubmit:async t=>{if(t.preventDefault(),F()){T(!0),k(null);try{await l({projectUrl:e,title:b.trim(),description:S.trim(),screenshots:i,timestamp:new Date().toISOString(),meta:{url:window.location.href,userAgent:navigator.userAgent,timestamp:new Date().toISOString(),screenSize:{width:window.innerWidth,height:window.innerHeight}}}),D(!0)}catch(e){console.error(`Failed to submit bug report:`,e),k(e instanceof Error?e.message:`Failed to submit bug report. Please try again.`)}finally{T(!1)}}},className:`space-y-5`,children:[(0,d.jsxs)(`div`,{children:[(0,d.jsxs)(`label`,{className:`block text-xs font-bold tracking-wide uppercase text-slate-700`,children:[`Bug Title / Name `,(0,d.jsx)(`span`,{className:`text-red-500`,children:`*`})]}),(0,d.jsx)(`input`,{type:`text`,value:b,onChange:e=>{x(e.target.value),A.title&&j(e=>({...e,title:void 0}))},placeholder:_,className:`mt-1.5 w-full rounded-xl border px-3.5 py-2.5 text-sm transition focus:outline-none focus:ring-2 ${A.title?`border-red-300 bg-red-50/50 text-red-900 focus:ring-red-400`:`border-slate-200 bg-white text-slate-800 focus:border-transparent focus:ring-blue-500`}`}),A.title&&(0,d.jsxs)(`p`,{className:`mt-1.5 flex items-center gap-1 text-xs text-red-600`,children:[(0,d.jsx)(u.AlertCircle,{className:`h-3.5 w-3.5`}),(0,d.jsx)(`span`,{children:A.title})]})]}),(0,d.jsxs)(`div`,{children:[(0,d.jsxs)(`label`,{className:`block text-xs font-bold tracking-wide uppercase text-slate-700`,children:[`Description `,(0,d.jsx)(`span`,{className:`text-red-500`,children:`*`})]}),(0,d.jsx)(`textarea`,{rows:4,value:S,onChange:e=>{C(e.target.value),A.description&&j(e=>({...e,description:void 0}))},placeholder:v,className:`mt-1.5 w-full rounded-xl border px-3.5 py-2.5 text-sm transition focus:outline-none focus:ring-2 ${A.description?`border-red-300 bg-red-50/50 text-red-900 focus:ring-red-400`:`border-slate-200 bg-white text-slate-800 focus:border-transparent focus:ring-blue-500`}`}),A.description&&(0,d.jsxs)(`p`,{className:`mt-1.5 flex items-center gap-1 text-xs text-red-600`,children:[(0,d.jsx)(u.AlertCircle,{className:`h-3.5 w-3.5`}),(0,d.jsx)(`span`,{children:A.description})]})]}),(0,d.jsxs)(`div`,{children:[(0,d.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,d.jsxs)(`label`,{className:`block text-xs font-bold tracking-wide uppercase text-slate-700`,children:[`Screenshots `,(0,d.jsx)(`span`,{className:`text-slate-400 font-normal lowercase`,children:`(optional)`})]}),(0,d.jsxs)(`span`,{className:`rounded-full bg-slate-100 px-2 py-0.5 text-xs font-semibold text-slate-600`,children:[i.length,` / 3`]})]}),(0,d.jsx)(`p`,{className:`mt-1 text-xs text-slate-500`,children:`Capture your screen and annotate with pencil, shapes, or arrows.`}),i.length>0&&(0,d.jsx)(`div`,{className:`mt-3 grid grid-cols-3 gap-2.5`,children:i.map((e,t)=>(0,d.jsxs)(`div`,{className:`group relative aspect-video overflow-hidden rounded-lg border border-slate-200 bg-slate-100 shadow-sm`,children:[(0,d.jsx)(`img`,{src:e.dataUrl,alt:`Screenshot ${t+1}`,className:`h-full w-full object-cover transition duration-200 group-hover:scale-105`}),(0,d.jsxs)(`span`,{className:`absolute top-1 left-1 rounded bg-black/60 px-1 py-0.2 text-[10px] font-semibold text-white`,children:[`#`,t+1]}),(0,d.jsxs)(`div`,{className:`absolute inset-0 flex items-center justify-center gap-1.5 bg-black/50 opacity-0 backdrop-blur-[1px] transition-opacity duration-200 group-hover:opacity-100`,children:[(0,d.jsx)(`button`,{type:`button`,onClick:()=>N(e.dataUrl),title:`Preview screenshot`,className:`flex h-7 w-7 items-center justify-center rounded-md bg-white/90 text-slate-700 shadow transition hover:bg-white hover:text-blue-600`,children:(0,d.jsx)(u.Eye,{className:`h-3.5 w-3.5`})}),(0,d.jsx)(`button`,{type:`button`,onClick:()=>o(e),title:`Re-edit / annotate`,className:`flex h-7 w-7 items-center justify-center rounded-md bg-white/90 text-slate-700 shadow transition hover:bg-white hover:text-blue-600`,children:(0,d.jsx)(u.Edit3,{className:`h-3.5 w-3.5`})}),(0,d.jsx)(`button`,{type:`button`,onClick:()=>s(e.id),title:`Delete screenshot`,className:`flex h-7 w-7 items-center justify-center rounded-md bg-red-600 text-white shadow transition hover:bg-red-700`,children:(0,d.jsx)(u.Trash2,{className:`h-3.5 w-3.5`})})]})]},e.id))}),(0,d.jsx)(`div`,{className:`mt-3`,children:i.length<3?(0,d.jsxs)(`button`,{type:`button`,onClick:a,className:`flex w-full items-center justify-center gap-2 rounded-xl border-2 border-dashed border-slate-300 bg-slate-50/70 py-3 text-xs font-semibold text-slate-600 transition hover:border-blue-400 hover:bg-blue-50/50 hover:text-blue-600`,children:[(0,d.jsx)(u.Camera,{className:`h-4 w-4 text-slate-500`}),(0,d.jsx)(`span`,{children:i.length===0?`Capture Screen & Annotate`:`Capture Another Screenshot (${3-i.length} left)`})]}):(0,d.jsx)(`div`,{className:`rounded-lg bg-amber-50 p-2.5 text-center text-xs text-amber-700 border border-amber-200`,children:`Maximum 3 screenshots attached. Delete one to take a new one.`})})]}),O&&(0,d.jsxs)(`div`,{className:`rounded-xl border border-red-200 bg-red-50 px-3.5 py-2.5 text-xs text-red-700 flex items-start gap-2`,children:[(0,d.jsx)(u.AlertCircle,{className:`h-4 w-4 shrink-0 mt-0.5`}),(0,d.jsx)(`span`,{children:O})]}),(0,d.jsxs)(`div`,{className:`pt-4 border-t border-slate-100 flex items-center justify-end gap-3`,children:[(0,d.jsx)(`button`,{type:`button`,onClick:n,className:`rounded-xl border border-slate-200 bg-white px-4 py-2.5 text-sm font-semibold text-slate-600 transition hover:bg-slate-50`,children:`Cancel`}),(0,d.jsx)(`button`,{type:`submit`,disabled:w,style:{backgroundColor:m},className:`flex items-center gap-2 rounded-xl px-5 py-2.5 text-sm font-semibold text-white shadow-md transition hover:brightness-110 active:scale-95 disabled:opacity-60`,children:w?(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(u.Loader2,{className:`h-4 w-4 animate-spin`}),(0,d.jsx)(`span`,{children:`Submitting...`})]}):(0,d.jsx)(`span`,{children:`Submit Bug Report`})})]})]})})]}),M&&(0,d.jsx)(`div`,{"data-bugdrop-widget":`true`,onClick:()=>N(null),className:`fixed inset-0 z-[100001] flex items-center justify-center bg-black/80 p-4 backdrop-blur-sm animate-fadeIn`,children:(0,d.jsxs)(`div`,{className:`relative max-h-[90vh] max-w-[90vw] overflow-hidden rounded-xl bg-slate-900 shadow-2xl`,onClick:e=>e.stopPropagation(),children:[(0,d.jsx)(`img`,{src:M,alt:`Screenshot Preview`,className:`max-h-[85vh] w-auto rounded-xl object-contain`}),(0,d.jsx)(`button`,{type:`button`,onClick:()=>N(null),className:`absolute top-3 right-3 flex h-8 w-8 items-center justify-center rounded-full bg-black/60 text-white shadow hover:bg-black/90`,children:(0,d.jsx)(u.X,{className:`h-4 w-4`})})]})})]})},h=[`#ef4444`,`#f97316`,`#eab308`,`#10b981`,`#3b82f6`,`#8b5cf6`,`#ec4899`,`#000000`,`#ffffff`],g=[{label:`S`,value:3},{label:`M`,value:6},{label:`L`,value:10},{label:`XL`,value:16}],_=({imageSrc:e,onSave:t,onCancel:n,primaryColor:r=`#2563eb`})=>{let i=(0,c.useRef)(null),a=(0,c.useRef)(null),o=(0,c.useRef)(null),[s,l]=(0,c.useState)(null),[p,m]=(0,c.useState)(1),[_,v]=(0,c.useState)({width:800,height:600}),[y,b]=(0,c.useState)(`pencil`),[x,S]=(0,c.useState)(`#ef4444`),[C,w]=(0,c.useState)(6),[T,E]=(0,c.useState)(null),[D,O]=(0,c.useState)([]),[k,A]=(0,c.useState)(null),[j,M]=(0,c.useState)(!1),[N,P]=(0,c.useState)(null),[F,I]=(0,c.useState)([[]]),[L,R]=(0,c.useState)(0);(0,c.useEffect)(()=>{let t=new window.Image;t.crossOrigin=`anonymous`,t.src=e,t.onload=()=>{l(t)}},[e]);let z=(0,c.useCallback)(()=>{if(!i.current||!s)return;let e=Math.max(300,i.current.clientWidth-48),t=Math.max(300,i.current.clientHeight-120),n=Math.min(e/s.naturalWidth,t/s.naturalHeight,1);m(n),v({width:Math.round(s.naturalWidth*n),height:Math.round(s.naturalHeight*n)})},[s]);(0,c.useEffect)(()=>(z(),window.addEventListener(`resize`,z),()=>window.removeEventListener(`resize`,z)),[z]),(0,c.useEffect)(()=>{if(o.current&&a.current){if(T){let e=a.current.findOne(`#`+T);if(e){o.current.nodes([e]),o.current.getLayer()?.batchDraw();return}}o.current.nodes([]),o.current.getLayer()?.batchDraw()}},[T,D]);let B=(0,c.useCallback)(e=>{I(t=>{let n=t.slice(0,L+1);return n.push(e),n}),R(e=>e+1)},[L]),V=(0,c.useCallback)(()=>{if(L>0){let e=L-1;R(e),O(F[e]),E(null)}},[L,F]),H=(0,c.useCallback)(()=>{if(L<F.length-1){let e=L+1;R(e),O(F[e]),E(null)}},[L,F]),U=()=>{if(D.length===0)return;let e=[];O(e),B(e),E(null)},W=(0,c.useCallback)(()=>{if(!T)return;let e=D.filter(e=>e.id!==T);O(e),B(e),E(null)},[T,D,B]);(0,c.useEffect)(()=>{let e=e=>{e.target instanceof HTMLInputElement||e.target instanceof HTMLTextAreaElement||((e.ctrlKey||e.metaKey)&&e.key===`z`?(e.shiftKey?H():V(),e.preventDefault()):(e.ctrlKey||e.metaKey)&&e.key===`y`?(H(),e.preventDefault()):e.key===`Delete`||e.key===`Backspace`?T&&(W(),e.preventDefault()):e.key===`Escape`&&(E(null),e.preventDefault()))};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[W,H,V,T]);let G=e=>{let t=a.current;if(!t||!s)return;let n=t.getPointerPosition();if(!n)return;let r=n.x/p,i=n.y/p;if(y===`select`){(e.target===t||e.target.hasName(`bg-image`))&&E(null);return}if(y===`eraser`){let n=e.target;if(n!==t&&!n.hasName(`bg-image`)){let e=n.id();if(e){let t=D.filter(t=>t.id!==e);O(t),B(t),E(null);return}}}E(null),M(!0),P({x:r,y:i});let o=`shape_${Date.now()}_${Math.random().toString(36).substring(2,7)}`;if(y===`pencil`||y===`eraser`){let e={id:o,type:`line`,tool:y,points:[r,i],stroke:y===`eraser`?`#ffffff`:x,strokeWidth:y===`eraser`?C*2.5:C};A(e)}else y===`rectangle`?A({id:o,type:`rectangle`,x:r,y:i,width:0,height:0,stroke:x,strokeWidth:C}):y===`circle`?A({id:o,type:`circle`,x:r,y:i,radius:0,stroke:x,strokeWidth:C}):y===`arrow`&&A({id:o,type:`arrow`,points:[r,i,r,i],stroke:x,fill:x,strokeWidth:C})},K=()=>{if(!j||!k||!N||!a.current)return;let e=a.current.getPointerPosition();if(!e)return;let t=e.x/p,n=e.y/p;if(k.type===`line`)A({...k,points:[...k.points,t,n]});else if(k.type===`rectangle`){let e=Math.min(N.x,t),r=Math.min(N.y,n),i=Math.abs(t-N.x),a=Math.abs(n-N.y);A({...k,x:e,y:r,width:i,height:a})}else if(k.type===`circle`){let e=Math.hypot(t-N.x,n-N.y);A({...k,radius:e})}else k.type===`arrow`&&A({...k,points:[N.x,N.y,t,n]})},q=()=>{if(!j||(M(!1),!k))return;let e=!1;if(k.type===`line`&&k.points.length>=2)e=!0;else if(k.type===`rectangle`&&k.width>6&&k.height>6)e=!0;else if(k.type===`circle`&&k.radius>5)e=!0;else if(k.type===`arrow`){let[t,n,r,i]=k.points;Math.hypot(r-t,i-n)>10&&(e=!0)}if(e){let e=[...D,k];O(e),B(e),(k.type===`rectangle`||k.type===`circle`||k.type===`arrow`)&&(E(k.id),b(`select`))}A(null),P(null)},J=(e,t)=>{let n=e.target,r=D.find(e=>e.id===t);if(r){if(r.type===`rectangle`){let e=n.scaleX(),i=n.scaleY();n.scaleX(1),n.scaleY(1);let a={...r,x:n.x(),y:n.y(),width:Math.max(10,n.width()*e),height:Math.max(10,n.height()*i),rotation:n.rotation()},o=D.map(e=>e.id===t?a:e);O(o),B(o)}else if(r.type===`circle`){let e=n.scaleX();n.scaleX(1),n.scaleY(1);let i={...r,x:n.x(),y:n.y(),radius:Math.max(6,r.radius*e),rotation:n.rotation()},a=D.map(e=>e.id===t?i:e);O(a),B(a)}else if(r.type===`arrow`){let e=n.scaleX(),i=n.scaleY();n.scaleX(1),n.scaleY(1);let[a,o,s,c]=r.points,l={...r,x:n.x(),y:n.y(),points:[a,o,a+(s-a)*e,o+(c-o)*i],rotation:n.rotation()},u=D.map(e=>e.id===t?l:e);O(u),B(u)}}},Y=(e,t)=>{let n=e.target;if(!D.find(e=>e.id===t))return;let r=D.map(e=>e.id===t?{...e,x:n.x(),y:n.y()}:e);O(r),B(r)};return(0,d.jsxs)(`div`,{ref:i,className:`fixed inset-0 z-[100000] flex flex-col bg-slate-950/90 backdrop-blur-md select-none text-white overflow-hidden animate-fadeIn`,style:{touchAction:`none`},children:[(0,d.jsxs)(`div`,{className:`flex h-16 shrink-0 items-center justify-between border-b border-slate-800 bg-slate-900/90 px-4 sm:px-6`,children:[(0,d.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,d.jsx)(`div`,{className:`flex h-8 w-8 items-center justify-center rounded-lg text-white font-bold text-sm shadow`,style:{backgroundColor:r},children:`BD`}),(0,d.jsxs)(`div`,{children:[(0,d.jsx)(`h1`,{className:`text-sm sm:text-base font-semibold leading-tight text-slate-100`,children:`Screenshot Editor`}),(0,d.jsx)(`p`,{className:`text-xs text-slate-400 hidden sm:block`,children:`Highlight issues with pencil, arrows, circles, and boxes`})]})]}),(0,d.jsxs)(`div`,{className:`flex items-center gap-2 sm:gap-3`,children:[(0,d.jsx)(`button`,{type:`button`,onClick:V,disabled:L<=0,title:`Undo (Ctrl+Z)`,className:`flex h-9 w-9 items-center justify-center rounded-lg border border-slate-700 bg-slate-800 text-slate-200 transition hover:bg-slate-700 hover:text-white disabled:opacity-40 disabled:pointer-events-none`,children:(0,d.jsx)(u.Undo2,{className:`h-4 w-4`})}),(0,d.jsx)(`button`,{type:`button`,onClick:H,disabled:L>=F.length-1,title:`Redo (Ctrl+Y)`,className:`flex h-9 w-9 items-center justify-center rounded-lg border border-slate-700 bg-slate-800 text-slate-200 transition hover:bg-slate-700 hover:text-white disabled:opacity-40 disabled:pointer-events-none`,children:(0,d.jsx)(u.Redo2,{className:`h-4 w-4`})}),(0,d.jsxs)(`button`,{type:`button`,onClick:U,disabled:D.length===0,title:`Clear all annotations`,className:`flex h-9 items-center gap-1.5 rounded-lg border border-slate-700 bg-slate-800 px-2.5 text-xs font-medium text-slate-300 transition hover:bg-slate-700 hover:text-white disabled:opacity-40 disabled:pointer-events-none`,children:[(0,d.jsx)(u.Trash2,{className:`h-3.5 w-3.5`}),(0,d.jsx)(`span`,{className:`hidden md:inline`,children:`Clear All`})]}),(0,d.jsx)(`div`,{className:`h-5 w-px bg-slate-700 mx-1`}),(0,d.jsxs)(`button`,{type:`button`,onClick:n,className:`flex h-9 items-center gap-1.5 rounded-lg border border-slate-700 bg-slate-800 px-3 text-xs sm:text-sm font-medium text-slate-200 transition hover:bg-slate-700 hover:text-white`,children:[(0,d.jsx)(u.X,{className:`h-4 w-4`}),(0,d.jsx)(`span`,{children:`Cancel`})]}),(0,d.jsxs)(`button`,{type:`button`,onClick:()=>{a.current&&(E(null),setTimeout(()=>{a.current&&t(a.current.toDataURL({pixelRatio:1/p,mimeType:`image/png`}))},60))},style:{backgroundColor:r},className:`flex h-9 items-center gap-1.5 rounded-lg px-4 text-xs sm:text-sm font-semibold text-white shadow-md transition hover:brightness-110 active:scale-95`,children:[(0,d.jsx)(u.Check,{className:`h-4 w-4`}),(0,d.jsx)(`span`,{children:`Add to Report`})]})]})]}),(0,d.jsxs)(`div`,{className:`absolute top-20 left-1/2 -translate-x-1/2 z-20 flex flex-wrap items-center justify-center gap-2 rounded-2xl border border-slate-700/80 bg-slate-900/95 p-2 shadow-2xl backdrop-blur-md`,children:[(0,d.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,d.jsx)(`button`,{type:`button`,onClick:()=>b(`select`),title:`Select & Move / Resize`,className:`flex h-9 w-9 items-center justify-center rounded-xl transition ${y===`select`?`bg-blue-600 text-white shadow-inner`:`text-slate-300 hover:bg-slate-800 hover:text-white`}`,children:(0,d.jsx)(u.MousePointer,{className:`h-4 w-4`})}),(0,d.jsx)(`button`,{type:`button`,onClick:()=>{b(`pencil`),E(null)},title:`Pencil / Draw`,className:`flex h-9 w-9 items-center justify-center rounded-xl transition ${y===`pencil`?`bg-blue-600 text-white shadow-inner`:`text-slate-300 hover:bg-slate-800 hover:text-white`}`,children:(0,d.jsx)(u.Pencil,{className:`h-4 w-4`})}),(0,d.jsx)(`button`,{type:`button`,onClick:()=>{b(`eraser`),E(null)},title:`Eraser (click or drag to erase)`,className:`flex h-9 w-9 items-center justify-center rounded-xl transition ${y===`eraser`?`bg-blue-600 text-white shadow-inner`:`text-slate-300 hover:bg-slate-800 hover:text-white`}`,children:(0,d.jsx)(u.Eraser,{className:`h-4 w-4`})}),(0,d.jsx)(`button`,{type:`button`,onClick:()=>{b(`rectangle`),E(null)},title:`Rectangle (Resizable)`,className:`flex h-9 w-9 items-center justify-center rounded-xl transition ${y===`rectangle`?`bg-blue-600 text-white shadow-inner`:`text-slate-300 hover:bg-slate-800 hover:text-white`}`,children:(0,d.jsx)(u.Square,{className:`h-4 w-4`})}),(0,d.jsx)(`button`,{type:`button`,onClick:()=>{b(`circle`),E(null)},title:`Circle (Resizable)`,className:`flex h-9 w-9 items-center justify-center rounded-xl transition ${y===`circle`?`bg-blue-600 text-white shadow-inner`:`text-slate-300 hover:bg-slate-800 hover:text-white`}`,children:(0,d.jsx)(u.Circle,{className:`h-4 w-4`})}),(0,d.jsx)(`button`,{type:`button`,onClick:()=>{b(`arrow`),E(null)},title:`Arrow (Resizable)`,className:`flex h-9 w-9 items-center justify-center rounded-xl transition ${y===`arrow`?`bg-blue-600 text-white shadow-inner`:`text-slate-300 hover:bg-slate-800 hover:text-white`}`,children:(0,d.jsx)(u.ArrowUpRight,{className:`h-4 w-4`})})]}),(0,d.jsx)(`div`,{className:`h-5 w-px bg-slate-700`}),(0,d.jsxs)(`div`,{className:`flex items-center gap-1.5 px-1`,children:[h.map(e=>(0,d.jsx)(`button`,{type:`button`,onClick:()=>S(e),title:e,style:{backgroundColor:e},className:`h-5 w-5 rounded-full border border-slate-700 transition-transform ${x===e?`scale-125 ring-2 ring-white ring-offset-1 ring-offset-slate-900`:`hover:scale-110`}`},e)),(0,d.jsxs)(`label`,{title:`Custom Color`,className:`relative flex h-6 w-6 cursor-pointer items-center justify-center rounded-full border border-slate-600 bg-slate-800 text-slate-300 hover:text-white transition`,children:[(0,d.jsx)(u.Palette,{className:`h-3.5 w-3.5`}),(0,d.jsx)(`input`,{type:`color`,value:x,onChange:e=>S(e.target.value),className:`absolute inset-0 opacity-0 cursor-pointer`})]})]}),(0,d.jsx)(`div`,{className:`h-5 w-px bg-slate-700`}),(0,d.jsx)(`div`,{className:`flex items-center gap-1`,children:g.map(e=>(0,d.jsx)(`button`,{type:`button`,onClick:()=>w(e.value),className:`flex h-7 w-7 items-center justify-center rounded-lg text-xs font-semibold transition ${C===e.value?`bg-slate-700 text-white ring-1 ring-slate-400`:`text-slate-400 hover:bg-slate-800 hover:text-white`}`,children:e.label},e.value))}),T&&(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(`div`,{className:`h-5 w-px bg-slate-700`}),(0,d.jsxs)(`button`,{type:`button`,onClick:W,title:`Delete Selected Shape (Del / Backspace)`,className:`flex h-8 items-center gap-1.5 rounded-xl bg-red-600/90 px-3 text-xs font-semibold text-white shadow hover:bg-red-600`,children:[(0,d.jsx)(u.Trash2,{className:`h-3.5 w-3.5`}),(0,d.jsx)(`span`,{children:`Delete`})]})]})]}),(0,d.jsx)(`div`,{className:`relative flex flex-1 items-center justify-center p-4 overflow-hidden`,children:s?(0,d.jsx)(`div`,{className:`relative shadow-2xl rounded-md overflow-hidden border border-slate-700 bg-slate-900`,style:{width:_.width,height:_.height,cursor:y===`select`?`default`:y===`eraser`?`cell`:`crosshair`},children:(0,d.jsxs)(f.Stage,{ref:a,width:_.width,height:_.height,scaleX:p,scaleY:p,onMouseDown:G,onMouseMove:K,onMouseUp:q,onTouchStart:G,onTouchMove:K,onTouchEnd:q,children:[(0,d.jsx)(f.Layer,{listening:!1,children:(0,d.jsx)(f.Image,{name:`bg-image`,image:s,width:s.naturalWidth,height:s.naturalHeight})}),(0,d.jsxs)(f.Layer,{children:[D.map(e=>{let t=y===`select`;return e.type===`line`?(0,d.jsx)(f.Line,{id:e.id,points:e.points,stroke:e.stroke,strokeWidth:e.strokeWidth,tension:.5,lineCap:`round`,lineJoin:`round`,globalCompositeOperation:e.tool===`eraser`?`destination-out`:`source-over`,draggable:t&&e.tool!==`eraser`,onClick:()=>{if(t&&E(e.id),y===`eraser`){let t=D.filter(t=>t.id!==e.id);O(t),B(t)}},onTap:()=>{t&&E(e.id)},onDragEnd:t=>Y(t,e.id)},e.id):e.type===`rectangle`?(0,d.jsx)(f.Rect,{id:e.id,x:e.x,y:e.y,width:e.width,height:e.height,stroke:e.stroke,strokeWidth:e.strokeWidth,rotation:e.rotation||0,draggable:t,onClick:()=>{if(t&&E(e.id),y===`eraser`){let t=D.filter(t=>t.id!==e.id);O(t),B(t)}},onTap:()=>{t&&E(e.id)},onTransformEnd:t=>J(t,e.id),onDragEnd:t=>Y(t,e.id)},e.id):e.type===`circle`?(0,d.jsx)(f.Circle,{id:e.id,x:e.x,y:e.y,radius:e.radius,stroke:e.stroke,strokeWidth:e.strokeWidth,rotation:e.rotation||0,draggable:t,onClick:()=>{if(t&&E(e.id),y===`eraser`){let t=D.filter(t=>t.id!==e.id);O(t),B(t)}},onTap:()=>{t&&E(e.id)},onTransformEnd:t=>J(t,e.id),onDragEnd:t=>Y(t,e.id)},e.id):e.type===`arrow`?(0,d.jsx)(f.Arrow,{id:e.id,points:e.points,pointerLength:14,pointerWidth:14,stroke:e.stroke,fill:e.fill,strokeWidth:e.strokeWidth,rotation:e.rotation||0,draggable:t,onClick:()=>{if(t&&E(e.id),y===`eraser`){let t=D.filter(t=>t.id!==e.id);O(t),B(t)}},onTap:()=>{t&&E(e.id)},onTransformEnd:t=>J(t,e.id),onDragEnd:t=>Y(t,e.id)},e.id):null}),k&&(0,d.jsxs)(d.Fragment,{children:[k.type===`line`&&(0,d.jsx)(f.Line,{points:k.points,stroke:k.stroke,strokeWidth:k.strokeWidth,tension:.5,lineCap:`round`,lineJoin:`round`,globalCompositeOperation:k.tool===`eraser`?`destination-out`:`source-over`}),k.type===`rectangle`&&(0,d.jsx)(f.Rect,{x:k.x,y:k.y,width:k.width,height:k.height,stroke:k.stroke,strokeWidth:k.strokeWidth,dash:[6,4]}),k.type===`circle`&&(0,d.jsx)(f.Circle,{x:k.x,y:k.y,radius:k.radius,stroke:k.stroke,strokeWidth:k.strokeWidth,dash:[6,4]}),k.type===`arrow`&&(0,d.jsx)(f.Arrow,{points:k.points,pointerLength:14,pointerWidth:14,stroke:k.stroke,fill:k.fill,strokeWidth:k.strokeWidth,dash:[6,4]})]}),(0,d.jsx)(f.Transformer,{ref:o,rotateEnabled:!0,enabledAnchors:[`top-left`,`top-right`,`bottom-left`,`bottom-right`,`middle-left`,`middle-right`,`top-center`,`bottom-center`],borderStroke:`#3b82f6`,borderDash:[4,4],anchorFill:`#ffffff`,anchorStroke:`#3b82f6`,anchorSize:9,anchorCornerRadius:2,boundBoxFunc:(e,t)=>t.width<10||t.height<10?e:t})]})]})}):(0,d.jsxs)(`div`,{className:`flex flex-col items-center gap-2 text-slate-400`,children:[(0,d.jsx)(`div`,{className:`h-8 w-8 animate-spin rounded-full border-2 border-blue-500 border-t-transparent`}),(0,d.jsx)(`p`,{className:`text-sm`,children:`Loading screenshot...`})]})}),(0,d.jsxs)(`div`,{className:`flex h-10 shrink-0 items-center justify-between border-t border-slate-800 bg-slate-900/80 px-4 text-xs text-slate-400`,children:[(0,d.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,d.jsxs)(`span`,{children:[`Active tool: `,(0,d.jsx)(`strong`,{className:`text-slate-200 capitalize`,children:y})]}),(0,d.jsxs)(`span`,{className:`hidden sm:inline`,children:[`Use `,(0,d.jsx)(`kbd`,{className:`rounded bg-slate-800 px-1 py-0.5 text-slate-300`,children:`Ctrl+Z`}),` to undo, `,(0,d.jsx)(`kbd`,{className:`rounded bg-slate-800 px-1 py-0.5 text-slate-300`,children:`Del`}),` to remove selected shape`]})]}),(0,d.jsx)(`div`,{children:s&&(0,d.jsxs)(`span`,{children:[`Original Resolution: `,s.naturalWidth,` x `,s.naturalHeight,`px`]})})]})]})},v=({projectUrl:e,onSubmit:t,uiSettings:n={},onSuccess:r,onError:i,isOpen:a,onToggle:o,className:s=``})=>{let{position:f=`bottom-right`,primaryColor:p=`#2563eb`,buttonSize:h=`md`,buttonText:g,buttonIcon:v,zIndex:y=99990}=n,[b,x]=(0,c.useState)(!1),S=a===void 0?b:a,C=e=>{a===void 0&&x(e),o?.(e)},[w,T]=(0,c.useState)([]),[E,D]=(0,c.useState)(!1),[O,k]=(0,c.useState)(!1),[A,j]=(0,c.useState)(null),M=e=>{switch(e){case`bottom-left`:return`bottom-6 left-6`;case`top-left`:return`top-6 left-6`;case`top-right`:return`top-6 right-6`;case`left`:return`top-1/2 -translate-y-1/2 left-4`;case`right`:return`top-1/2 -translate-y-1/2 right-4`;default:return`bottom-6 right-6`}},N=(e=>{switch(e){case`sm`:return{button:`h-10 px-3.5 gap-2 text-xs font-semibold rounded-full shadow-md`,icon:`h-4 w-4`};case`lg`:return{button:`h-14 px-5 gap-3 text-base font-bold rounded-full shadow-xl`,icon:`h-6 w-6`};default:return{button:`h-12 px-4 gap-2.5 text-sm font-semibold rounded-full shadow-lg`,icon:`h-5 w-5`}}})(h);return E?null:(0,d.jsxs)(d.Fragment,{children:[!O&&(0,d.jsx)(`div`,{"data-bugdrop-widget":`true`,className:`fixed ${M(f)} ${s}`,style:{zIndex:y},children:(0,d.jsxs)(`button`,{type:`button`,onClick:()=>C(!S),style:{backgroundColor:p},className:`group flex items-center justify-center text-white transition-all duration-200 hover:brightness-110 active:scale-95 ${N.button}`,"aria-label":S?`Close bug report form`:`Open bug report form`,title:S?`Close Bug Report`:`Report a Bug`,children:[S?(0,d.jsx)(u.X,{className:N.icon}):v||(0,d.jsx)(u.Bug,{className:N.icon}),g&&(0,d.jsx)(`span`,{children:g}),w.length>0&&!S&&(0,d.jsx)(`span`,{className:`flex h-5 w-5 items-center justify-center rounded-full bg-white text-[11px] font-bold text-slate-900 shadow`,children:w.length})]})}),!O&&(0,d.jsx)(m,{projectUrl:e,isOpen:S,onClose:()=>C(!1),uiSettings:n,screenshots:w,onTriggerScreenshot:async()=>{D(!0);try{await new Promise(e=>setTimeout(e,180));let e=(await(0,l.default)(document.documentElement,{useCORS:!0,allowTaint:!0,logging:!1,scrollX:0,scrollY:-window.scrollY,windowWidth:document.documentElement.offsetWidth,windowHeight:document.documentElement.offsetHeight,ignoreElements:e=>e.getAttribute(`data-bugdrop-widget`)===`true`||e.classList.contains(`bugdrop-ignore`)})).toDataURL(`image/png`);j({dataUrl:e,isNew:!0}),k(!0)}catch(e){console.error(`Error taking screenshot:`,e),alert(`Could not capture screenshot. Please try again.`)}finally{D(!1)}},onEditScreenshot:e=>{j({id:e.id,dataUrl:e.dataUrl,isNew:!1}),k(!0)},onDeleteScreenshot:e=>{T(t=>t.filter(t=>t.id!==e))},onSubmitReport:async e=>{try{await t(e),r?.(e)}catch(e){let t=e instanceof Error?e:Error(`Failed to submit bug report`);throw i?.(t),t}}}),O&&A&&(0,d.jsx)(_,{imageSrc:A.dataUrl,onSave:e=>{if(A?.isNew){if(w.length<3){let t={id:`ss_${Date.now()}_${Math.random().toString(36).substring(2,6)}`,dataUrl:e,createdAt:Date.now()};T(e=>[...e,t])}}else A?.id&&T(t=>t.map(t=>t.id===A.id?{...t,dataUrl:e}:t));k(!1),j(null),C(!0)},onCancel:()=>{k(!1),j(null),C(!0)},primaryColor:p})]})};exports.Widget=v;
|
|
2
|
+
//# sourceMappingURL=bug-widget-library.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bug-widget-library.cjs","names":["useState","_Fragment","Sparkles","X","CheckCircle2","AlertCircle","Eye","Edit3","Trash2","Camera","Loader2","useRef","useState","useCallback","Undo2","Redo2","Trash2","X","Check","MousePointer","Pencil","Eraser","Square","CircleIcon","ArrowUpRight","Palette","_Fragment","Stage","Layer","KonvaImage","Line","Rect","Circle","Arrow","Transformer","useState","_Fragment","X","Bug","__create","__defProp","__getOwnPropDesc","__getOwnPropNames","__getProtoOf","__hasOwnProp","__copyProps","from","keys","i","n","key","to","except","k","desc","__toESM","mod","isNodeMode","target","react","html2canvas","lucide_react","react_jsx_runtime","react_konva","getProjectLabel","projectUrl","Form","uiSettings","isLeft","pos","position","reportTitle","setReportTitle","description","setDescription","isSubmitting","setIsSubmitting","isSuccess","setIsSuccess","submitError","setSubmitError","errors","setErrors","previewImage","setPreviewImage","projectLabel","validate","errs","onClose","isOpen","title","primaryColor","subtitle","screenshots","e","onSubmitReport","err","prev","placeholderTitle","placeholderDescription","s","idx","onEditScreenshot","onDeleteScreenshot","onTriggerScreenshot","PRESET_COLORS","STROKE_WIDTHS","KonvaEditor","containerRef","stageRef","transformerRef","image","setImage","scale","setScale","stageDimensions","setStageDimensions","tool","setTool","color","setColor","strokeWidth","setStrokeWidth","selectedId","setSelectedId","shapes","setShapes","draftShape","setDraftShape","isDrawing","setIsDrawing","startPoint","setStartPoint","history","setHistory","historyStep","setHistoryStep","img","imageSrc","updateDimensions","availWidth","availHeight","fitScale","selectedNode","pushHistory","newHistory","newShapes","handleUndo","newStep","handleRedo","handleClearAll","handleDeleteSelected","handleKeyDown","handlePointerDown","stage","pointer","x","y","clickedNode","shapeId","id","newLine","handlePointerMove","rx","ry","rw","rh","radius","handlePointerUp","isValid","x1","y1","x2","y2","nextShapes","handleTransformEnd","node","targetShape","scaleX","scaleY","updated","handleDragEnd","onCancel","onSave","c","sw","isSelectable","shape","next","newBox","oldBox","Widget","controlledIsOpen","internalIsOpen","setInternalIsOpen","setOpen","open","onToggle","setScreenshots","isCapturing","setIsCapturing","isEditorOpen","setIsEditorOpen","editingScreenshot","setEditingScreenshot","getPositionClasses","sizeClasses","size","buttonSize","className","buttonIcon","buttonText","resolve","dataUrl","element","item","onSubmit","reportData","onSuccess","error","onError","newItem","editedDataUrl"],"sources":["../src/components/Form.tsx","../src/components/KonvaEditor.tsx","../src/components/Widget.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport {\n Camera,\n X,\n Trash2,\n Edit3,\n Eye,\n CheckCircle2,\n AlertCircle,\n Loader2,\n Sparkles,\n} from 'lucide-react';\nimport type {\n BugReportData,\n ScreenshotItem,\n WidgetUiSettings,\n WidgetPosition,\n} from '../types';\n\ninterface FormProps {\n projectUrl: string;\n isOpen: boolean;\n onClose: () => void;\n uiSettings?: WidgetUiSettings;\n screenshots: ScreenshotItem[];\n onTriggerScreenshot: () => void;\n onEditScreenshot: (screenshot: ScreenshotItem) => void;\n onDeleteScreenshot: (id: string) => void;\n onSubmitReport: (data: BugReportData) => Promise<void> | void;\n}\n\nfunction getProjectLabel(projectUrl: string): string {\n try {\n return new URL(projectUrl).hostname;\n } catch {\n return 'project';\n }\n}\n\nexport const Form: React.FC<FormProps> = ({\n projectUrl,\n isOpen,\n onClose,\n uiSettings = {},\n screenshots,\n onTriggerScreenshot,\n onEditScreenshot,\n onDeleteScreenshot,\n onSubmitReport,\n}) => {\n const {\n position = 'bottom-right',\n primaryColor = '#2563eb',\n title = 'Report a Bug',\n subtitle = 'Found an issue? Let us know with details and screenshots.',\n placeholderTitle = 'e.g. Broken checkout button on cart page',\n placeholderDescription = 'Describe what happened, steps to reproduce, and expected result...',\n } = uiSettings;\n\n const isLeftPosition = (pos: WidgetPosition) =>\n pos === 'bottom-left' || pos === 'top-left' || pos === 'left';\n\n const isLeft = isLeftPosition(position);\n\n // Form input states\n const [reportTitle, setReportTitle] = useState('');\n const [description, setDescription] = useState('');\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isSuccess, setIsSuccess] = useState(false);\n const [submitError, setSubmitError] = useState<string | null>(null);\n const [errors, setErrors] = useState<{ title?: string; description?: string }>({});\n const [previewImage, setPreviewImage] = useState<string | null>(null);\n const projectLabel = getProjectLabel(projectUrl);\n\n // Form validation\n const validate = () => {\n const errs: { title?: string; description?: string } = {};\n if (!reportTitle.trim()) {\n errs.title = 'Title / bug name is required.';\n }\n if (!description.trim()) {\n errs.description = 'Description is required.';\n }\n setErrors(errs);\n return Object.keys(errs).length === 0;\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!validate()) return;\n\n setIsSubmitting(true);\n setSubmitError(null);\n try {\n const reportData: BugReportData = {\n projectUrl,\n title: reportTitle.trim(),\n description: description.trim(),\n screenshots,\n timestamp: new Date().toISOString(),\n meta: {\n url: window.location.href,\n userAgent: navigator.userAgent,\n timestamp: new Date().toISOString(),\n screenSize: {\n width: window.innerWidth,\n height: window.innerHeight,\n },\n },\n };\n\n await onSubmitReport(reportData);\n setIsSuccess(true);\n } catch (err) {\n console.error('Failed to submit bug report:', err);\n setSubmitError(\n err instanceof Error ? err.message : 'Failed to submit bug report. Please try again.'\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const handleReset = () => {\n setReportTitle('');\n setDescription('');\n setErrors({});\n setSubmitError(null);\n setIsSuccess(false);\n };\n\n // Determine slide animation direction\n const slideClass = isLeft\n ? isOpen\n ? 'translate-x-0 opacity-100 pointer-events-auto'\n : '-translate-x-full opacity-0 pointer-events-none'\n : isOpen\n ? 'translate-x-0 opacity-100 pointer-events-auto'\n : 'translate-x-full opacity-0 pointer-events-none';\n\n return (\n <>\n {/* Subtle backdrop overlay */}\n <div\n data-bugdrop-widget=\"true\"\n onClick={onClose}\n className={`fixed inset-0 z-[99990] bg-slate-900/40 backdrop-blur-sm transition-opacity duration-300 ${\n isOpen ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'\n }`}\n />\n\n {/* Slide-in Drawer Container */}\n <aside\n data-bugdrop-widget=\"true\"\n className={`fixed top-0 z-[99995] flex h-full w-full max-w-md flex-col bg-white shadow-2xl transition-all duration-300 ease-out sm:max-w-lg ${\n isLeft ? 'left-0 border-r border-slate-200' : 'right-0 border-l border-slate-200'\n } ${slideClass}`}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n >\n {/* Header */}\n <div className=\"flex shrink-0 items-center justify-between border-b border-slate-100 px-6 py-5\">\n <div className=\"flex items-center gap-3\">\n <div\n className=\"flex h-10 w-10 items-center justify-center rounded-xl text-white shadow-md font-bold\"\n style={{ backgroundColor: primaryColor }}\n >\n <Sparkles className=\"h-5 w-5\" />\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <h2 className=\"text-lg font-bold text-slate-800\">{title}</h2>\n <span\n className=\"rounded-md bg-slate-100 px-2 py-0.5 text-[11px] font-semibold tracking-wider text-slate-500\"\n title={projectUrl}\n >\n {projectLabel}\n </span>\n </div>\n <p className=\"mt-0.5 text-xs text-slate-500\">{subtitle}</p>\n </div>\n </div>\n\n <button\n type=\"button\"\n onClick={onClose}\n className=\"flex h-8 w-8 items-center justify-center rounded-lg text-slate-400 transition hover:bg-slate-100 hover:text-slate-600\"\n >\n <X className=\"h-5 w-5\" />\n </button>\n </div>\n\n {/* Content Area */}\n <div className=\"flex-1 overflow-y-auto px-6 py-5\">\n {isSuccess ? (\n <div className=\"flex h-full flex-col items-center justify-center text-center py-10 animate-fadeIn\">\n <div\n className=\"flex h-16 w-16 items-center justify-center rounded-full text-white shadow-lg mb-4\"\n style={{ backgroundColor: primaryColor }}\n >\n <CheckCircle2 className=\"h-9 w-9\" />\n </div>\n <h3 className=\"text-xl font-bold text-slate-800\">\n Bug Report Submitted!\n </h3>\n <p className=\"mt-2 text-sm text-slate-500 max-w-xs\">\n Thank you! Your bug report with {screenshots.length} screenshot{screenshots.length !== 1 ? 's' : ''} has been captured and logged.\n </p>\n\n <div className=\"mt-8 flex flex-col sm:flex-row gap-3 w-full\">\n <button\n type=\"button\"\n onClick={handleReset}\n className=\"flex-1 rounded-xl border border-slate-200 bg-white py-2.5 text-sm font-semibold text-slate-700 shadow-sm transition hover:bg-slate-50\"\n >\n Report Another Bug\n </button>\n <button\n type=\"button\"\n onClick={onClose}\n style={{ backgroundColor: primaryColor }}\n className=\"flex-1 rounded-xl py-2.5 text-sm font-semibold text-white shadow-md transition hover:brightness-110\"\n >\n Close\n </button>\n </div>\n </div>\n ) : (\n <form onSubmit={handleSubmit} className=\"space-y-5\">\n {/* Bug Title / Name (Required) */}\n <div>\n <label className=\"block text-xs font-bold tracking-wide uppercase text-slate-700\">\n Bug Title / Name <span className=\"text-red-500\">*</span>\n </label>\n <input\n type=\"text\"\n value={reportTitle}\n onChange={(e) => {\n setReportTitle(e.target.value);\n if (errors.title) setErrors((prev) => ({ ...prev, title: undefined }));\n }}\n placeholder={placeholderTitle}\n className={`mt-1.5 w-full rounded-xl border px-3.5 py-2.5 text-sm transition focus:outline-none focus:ring-2 ${\n errors.title\n ? 'border-red-300 bg-red-50/50 text-red-900 focus:ring-red-400'\n : 'border-slate-200 bg-white text-slate-800 focus:border-transparent focus:ring-blue-500'\n }`}\n />\n {errors.title && (\n <p className=\"mt-1.5 flex items-center gap-1 text-xs text-red-600\">\n <AlertCircle className=\"h-3.5 w-3.5\" />\n <span>{errors.title}</span>\n </p>\n )}\n </div>\n\n {/* Bug Description (Required) */}\n <div>\n <label className=\"block text-xs font-bold tracking-wide uppercase text-slate-700\">\n Description <span className=\"text-red-500\">*</span>\n </label>\n <textarea\n rows={4}\n value={description}\n onChange={(e) => {\n setDescription(e.target.value);\n if (errors.description) {\n setErrors((prev) => ({ ...prev, description: undefined }));\n }\n }}\n placeholder={placeholderDescription}\n className={`mt-1.5 w-full rounded-xl border px-3.5 py-2.5 text-sm transition focus:outline-none focus:ring-2 ${\n errors.description\n ? 'border-red-300 bg-red-50/50 text-red-900 focus:ring-red-400'\n : 'border-slate-200 bg-white text-slate-800 focus:border-transparent focus:ring-blue-500'\n }`}\n />\n {errors.description && (\n <p className=\"mt-1.5 flex items-center gap-1 text-xs text-red-600\">\n <AlertCircle className=\"h-3.5 w-3.5\" />\n <span>{errors.description}</span>\n </p>\n )}\n </div>\n\n {/* Screenshots Section (Max 3, Optional) */}\n <div>\n <div className=\"flex items-center justify-between\">\n <label className=\"block text-xs font-bold tracking-wide uppercase text-slate-700\">\n Screenshots <span className=\"text-slate-400 font-normal lowercase\">(optional)</span>\n </label>\n <span className=\"rounded-full bg-slate-100 px-2 py-0.5 text-xs font-semibold text-slate-600\">\n {screenshots.length} / 3\n </span>\n </div>\n <p className=\"mt-1 text-xs text-slate-500\">\n Capture your screen and annotate with pencil, shapes, or arrows.\n </p>\n\n {/* Screenshot Thumbnails Grid */}\n {screenshots.length > 0 && (\n <div className=\"mt-3 grid grid-cols-3 gap-2.5\">\n {screenshots.map((s, idx) => (\n <div\n key={s.id}\n className=\"group relative aspect-video overflow-hidden rounded-lg border border-slate-200 bg-slate-100 shadow-sm\"\n >\n <img\n src={s.dataUrl}\n alt={`Screenshot ${idx + 1}`}\n className=\"h-full w-full object-cover transition duration-200 group-hover:scale-105\"\n />\n\n {/* Top badge */}\n <span className=\"absolute top-1 left-1 rounded bg-black/60 px-1 py-0.2 text-[10px] font-semibold text-white\">\n #{idx + 1}\n </span>\n\n {/* Hover Overlay with actions */}\n <div className=\"absolute inset-0 flex items-center justify-center gap-1.5 bg-black/50 opacity-0 backdrop-blur-[1px] transition-opacity duration-200 group-hover:opacity-100\">\n <button\n type=\"button\"\n onClick={() => setPreviewImage(s.dataUrl)}\n title=\"Preview screenshot\"\n className=\"flex h-7 w-7 items-center justify-center rounded-md bg-white/90 text-slate-700 shadow transition hover:bg-white hover:text-blue-600\"\n >\n <Eye className=\"h-3.5 w-3.5\" />\n </button>\n <button\n type=\"button\"\n onClick={() => onEditScreenshot(s)}\n title=\"Re-edit / annotate\"\n className=\"flex h-7 w-7 items-center justify-center rounded-md bg-white/90 text-slate-700 shadow transition hover:bg-white hover:text-blue-600\"\n >\n <Edit3 className=\"h-3.5 w-3.5\" />\n </button>\n <button\n type=\"button\"\n onClick={() => onDeleteScreenshot(s.id)}\n title=\"Delete screenshot\"\n className=\"flex h-7 w-7 items-center justify-center rounded-md bg-red-600 text-white shadow transition hover:bg-red-700\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n </div>\n ))}\n </div>\n )}\n\n {/* Add Screenshot Trigger Button */}\n <div className=\"mt-3\">\n {screenshots.length < 3 ? (\n <button\n type=\"button\"\n onClick={onTriggerScreenshot}\n className=\"flex w-full items-center justify-center gap-2 rounded-xl border-2 border-dashed border-slate-300 bg-slate-50/70 py-3 text-xs font-semibold text-slate-600 transition hover:border-blue-400 hover:bg-blue-50/50 hover:text-blue-600\"\n >\n <Camera className=\"h-4 w-4 text-slate-500\" />\n <span>\n {screenshots.length === 0\n ? 'Capture Screen & Annotate'\n : `Capture Another Screenshot (${3 - screenshots.length} left)`}\n </span>\n </button>\n ) : (\n <div className=\"rounded-lg bg-amber-50 p-2.5 text-center text-xs text-amber-700 border border-amber-200\">\n Maximum 3 screenshots attached. Delete one to take a new one.\n </div>\n )}\n </div>\n </div>\n\n {submitError && (\n <div className=\"rounded-xl border border-red-200 bg-red-50 px-3.5 py-2.5 text-xs text-red-700 flex items-start gap-2\">\n <AlertCircle className=\"h-4 w-4 shrink-0 mt-0.5\" />\n <span>{submitError}</span>\n </div>\n )}\n\n {/* Form Actions */}\n <div className=\"pt-4 border-t border-slate-100 flex items-center justify-end gap-3\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-xl border border-slate-200 bg-white px-4 py-2.5 text-sm font-semibold text-slate-600 transition hover:bg-slate-50\"\n >\n Cancel\n </button>\n\n <button\n type=\"submit\"\n disabled={isSubmitting}\n style={{ backgroundColor: primaryColor }}\n className=\"flex items-center gap-2 rounded-xl px-5 py-2.5 text-sm font-semibold text-white shadow-md transition hover:brightness-110 active:scale-95 disabled:opacity-60\"\n >\n {isSubmitting ? (\n <>\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n <span>Submitting...</span>\n </>\n ) : (\n <span>Submit Bug Report</span>\n )}\n </button>\n </div>\n </form>\n )}\n </div>\n </aside>\n\n {/* Lightbox Preview Modal for zoomed screenshot */}\n {previewImage && (\n <div\n data-bugdrop-widget=\"true\"\n onClick={() => setPreviewImage(null)}\n className=\"fixed inset-0 z-[100001] flex items-center justify-center bg-black/80 p-4 backdrop-blur-sm animate-fadeIn\"\n >\n <div\n className=\"relative max-h-[90vh] max-w-[90vw] overflow-hidden rounded-xl bg-slate-900 shadow-2xl\"\n onClick={(e) => e.stopPropagation()}\n >\n <img\n src={previewImage}\n alt=\"Screenshot Preview\"\n className=\"max-h-[85vh] w-auto rounded-xl object-contain\"\n />\n <button\n type=\"button\"\n onClick={() => setPreviewImage(null)}\n className=\"absolute top-3 right-3 flex h-8 w-8 items-center justify-center rounded-full bg-black/60 text-white shadow hover:bg-black/90\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n )}\n </>\n );\n};","import React, { useState, useRef, useEffect, useCallback } from 'react';\nimport {\n Stage,\n Layer,\n Image as KonvaImage,\n Line,\n Rect,\n Circle,\n Arrow,\n Transformer,\n} from 'react-konva';\nimport type Konva from 'konva';\nimport {\n Pencil,\n Eraser,\n Square,\n Circle as CircleIcon,\n ArrowUpRight,\n MousePointer,\n Undo2,\n Redo2,\n Trash2,\n Check,\n X,\n Palette,\n} from 'lucide-react';\nimport type {\n EditorTool,\n AnnotationShape,\n LineAnnotation,\n RectAnnotation,\n CircleAnnotation,\n ArrowAnnotation,\n} from '../types';\n\ninterface KonvaEditorProps {\n imageSrc: string;\n onSave: (editedDataUrl: string) => void;\n onCancel: () => void;\n primaryColor?: string;\n}\n\nconst PRESET_COLORS = [\n '#ef4444', // Red\n '#f97316', // Orange\n '#eab308', // Yellow\n '#10b981', // Green\n '#3b82f6', // Blue\n '#8b5cf6', // Purple\n '#ec4899', // Pink\n '#000000', // Black\n '#ffffff', // White\n];\n\nconst STROKE_WIDTHS = [\n { label: 'S', value: 3 },\n { label: 'M', value: 6 },\n { label: 'L', value: 10 },\n { label: 'XL', value: 16 },\n];\n\nexport const KonvaEditor: React.FC<KonvaEditorProps> = ({\n imageSrc,\n onSave,\n onCancel,\n primaryColor = '#2563eb',\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const stageRef = useRef<Konva.Stage>(null);\n const transformerRef = useRef<Konva.Transformer>(null);\n\n const [image, setImage] = useState<HTMLImageElement | null>(null);\n const [scale, setScale] = useState<number>(1);\n const [stageDimensions, setStageDimensions] = useState({ width: 800, height: 600 });\n\n // Tool state\n const [tool, setTool] = useState<EditorTool>('pencil');\n const [color, setColor] = useState<string>('#ef4444');\n const [strokeWidth, setStrokeWidth] = useState<number>(6);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n\n // Shapes & drawing state\n const [shapes, setShapes] = useState<AnnotationShape[]>([]);\n const [draftShape, setDraftShape] = useState<AnnotationShape | null>(null);\n const [isDrawing, setIsDrawing] = useState(false);\n const [startPoint, setStartPoint] = useState<{ x: number; y: number } | null>(null);\n\n // History stack for Undo / Redo\n const [history, setHistory] = useState<AnnotationShape[][]>([[]]);\n const [historyStep, setHistoryStep] = useState<number>(0);\n\n // Load screenshot image\n useEffect(() => {\n const img = new window.Image();\n img.crossOrigin = 'anonymous';\n img.src = imageSrc;\n img.onload = () => {\n setImage(img);\n };\n }, [imageSrc]);\n\n // Compute responsive stage scaling to fit container\n const updateDimensions = useCallback(() => {\n if (!containerRef.current || !image) return;\n const paddingX = 48;\n const paddingY = 120;\n const availWidth = Math.max(300, containerRef.current.clientWidth - paddingX);\n const availHeight = Math.max(300, containerRef.current.clientHeight - paddingY);\n\n const fitScale = Math.min(\n availWidth / image.naturalWidth,\n availHeight / image.naturalHeight,\n 1\n );\n\n setScale(fitScale);\n setStageDimensions({\n width: Math.round(image.naturalWidth * fitScale),\n height: Math.round(image.naturalHeight * fitScale),\n });\n }, [image]);\n\n useEffect(() => {\n updateDimensions();\n window.addEventListener('resize', updateDimensions);\n return () => window.removeEventListener('resize', updateDimensions);\n }, [updateDimensions]);\n\n // Update Transformer attachment when selection or shapes change\n useEffect(() => {\n if (!transformerRef.current || !stageRef.current) return;\n if (selectedId) {\n const selectedNode = stageRef.current.findOne('#' + selectedId);\n if (selectedNode) {\n transformerRef.current.nodes([selectedNode]);\n transformerRef.current.getLayer()?.batchDraw();\n return;\n }\n }\n transformerRef.current.nodes([]);\n transformerRef.current.getLayer()?.batchDraw();\n }, [selectedId, shapes]);\n\n // Push new state to history\n const pushHistory = useCallback((newShapes: AnnotationShape[]) => {\n setHistory((prev) => {\n const newHistory = prev.slice(0, historyStep + 1);\n newHistory.push(newShapes);\n return newHistory;\n });\n setHistoryStep((prev) => prev + 1);\n }, [historyStep]);\n\n const handleUndo = useCallback(() => {\n if (historyStep > 0) {\n const newStep = historyStep - 1;\n setHistoryStep(newStep);\n setShapes(history[newStep]);\n setSelectedId(null);\n }\n }, [historyStep, history]);\n\n const handleRedo = useCallback(() => {\n if (historyStep < history.length - 1) {\n const newStep = historyStep + 1;\n setHistoryStep(newStep);\n setShapes(history[newStep]);\n setSelectedId(null);\n }\n }, [historyStep, history]);\n\n const handleClearAll = () => {\n if (shapes.length === 0) return;\n const newShapes: AnnotationShape[] = [];\n setShapes(newShapes);\n pushHistory(newShapes);\n setSelectedId(null);\n };\n\n const handleDeleteSelected = useCallback(() => {\n if (!selectedId) return;\n const newShapes = shapes.filter((s) => s.id !== selectedId);\n setShapes(newShapes);\n pushHistory(newShapes);\n setSelectedId(null);\n }, [selectedId, shapes, pushHistory]);\n\n // Keyboard shortcuts\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) {\n return;\n }\n if ((e.ctrlKey || e.metaKey) && e.key === 'z') {\n if (e.shiftKey) {\n handleRedo();\n } else {\n handleUndo();\n }\n e.preventDefault();\n } else if ((e.ctrlKey || e.metaKey) && e.key === 'y') {\n handleRedo();\n e.preventDefault();\n } else if (e.key === 'Delete' || e.key === 'Backspace') {\n if (selectedId) {\n handleDeleteSelected();\n e.preventDefault();\n }\n } else if (e.key === 'Escape') {\n setSelectedId(null);\n e.preventDefault();\n }\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [handleDeleteSelected, handleRedo, handleUndo, selectedId]);\n\n // Pointer event handlers for drawing shapes\n const handlePointerDown = (e: Konva.KonvaEventObject<MouseEvent | TouchEvent>) => {\n const stage = stageRef.current;\n if (!stage || !image) return;\n\n const pointer = stage.getPointerPosition();\n if (!pointer) return;\n\n // Convert to unscaled natural image coordinates\n const x = pointer.x / scale;\n const y = pointer.y / scale;\n\n // Select Tool behavior\n if (tool === 'select') {\n const clickedOnEmpty = e.target === stage || e.target.hasName('bg-image');\n if (clickedOnEmpty) {\n setSelectedId(null);\n }\n return;\n }\n\n // Eraser Tool click behavior: if clicked on an existing shape, remove it immediately\n if (tool === 'eraser') {\n const clickedNode = e.target;\n if (clickedNode !== stage && !clickedNode.hasName('bg-image')) {\n const shapeId = clickedNode.id();\n if (shapeId) {\n const newShapes = shapes.filter((s) => s.id !== shapeId);\n setShapes(newShapes);\n pushHistory(newShapes);\n setSelectedId(null);\n return;\n }\n }\n }\n\n // Deselect any selected shape while drawing new annotations\n setSelectedId(null);\n setIsDrawing(true);\n setStartPoint({ x, y });\n\n const id = `shape_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`;\n\n if (tool === 'pencil' || tool === 'eraser') {\n const newLine: LineAnnotation = {\n id,\n type: 'line',\n tool,\n points: [x, y],\n stroke: tool === 'eraser' ? '#ffffff' : color,\n strokeWidth: tool === 'eraser' ? strokeWidth * 2.5 : strokeWidth,\n };\n setDraftShape(newLine);\n } else if (tool === 'rectangle') {\n const newRect: RectAnnotation = {\n id,\n type: 'rectangle',\n x,\n y,\n width: 0,\n height: 0,\n stroke: color,\n strokeWidth,\n };\n setDraftShape(newRect);\n } else if (tool === 'circle') {\n const newCircle: CircleAnnotation = {\n id,\n type: 'circle',\n x,\n y,\n radius: 0,\n stroke: color,\n strokeWidth,\n };\n setDraftShape(newCircle);\n } else if (tool === 'arrow') {\n const newArrow: ArrowAnnotation = {\n id,\n type: 'arrow',\n points: [x, y, x, y],\n stroke: color,\n fill: color,\n strokeWidth,\n };\n setDraftShape(newArrow);\n }\n };\n\n const handlePointerMove = () => {\n if (!isDrawing || !draftShape || !startPoint || !stageRef.current) return;\n\n const pointer = stageRef.current.getPointerPosition();\n if (!pointer) return;\n\n const x = pointer.x / scale;\n const y = pointer.y / scale;\n\n if (draftShape.type === 'line') {\n setDraftShape({\n ...draftShape,\n points: [...draftShape.points, x, y],\n });\n } else if (draftShape.type === 'rectangle') {\n const rx = Math.min(startPoint.x, x);\n const ry = Math.min(startPoint.y, y);\n const rw = Math.abs(x - startPoint.x);\n const rh = Math.abs(y - startPoint.y);\n setDraftShape({\n ...draftShape,\n x: rx,\n y: ry,\n width: rw,\n height: rh,\n });\n } else if (draftShape.type === 'circle') {\n const radius = Math.hypot(x - startPoint.x, y - startPoint.y);\n setDraftShape({\n ...draftShape,\n radius,\n });\n } else if (draftShape.type === 'arrow') {\n setDraftShape({\n ...draftShape,\n points: [startPoint.x, startPoint.y, x, y],\n });\n }\n };\n\n const handlePointerUp = () => {\n if (!isDrawing) return;\n setIsDrawing(false);\n if (!draftShape) return;\n\n let isValid = false;\n if (draftShape.type === 'line' && draftShape.points.length >= 2) {\n isValid = true;\n } else if (\n draftShape.type === 'rectangle' &&\n draftShape.width > 6 &&\n draftShape.height > 6\n ) {\n isValid = true;\n } else if (draftShape.type === 'circle' && draftShape.radius > 5) {\n isValid = true;\n } else if (draftShape.type === 'arrow') {\n const [x1, y1, x2, y2] = draftShape.points;\n if (Math.hypot(x2 - x1, y2 - y1) > 10) {\n isValid = true;\n }\n }\n\n if (isValid) {\n const nextShapes = [...shapes, draftShape];\n setShapes(nextShapes);\n pushHistory(nextShapes);\n\n // Automatically select shapes (rect, circle, arrow) for immediate resizing\n if (\n draftShape.type === 'rectangle' ||\n draftShape.type === 'circle' ||\n draftShape.type === 'arrow'\n ) {\n setSelectedId(draftShape.id);\n setTool('select');\n }\n }\n\n setDraftShape(null);\n setStartPoint(null);\n };\n\n // Transform and Drag updates for resizable shapes\n const handleTransformEnd = (e: Konva.KonvaEventObject<Event>, id: string) => {\n const node = e.target;\n const targetShape = shapes.find((s) => s.id === id);\n if (!targetShape) return;\n\n if (targetShape.type === 'rectangle') {\n const scaleX = node.scaleX();\n const scaleY = node.scaleY();\n node.scaleX(1);\n node.scaleY(1);\n const updated: RectAnnotation = {\n ...targetShape,\n x: node.x(),\n y: node.y(),\n width: Math.max(10, node.width() * scaleX),\n height: Math.max(10, node.height() * scaleY),\n rotation: node.rotation(),\n };\n const nextShapes = shapes.map((s) => (s.id === id ? updated : s));\n setShapes(nextShapes);\n pushHistory(nextShapes);\n } else if (targetShape.type === 'circle') {\n const scaleX = node.scaleX();\n node.scaleX(1);\n node.scaleY(1);\n const updated: CircleAnnotation = {\n ...targetShape,\n x: node.x(),\n y: node.y(),\n radius: Math.max(6, targetShape.radius * scaleX),\n rotation: node.rotation(),\n };\n const nextShapes = shapes.map((s) => (s.id === id ? updated : s));\n setShapes(nextShapes);\n pushHistory(nextShapes);\n } else if (targetShape.type === 'arrow') {\n const scaleX = node.scaleX();\n const scaleY = node.scaleY();\n node.scaleX(1);\n node.scaleY(1);\n const [x1, y1, x2, y2] = targetShape.points;\n const updated: ArrowAnnotation = {\n ...targetShape,\n x: node.x(),\n y: node.y(),\n points: [x1, y1, x1 + (x2 - x1) * scaleX, y1 + (y2 - y1) * scaleY],\n rotation: node.rotation(),\n };\n const nextShapes = shapes.map((s) => (s.id === id ? updated : s));\n setShapes(nextShapes);\n pushHistory(nextShapes);\n }\n };\n\n const handleDragEnd = (e: Konva.KonvaEventObject<DragEvent>, id: string) => {\n const node = e.target;\n const targetShape = shapes.find((s) => s.id === id);\n if (!targetShape) return;\n\n const nextShapes = shapes.map((s) => {\n if (s.id === id) {\n return {\n ...s,\n x: node.x(),\n y: node.y(),\n };\n }\n return s;\n });\n setShapes(nextShapes);\n pushHistory(nextShapes);\n };\n\n // Finalize and export screenshot with annotations\n const handleExport = () => {\n if (!stageRef.current) return;\n // Deselect any transformer handles so they aren't included in the exported image\n setSelectedId(null);\n\n // Allow React state to flush transformer detachment before export\n setTimeout(() => {\n if (!stageRef.current) return;\n const exportedDataUrl = stageRef.current.toDataURL({\n pixelRatio: 1 / scale,\n mimeType: 'image/png',\n });\n onSave(exportedDataUrl);\n }, 60);\n };\n\n return (\n <div\n ref={containerRef}\n className=\"fixed inset-0 z-[100000] flex flex-col bg-slate-950/90 backdrop-blur-md select-none text-white overflow-hidden animate-fadeIn\"\n style={{ touchAction: 'none' }}\n >\n {/* Top Header Bar */}\n <div className=\"flex h-16 shrink-0 items-center justify-between border-b border-slate-800 bg-slate-900/90 px-4 sm:px-6\">\n <div className=\"flex items-center gap-3\">\n <div\n className=\"flex h-8 w-8 items-center justify-center rounded-lg text-white font-bold text-sm shadow\"\n style={{ backgroundColor: primaryColor }}\n >\n BD\n </div>\n <div>\n <h1 className=\"text-sm sm:text-base font-semibold leading-tight text-slate-100\">\n Screenshot Editor\n </h1>\n <p className=\"text-xs text-slate-400 hidden sm:block\">\n Highlight issues with pencil, arrows, circles, and boxes\n </p>\n </div>\n </div>\n\n {/* Top Actions: Undo, Redo, Clear, Cancel, Save */}\n <div className=\"flex items-center gap-2 sm:gap-3\">\n <button\n type=\"button\"\n onClick={handleUndo}\n disabled={historyStep <= 0}\n title=\"Undo (Ctrl+Z)\"\n className=\"flex h-9 w-9 items-center justify-center rounded-lg border border-slate-700 bg-slate-800 text-slate-200 transition hover:bg-slate-700 hover:text-white disabled:opacity-40 disabled:pointer-events-none\"\n >\n <Undo2 className=\"h-4 w-4\" />\n </button>\n <button\n type=\"button\"\n onClick={handleRedo}\n disabled={historyStep >= history.length - 1}\n title=\"Redo (Ctrl+Y)\"\n className=\"flex h-9 w-9 items-center justify-center rounded-lg border border-slate-700 bg-slate-800 text-slate-200 transition hover:bg-slate-700 hover:text-white disabled:opacity-40 disabled:pointer-events-none\"\n >\n <Redo2 className=\"h-4 w-4\" />\n </button>\n <button\n type=\"button\"\n onClick={handleClearAll}\n disabled={shapes.length === 0}\n title=\"Clear all annotations\"\n className=\"flex h-9 items-center gap-1.5 rounded-lg border border-slate-700 bg-slate-800 px-2.5 text-xs font-medium text-slate-300 transition hover:bg-slate-700 hover:text-white disabled:opacity-40 disabled:pointer-events-none\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n <span className=\"hidden md:inline\">Clear All</span>\n </button>\n\n <div className=\"h-5 w-px bg-slate-700 mx-1\" />\n\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"flex h-9 items-center gap-1.5 rounded-lg border border-slate-700 bg-slate-800 px-3 text-xs sm:text-sm font-medium text-slate-200 transition hover:bg-slate-700 hover:text-white\"\n >\n <X className=\"h-4 w-4\" />\n <span>Cancel</span>\n </button>\n\n <button\n type=\"button\"\n onClick={handleExport}\n style={{ backgroundColor: primaryColor }}\n className=\"flex h-9 items-center gap-1.5 rounded-lg px-4 text-xs sm:text-sm font-semibold text-white shadow-md transition hover:brightness-110 active:scale-95\"\n >\n <Check className=\"h-4 w-4\" />\n <span>Add to Report</span>\n </button>\n </div>\n </div>\n\n {/* Floating Toolbar */}\n <div className=\"absolute top-20 left-1/2 -translate-x-1/2 z-20 flex flex-wrap items-center justify-center gap-2 rounded-2xl border border-slate-700/80 bg-slate-900/95 p-2 shadow-2xl backdrop-blur-md\">\n {/* Tool selector buttons */}\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => setTool('select')}\n title=\"Select & Move / Resize\"\n className={`flex h-9 w-9 items-center justify-center rounded-xl transition ${\n tool === 'select'\n ? 'bg-blue-600 text-white shadow-inner'\n : 'text-slate-300 hover:bg-slate-800 hover:text-white'\n }`}\n >\n <MousePointer className=\"h-4 w-4\" />\n </button>\n\n <button\n type=\"button\"\n onClick={() => {\n setTool('pencil');\n setSelectedId(null);\n }}\n title=\"Pencil / Draw\"\n className={`flex h-9 w-9 items-center justify-center rounded-xl transition ${\n tool === 'pencil'\n ? 'bg-blue-600 text-white shadow-inner'\n : 'text-slate-300 hover:bg-slate-800 hover:text-white'\n }`}\n >\n <Pencil className=\"h-4 w-4\" />\n </button>\n\n <button\n type=\"button\"\n onClick={() => {\n setTool('eraser');\n setSelectedId(null);\n }}\n title=\"Eraser (click or drag to erase)\"\n className={`flex h-9 w-9 items-center justify-center rounded-xl transition ${\n tool === 'eraser'\n ? 'bg-blue-600 text-white shadow-inner'\n : 'text-slate-300 hover:bg-slate-800 hover:text-white'\n }`}\n >\n <Eraser className=\"h-4 w-4\" />\n </button>\n\n <button\n type=\"button\"\n onClick={() => {\n setTool('rectangle');\n setSelectedId(null);\n }}\n title=\"Rectangle (Resizable)\"\n className={`flex h-9 w-9 items-center justify-center rounded-xl transition ${\n tool === 'rectangle'\n ? 'bg-blue-600 text-white shadow-inner'\n : 'text-slate-300 hover:bg-slate-800 hover:text-white'\n }`}\n >\n <Square className=\"h-4 w-4\" />\n </button>\n\n <button\n type=\"button\"\n onClick={() => {\n setTool('circle');\n setSelectedId(null);\n }}\n title=\"Circle (Resizable)\"\n className={`flex h-9 w-9 items-center justify-center rounded-xl transition ${\n tool === 'circle'\n ? 'bg-blue-600 text-white shadow-inner'\n : 'text-slate-300 hover:bg-slate-800 hover:text-white'\n }`}\n >\n <CircleIcon className=\"h-4 w-4\" />\n </button>\n\n <button\n type=\"button\"\n onClick={() => {\n setTool('arrow');\n setSelectedId(null);\n }}\n title=\"Arrow (Resizable)\"\n className={`flex h-9 w-9 items-center justify-center rounded-xl transition ${\n tool === 'arrow'\n ? 'bg-blue-600 text-white shadow-inner'\n : 'text-slate-300 hover:bg-slate-800 hover:text-white'\n }`}\n >\n <ArrowUpRight className=\"h-4 w-4\" />\n </button>\n </div>\n\n <div className=\"h-5 w-px bg-slate-700\" />\n\n {/* Color Palette Switcher */}\n <div className=\"flex items-center gap-1.5 px-1\">\n {PRESET_COLORS.map((c) => (\n <button\n key={c}\n type=\"button\"\n onClick={() => setColor(c)}\n title={c}\n style={{ backgroundColor: c }}\n className={`h-5 w-5 rounded-full border border-slate-700 transition-transform ${\n color === c ? 'scale-125 ring-2 ring-white ring-offset-1 ring-offset-slate-900' : 'hover:scale-110'\n }`}\n />\n ))}\n\n {/* Custom color input */}\n <label\n title=\"Custom Color\"\n className=\"relative flex h-6 w-6 cursor-pointer items-center justify-center rounded-full border border-slate-600 bg-slate-800 text-slate-300 hover:text-white transition\"\n >\n <Palette className=\"h-3.5 w-3.5\" />\n <input\n type=\"color\"\n value={color}\n onChange={(e) => setColor(e.target.value)}\n className=\"absolute inset-0 opacity-0 cursor-pointer\"\n />\n </label>\n </div>\n\n <div className=\"h-5 w-px bg-slate-700\" />\n\n {/* Stroke Width Selector */}\n <div className=\"flex items-center gap-1\">\n {STROKE_WIDTHS.map((sw) => (\n <button\n key={sw.value}\n type=\"button\"\n onClick={() => setStrokeWidth(sw.value)}\n className={`flex h-7 w-7 items-center justify-center rounded-lg text-xs font-semibold transition ${\n strokeWidth === sw.value\n ? 'bg-slate-700 text-white ring-1 ring-slate-400'\n : 'text-slate-400 hover:bg-slate-800 hover:text-white'\n }`}\n >\n {sw.label}\n </button>\n ))}\n </div>\n\n {/* Delete button if a shape is selected */}\n {selectedId && (\n <>\n <div className=\"h-5 w-px bg-slate-700\" />\n <button\n type=\"button\"\n onClick={handleDeleteSelected}\n title=\"Delete Selected Shape (Del / Backspace)\"\n className=\"flex h-8 items-center gap-1.5 rounded-xl bg-red-600/90 px-3 text-xs font-semibold text-white shadow hover:bg-red-600\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n <span>Delete</span>\n </button>\n </>\n )}\n </div>\n\n {/* Main Canvas Workspace */}\n <div className=\"relative flex flex-1 items-center justify-center p-4 overflow-hidden\">\n {!image ? (\n <div className=\"flex flex-col items-center gap-2 text-slate-400\">\n <div className=\"h-8 w-8 animate-spin rounded-full border-2 border-blue-500 border-t-transparent\" />\n <p className=\"text-sm\">Loading screenshot...</p>\n </div>\n ) : (\n <div\n className=\"relative shadow-2xl rounded-md overflow-hidden border border-slate-700 bg-slate-900\"\n style={{\n width: stageDimensions.width,\n height: stageDimensions.height,\n cursor:\n tool === 'select'\n ? 'default'\n : tool === 'eraser'\n ? 'cell'\n : 'crosshair',\n }}\n >\n <Stage\n ref={stageRef}\n width={stageDimensions.width}\n height={stageDimensions.height}\n scaleX={scale}\n scaleY={scale}\n onMouseDown={handlePointerDown}\n onMouseMove={handlePointerMove}\n onMouseUp={handlePointerUp}\n onTouchStart={handlePointerDown}\n onTouchMove={handlePointerMove}\n onTouchEnd={handlePointerUp}\n >\n {/* Background Layer: Screenshot Image */}\n <Layer listening={false}>\n <KonvaImage\n name=\"bg-image\"\n image={image}\n width={image.naturalWidth}\n height={image.naturalHeight}\n />\n </Layer>\n\n {/* Annotations Layer */}\n <Layer>\n {shapes.map((shape) => {\n const isSelectable = tool === 'select';\n\n if (shape.type === 'line') {\n return (\n <Line\n key={shape.id}\n id={shape.id}\n points={shape.points}\n stroke={shape.stroke}\n strokeWidth={shape.strokeWidth}\n tension={0.5}\n lineCap=\"round\"\n lineJoin=\"round\"\n globalCompositeOperation={\n shape.tool === 'eraser' ? 'destination-out' : 'source-over'\n }\n draggable={isSelectable && shape.tool !== 'eraser'}\n onClick={() => {\n if (isSelectable) setSelectedId(shape.id);\n if (tool === 'eraser') {\n const next = shapes.filter((s) => s.id !== shape.id);\n setShapes(next);\n pushHistory(next);\n }\n }}\n onTap={() => {\n if (isSelectable) setSelectedId(shape.id);\n }}\n onDragEnd={(e) => handleDragEnd(e, shape.id)}\n />\n );\n }\n\n if (shape.type === 'rectangle') {\n return (\n <Rect\n key={shape.id}\n id={shape.id}\n x={shape.x}\n y={shape.y}\n width={shape.width}\n height={shape.height}\n stroke={shape.stroke}\n strokeWidth={shape.strokeWidth}\n rotation={shape.rotation || 0}\n draggable={isSelectable}\n onClick={() => {\n if (isSelectable) setSelectedId(shape.id);\n if (tool === 'eraser') {\n const next = shapes.filter((s) => s.id !== shape.id);\n setShapes(next);\n pushHistory(next);\n }\n }}\n onTap={() => {\n if (isSelectable) setSelectedId(shape.id);\n }}\n onTransformEnd={(e) => handleTransformEnd(e, shape.id)}\n onDragEnd={(e) => handleDragEnd(e, shape.id)}\n />\n );\n }\n\n if (shape.type === 'circle') {\n return (\n <Circle\n key={shape.id}\n id={shape.id}\n x={shape.x}\n y={shape.y}\n radius={shape.radius}\n stroke={shape.stroke}\n strokeWidth={shape.strokeWidth}\n rotation={shape.rotation || 0}\n draggable={isSelectable}\n onClick={() => {\n if (isSelectable) setSelectedId(shape.id);\n if (tool === 'eraser') {\n const next = shapes.filter((s) => s.id !== shape.id);\n setShapes(next);\n pushHistory(next);\n }\n }}\n onTap={() => {\n if (isSelectable) setSelectedId(shape.id);\n }}\n onTransformEnd={(e) => handleTransformEnd(e, shape.id)}\n onDragEnd={(e) => handleDragEnd(e, shape.id)}\n />\n );\n }\n\n if (shape.type === 'arrow') {\n return (\n <Arrow\n key={shape.id}\n id={shape.id}\n points={shape.points}\n pointerLength={14}\n pointerWidth={14}\n stroke={shape.stroke}\n fill={shape.fill}\n strokeWidth={shape.strokeWidth}\n rotation={shape.rotation || 0}\n draggable={isSelectable}\n onClick={() => {\n if (isSelectable) setSelectedId(shape.id);\n if (tool === 'eraser') {\n const next = shapes.filter((s) => s.id !== shape.id);\n setShapes(next);\n pushHistory(next);\n }\n }}\n onTap={() => {\n if (isSelectable) setSelectedId(shape.id);\n }}\n onTransformEnd={(e) => handleTransformEnd(e, shape.id)}\n onDragEnd={(e) => handleDragEnd(e, shape.id)}\n />\n );\n }\n\n return null;\n })}\n\n {/* Live Draft Shape during drag */}\n {draftShape && (\n <>\n {draftShape.type === 'line' && (\n <Line\n points={draftShape.points}\n stroke={draftShape.stroke}\n strokeWidth={draftShape.strokeWidth}\n tension={0.5}\n lineCap=\"round\"\n lineJoin=\"round\"\n globalCompositeOperation={\n draftShape.tool === 'eraser'\n ? 'destination-out'\n : 'source-over'\n }\n />\n )}\n {draftShape.type === 'rectangle' && (\n <Rect\n x={draftShape.x}\n y={draftShape.y}\n width={draftShape.width}\n height={draftShape.height}\n stroke={draftShape.stroke}\n strokeWidth={draftShape.strokeWidth}\n dash={[6, 4]}\n />\n )}\n {draftShape.type === 'circle' && (\n <Circle\n x={draftShape.x}\n y={draftShape.y}\n radius={draftShape.radius}\n stroke={draftShape.stroke}\n strokeWidth={draftShape.strokeWidth}\n dash={[6, 4]}\n />\n )}\n {draftShape.type === 'arrow' && (\n <Arrow\n points={draftShape.points}\n pointerLength={14}\n pointerWidth={14}\n stroke={draftShape.stroke}\n fill={draftShape.fill}\n strokeWidth={draftShape.strokeWidth}\n dash={[6, 4]}\n />\n )}\n </>\n )}\n\n {/* Transformer for selected shape */}\n <Transformer\n ref={transformerRef}\n rotateEnabled={true}\n enabledAnchors={[\n 'top-left',\n 'top-right',\n 'bottom-left',\n 'bottom-right',\n 'middle-left',\n 'middle-right',\n 'top-center',\n 'bottom-center',\n ]}\n borderStroke=\"#3b82f6\"\n borderDash={[4, 4]}\n anchorFill=\"#ffffff\"\n anchorStroke=\"#3b82f6\"\n anchorSize={9}\n anchorCornerRadius={2}\n boundBoxFunc={(oldBox, newBox) => {\n if (newBox.width < 10 || newBox.height < 10) {\n return oldBox;\n }\n return newBox;\n }}\n />\n </Layer>\n </Stage>\n </div>\n )}\n </div>\n\n {/* Bottom helper hints bar */}\n <div className=\"flex h-10 shrink-0 items-center justify-between border-t border-slate-800 bg-slate-900/80 px-4 text-xs text-slate-400\">\n <div className=\"flex items-center gap-4\">\n <span>\n Active tool: <strong className=\"text-slate-200 capitalize\">{tool}</strong>\n </span>\n <span className=\"hidden sm:inline\">\n Use <kbd className=\"rounded bg-slate-800 px-1 py-0.5 text-slate-300\">Ctrl+Z</kbd> to undo, <kbd className=\"rounded bg-slate-800 px-1 py-0.5 text-slate-300\">Del</kbd> to remove selected shape\n </span>\n </div>\n <div>\n {image && (\n <span>\n Original Resolution: {image.naturalWidth} x {image.naturalHeight}px\n </span>\n )}\n </div>\n </div>\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport html2canvas from 'html2canvas';\nimport { Bug, X } from 'lucide-react';\nimport { Form } from './Form';\nimport { KonvaEditor } from './KonvaEditor';\nimport type {\n WidgetProps,\n WidgetPosition,\n WidgetButtonSize,\n ScreenshotItem,\n BugReportData,\n} from '../types';\n\nexport const Widget: React.FC<WidgetProps> = ({\n projectUrl,\n onSubmit,\n uiSettings = {},\n onSuccess,\n onError,\n isOpen: controlledIsOpen,\n onToggle,\n className = '',\n}) => {\n const {\n position = 'bottom-right',\n primaryColor = '#2563eb',\n buttonSize = 'md',\n buttonText,\n buttonIcon,\n zIndex = 99990,\n } = uiSettings;\n\n // Uncontrolled or controlled open state\n const [internalIsOpen, setInternalIsOpen] = useState(false);\n const isOpen = controlledIsOpen !== undefined ? controlledIsOpen : internalIsOpen;\n\n const setOpen = (open: boolean) => {\n if (controlledIsOpen === undefined) {\n setInternalIsOpen(open);\n }\n onToggle?.(open);\n };\n\n // Screenshots state (max 3)\n const [screenshots, setScreenshots] = useState<ScreenshotItem[]>([]);\n\n // Screenshot capture & Konva editor state\n const [isCapturing, setIsCapturing] = useState(false);\n const [isEditorOpen, setIsEditorOpen] = useState(false);\n const [editingScreenshot, setEditingScreenshot] = useState<{\n id?: string;\n dataUrl: string;\n isNew: boolean;\n } | null>(null);\n\n // Position CSS classes for the trigger button\n const getPositionClasses = (pos: WidgetPosition): string => {\n switch (pos) {\n case 'bottom-left':\n return 'bottom-6 left-6';\n case 'top-left':\n return 'top-6 left-6';\n case 'top-right':\n return 'top-6 right-6';\n case 'left':\n return 'top-1/2 -translate-y-1/2 left-4';\n case 'right':\n return 'top-1/2 -translate-y-1/2 right-4';\n case 'bottom-right':\n default:\n return 'bottom-6 right-6';\n }\n };\n\n // Size CSS classes for the trigger button\n const getSizeClasses = (size: WidgetButtonSize): { button: string; icon: string } => {\n switch (size) {\n case 'sm':\n return {\n button: 'h-10 px-3.5 gap-2 text-xs font-semibold rounded-full shadow-md',\n icon: 'h-4 w-4',\n };\n case 'lg':\n return {\n button: 'h-14 px-5 gap-3 text-base font-bold rounded-full shadow-xl',\n icon: 'h-6 w-6',\n };\n case 'md':\n default:\n return {\n button: 'h-12 px-4 gap-2.5 text-sm font-semibold rounded-full shadow-lg',\n icon: 'h-5 w-5',\n };\n }\n };\n\n const sizeClasses = getSizeClasses(buttonSize);\n\n // Take screenshot flow\n const handleTriggerScreenshot = async () => {\n // 1. Mark as capturing to immediately hide all widget UI (button and form)\n setIsCapturing(true);\n\n try {\n // 2. Wait for DOM to repaint without widget elements\n await new Promise((resolve) => setTimeout(resolve, 180));\n\n // 3. Capture screen using html2canvas\n const canvas = await html2canvas(document.documentElement, {\n useCORS: true,\n allowTaint: true,\n logging: false,\n scrollX: 0,\n scrollY: -window.scrollY,\n windowWidth: document.documentElement.offsetWidth,\n windowHeight: document.documentElement.offsetHeight,\n ignoreElements: (element) => {\n return (\n element.getAttribute('data-bugdrop-widget') === 'true' ||\n element.classList.contains('bugdrop-ignore')\n );\n },\n });\n\n const dataUrl = canvas.toDataURL('image/png');\n\n // 4. Open Konva editor with captured screenshot\n setEditingScreenshot({\n dataUrl,\n isNew: true,\n });\n setIsEditorOpen(true);\n } catch (err) {\n console.error('Error taking screenshot:', err);\n alert('Could not capture screenshot. Please try again.');\n } finally {\n setIsCapturing(false);\n }\n };\n\n // Re-edit an existing screenshot from the form\n const handleEditExistingScreenshot = (item: ScreenshotItem) => {\n setEditingScreenshot({\n id: item.id,\n dataUrl: item.dataUrl,\n isNew: false,\n });\n setIsEditorOpen(true);\n };\n\n // Delete a screenshot\n const handleDeleteScreenshot = (id: string) => {\n setScreenshots((prev) => prev.filter((s) => s.id !== id));\n };\n\n // Save edited screenshot from Konva editor\n const handleSaveEditor = (editedDataUrl: string) => {\n if (editingScreenshot?.isNew) {\n if (screenshots.length < 3) {\n const newItem: ScreenshotItem = {\n id: `ss_${Date.now()}_${Math.random().toString(36).substring(2, 6)}`,\n dataUrl: editedDataUrl,\n createdAt: Date.now(),\n };\n setScreenshots((prev) => [...prev, newItem]);\n }\n } else if (editingScreenshot?.id) {\n // Update existing\n setScreenshots((prev) =>\n prev.map((s) =>\n s.id === editingScreenshot.id ? { ...s, dataUrl: editedDataUrl } : s\n )\n );\n }\n\n setIsEditorOpen(false);\n setEditingScreenshot(null);\n setOpen(true); // Return to form\n };\n\n // Cancel Konva editor\n const handleCancelEditor = () => {\n setIsEditorOpen(false);\n setEditingScreenshot(null);\n setOpen(true); // Return to form\n };\n\n // Hand off the report to the consumer's onSubmit handler\n const handleSubmitReport = async (reportData: BugReportData) => {\n try {\n await onSubmit(reportData);\n onSuccess?.(reportData);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to submit bug report');\n onError?.(error);\n throw error;\n }\n };\n\n // If capturing screenshot, completely hide widget elements from DOM/render\n if (isCapturing) {\n return null;\n }\n\n return (\n <>\n {/* Floating Widget Trigger Button */}\n {!isEditorOpen && (\n <div\n data-bugdrop-widget=\"true\"\n className={`fixed ${getPositionClasses(position)} ${className}`}\n style={{ zIndex }}\n >\n <button\n type=\"button\"\n onClick={() => setOpen(!isOpen)}\n style={{ backgroundColor: primaryColor }}\n className={`group flex items-center justify-center text-white transition-all duration-200 hover:brightness-110 active:scale-95 ${sizeClasses.button}`}\n aria-label={isOpen ? 'Close bug report form' : 'Open bug report form'}\n title={isOpen ? 'Close Bug Report' : 'Report a Bug'}\n >\n {isOpen ? (\n <X className={sizeClasses.icon} />\n ) : buttonIcon ? (\n buttonIcon\n ) : (\n <Bug className={sizeClasses.icon} />\n )}\n\n {buttonText && <span>{buttonText}</span>}\n\n {/* Notification Badge if screenshots are attached */}\n {screenshots.length > 0 && !isOpen && (\n <span className=\"flex h-5 w-5 items-center justify-center rounded-full bg-white text-[11px] font-bold text-slate-900 shadow\">\n {screenshots.length}\n </span>\n )}\n </button>\n </div>\n )}\n\n {/* Slide-in Form Drawer */}\n {!isEditorOpen && (\n <Form\n projectUrl={projectUrl}\n isOpen={isOpen}\n onClose={() => setOpen(false)}\n uiSettings={uiSettings}\n screenshots={screenshots}\n onTriggerScreenshot={handleTriggerScreenshot}\n onEditScreenshot={handleEditExistingScreenshot}\n onDeleteScreenshot={handleDeleteScreenshot}\n onSubmitReport={handleSubmitReport}\n />\n )}\n\n {/* Konva Annotation Editor Modal */}\n {isEditorOpen && editingScreenshot && (\n <KonvaEditor\n imageSrc={editingScreenshot.dataUrl}\n onSave={handleSaveEditor}\n onCancel={handleCancelEditor}\n primaryColor={primaryColor}\n />\n )}\n </>\n );\n};"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
*,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border:0 solid #e5e7eb}:before,:after{--tw-content:""}html,:host{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:#0000;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder{opacity:1;color:#9ca3af}textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (width>=640px){.container{max-width:640px}}@media (width>=768px){.container{max-width:768px}}@media (width>=1024px){.container{max-width:1024px}}@media (width>=1280px){.container{max-width:1280px}}@media (width>=1536px){.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.bottom-6{bottom:1.5rem}.left-0{left:0}.left-1{left:.25rem}.left-1\/2{left:50%}.left-4{left:1rem}.left-6{left:1.5rem}.right-0{right:0}.right-3{right:.75rem}.right-4{right:1rem}.right-6{right:1.5rem}.top-0{top:0}.top-1{top:.25rem}.top-1\/2{top:50%}.top-20{top:5rem}.top-3{top:.75rem}.top-6{top:1.5rem}.z-20{z-index:20}.z-\[100000\]{z-index:100000}.z-\[100001\]{z-index:100001}.z-\[99990\]{z-index:99990}.z-\[99995\]{z-index:99995}.mx-1{margin-left:.25rem;margin-right:.25rem}.mb-4{margin-bottom:1rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-8{margin-top:2rem}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.aspect-video{aspect-ratio:16/9}.h-10{height:2.5rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-16{height:4rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-full{height:100%}.max-h-\[85vh\]{max-height:85vh}.max-h-\[90vh\]{max-height:90vh}.w-10{width:2.5rem}.w-16{width:4rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-auto{width:auto}.w-full{width:100%}.w-px{width:1px}.max-w-\[90vw\]{max-width:90vw}.max-w-md{max-width:28rem}.max-w-xs{max-width:20rem}.flex-1{flex:1}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x:-50%;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-x-full{--tw-translate-x:-100%;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y:-50%;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x:0px;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-full{--tw-translate-x:100%;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-125{--tw-scale-x:1.25;--tw-scale-y:1.25;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:1s linear infinite spin}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;user-select:none}.resize{resize:both}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-amber-200{--tw-border-opacity:1;border-color:rgb(253 230 138/var(--tw-border-opacity,1))}.border-blue-500{--tw-border-opacity:1;border-color:rgb(59 130 246/var(--tw-border-opacity,1))}.border-red-200{--tw-border-opacity:1;border-color:rgb(254 202 202/var(--tw-border-opacity,1))}.border-red-300{--tw-border-opacity:1;border-color:rgb(252 165 165/var(--tw-border-opacity,1))}.border-slate-100{--tw-border-opacity:1;border-color:rgb(241 245 249/var(--tw-border-opacity,1))}.border-slate-200{--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity,1))}.border-slate-300{--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity,1))}.border-slate-600{--tw-border-opacity:1;border-color:rgb(71 85 105/var(--tw-border-opacity,1))}.border-slate-700{--tw-border-opacity:1;border-color:rgb(51 65 85/var(--tw-border-opacity,1))}.border-slate-700\/80{border-color:#334155cc}.border-slate-800{--tw-border-opacity:1;border-color:rgb(30 41 59/var(--tw-border-opacity,1))}.border-t-transparent{border-top-color:#0000}.bg-amber-50{--tw-bg-opacity:1;background-color:rgb(255 251 235/var(--tw-bg-opacity,1))}.bg-black\/50{background-color:#00000080}.bg-black\/60{background-color:#0009}.bg-black\/80{background-color:#000c}.bg-blue-600{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1))}.bg-red-50{--tw-bg-opacity:1;background-color:rgb(254 242 242/var(--tw-bg-opacity,1))}.bg-red-50\/50{background-color:#fef2f280}.bg-red-600{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity,1))}.bg-red-600\/90{background-color:#dc2626e6}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1))}.bg-slate-50\/70{background-color:#f8fafcb3}.bg-slate-700{--tw-bg-opacity:1;background-color:rgb(51 65 85/var(--tw-bg-opacity,1))}.bg-slate-800{--tw-bg-opacity:1;background-color:rgb(30 41 59/var(--tw-bg-opacity,1))}.bg-slate-900{--tw-bg-opacity:1;background-color:rgb(15 23 42/var(--tw-bg-opacity,1))}.bg-slate-900\/40{background-color:#0f172a66}.bg-slate-900\/80{background-color:#0f172acc}.bg-slate-900\/90{background-color:#0f172ae6}.bg-slate-900\/95{background-color:#0f172af2}.bg-slate-950\/90{background-color:#020617e6}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-white\/90{background-color:#ffffffe6}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-4{padding:1rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.pt-4{padding-top:1rem}.text-center{text-align:center}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize{text-transform:capitalize}.leading-tight{line-height:1.25}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.text-amber-700{--tw-text-opacity:1;color:rgb(180 83 9/var(--tw-text-opacity,1))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity,1))}.text-red-900{--tw-text-opacity:1;color:rgb(127 29 29/var(--tw-text-opacity,1))}.text-slate-100{--tw-text-opacity:1;color:rgb(241 245 249/var(--tw-text-opacity,1))}.text-slate-200{--tw-text-opacity:1;color:rgb(226 232 240/var(--tw-text-opacity,1))}.text-slate-300{--tw-text-opacity:1;color:rgb(203 213 225/var(--tw-text-opacity,1))}.text-slate-400{--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}.text-slate-500{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}.text-slate-600{--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1))}.text-slate-700{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity,1))}.text-slate-800{--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}.text-slate-900{--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.opacity-0{opacity:0}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 #0000001a, 0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px #00000040;--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.shadow-inner{--tw-shadow:inset 0 2px 4px 0 #0000000d;--tw-shadow-colored:inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px #0000001a, 0 8px 10px -6px #0000001a;--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow,0 0 #0000)}.ring-2{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow,0 0 #0000)}.ring-slate-400{--tw-ring-opacity:1;--tw-ring-color:rgb(148 163 184/var(--tw-ring-opacity,1))}.ring-white{--tw-ring-opacity:1;--tw-ring-color:rgb(255 255 255/var(--tw-ring-opacity,1))}.ring-offset-1{--tw-ring-offset-width:1px}.ring-offset-slate-900{--tw-ring-offset-color:#0f172a}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-\[1px\]{--tw-backdrop-blur:blur(1px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-md{--tw-backdrop-blur:blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter,backdrop-filter;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-all{transition-property:all;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-opacity{transition-property:opacity;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-transform{transition-property:transform;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.hover\:scale-110:hover{--tw-scale-x:1.1;--tw-scale-y:1.1;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:border-blue-400:hover{--tw-border-opacity:1;border-color:rgb(96 165 250/var(--tw-border-opacity,1))}.hover\:bg-black\/90:hover{background-color:#000000e6}.hover\:bg-blue-50\/50:hover{background-color:#eff6ff80}.hover\:bg-red-600:hover{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity,1))}.hover\:bg-red-700:hover{--tw-bg-opacity:1;background-color:rgb(185 28 28/var(--tw-bg-opacity,1))}.hover\:bg-slate-100:hover{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1))}.hover\:bg-slate-50:hover{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity,1))}.hover\:bg-slate-700:hover{--tw-bg-opacity:1;background-color:rgb(51 65 85/var(--tw-bg-opacity,1))}.hover\:bg-slate-800:hover{--tw-bg-opacity:1;background-color:rgb(30 41 59/var(--tw-bg-opacity,1))}.hover\:bg-white:hover{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.hover\:text-blue-600:hover{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.hover\:text-slate-600:hover{--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1))}.hover\:text-white:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.hover\:brightness-110:hover{--tw-brightness:brightness(1.1);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.focus\:border-transparent:focus{border-color:#0000}.focus\:outline-none:focus{outline-offset:2px;outline:2px solid #0000}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow,0 0 #0000)}.focus\:ring-blue-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.focus\:ring-red-400:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(248 113 113/var(--tw-ring-opacity,1))}.active\:scale-95:active{--tw-scale-x:.95;--tw-scale-y:.95;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-60:disabled{opacity:.6}.group:hover .group-hover\:scale-105{--tw-scale-x:1.05;--tw-scale-y:1.05;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:opacity-100{opacity:1}@media (width>=640px){.sm\:block{display:block}.sm\:inline{display:inline}.sm\:max-w-lg{max-width:32rem}.sm\:flex-row{flex-direction:row}.sm\:gap-3{gap:.75rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:text-base{font-size:1rem;line-height:1.5rem}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}}@media (width>=768px){.md\:inline{display:inline}}
|
|
2
|
+
/*$vite$:1*/
|