react-visual-feedback 1.1.0 → 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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Murali
3
+ Copyright (c) 2025 Murali Vvrsn Gurajapu
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,36 +1,48 @@
1
- # Murali Feedback Widget React
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
- - 📸 Automatic screenshot capture of selected elements
9
+ - 📸 Automatic screenshot capture of selected elements with perfect CSS rendering
9
10
  - 📝 Feedback form with rich context
10
11
  - ⚡ Lightweight and performant
11
- - 🎨 Customizable styling
12
- - ⌨️ Keyboard shortcuts (Ctrl+Q to activate, Esc to cancel)
12
+ - 🎨 Works with any CSS framework (Tailwind, Bootstrap, Material-UI, etc.)
13
+ - ⌨️ Keyboard shortcuts (Ctrl+Q to activate, Esc to cancel, Ctrl+Enter to submit)
14
+ - 🌓 Dark mode support
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)
13
25
 
14
26
  ## Installation
15
27
 
16
28
  ```bash
17
- npm install murali-feedback-widget-react
29
+ npm install react-visual-feedback
18
30
  ```
19
31
 
20
32
  **Important:** Import the CSS file in your application:
21
33
 
22
34
  ```jsx
23
- import 'murali-feedback-widget-react/dist/index.css';
35
+ import 'react-visual-feedback/dist/index.css';
24
36
  ```
25
37
 
26
38
  ## Quick Start
27
39
 
28
- ### 1. Wrap your app with FeedbackProvider
40
+ ### Basic Usage (Feedback Only)
29
41
 
30
42
  ```jsx
31
43
  import React from 'react';
32
- import { FeedbackProvider } from 'murali-feedback-widget-react';
33
- import 'murali-feedback-widget-react/dist/index.css';
44
+ import { FeedbackProvider } from 'react-visual-feedback';
45
+ import 'react-visual-feedback/dist/index.css';
34
46
 
35
47
  function App() {
36
48
  const handleFeedbackSubmit = async (feedbackData) => {
@@ -53,269 +65,399 @@ function App() {
53
65
  export default App;
54
66
  ```
55
67
 
56
- ### 2. Add a feedback trigger button (optional)
68
+ ### With Dashboard (Full Feature Set)
57
69
 
58
70
  ```jsx
59
- import { useFeedback } from 'murali-feedback-widget-react';
71
+ import React from 'react';
72
+ import { FeedbackProvider, useFeedback } from 'react-visual-feedback';
73
+ import 'react-visual-feedback/dist/index.css';
60
74
 
61
- function FeedbackButton() {
62
- const { setIsActive } = useFeedback();
75
+ function FeedbackButtons() {
76
+ const { isActive, setIsActive, setIsDashboardOpen } = useFeedback();
63
77
 
64
78
  return (
65
- <button onClick={() => setIsActive(true)}>
66
- Report Issue
67
- </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>
68
87
  );
69
88
  }
70
- ```
71
89
 
72
- ## Usage
73
-
74
- ### Keyboard Shortcut
75
- Press **Ctrl+Q** to activate the feedback widget. Press **Esc** to deactivate.
76
-
77
- ### Programmatic Activation (Uncontrolled Mode)
78
- Use the `useFeedback` hook to control the widget programmatically:
79
-
80
- ```jsx
81
- import { useFeedback } from 'murali-feedback-widget-react';
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
+ };
82
99
 
83
- function MyComponent() {
84
- 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
+ };
85
109
 
86
110
  return (
87
- <button onClick={() => setIsActive(!isActive)}>
88
- {isActive ? 'Cancel Feedback' : 'Give Feedback'}
89
- </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>
90
122
  );
91
123
  }
124
+
125
+ export default App;
92
126
  ```
93
127
 
94
- ### Controlled Mode
95
- You can control the widget's active state from the parent component:
128
+ ## Dashboard Features
96
129
 
97
- ```jsx
98
- import React, { useState } from 'react';
99
- import { FeedbackProvider } from 'murali-feedback-widget-react';
130
+ ### Status Options
100
131
 
101
- function App() {
102
- const [isFeedbackActive, setIsFeedbackActive] = useState(false);
132
+ The dashboard includes 7 professional status options:
103
133
 
104
- const handleFeedbackSubmit = async (feedbackData) => {
105
- console.log('Feedback:', feedbackData);
106
- // Submit to your backend
107
- };
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 |
108
143
 
109
- return (
110
- <div>
111
- <button onClick={() => setIsFeedbackActive(!isFeedbackActive)}>
112
- {isFeedbackActive ? 'Cancel' : 'Report Bug'}
113
- </button>
144
+ ### Developer vs User Mode
114
145
 
115
- <FeedbackProvider
116
- onSubmit={handleFeedbackSubmit}
117
- isActive={isFeedbackActive}
118
- onActiveChange={setIsFeedbackActive}
119
- >
120
- <YourApp />
121
- </FeedbackProvider>
122
- </div>
123
- );
124
- }
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
+ >
125
175
  ```
