@namphuongtechnologi/np-hub 0.1.9 → 0.1.11
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 +194 -74
- package/dist/{chunk-6R272D5G.js → chunk-Y7JSRJAC.js} +274 -68
- package/dist/chunk-Y7JSRJAC.js.map +1 -0
- package/dist/index.cjs +273 -67
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/np-hub.min.global.js +210 -14
- package/dist/react.cjs +286 -70
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +11 -2
- package/dist/react.d.ts +11 -2
- package/dist/react.js +14 -4
- package/dist/react.js.map +1 -1
- package/dist/register.cjs +273 -67
- package/dist/register.cjs.map +1 -1
- package/dist/register.js +1 -1
- package/dist/{support-widget.element-ZfHBgoIV.d.cts → support-widget.element-ByuF6TAw.d.cts} +10 -2
- package/dist/{support-widget.element-ZfHBgoIV.d.ts → support-widget.element-ByuF6TAw.d.ts} +10 -2
- package/docs/DEVELOPER_GUIDE.md +123 -93
- package/docs/PUBLIC_RELEASE.md +63 -45
- package/docs/USAGE_STATIC_REACT.md +178 -9
- package/package.json +1 -1
- package/dist/chunk-6R272D5G.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,24 +1,55 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @namphuongtechnologi/np-hub
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Floating support widget for Nam Phương So applications. Drop it into any static site or React app — users open a form, submit a support request, and the request is sent to the Nam Phương API.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@namphuongtechnologi/np-hub)
|
|
6
|
+
[](./LICENSE)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **Web Component** (`<np-hub>`) — works in plain HTML and most frameworks
|
|
13
|
+
- **React wrapper** — typed `SupportWidget` component
|
|
14
|
+
- **Drag-and-drop launcher** — position persists in `localStorage`
|
|
15
|
+
- **Form prefill** — optional user / content / attachment seeding; required fields still validated on submit
|
|
16
|
+
- **Submit feedback toast** — centered popup on success or API error; auto-closes or user can dismiss
|
|
17
|
+
- **Environment switch** — Production by default; Development via `isDev` / `is-dev`
|
|
4
18
|
|
|
5
19
|
---
|
|
6
20
|
|
|
7
|
-
##
|
|
21
|
+
## Installation
|
|
8
22
|
|
|
9
|
-
|
|
23
|
+
```bash
|
|
24
|
+
npm install @namphuongtechnologi/np-hub
|
|
25
|
+
```
|
|
10
26
|
|
|
11
|
-
|
|
27
|
+
**CDN (static HTML, no npm):**
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
https://cdn.jsdelivr.net/npm/@namphuongtechnologi/np-hub@0.1.9/dist/np-hub.min.global.js
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Quick start
|
|
36
|
+
|
|
37
|
+
### Static HTML
|
|
38
|
+
|
|
39
|
+
Create a config script, then include it once in your page.
|
|
40
|
+
|
|
41
|
+
**`np-hub.js`**
|
|
12
42
|
|
|
13
43
|
```js
|
|
14
44
|
var NP_HUB_CDN =
|
|
15
|
-
"https://cdn.jsdelivr.net/npm/@namphuongtechnologi/np-hub@0.1.
|
|
45
|
+
"https://cdn.jsdelivr.net/npm/@namphuongtechnologi/np-hub@0.1.9/dist/np-hub.min.global.js";
|
|
16
46
|
|
|
17
47
|
function initNpHub() {
|
|
18
48
|
var widget = document.createElement("np-hub");
|
|
49
|
+
|
|
19
50
|
widget.setConfig({
|
|
20
51
|
projectId: "NPP",
|
|
21
|
-
isDev:
|
|
52
|
+
isDev: false,
|
|
22
53
|
priority: 0,
|
|
23
54
|
coordinators: [],
|
|
24
55
|
emailContacts: [],
|
|
@@ -26,25 +57,12 @@ function initNpHub() {
|
|
|
26
57
|
|
|
27
58
|
document.body.appendChild(widget);
|
|
28
59
|
|
|
29
|
-
// Optional khi config — chỉ prefill; form UI vẫn bắt buộc nhập
|
|
30
|
-
// widget.setUser({
|
|
31
|
-
// name: "Nguyen Van A",
|
|
32
|
-
// email: "a@gmail.com",
|
|
33
|
-
// phoneNumber: "0912345678",
|
|
34
|
-
// });
|
|
35
|
-
|
|
36
|
-
// Optional khi config — chỉ prefill nội dung/file
|
|
37
|
-
// widget.setFormPrefill({
|
|
38
|
-
// content: "Mô tả sự cố cần hỗ trợ...",
|
|
39
|
-
// attachments: [],
|
|
40
|
-
// });
|
|
41
|
-
|
|
42
60
|
widget.addEventListener("np-hub-submit-success", function (event) {
|
|
43
|
-
console.log("
|
|
61
|
+
console.log("Support request created:", event.detail);
|
|
44
62
|
});
|
|
45
63
|
|
|
46
64
|
widget.addEventListener("np-hub-submit-error", function (event) {
|
|
47
|
-
console.error("
|
|
65
|
+
console.error("Support request failed:", event.detail);
|
|
48
66
|
});
|
|
49
67
|
}
|
|
50
68
|
|
|
@@ -54,7 +72,7 @@ script.onload = initNpHub;
|
|
|
54
72
|
document.head.appendChild(script);
|
|
55
73
|
```
|
|
56
74
|
|
|
57
|
-
**`index.html`**
|
|
75
|
+
**`index.html`**
|
|
58
76
|
|
|
59
77
|
```html
|
|
60
78
|
<!doctype html>
|
|
@@ -70,17 +88,11 @@ document.head.appendChild(script);
|
|
|
70
88
|
</html>
|
|
71
89
|
```
|
|
72
90
|
|
|
73
|
-
|
|
91
|
+
Full example: [`examples/static-html/`](./examples/static-html/).
|
|
74
92
|
|
|
75
|
-
|
|
93
|
+
### React
|
|
76
94
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
npm install @namphuongtechnologi/np-hub
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
Import `SupportWidget` và đặt **một lần** ở root app (ví dụ `App.tsx`, `main.tsx` hoặc root layout):
|
|
95
|
+
Mount **once** at the application root (`App.tsx`, `main.tsx`, or root layout).
|
|
84
96
|
|
|
85
97
|
```tsx
|
|
86
98
|
import { SupportWidget } from "@namphuongtechnologi/np-hub/react";
|
|
@@ -88,65 +100,173 @@ import { SupportWidget } from "@namphuongtechnologi/np-hub/react";
|
|
|
88
100
|
export default function App() {
|
|
89
101
|
return (
|
|
90
102
|
<>
|
|
91
|
-
{/*
|
|
103
|
+
{/* app content */}
|
|
92
104
|
<SupportWidget
|
|
93
105
|
projectId="NPP"
|
|
94
|
-
isDev
|
|
106
|
+
isDev={false}
|
|
95
107
|
priority={0}
|
|
96
108
|
coordinators={[]}
|
|
97
109
|
emailContacts={[]}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
// name: "Nguyen Van A",
|
|
101
|
-
// email: "a@gmail.com",
|
|
102
|
-
// phoneNumber: "0912345678",
|
|
103
|
-
// }}
|
|
104
|
-
// formPrefill={{
|
|
105
|
-
// content: "Mô tả sự cố cần hỗ trợ...",
|
|
106
|
-
// attachments: [],
|
|
107
|
-
// }}
|
|
108
|
-
onSubmitSuccess={(detail) => console.log("Thành công:", detail)}
|
|
109
|
-
onSubmitError={(error) => console.error("Lỗi:", error)}
|
|
110
|
+
onSubmitSuccess={(detail) => console.log("Success:", detail)}
|
|
111
|
+
onSubmitError={(error) => console.error("Error:", error)}
|
|
110
112
|
/>
|
|
111
113
|
</>
|
|
112
114
|
);
|
|
113
115
|
}
|
|
114
116
|
```
|
|
115
117
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
|
123
|
-
|
|
|
124
|
-
| `
|
|
125
|
-
| `
|
|
126
|
-
| `
|
|
127
|
-
| `
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Configuration
|
|
121
|
+
|
|
122
|
+
### `setConfig` / React props
|
|
123
|
+
|
|
124
|
+
| Name | Required | Default | Description |
|
|
125
|
+
| --------------- | -------- | ------------- | ------------------------------------------------ |
|
|
126
|
+
| `projectId` | No | — | Project code forwarded to the API |
|
|
127
|
+
| `isDev` | No | `false` | `true` → Development API; otherwise Production |
|
|
128
|
+
| `priority` | No | `0` | Request priority |
|
|
129
|
+
| `coordinators` | No | `[]` | Coordinator email list |
|
|
130
|
+
| `emailContacts` | No | `[]` | Contact emails that receive the notification |
|
|
131
|
+
| `toastDuration` | No | `4000` | Toast auto-close delay in milliseconds |
|
|
132
|
+
|
|
133
|
+
### Prefill (optional)
|
|
134
|
+
|
|
135
|
+
| Name | Method / prop | Description |
|
|
136
|
+
| ------------- | ----------------- | --------------------------------------------------------------------------- |
|
|
137
|
+
| User | `setUser` / `user` | Prefills name, email, phone. Form UI still requires these fields on submit. |
|
|
138
|
+
| Form content | `setFormPrefill` / `formPrefill` | Prefills `content` and `attachments`. |
|
|
139
|
+
|
|
140
|
+
```js
|
|
141
|
+
// Web Component
|
|
142
|
+
widget.setUser({
|
|
143
|
+
name: "Nguyen Van A",
|
|
144
|
+
email: "a@example.com",
|
|
145
|
+
phoneNumber: "0912345678",
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
widget.setFormPrefill({
|
|
149
|
+
content: "Describe the issue...",
|
|
150
|
+
attachments: [],
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
// React
|
|
156
|
+
<SupportWidget
|
|
157
|
+
projectId="NPP"
|
|
158
|
+
user={{
|
|
159
|
+
name: "Nguyen Van A",
|
|
160
|
+
email: "a@example.com",
|
|
161
|
+
phoneNumber: "0912345678",
|
|
162
|
+
}}
|
|
163
|
+
formPrefill={{
|
|
164
|
+
content: "Describe the issue...",
|
|
165
|
+
attachments: [],
|
|
166
|
+
}}
|
|
167
|
+
/>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Launcher size & position
|
|
171
|
+
|
|
172
|
+
Default: **65×65px**, anchored **20px** from the bottom-right corner.
|
|
173
|
+
|
|
174
|
+
| Attribute / prop | Description |
|
|
175
|
+
| ---------------------- | ------------------------------------------------ |
|
|
176
|
+
| `width` / `height` | Launcher size (default `65`) |
|
|
177
|
+
| `right` / `bottom` | Offset from bottom-right (default `20`) |
|
|
178
|
+
| `left` / `top` | Use instead of `right` / `bottom` for other corners |
|
|
179
|
+
|
|
180
|
+
Numeric values from React props are treated as pixels. After the user drags the launcher, the stored `localStorage` position takes precedence.
|
|
181
|
+
|
|
182
|
+
```js
|
|
183
|
+
widget.setAttribute("right", "24");
|
|
184
|
+
widget.setAttribute("bottom", "24");
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
```tsx
|
|
188
|
+
<SupportWidget projectId="NPP" right={24} bottom={24} />
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Submit feedback toast
|
|
192
|
+
|
|
193
|
+
After a successful API submit or an API/exception failure, the widget shows a **centered toast** with the result message.
|
|
194
|
+
|
|
195
|
+
| Behavior | Detail |
|
|
196
|
+
| -------- | ------ |
|
|
197
|
+
| When shown | Submit success, or API / runtime error |
|
|
198
|
+
| When hidden | Missing required fields (only inline field highlighting) |
|
|
199
|
+
| Auto-close | After `toastDuration` ms (default `4000`) |
|
|
200
|
+
| Manual close | User can dismiss via the `×` button |
|
|
201
|
+
| Success follow-up | Modal closes automatically ~1.2s after success |
|
|
202
|
+
|
|
203
|
+
```js
|
|
204
|
+
widget.setConfig({
|
|
205
|
+
projectId: "NPP",
|
|
206
|
+
toastDuration: 6000, // auto-close after 6 seconds
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
<SupportWidget projectId="NPP" toastDuration={6000} />
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Events & methods
|
|
217
|
+
|
|
218
|
+
### Events (Web Component)
|
|
219
|
+
|
|
220
|
+
| Event | When |
|
|
221
|
+
| ----------------------- | --------------------------------- |
|
|
222
|
+
| `np-hub-open` | Modal opens |
|
|
223
|
+
| `np-hub-close` | Modal closes |
|
|
224
|
+
| `np-hub-submit-success` | API accepted the support request |
|
|
225
|
+
| `np-hub-submit-error` | Validation or API failure |
|
|
226
|
+
|
|
227
|
+
React equivalent props: `onOpen`, `onClose`, `onSubmitSuccess`, `onSubmitError`.
|
|
228
|
+
|
|
229
|
+
### Methods (Web Component)
|
|
230
|
+
|
|
231
|
+
| Method | Description |
|
|
232
|
+
| ---------------------- | ------------------------------ |
|
|
233
|
+
| `setConfig(config)` | Apply project / API settings |
|
|
234
|
+
| `setUser(user)` | Prefill requester fields |
|
|
235
|
+
| `setFormPrefill(data)` | Prefill content / attachments |
|
|
236
|
+
| `open()` / `close()` | Open or close the modal |
|
|
131
237
|
|
|
132
238
|
---
|
|
133
239
|
|
|
134
|
-
##
|
|
240
|
+
## API environments
|
|
241
|
+
|
|
242
|
+
| Environment | Base URL |
|
|
243
|
+
| ----------------------------------- | ------------------------------------------------- |
|
|
244
|
+
| Production (default) | `https://namphuong-api.azurewebsites.net` |
|
|
245
|
+
| Development (`isDev` / `is-dev`) | `https://namphuong-api-dev.azurewebsites.net` |
|
|
135
246
|
|
|
136
|
-
|
|
137
|
-
| -------------------------------- | --------------------------------------------- |
|
|
138
|
-
| Production (mặc định) | `https://namphuong-api.azurewebsites.net` |
|
|
139
|
-
| Development (`is-dev` / `isDev`) | `https://namphuong-api-dev.azurewebsites.net` |
|
|
247
|
+
---
|
|
140
248
|
|
|
141
|
-
##
|
|
249
|
+
## Troubleshooting
|
|
142
250
|
|
|
143
|
-
|
|
|
144
|
-
|
|
|
145
|
-
| `projectId cannot be empty.`
|
|
146
|
-
| `user.name/email/phoneNumber is required.`
|
|
147
|
-
| `Content is required.`
|
|
148
|
-
|
|
|
251
|
+
| Error | Resolution |
|
|
252
|
+
| ---------------------------------------------- | -------------------------------------------------------------------------- |
|
|
253
|
+
| `projectId cannot be empty.` | If provided, `projectId` / `project-id` must be a non-empty string |
|
|
254
|
+
| `user.name/email/phoneNumber is required.` | Requester fields are required on submit; `user` only prefills |
|
|
255
|
+
| `Content is required.` | User must enter message content before submit |
|
|
256
|
+
| API call fails in local testing | Set `isDev` / `is-dev` when targeting the Development environment |
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Documentation
|
|
261
|
+
|
|
262
|
+
| Document | Audience |
|
|
263
|
+
| -------- | -------- |
|
|
264
|
+
| [Usage (static & React)](./docs/USAGE_STATIC_REACT.md) | Integrators |
|
|
265
|
+
| [Developer guide](./docs/DEVELOPER_GUIDE.md) | Contributors |
|
|
266
|
+
| [Public release](./docs/PUBLIC_RELEASE.md) | Maintainers |
|
|
267
|
+
|
|
268
|
+
---
|
|
149
269
|
|
|
150
270
|
## License
|
|
151
271
|
|
|
152
|
-
MIT
|
|
272
|
+
MIT © Nam Phương So
|