react-visual-feedback 1.1.1 → 1.2.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 CHANGED
@@ -1,9 +1,10 @@
1
1
  # React Visual Feedback
2
2
 
3
- A powerful, visual feedback collection tool for React applications. Users can select any element on your page, and the widget automatically captures a screenshot and context information.
3
+ A powerful, visual feedback collection tool for React applications with an integrated dashboard for managing user feedback. Users can select any element on your page, and the widget automatically captures a screenshot and context information.
4
4
 
5
5
  ## Features
6
6
 
7
+ ### Feedback Collection
7
8
  - 🎯 Visual element selection with hover highlighting
8
9
  - 📸 Automatic screenshot capture of selected elements with perfect CSS rendering
9
10
  - 📝 Feedback form with rich context
@@ -12,6 +13,16 @@ A powerful, visual feedback collection tool for React applications. Users can se
12
13
  - ⌨️ Keyboard shortcuts (Ctrl+Q to activate, Esc to cancel, Ctrl+Enter to submit)
13
14
  - 🌓 Dark mode support
14
15
 
16
+ ### Feedback Dashboard (New!)
17
+ - 📊 **Professional dashboard** with localStorage or custom data source
18
+ - 👨‍💻 **Developer mode** with full technical details
19
+ - 👤 **User mode** for simplified feedback view
20
+ - 🏷️ **Status management** with 7 professional status options
21
+ - ✅ **Custom dropdown** with smooth animations
22
+ - 🔒 **Permission system** - Users can only view, developers can manage
23
+ - 🔄 **Status change callbacks** for database synchronization
24
+ - ⌨️ Dashboard keyboard shortcut (Ctrl+Shift+Q)
25
+
15
26
  ## Installation
16
27
 
17
28
  ```bash
@@ -26,7 +37,7 @@ import 'react-visual-feedback/dist/index.css';
26
37
 
27
38
  ## Quick Start
28
39
 
29
- ### 1. Wrap your app with FeedbackProvider
40
+ ### Basic Usage (Feedback Only)
30
41
 
31
42
  ```jsx
32
43
  import React from 'react';