126
176
 
127
177
  ## API Reference
128
178
 
129
- ### 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 |
130
194
 
131
- The main provider component that wraps your application.
195
+ ### useFeedback Hook
196
+
197
+ ```jsx
198
+ const { isActive, setIsActive, setIsDashboardOpen } = useFeedback();
199
+ ```
200
+
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
132
205
 
133
- **Props:**
134
- - `onSubmit` (required): `(feedbackData) => Promise<void>` - Callback function when feedback is submitted
135
- - `children`: React nodes
136
- - `isActive` (optional): `boolean` - Control the widget active state from parent (controlled mode)
137
- - `onActiveChange` (optional): `(active: boolean) => void` - Callback when active state changes (used with controlled mode)
206
+ ### Feedback Data Structure
138
207
 
139
- **Feedback Data Structure:**
140
- ```javascript
208
+ ```typescript
141
209
  {
142
- 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,
143
217
  elementInfo: {
144
- tagName: "div",
145
- id: "element-id",
146
- className: "element-classes",
147
- xpath: "//div[@id='element-id']",
148
- innerText: "Element text content",
149
- attributes: { /* element attributes */ }
218
+ tagName: string,
219
+ id: string,
220
+ className: string,
221
+ selector: string,
222
+ text: string,
223
+ position: {
224
+ x: number,
225
+ y: number,
226
+ width: number,
227
+ height: number
228
+ },
229
+ styles: {
230
+ backgroundColor: string,
231
+ color: string,
232
+ fontSize: string,
233
+ fontFamily: string
234
+ }
235
+ },
236
+ screenshot: string, // Base64 encoded PNG
237
+ viewport: {
238
+ width: number,
239
+ height: number
150
240
  },
151
- screenshot: "data:image/png;base64,...", // Base64 encoded screenshot
152
- url: "https://yourapp.com/current-page",
153
- userAgent: "Mozilla/5.0...",
154
- timestamp: "2025-10-22T10:30:00.000Z"
241
+ userAgent: string
155
242
  }
156
243
  ```
157
244
 
158
- ### useFeedback
245
+ ## Keyboard Shortcuts
159
246
 
160
- 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) |
161
253
 
162
- **Returns:**
163
- - `isActive`: boolean - Whether the widget is currently active
164
- - `setIsActive`: (active: boolean) => void - Function to activate/deactivate the widget
254
+ ## Usage Examples
165
255
 
166
- ## Styling
256
+ ### Example 1: Basic Feedback Collection
167
257
 
168
- The widget comes with default styles, but you can customize them by targeting these CSS classes:
258
+ ```jsx
259
+ import { FeedbackProvider, useFeedback } from 'react-visual-feedback';
260
+ import 'react-visual-feedback/dist/index.css';
169
261
 
170
- ```css
171
- .feedback-overlay { /* Background overlay when active */ }
172
- .feedback-highlight { /* Element highlight border */ }
173
- .feedback-tooltip { /* Element info tooltip */ }
174
- .feedback-modal { /* Feedback form modal */ }
175
- .feedback-backdrop { /* Modal backdrop */ }
262
+ function FeedbackButton() {
263
+ const { setIsActive } = useFeedback();
264
+ return <button onClick={() => setIsActive(true)}>Report Issue</button>;
265
+ }
266
+
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
+ }
176
280
  ```
177
281
 
178
- ## Example Implementation
282
+ ### Example 2: Full Dashboard with Status Management
179
283
 
180
284
  ```jsx
181
- import React from 'react';
182
- import { FeedbackProvider, useFeedback } from 'murali-feedback-widget-react';
285
+ function App() {
286
+ const [isDeveloper, setIsDeveloper] = useState(true);
183
287
 
184
- function FeedbackButton() {
185
- 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
+ };
186
295
 
187
296
  return (
188
- <button
189
- onClick={() => setIsActive(true)}
190
- style={{
191
- position: 'fixed',
192
- bottom: '20px',
193
- right: '20px',
194
- padding: '10px 20px',
195
- background: '#007bff',
196
- color: 'white',
197
- border: 'none',
198
- borderRadius: '5px',
199
- cursor: 'pointer'
200
- }}
297
+ <FeedbackProvider
298
+ dashboard={true}
299
+ isDeveloper={isDeveloper}
300
+ onSubmit={handleFeedbackSubmit}
301
+ onStatusChange={handleStatusChange}
302
+ userName="Jane Smith"
303
+ userEmail="jane@company.com"
201
304
  >
202
- {isActive ? 'Select Element...' : 'Report Bug'}
203
- </button>
305
+ <YourApp />
306
+ </FeedbackProvider>
204
307
  );
205
308
  }
309
+ ```
310
+
311
+ ### Example 3: Custom Data Source
206
312
 
