Feedback widget plugin for Patch-Adams - inject a feedback form into Rise courses
npm install @patch-adams/plugin-feedbackA feedback widget plugin for Patch-Adams that injects a customizable feedback form into Rise courses.
- Star rating (configurable 3-10 stars)
- Issue type dropdown with subtypes
- Comment field with character counter
- Auto-detects language from or attribute
- Live language switching (English/French)
- Submits to configurable endpoint
- Fully customizable appearance and behavior
``bash`
npm install @patch-adams/plugin-feedback
Configure the feedback plugin in your patch configuration:
`typescript
import { patchCourse } from '@patch-adams/core';
import feedbackPlugin from '@patch-adams/plugin-feedback';
const result = await patchCourse(courseZip, {
plugins: {
feedback: {
enabled: true,
tabText: 'Feedback',
tabColor: '#da291c',
position: 'right',
endpoint: 'https://api.example.com/feedback',
showRating: true,
showIssueType: true,
showComment: true,
},
},
});
`
The widget automatically detects the language from the HTML document:
1. Checks attribute
2. Falls back to
attribute
3. Falls back to config.locale value
4. Defaults to EnglishLanguage variants are normalized:
fr-CA → fr, en-US → enLive switching: If the
lang attribute changes at runtime (e.g., via JavaScript or DevTools), the widget automatically re-renders with the new language.Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
|
enabled | boolean | true | Enable/disable the plugin |
| endpoint | string | - | URL to POST feedback data |
| method | 'POST' \| 'PUT' | 'POST' | HTTP method |
| headers | object | - | Additional headers for the request |
| position | 'left' \| 'right' | 'right' | Tab position |
| tabText | string | 'Feedback' | Text on the tab button |
| tabColor | string | '#da291c' | Tab background color |
| tabTextColor | string | '#ffffff' | Tab text color |
| zIndex | number | 9999 | Widget z-index |
| showRating | boolean | true | Show star rating |
| ratingRequired | boolean | false | Require rating to submit |
| ratingStars | number | 5 | Number of stars (3-10) |
| showIssueType | boolean | true | Show issue type dropdown |
| issueTypeRequired | boolean | false | Require issue type |
| issueTypes | array | default types | Custom issue types |
| showComment | boolean | true | Show comment field |
| commentRequired | boolean | false | Require comment |
| commentMaxLength | number | 500 | Max comment length |
| locale | 'en' \| 'fr' | 'en' | Default locale (auto-detected at runtime) |
| translations | object | - | Custom translation overrides |
| autoClose | boolean | true | Auto-close after success |
| autoCloseDelay | number | 2000 | Delay before auto-close (ms) |
| debug | boolean | false | Enable debug logging |
| includeMetadata | object | all true | What metadata to include |Custom Issue Types
`typescript
{
issueTypes: [
{
id: 'content',
label: 'Content Issue',
subtypes: [
{ id: 'typo', label: 'Typo / Grammar' },
{ id: 'incorrect', label: 'Incorrect Information' },
],
},
{
id: 'technical',
label: 'Technical Issue',
},
{
id: 'other',
label: 'Other',
},
],
}
`Metadata
By default, feedback submissions include:
-
courseId - From data-pa-course-id attribute on
- courseTitle - From LRS bridge if available
- lessonId - Current URL hash or pathname
- userAgent - Browser user agent
- timestamp - ISO 8601 timestamp
- url - Current page URLSubmitted Data Format
`json
{
"rating": 4,
"issueType": "content",
"issueSubtype": "typo",
"comment": "Found a typo on slide 3",
"metadata": {
"courseId": "course-123",
"courseTitle": "Safety Training",
"lessonId": "#/lessons/intro",
"userAgent": "Mozilla/5.0...",
"timestamp": "2024-01-15T10:30:00.000Z",
"url": "https://example.com/course/#/lessons/intro"
}
}
``MIT