@@ -54,293 +65,393 @@ function App() {
54
65
  export default App;
55
66
  ```
56
67
 
57
- ### 2. Add a feedback trigger button (optional)
68
+ ### With Dashboard (Full Feature Set)
58
69
 
59
70
  ```jsx
60
- import { useFeedback } from 'react-visual-feedback';
71
+ import React from 'react';
72
+ import { FeedbackProvider, useFeedback } from 'react-visual-feedback';
73
+ import 'react-visual-feedback/dist/index.css';
61
74
 
62
- function FeedbackButton() {
63
- const { setIsActive } = useFeedback();
75
+ function FeedbackButtons() {
76
+ const { isActive, setIsActive, setIsDashboardOpen } = useFeedback();
64
77
 
65
78
  return (
66
- <button onClick={() => setIsActive(true)}>
67
- Report Issue
68
- </button>
79
+ <div style={{ position: 'fixed', bottom: 20, right: 20, display: 'flex', gap: 10 }}>
80
+ <button onClick={() => setIsDashboardOpen(true)}>
81
+ 📊 Dashboard
82
+ </button>
83
+ <button onClick={() => setIsActive(!isActive)}>
84
+ {isActive ? '✕ Cancel' : '💬 Report Issue'}
85
+ </button>
86
+ </div>
69
87
  );
70
88
  }
71
- ```
72
-
73
- ## Usage
74
-
75
- ### Keyboard Shortcuts
76
- - **Ctrl+Q** - Activate feedback mode
77
- - **Esc** - Cancel/deactivate
78
- - **Ctrl+Enter** - Submit feedback (when form is open)
79
89
 
80
- ### Programmatic Activation (Uncontrolled Mode)
81
- Use the `useFeedback` hook to control the widget programmatically:
82
-
83
- ```jsx
84
- import { useFeedback } from 'react-visual-feedback';
90
+ function App() {
91
+ const handleFeedbackSubmit = async (feedbackData) => {
92
+ console.log('Feedback received:', feedbackData);
93
+ await fetch('/api/feedback', {
94
+ method: 'POST',
95
+ headers: { 'Content-Type': 'application/json' },
96
+ body: JSON.stringify(feedbackData)
97
+ });
98
+ };
85
99
 
86
- function MyComponent() {
87
- const { isActive, setIsActive } = useFeedback();
100
+ const handleStatusChange = async ({ id, status }) => {
101
+ console.log('Status changed:', { id, status });
102
+ // Update your database
103
+ await fetch(`/api/feedback/${id}/status`, {
104
+ method: 'PATCH',
105
+ headers: { 'Content-Type': 'application/json' },
106
+ body: JSON.stringify({ status })
107
+ });
108
+ };
88
109
 
89
110
  return (
90
- <button onClick={() => setIsActive(!isActive)}>
91
- {isActive ? 'Cancel Feedback' : 'Give Feedback'}
92
- </button>
111
+ <FeedbackProvider
112
+ onSubmit={handleFeedbackSubmit}
113
+ onStatusChange={handleStatusChange}
114
+ dashboard={true}
115
+ isDeveloper={true} // Set to false for user mode
116
+ userName="John Doe"
117
+ userEmail="john@example.com"
118
+ >
119
+ <YourApp />
120
+ <FeedbackButtons />
121
+ </FeedbackProvider>
93
122
  );
94
123
  }
124
+
125
+ export default App;
95
126
  ```
96
127
 
97
- ### Controlled Mode
98
- You can control the widget's active state from the parent component:
128
+ ## Dashboard Features
99
129
 
100
- ```jsx
101
- import React, { useState } from 'react';
102
- import { FeedbackProvider } from 'react-visual-feedback';
130
+ ### Status Options
103
131
 
104
- function App() {
105
- const [isFeedbackActive, setIsFeedbackActive] = useState(false);
132
+ The dashboard includes 7 professional status options:
106
133
 
107
- const handleFeedbackSubmit = async (feedbackData) => {
108
- console.log('Feedback:', feedbackData);
109
- // Submit to your backend
110
- };
134
+ | Status | Color | Description |
135
+ |--------|-------|-------------|
136
+ | **Reported** 🔴 | Red | Initial feedback submission |
137
+ | **Opened** 🟠 | Amber | Acknowledged and under review |
138
+ | **Doing it** 🔵 | Blue | Actively being worked on |
139
+ | **Resolved** 🟢 | Green | Fixed and ready |
140
+ | **Released** 🟣 | Purple | Deployed to production |
141
+ | **Blocked** 🔴 | Red | Waiting on dependencies |
142
+ | **Won't do** ⚪ | Gray | Not planned for implementation |
111
143
 
112
- return (
113
- <div>
114
- <button onClick={() => setIsFeedbackActive(!isFeedbackActive)}>
115
- {isFeedbackActive ? 'Cancel' : 'Report Bug'}
116
- </button>
144
+ ### Developer vs User Mode
117
145
 
118
- <FeedbackProvider
119
- onSubmit={handleFeedbackSubmit}
120
- isActive={isFeedbackActive}
121
- onActiveChange={setIsFeedbackActive}
122
- >
123
- <YourApp />
124
- </FeedbackProvider>
125
- </div>
126
- );
127
- }
146
+ #### Developer Mode (`isDeveloper={true}`)
147
+ - ✅ View all technical details (element info, CSS, viewport, user agent)
148
+ - ✅ Change feedback status
149
+ - ✅ Delete feedback items
150
+ - ✅ Full control over feedback management
151
+
152
+ #### User Mode (`isDeveloper={false}`)
153
+ - ✅ View feedback submissions
154
+ - ✅ See current status (read-only)
155
+ - ❌ Cannot change status
156
+ - ❌ Cannot delete items
157
+ - Perfect for product managers and stakeholders
158
+
159
+ ### Data Persistence
160
+
161
+ The dashboard supports two modes:
162
+
163
+ 1. **localStorage** (default) - Automatic persistence in browser
164
+ 2. **Custom data source** - Pass your own data via `dashboardData` prop
165
+
166
+ ```jsx
167
+ // Using localStorage (automatic)
168
+ <FeedbackProvider dashboard={true}>
169
+
170
+ // Using custom data source
171
+ <FeedbackProvider
172
+ dashboard={true}
173
+ dashboardData={yourFeedbackArray}
174
+ >
128
175
  ```
129
176
 
130
177
  ## API Reference
131
178
 
132
- ### FeedbackProvider
179
+ ### FeedbackProvider Props
180
+
181
+ | Prop | Type | Required | Default | Description |
182
+ |------|------|----------|---------|-------------|
183
+ | `onSubmit` | `(feedbackData) => Promise<void>` | Yes | - | Callback when feedback is submitted |
184
+ | `onStatusChange` | `({ id, status }) => void` | No | - | Callback when status changes |
185
+ | `children` | `ReactNode` | Yes | - | Your app components |
186
+ | `dashboard` | `boolean` | No | `false` | Enable dashboard feature |
187
+ | `dashboardData` | `Array` | No | `undefined` | Custom feedback data (uses localStorage if undefined) |
188
+ | `isDeveloper` | `boolean` | No | `false` | Enable developer mode with full permissions |
189
+ | `isUser` | `boolean` | No | `true` | Enable user mode (read-only) |
190
+ | `userName` | `string` | No | `'Anonymous'` | User name for feedback submissions |
191
+ | `userEmail` | `string` | No | `null` | User email for feedback submissions |
192
+ | `isActive` | `boolean` | No | `undefined` | Control widget active state (controlled mode) |
193
+ | `onActiveChange` | `(active: boolean) => void` | No | - | Callback when active state changes |
194
+
195
+ ### useFeedback Hook
196
+
197
+ ```jsx
198
+ const { isActive, setIsActive, setIsDashboardOpen } = useFeedback();
199
+ ```
133
200
 
134
- The main provider component that wraps your application.
201
+ **Returns:**
202
+ - `isActive`: `boolean` - Whether feedback mode is active
203
+ - `setIsActive`: `(active: boolean) => void` - Activate/deactivate feedback mode
204
+ - `setIsDashboardOpen`: `(open: boolean) => void` - Open/close dashboard
135
205
 
136
- **Props:**
137
- - `onSubmit` (required): `(feedbackData) => Promise<void>` - Callback function when feedback is submitted
138
- - `children`: React nodes
139
- - `isActive` (optional): `boolean` - Control the widget active state from parent (controlled mode)
140
- - `onActiveChange` (optional): `(active: boolean) => void` - Callback when active state changes (used with controlled mode)
206
+ ### Feedback Data Structure
141
207
 
142
- **Feedback Data Structure:**
143
- ```javascript
208
+ ```typescript
144
209
  {
145
- feedback: "User's feedback text",
210
+ id: string,
211
+ feedback: string,
212
+ userName: string,
213
+ userEmail: string | null,
214
+ status: 'reported' | 'opened' | 'doingIt' | 'resolved' | 'released' | 'blocked' | 'wontDo',
215
+ timestamp: string, // ISO 8601 format
216
+ url: string,
146
217
  elementInfo: {
147
- tagName: "div",
148
- id: "element-id",
149
- className: "element-classes",
150
- selector: "div.card > button.primary",
151
- textContent: "Element text content",
218
+ tagName: string,
219
+ id: string,
220
+ className: string,
221
+ selector: string,
222
+ text: string,
152
223
  position: {
153
- x: 100,
154
- y: 200,
155
- width: 300,
156
- height: 50
224
+ x: number,
225
+ y: number,
226
+ width: number,
227
+ height: number
157
228
  },
158
229
  styles: {
159
- backgroundColor: "rgb(255, 255, 255)",
160
- color: "rgb(0, 0, 0)",
161
- fontSize: "16px",
162
- fontFamily: "Arial, sans-serif"
230
+ backgroundColor: string,
231
+ color: string,
232
+ fontSize: string,
233
+ fontFamily: string
163
234
  }
164
235
  },
165
- screenshot: "data:image/png;base64,...", // Base64 encoded screenshot
166
- url: "https://yourapp.com/current-page",
167
- userAgent: "Mozilla/5.0...",
168
- timestamp: "2025-10-22T10:30:00.000Z"
236
+ screenshot: string, // Base64 encoded PNG
237
+ viewport: {
238
+ width: number,
239
+ height: number
240
+ },
241
+ userAgent: string
169
242
  }
170
243
  ```
171
244
 
172
- ### useFeedback
245
+ ## Keyboard Shortcuts
173
246
 
174
- Hook to access feedback widget state and controls.
247
+ | Shortcut | Action |
248
+ |----------|--------|
249
+ | `Ctrl+Q` | Activate feedback mode |
250
+ | `Ctrl+Shift+Q` | Open dashboard (when dashboard is enabled) |
251
+ | `Esc` | Cancel/close feedback mode or dashboard |
252
+ | `Ctrl+Enter` | Submit feedback (when form is open) |
175
253
 
176
- **Returns:**
177
- - `isActive`: boolean - Whether the widget is currently active
178
- - `setIsActive`: (active: boolean) => void - Function to activate/deactivate the widget
254
+ ## Usage Examples
179
255
 
180
- ## Styling
256
+ ### Example 1: Basic Feedback Collection
257
+
258
+ ```jsx
259
+ import { FeedbackProvider, useFeedback } from 'react-visual-feedback';
260
+ import 'react-visual-feedback/dist/index.css';
181
261
 
182
- The widget comes with default styles, but you can customize them by targeting these CSS classes:
262
+ function FeedbackButton() {
263
+ const { setIsActive } = useFeedback();
264
+ return <button onClick={() => setIsActive(true)}>Report Issue</button>;
265
+ }
183
266
 
184
- ```css
185
- .feedback-overlay { /* Background overlay when active */ }
186
- .feedback-highlight { /* Element highlight border */ }
187
- .feedback-tooltip { /* Element info tooltip */ }
188
- .feedback-modal { /* Feedback form modal */ }
189
- .feedback-backdrop { /* Modal backdrop */ }
190
- .feedback-modal-content { /* Modal content container */ }
191
- .feedback-screenshot { /* Screenshot preview */ }
267
+ function App() {
268
+ return (
269
+ <FeedbackProvider onSubmit={async (data) => {
270
+ await fetch('/api/feedback', {
271
+ method: 'POST',
272
+ body: JSON.stringify(data)
273
+ });
274
+ }}>
275
+ <YourApp />
276
+ <FeedbackButton />
277
+ </FeedbackProvider>
278
+ );
279
+ }
192
280
  ```
193
281
 
194
- ## Example Implementation
282
+ ### Example 2: Full Dashboard with Status Management
195
283
 
196
284
  ```jsx
197
- import React from 'react';
198
- import { FeedbackProvider, useFeedback } from 'react-visual-feedback';
199
- import 'react-visual-feedback/dist/index.css';
285
+ function App() {
286
+ const [isDeveloper, setIsDeveloper] = useState(true);
200
287
 
201
- function FeedbackButton() {
202
- const { isActive, setIsActive } = useFeedback();
288
+ const handleStatusChange = async ({ id, status }) => {
289
+ // Update database
290
+ await fetch(`/api/feedback/${id}`, {
291
+ method: 'PATCH',
292
+ body: JSON.stringify({ status })
293
+ });
294
+ };
203
295
 
204
296
  return (
205
- <button
206
- onClick={() => setIsActive(true)}
207
- style={{
208
- position: 'fixed',
209
- bottom: '20px',
210
- right: '20px',
211
- padding: '12px 24px',
212
- background: isActive ? '#ef4444' : '#3b82f6',
213
- color: 'white',
214
- border: 'none',
215
- borderRadius: '8px',
216
- cursor: 'pointer',
217
- fontWeight: 'bold',
218
- boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)'
219
- }}
297
+ <FeedbackProvider
298
+ dashboard={true}
299
+ isDeveloper={isDeveloper}
300
+ onSubmit={handleFeedbackSubmit}
301
+ onStatusChange={handleStatusChange}
302
+ userName="Jane Smith"
303
+ userEmail="jane@company.com"
220
304
  >
221
- {isActive ? '✕ Cancel' : '💬 Report Issue'}
222
- </button>
305
+ <YourApp />
306
+ </FeedbackProvider>
223
307
  );
224
308
  }
309
+ ```
225
310
 
311
+ ### Example 3: Custom Data Source
312
+
313
+ ```jsx
226
314
  function App() {
227
- const handleFeedbackSubmit = async (feedbackData) => {
228
- try {
229
- const response = await fetch('https://your-api.com/feedback', {
230
- method: 'POST',
231
- headers: { 'Content-Type': 'application/json' },
232
- body: JSON.stringify(feedbackData)
233
- });
315
+ const [feedbackData, setFeedbackData] = useState([]);
234
316
 
235
- if (response.ok) {
236
- alert('Thank you for your feedback!');
237
- }
238
- } catch (error) {
239
- alert('Failed to submit feedback. Please try again.');
240
- }
241
- };
317
+ useEffect(() => {
318
+ // Load feedback from your API
319
+ fetch('/api/feedback')
320
+ .then(res => res.json())
321
+ .then(setFeedbackData);
322
+ }, []);
242
323
 
243
324
  return (
244
- <FeedbackProvider onSubmit={handleFeedbackSubmit}>
245
- <div>
246
- <h1>My Application</h1>
247
- <p>Press Ctrl+Q or click the button to report issues</p>
248
- <FeedbackButton />
249
- </div>
325
+ <FeedbackProvider
326
+ dashboard={true}
327
+ dashboardData={feedbackData}
328
+ isDeveloper={true}
329
+ onStatusChange={async ({ id, status }) => {
330
+ // Update API
331
+ await fetch(`/api/feedback/${id}`, {
332
+ method: 'PATCH',
333
+ body: JSON.stringify({ status })
334
+ });
335
+ // Reload data
336
+ const updated = await fetch('/api/feedback').then(r => r.json());
337
+ setFeedbackData(updated);
338
+ }}
339
+ >
340
+ <YourApp />
250
341
  </FeedbackProvider>
251
342
  );
252
343
  }
344
+ ```
253
345
 
254
- export default App;
346
+ ## Styling
347
+
348
+ The widget comes with default styles, but you can customize them:
349
+
350
+ ```css
351
+ /* Feedback Collection */
352
+ .feedback-overlay { /* Background overlay */ }
353
+ .feedback-highlight { /* Element highlight */ }
354
+ .feedback-tooltip { /* Element info tooltip */ }
355
+ .feedback-modal { /* Feedback form modal */ }
356
+ .feedback-backdrop { /* Modal backdrop */ }
357
+
358
+ /* Dashboard */
359
+ .feedback-dashboard { /* Dashboard container */ }
360
+ .feedback-dashboard-backdrop { /* Dashboard backdrop */ }
255
361
  ```
256
362
 
257
363
  ## How It Works
258
364
 
365
+ ### Feedback Collection Flow
366
+
259
367
  1. User activates the widget (Ctrl+Q or button click)
260
368
  2. User hovers over elements to see them highlighted
261
369
  3. User clicks on the problematic element
262
- 4. Widget captures a pixel-perfect screenshot of the selected element
263
- 5. Feedback form appears with element context pre-filled and large screenshot preview
264
- 6. User enters their feedback and submits (or presses Ctrl+Enter)
265
- 7. Your `onSubmit` handler receives all the data
370
+ 4. Widget captures a pixel-perfect screenshot
371
+ 5. Feedback form appears with context pre-filled
372
+ 6. User enters feedback and submits
373
+ 7. Your `onSubmit` handler receives all data
374
+
375
+ ### Dashboard Flow
376
+
377
+ 1. User opens dashboard (Ctrl+Shift+Q or programmatically)
378
+ 2. Dashboard displays all feedback submissions
379
+ 3. Developer can change status via dropdown
380
+ 4. Status change triggers `onStatusChange` callback
381
+ 5. Your backend updates the database
382
+ 6. Dashboard reflects the new status
266
383
 
267
384
  ## Browser Support
268
385
 
269
- - Chrome/Edge: ✅
270
- - Firefox: ✅
271
- - Safari: ✅
272
- - Opera: ✅
386
+ - Chrome/Edge
387
+ - Firefox
388
+ - Safari
389
+ - Opera
273
390
 
274
391
  ## Screenshot Capture
275
392
 
276
- The widget uses `html-to-image` library for accurate screenshot capture with fallback to `html2canvas`. This ensures:
277
- - Perfect CSS rendering including Tailwind, Bootstrap, and custom styles
278
- - Accurate colors, fonts, and layout
279
- - Support for gradients, shadows, and modern CSS features
280
- - High-resolution screenshots (2x pixel ratio)
393
+ Uses `html-to-image` with `html2canvas` fallback for:
394
+ - Perfect CSS rendering
395
+ - Tailwind, Bootstrap, Material-UI support
396
+ - Gradients, shadows, modern CSS
397
+ - High-resolution (2x pixel ratio)
281
398
 
282
399
  ## Dependencies
283
400
 
284
401
  - React ^16.8.0 || ^17.0.0 || ^18.0.0
285
402
  - react-dom ^16.8.0 || ^17.0.0 || ^18.0.0
286
403
  - html-to-image ^1.11.13
287
- - html2canvas ^1.4.1 (fallback)
404
+ - html2canvas ^1.4.1
288
405
  - lucide-react ^0.263.1
289
406
 
290
- ## Local Development & Testing
291
-
292
- Want to test the widget locally? We've included a complete example app!
293
-
294
- ### Quick Start
407
+ ## Local Development
295
408
 
296
409
  ```bash
297
- # 1. Clone the repository
410
+ # Clone repository
298
411
  git clone https://github.com/Murali1889/react-feedback-widget.git
299
412
  cd react-feedback-widget
300
413
 
301
- # 2. Install dependencies
414
+ # Install dependencies
302
415
  npm install
303
416
 
304
- # 3. Build the widget
417
+ # Build the widget
305
418
  npm run build
306
419
 
307
- # 4. Run the example app
420
+ # Run example app
308
421
  cd example
309
422
  npm install
310
423
  npm run dev
311
424
  ```
312
425
 
313
- The example app will open at `http://localhost:8080` with a fully working demo!
314
-
315
- ### What's Included
316
-
317
- - ✅ Complete working example with Tailwind CSS
318
- - ✅ Both light and dark mode support
319
- - ✅ Controlled and uncontrolled mode examples
320
- - ✅ Interactive test elements (buttons, forms, cards, gradients)
321
- - ✅ Console logging to see feedback data
322
- - ✅ Hot reload for fast development
426
+ Visit `http://localhost:8080` to see the demo!
323
427
 
324
- ### Making Changes
428
+ ## What's New in v1.2.0
325
429
 
326
- 1. Edit source files in `src/`
327
- 2. Run `npm run build` in the root directory
328
- 3. Refresh the example app browser - changes will be reflected!
430
+ ### Dashboard Feature
431
+ - 📊 Complete feedback management dashboard
432
+ - 👨‍💻 Developer/User mode with permission system
433
+ - 🏷️ 7 professional status options with custom dropdown
434
+ - 🔄 Status change callbacks for database sync
435
+ - 💾 localStorage or custom data source support
436
+ - 📅 Improved timestamp formatting (e.g., "21 Oct 2025 at 9:35 PM")
329
437
 
330
- See `example/README.md` for more details.
438
+ ### UI Improvements
439
+ - ✨ Smooth animations for status dropdown
440
+ - 🎨 Professional minimal design
441
+ - 🔒 Read-only status for users
442
+ - 🗑️ Conditional delete permissions
331
443
 
332
444
  ## License
333
445
 
334
- MIT © 2025 Murali
446
+ MIT © 2025 Murali Vvrsn Gurajapu
335
447
 
336
448
  ## Contributing
337
449
 
338
- Contributions are welcome! Please feel free to submit a Pull Request.
450
+ Contributions welcome! Please submit a Pull Request.
339
451
 
340
452
  ## Issues
341
453
 
342
- If you encounter any issues, please report them at:
343
- https://github.com/Murali1889/react-feedback-widget/issues
454
+ Report issues at: https://github.com/Murali1889/react-feedback-widget/issues
344
455
 
345
456
  ## Author
346
457