313
+ ```jsx
207
314
  function App() {
208
- const handleFeedbackSubmit = async (feedbackData) => {
209
- try {
210
- const response = await fetch('https://your-api.com/feedback', {
211
- method: 'POST',
212
- headers: { 'Content-Type': 'application/json' },
213
- body: JSON.stringify(feedbackData)
214
- });
315
+ const [feedbackData, setFeedbackData] = useState([]);
215
316
 
216
- if (response.ok) {
217
- alert('Thank you for your feedback!');
218
- }
219
- } catch (error) {
220
- console.error('Failed to submit feedback:', error);
221
- alert('Failed to submit feedback. Please try again.');
222
- }
223
- };
317
+ useEffect(() => {
318
+ // Load feedback from your API
319
+ fetch('/api/feedback')
320
+ .then(res => res.json())
321
+ .then(setFeedbackData);
322
+ }, []);
224
323
 
225
324
  return (
226
- <FeedbackProvider onSubmit={handleFeedbackSubmit}>
227
- <div>
228
- <h1>My Application</h1>
229
- <p>Press Ctrl+Q or click the button to report issues</p>
230
- <FeedbackButton />
231
- </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 />
232
341
  </FeedbackProvider>
233
342
  );
234
343
  }
344
+ ```
235
345
 
236
- 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 */ }
237
361
  ```
238
362
 
239
363
  ## How It Works
240
364
 
365
+ ### Feedback Collection Flow
366
+
241
367
  1. User activates the widget (Ctrl+Q or button click)
242
368
  2. User hovers over elements to see them highlighted
243
369
  3. User clicks on the problematic element
244
- 4. Widget captures a screenshot of the selected element
245
- 5. Feedback form appears with element context pre-filled
246
- 6. User enters their feedback and submits
247
- 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
248
383
 
249
384
  ## Browser Support
250
385
 
251
- - Chrome/Edge: ✅
252
- - Firefox: ✅
253
- - Safari: ✅
254
- - Opera: ✅
386
+ - Chrome/Edge
387
+ - Firefox
388
+ - Safari
389
+ - Opera
390
+
391
+ ## Screenshot Capture
255
392
 
256
- Requires `html2canvas` for screenshot functionality.
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)
257
398
 
258
399
  ## Dependencies
259
400
 
260
401
  - React ^16.8.0 || ^17.0.0 || ^18.0.0
261
402
  - react-dom ^16.8.0 || ^17.0.0 || ^18.0.0
403
+ - html-to-image ^1.11.13
262
404
  - html2canvas ^1.4.1
263
405
  - lucide-react ^0.263.1
264
406
 
265
- ## Local Development & Testing
266
-
267
- Want to test the widget locally? We've included a complete example app!
268
-
269
- ### Quick Start
407
+ ## Local Development
270
408
 
271
409
  ```bash
272
- # 1. Clone the repository
410
+ # Clone repository
273
411
  git clone https://github.com/Murali1889/react-feedback-widget.git
274
412
  cd react-feedback-widget
275
413
 
276
- # 2. Install dependencies
414
+ # Install dependencies
277
415
  npm install
278
416
 
279
- # 3. Build the widget
417
+ # Build the widget
280
418
  npm run build
281
419
 
282
- # 4. Run the example app
420
+ # Run example app
283
421
  cd example
284
422
  npm install
285
423
  npm run dev
286
424
  ```
287
425
 
288
- The example app will open at `http://localhost:3000` with a fully working demo!
289
-
290
- ### What's Included
426
+ Visit `http://localhost:8080` to see the demo!
291
427
 
292
- - Complete working example with UI
293
- - ✅ Both controlled and uncontrolled mode examples
294
- - ✅ Interactive test elements (buttons, forms, images)
295
- - ✅ Console logging to see feedback data
296
- - ✅ Hot reload for fast development
428
+ ## What's New in v1.2.0
297
429
 
298
- ### Making Changes
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")
299
437
 
300
- 1. Edit source files in `src/`
301
- 2. Run `npm run build` in the root directory
302
- 3. Refresh the example app browser - changes will be reflected!
303
-
304
- 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
305
443
 
306
444
  ## License
307
445
 
308
- MIT © Murali
446
+ MIT © 2025 Murali Vvrsn Gurajapu
309
447
 
310
448
  ## Contributing
311
449
 
312
- Contributions are welcome! Please feel free to submit a Pull Request.
450
+ Contributions welcome! Please submit a Pull Request.
313
451
 
314
452
  ## Issues
315
453
 
316
- If you encounter any issues, please report them at:
317
- https://github.com/Murali1889/react-feedback-widget/issues
454
+ Report issues at: https://github.com/Murali1889/react-feedback-widget/issues
318
455
 
319
456
  ## Author
320
457
 
321
- Murali
458
+ **Murali**
459
+ Email: murali.g@hyperverge.co
460
+
461
+ ---
462
+
463
+ Made with ❤️ for better user feedback collection