@namphuongtechnologi/np-hub 0.1.7 → 0.1.8

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.
@@ -61,10 +61,10 @@ var WIDGET_EVENTS = {
61
61
  var np_support_logo_default = "data:image/png;base64,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";
62
62
 
63
63
  // src/component/support-widget.styles.css
64
- var support_widget_styles_default = '@import url("https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap");\n\n:host {\n --np-primary: #003c82;\n --np-primary-dark: #002a5c;\n --np-primary-soft: rgba(0, 60, 130, 0.08);\n --np-border: #e2e8f0;\n --np-text: #0f172a;\n --np-text-muted: #64748b;\n font-family: "Outfit", sans-serif;\n display: block;\n position: fixed;\n right: 20px;\n bottom: 20px;\n z-index: 10000;\n}\n\n.launcher {\n width: var(--np-hub-width, 72px);\n height: var(--np-hub-height, 72px);\n border: none;\n border-radius: 50%;\n cursor: grab;\n box-shadow: 0 8px 28px rgba(0, 60, 130, 0.2);\n background-color: #ffffff;\n background-image: var(--np-hub-icon);\n background-position: center;\n background-repeat: no-repeat;\n background-size: 75%;\n transition:\n transform 0.2s ease,\n box-shadow 0.2s ease;\n}\n\n.launcher:hover {\n transform: scale(1.05);\n box-shadow: 0 12px 32px rgba(0, 60, 130, 0.3);\n}\n\n.launcher:active {\n cursor: grabbing;\n}\n\n.modal {\n position: fixed;\n inset: 0;\n background: rgba(15, 23, 42, 0.55);\n backdrop-filter: blur(6px);\n display: none;\n align-items: center;\n justify-content: center;\n padding: 16px;\n opacity: 0;\n transition: opacity 0.25s ease-out;\n}\n\n.modal.show {\n display: flex;\n opacity: 1;\n}\n\n.dialog {\n width: min(540px, 100%);\n max-height: calc(100vh - 32px);\n overflow-y: auto;\n background: #ffffff;\n border-radius: 20px;\n box-shadow: 0 24px 60px rgba(15, 23, 42, 0.22);\n padding: 28px 32px 32px;\n box-sizing: border-box;\n position: relative;\n transform: translateY(24px) scale(0.98);\n transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.modal.show .dialog {\n transform: translateY(0) scale(1);\n}\n\n.dialog::-webkit-scrollbar {\n width: 8px;\n}\n\n.dialog::-webkit-scrollbar-thumb {\n background: #cbd5e1;\n border-radius: 8px;\n}\n\n.header {\n display: flex;\n align-items: center;\n justify-content: center;\n padding-bottom: 18px;\n margin-bottom: 22px;\n border-bottom: 1px solid var(--np-border);\n position: relative;\n}\n\n.title {\n margin: 0;\n font-size: 22px;\n font-weight: 700;\n color: var(--np-primary);\n text-align: center;\n letter-spacing: -0.01em;\n}\n\n.close-btn {\n border: none;\n background: #f1f5f9;\n color: #64748b;\n font-size: 20px;\n line-height: 1;\n cursor: pointer;\n position: absolute;\n right: 0;\n top: 0;\n bottom: 18px;\n margin: auto 0;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n transition:\n background 0.15s ease,\n color 0.15s ease,\n transform 0.15s ease;\n}\n\n.close-btn:hover {\n background: #e2e8f0;\n color: #0f172a;\n transform: rotate(90deg);\n}\n\n.form-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 18px;\n}\n\n.field {\n display: flex;\n flex-direction: column;\n gap: 7px;\n}\n\n.field.full {\n grid-column: 1 / -1;\n}\n\nlabel {\n font-size: 13.5px;\n font-weight: 600;\n color: #334155;\n}\n\n.required {\n color: #ef4444;\n margin-right: 3px;\n}\n\ninput,\ntextarea {\n width: 100%;\n box-sizing: border-box;\n border: 1px solid #d5dde7;\n border-radius: 10px;\n font-size: 14px;\n padding: 12px 14px;\n color: var(--np-text);\n outline: none;\n font-family: inherit;\n background: #fbfcfe;\n transition:\n border-color 0.15s ease,\n box-shadow 0.15s ease,\n background 0.15s ease;\n}\n\ntextarea {\n min-height: 120px;\n resize: vertical;\n line-height: 1.5;\n}\n\ninput::placeholder,\ntextarea::placeholder {\n color: #94a3b8;\n}\n\ninput:hover,\ntextarea:hover {\n border-color: #b6c2d1;\n}\n\ninput:focus,\ntextarea:focus {\n border-color: var(--np-primary);\n background: #ffffff;\n box-shadow: 0 0 0 4px var(--np-primary-soft);\n}\n\n.input-wrap {\n position: relative;\n}\n\n.input-wrap input,\n.input-wrap textarea {\n padding-right: 40px;\n}\n\n.btn-clear {\n position: absolute;\n right: 10px;\n top: 50%;\n transform: translateY(-50%);\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 50%;\n background: #e2e8f0;\n color: #64748b;\n font-size: 16px;\n line-height: 1;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n opacity: 0;\n pointer-events: none;\n transition:\n opacity 0.15s ease,\n background 0.15s ease,\n color 0.15s ease;\n}\n\n.input-wrap.has-value:hover .btn-clear,\n.input-wrap.has-value:focus-within .btn-clear {\n opacity: 1;\n pointer-events: auto;\n}\n\n.btn-clear:hover {\n background: #cbd5e1;\n color: #0f172a;\n}\n\n.input-wrap--textarea .btn-clear {\n top: 12px;\n transform: none;\n}\n\n/* File upload styling */\n.upload-zone {\n display: flex;\n align-items: center;\n gap: 16px;\n background: #f8fafc;\n border: 1.5px dashed #cbd5e1;\n padding: 16px 20px;\n border-radius: 12px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n user-select: none;\n outline: none;\n}\n\n.upload-zone:hover {\n background: var(--np-primary-soft);\n border-color: var(--np-primary);\n}\n\n.upload-zone:focus-visible {\n border-color: var(--np-primary);\n box-shadow: 0 0 0 4px var(--np-primary-soft);\n}\n\n.upload-zone.dragover {\n background: rgba(0, 60, 130, 0.08);\n border-color: var(--np-primary);\n transform: scale(1.005);\n}\n\n.upload-icon-wrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: 10px;\n background: #ffffff;\n border: 1px solid #e2e8f0;\n color: #64748b;\n box-shadow: 0 2px 4px rgba(15, 23, 42, 0.04);\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.upload-zone:hover .upload-icon-wrapper,\n.upload-zone.dragover .upload-icon-wrapper {\n color: var(--np-primary);\n border-color: rgba(0, 60, 130, 0.15);\n box-shadow: 0 4px 8px rgba(0, 60, 130, 0.08);\n}\n\n.upload-text-container {\n display: flex;\n flex-direction: column;\n gap: 3px;\n flex: 1;\n}\n\n.upload-main-text {\n font-size: 13px;\n font-weight: 600;\n color: #334155;\n transition: color 0.2s ease;\n}\n\n.upload-zone:hover .upload-main-text {\n color: var(--np-primary);\n}\n\n.upload-sub-text {\n font-size: 11px;\n color: #64748b;\n line-height: 1.4;\n}\n\n.file-list {\n margin-top: 14px;\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));\n gap: 12px;\n}\n\n.file-item {\n position: relative;\n display: flex;\n flex-direction: column;\n background: #ffffff;\n border: 1px solid #e2e8f0;\n border-radius: 12px;\n font-size: 11px;\n color: #475569;\n box-shadow: 0 2px 5px rgba(15, 23, 42, 0.03);\n animation: file-in 0.2s cubic-bezier(0.16, 1, 0.3, 1);\n transition: all 0.2s ease;\n overflow: hidden;\n}\n\n.file-item:hover {\n border-color: #cbd5e1;\n box-shadow: 0 4px 12px rgba(15, 23, 42, 0.08);\n transform: translateY(-2px);\n}\n\n.file-preview-trigger {\n border: none;\n background: none;\n padding: 0;\n margin: 0;\n cursor: pointer;\n display: flex;\n flex-direction: column;\n width: 100%;\n color: inherit;\n font: inherit;\n}\n\n.file-thumb {\n width: 100%;\n aspect-ratio: 1 / 1;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #f8fafc;\n border-bottom: 1px solid #f1f5f9;\n position: relative;\n overflow: hidden;\n transition: background 0.2s ease;\n}\n\n.file-thumb img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n transition: transform 0.25s ease;\n}\n\n.file-item:hover .file-thumb img {\n transform: scale(1.06);\n}\n\n.file-thumb--icon {\n color: #64748b;\n background: #f1f5f9;\n}\n\n.file-item:hover .file-thumb--icon {\n background: #e2e8f0;\n color: var(--np-primary);\n}\n\n@keyframes file-in {\n from {\n opacity: 0;\n transform: translateY(6px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.file-info-container {\n padding: 8px 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n box-sizing: border-box;\n}\n\n.file-item .file-name {\n width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n line-height: 1.2;\n color: #334155;\n font-size: 11px;\n font-weight: 500;\n text-align: center;\n}\n\n.file-badge {\n position: absolute;\n top: 6px;\n left: 6px;\n z-index: 2;\n padding: 3px 6px;\n border-radius: 6px;\n font-size: 9px;\n font-weight: 600;\n line-height: 1;\n color: #0369a1;\n background: rgba(224, 242, 254, 0.9);\n border: 1px solid rgba(186, 230, 253, 0.8);\n backdrop-filter: blur(4px);\n box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05);\n}\n\n.file-item .btn-remove {\n position: absolute;\n top: 6px;\n right: 6px;\n z-index: 2;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(255, 255, 255, 0.9);\n border: 1px solid #e2e8f0;\n border-radius: 50%;\n color: #64748b;\n cursor: pointer;\n padding: 0;\n box-shadow: 0 2px 4px rgba(15, 23, 42, 0.06);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n backdrop-filter: blur(4px);\n}\n\n.file-item .btn-remove svg {\n width: 8px;\n height: 8px;\n stroke-width: 3px;\n transition: transform 0.2s ease;\n}\n\n.file-item .btn-remove:hover {\n color: #ffffff;\n background: #ef4444;\n border-color: #ef4444;\n transform: scale(1.1);\n box-shadow: 0 3px 8px rgba(239, 68, 68, 0.25);\n}\n\n.file-item .btn-remove:hover svg {\n transform: rotate(90deg);\n}\n\n/* File preview popup */\n.preview-overlay {\n position: fixed;\n inset: 0;\n z-index: 20;\n display: none;\n align-items: center;\n justify-content: center;\n padding: 24px;\n background: rgba(15, 23, 42, 0.72);\n backdrop-filter: blur(4px);\n opacity: 0;\n transition: opacity 0.2s ease-out;\n}\n\n.preview-overlay.show {\n display: flex;\n opacity: 1;\n}\n\n.preview-box {\n position: relative;\n max-width: min(720px, 100%);\n max-height: calc(100vh - 96px);\n background: #ffffff;\n border-radius: 16px;\n padding: 16px;\n box-shadow: 0 24px 60px rgba(15, 23, 42, 0.35);\n display: flex;\n flex-direction: column;\n}\n\n.preview-close {\n position: absolute;\n top: -14px;\n right: -14px;\n width: 34px;\n height: 34px;\n border-radius: 50%;\n border: none;\n background: #ffffff;\n color: #334155;\n font-size: 22px;\n line-height: 1;\n cursor: pointer;\n box-shadow: 0 4px 12px rgba(15, 23, 42, 0.25);\n transition:\n color 0.15s ease,\n transform 0.15s ease;\n}\n\n.preview-close:hover {\n color: #ef4444;\n transform: scale(1.05);\n}\n\n.preview-body {\n overflow: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.preview-body img {\n max-width: 100%;\n max-height: calc(100vh - 140px);\n object-fit: contain;\n border-radius: 8px;\n display: block;\n}\n\n.preview-file {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 32px 40px;\n text-align: center;\n color: var(--np-text);\n}\n\n.preview-file svg {\n color: var(--np-primary);\n}\n\n.preview-file .preview-file-name {\n font-size: 14px;\n font-weight: 600;\n word-break: break-all;\n}\n\n.preview-file a {\n color: var(--np-primary);\n font-size: 13px;\n font-weight: 600;\n text-decoration: none;\n}\n\n.preview-file a:hover {\n text-decoration: underline;\n}\n\n.actions {\n margin-top: 28px;\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n}\n\n.btn {\n border-radius: 10px;\n padding: 12px 26px;\n font-size: 15px;\n font-weight: 600;\n font-family: inherit;\n cursor: pointer;\n transition: all 0.18s ease;\n min-width: 120px;\n}\n\n.btn:active {\n transform: translateY(1px);\n}\n\n.btn-secondary {\n background: #ffffff;\n border: 1px solid #d5dde7;\n color: #334155;\n}\n\n.btn-secondary:hover {\n background: #f1f5f9;\n border-color: #b6c2d1;\n}\n\n.btn-primary {\n background: linear-gradient(\n 135deg,\n var(--np-primary),\n var(--np-primary-dark)\n );\n border: 1px solid var(--np-primary-dark);\n color: #ffffff;\n box-shadow: 0 6px 16px rgba(0, 60, 130, 0.28);\n}\n\n.btn-primary:hover {\n box-shadow: 0 8px 22px rgba(0, 60, 130, 0.38);\n filter: brightness(1.06);\n}\n\n@media (max-width: 480px) {\n .dialog {\n padding: 24px 20px 24px;\n border-radius: 16px;\n }\n\n .form-grid {\n grid-template-columns: 1fr;\n }\n\n .actions {\n justify-content: stretch;\n }\n\n .actions .btn {\n flex: 1;\n }\n}\n';
64
+ var support_widget_styles_default = '@import url("https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap");\n\n:host {\n --np-primary: #003c82;\n --np-primary-dark: #002a5c;\n --np-primary-soft: rgba(0, 60, 130, 0.08);\n --np-border: #e2e8f0;\n --np-text: #0f172a;\n --np-text-muted: #64748b;\n font-family: "Outfit", sans-serif;\n display: block;\n position: fixed;\n right: 20px;\n bottom: 20px;\n z-index: 10000;\n}\n\n.launcher {\n width: var(--np-hub-width, 72px);\n height: var(--np-hub-height, 72px);\n border: none;\n border-radius: 50%;\n cursor: grab;\n box-shadow: 0 8px 28px rgba(0, 60, 130, 0.2);\n background-color: #ffffff;\n background-image: var(--np-hub-icon);\n background-position: center;\n background-repeat: no-repeat;\n background-size: 75%;\n transition:\n transform 0.2s ease,\n box-shadow 0.2s ease;\n}\n\n.launcher:hover {\n transform: scale(1.05);\n box-shadow: 0 12px 32px rgba(0, 60, 130, 0.3);\n}\n\n.launcher:active {\n cursor: grabbing;\n}\n\n.modal {\n position: fixed;\n inset: 0;\n background: rgba(15, 23, 42, 0.55);\n backdrop-filter: blur(6px);\n display: none;\n align-items: center;\n justify-content: center;\n padding: 16px;\n opacity: 0;\n transition: opacity 0.25s ease-out;\n}\n\n.modal.show {\n display: flex;\n opacity: 1;\n}\n\n.dialog {\n width: min(540px, 100%);\n max-height: calc(100vh - 32px);\n overflow-y: auto;\n background: #ffffff;\n border-radius: 20px;\n box-shadow: 0 24px 60px rgba(15, 23, 42, 0.22);\n padding: 28px 32px 32px;\n box-sizing: border-box;\n position: relative;\n transform: translateY(24px) scale(0.98);\n transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.modal.show .dialog {\n transform: translateY(0) scale(1);\n}\n\n.dialog::-webkit-scrollbar {\n width: 8px;\n}\n\n.dialog::-webkit-scrollbar-thumb {\n background: #cbd5e1;\n border-radius: 8px;\n}\n\n.header {\n display: flex;\n align-items: center;\n justify-content: center;\n padding-bottom: 18px;\n margin-bottom: 22px;\n border-bottom: 1px solid var(--np-border);\n position: relative;\n}\n\n.title {\n margin: 0;\n font-size: 22px;\n font-weight: 700;\n color: var(--np-primary);\n text-align: center;\n letter-spacing: -0.01em;\n}\n\n.close-btn {\n border: none;\n background: #f1f5f9;\n color: #64748b;\n font-size: 20px;\n line-height: 1;\n cursor: pointer;\n position: absolute;\n right: 0;\n top: 0;\n bottom: 18px;\n margin: auto 0;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n transition:\n background 0.15s ease,\n color 0.15s ease,\n transform 0.15s ease;\n}\n\n.close-btn:hover {\n background: #e2e8f0;\n color: #0f172a;\n transform: rotate(90deg);\n}\n\n.form-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 18px;\n}\n\n.field {\n display: flex;\n flex-direction: column;\n gap: 7px;\n}\n\n.field-error {\n margin: 0;\n min-height: 16px;\n font-size: 12px;\n line-height: 1.35;\n color: #dc2626;\n}\n\n.field.full {\n grid-column: 1 / -1;\n}\n\nlabel {\n font-size: 13.5px;\n font-weight: 600;\n color: #334155;\n}\n\n.required {\n color: #ef4444;\n margin-right: 3px;\n}\n\ninput,\ntextarea {\n width: 100%;\n box-sizing: border-box;\n border: 1px solid #d5dde7;\n border-radius: 10px;\n font-size: 14px;\n padding: 12px 14px;\n color: var(--np-text);\n outline: none;\n font-family: inherit;\n background: #fbfcfe;\n transition:\n border-color 0.15s ease,\n box-shadow 0.15s ease,\n background 0.15s ease;\n}\n\ntextarea {\n min-height: 120px;\n resize: vertical;\n line-height: 1.5;\n}\n\ninput::placeholder,\ntextarea::placeholder {\n color: #94a3b8;\n}\n\ninput:hover,\ntextarea:hover {\n border-color: #b6c2d1;\n}\n\ninput:focus,\ntextarea:focus {\n border-color: var(--np-primary);\n background: #ffffff;\n box-shadow: 0 0 0 4px var(--np-primary-soft);\n}\n\n.input-wrap.has-error input,\n.input-wrap.has-error textarea {\n border-color: #ef4444;\n background: #fff7f7;\n}\n\n.input-wrap.has-error input:focus,\n.input-wrap.has-error textarea:focus {\n border-color: #ef4444;\n box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.15);\n}\n\n.input-wrap {\n position: relative;\n}\n\n.input-wrap input,\n.input-wrap textarea {\n padding-right: 40px;\n}\n\n.btn-clear {\n position: absolute;\n right: 10px;\n top: 50%;\n transform: translateY(-50%);\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 50%;\n background: #e2e8f0;\n color: #64748b;\n font-size: 16px;\n line-height: 1;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n opacity: 0;\n pointer-events: none;\n transition:\n opacity 0.15s ease,\n background 0.15s ease,\n color 0.15s ease;\n}\n\n.input-wrap.has-value:hover .btn-clear,\n.input-wrap.has-value:focus-within .btn-clear {\n opacity: 1;\n pointer-events: auto;\n}\n\n.btn-clear:hover {\n background: #cbd5e1;\n color: #0f172a;\n}\n\n.input-wrap--textarea .btn-clear {\n top: 12px;\n transform: none;\n}\n\n/* File upload styling */\n.upload-zone {\n display: flex;\n align-items: center;\n gap: 16px;\n background: #f8fafc;\n border: 1.5px dashed #cbd5e1;\n padding: 16px 20px;\n border-radius: 12px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n user-select: none;\n outline: none;\n}\n\n.upload-zone:hover {\n background: var(--np-primary-soft);\n border-color: var(--np-primary);\n}\n\n.upload-zone:focus-visible {\n border-color: var(--np-primary);\n box-shadow: 0 0 0 4px var(--np-primary-soft);\n}\n\n.upload-zone.dragover {\n background: rgba(0, 60, 130, 0.08);\n border-color: var(--np-primary);\n transform: scale(1.005);\n}\n\n.upload-icon-wrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: 10px;\n background: #ffffff;\n border: 1px solid #e2e8f0;\n color: #64748b;\n box-shadow: 0 2px 4px rgba(15, 23, 42, 0.04);\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.upload-zone:hover .upload-icon-wrapper,\n.upload-zone.dragover .upload-icon-wrapper {\n color: var(--np-primary);\n border-color: rgba(0, 60, 130, 0.15);\n box-shadow: 0 4px 8px rgba(0, 60, 130, 0.08);\n}\n\n.upload-text-container {\n display: flex;\n flex-direction: column;\n gap: 3px;\n flex: 1;\n}\n\n.upload-main-text {\n font-size: 13px;\n font-weight: 600;\n color: #334155;\n transition: color 0.2s ease;\n}\n\n.upload-zone:hover .upload-main-text {\n color: var(--np-primary);\n}\n\n.upload-sub-text {\n font-size: 11px;\n color: #64748b;\n line-height: 1.4;\n}\n\n.file-list {\n margin-top: 14px;\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));\n gap: 12px;\n}\n\n.file-item {\n position: relative;\n display: flex;\n flex-direction: column;\n background: #ffffff;\n border: 1px solid #e2e8f0;\n border-radius: 12px;\n font-size: 11px;\n color: #475569;\n box-shadow: 0 2px 5px rgba(15, 23, 42, 0.03);\n animation: file-in 0.2s cubic-bezier(0.16, 1, 0.3, 1);\n transition: all 0.2s ease;\n overflow: hidden;\n}\n\n.file-item:hover {\n border-color: #cbd5e1;\n box-shadow: 0 4px 12px rgba(15, 23, 42, 0.08);\n transform: translateY(-2px);\n}\n\n.file-preview-trigger {\n border: none;\n background: none;\n padding: 0;\n margin: 0;\n cursor: pointer;\n display: flex;\n flex-direction: column;\n width: 100%;\n color: inherit;\n font: inherit;\n}\n\n.file-thumb {\n width: 100%;\n aspect-ratio: 1 / 1;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #f8fafc;\n border-bottom: 1px solid #f1f5f9;\n position: relative;\n overflow: hidden;\n transition: background 0.2s ease;\n}\n\n.file-thumb img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n transition: transform 0.25s ease;\n}\n\n.file-item:hover .file-thumb img {\n transform: scale(1.06);\n}\n\n.file-thumb--icon {\n color: #64748b;\n background: #f1f5f9;\n}\n\n.file-item:hover .file-thumb--icon {\n background: #e2e8f0;\n color: var(--np-primary);\n}\n\n@keyframes file-in {\n from {\n opacity: 0;\n transform: translateY(6px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.file-info-container {\n padding: 8px 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n box-sizing: border-box;\n}\n\n.file-item .file-name {\n width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n line-height: 1.2;\n color: #334155;\n font-size: 11px;\n font-weight: 500;\n text-align: center;\n}\n\n.file-badge {\n position: absolute;\n top: 6px;\n left: 6px;\n z-index: 2;\n padding: 3px 6px;\n border-radius: 6px;\n font-size: 9px;\n font-weight: 600;\n line-height: 1;\n color: #0369a1;\n background: rgba(224, 242, 254, 0.9);\n border: 1px solid rgba(186, 230, 253, 0.8);\n backdrop-filter: blur(4px);\n box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05);\n}\n\n.file-item .btn-remove {\n position: absolute;\n top: 6px;\n right: 6px;\n z-index: 2;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(255, 255, 255, 0.9);\n border: 1px solid #e2e8f0;\n border-radius: 50%;\n color: #64748b;\n cursor: pointer;\n padding: 0;\n box-shadow: 0 2px 4px rgba(15, 23, 42, 0.06);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n backdrop-filter: blur(4px);\n}\n\n.file-item .btn-remove svg {\n width: 8px;\n height: 8px;\n stroke-width: 3px;\n transition: transform 0.2s ease;\n}\n\n.file-item .btn-remove:hover {\n color: #ffffff;\n background: #ef4444;\n border-color: #ef4444;\n transform: scale(1.1);\n box-shadow: 0 3px 8px rgba(239, 68, 68, 0.25);\n}\n\n.file-item .btn-remove:hover svg {\n transform: rotate(90deg);\n}\n\n/* File preview popup */\n.preview-overlay {\n position: fixed;\n inset: 0;\n z-index: 20;\n display: none;\n align-items: center;\n justify-content: center;\n padding: 24px;\n background: rgba(15, 23, 42, 0.72);\n backdrop-filter: blur(4px);\n opacity: 0;\n transition: opacity 0.2s ease-out;\n}\n\n.preview-overlay.show {\n display: flex;\n opacity: 1;\n}\n\n.preview-box {\n position: relative;\n max-width: min(720px, 100%);\n max-height: calc(100vh - 96px);\n background: #ffffff;\n border-radius: 16px;\n padding: 16px;\n box-shadow: 0 24px 60px rgba(15, 23, 42, 0.35);\n display: flex;\n flex-direction: column;\n}\n\n.preview-close {\n position: absolute;\n top: -14px;\n right: -14px;\n width: 34px;\n height: 34px;\n border-radius: 50%;\n border: none;\n background: #ffffff;\n color: #334155;\n font-size: 22px;\n line-height: 1;\n cursor: pointer;\n box-shadow: 0 4px 12px rgba(15, 23, 42, 0.25);\n transition:\n color 0.15s ease,\n transform 0.15s ease;\n}\n\n.preview-close:hover {\n color: #ef4444;\n transform: scale(1.05);\n}\n\n.preview-body {\n overflow: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.preview-body img {\n max-width: 100%;\n max-height: calc(100vh - 140px);\n object-fit: contain;\n border-radius: 8px;\n display: block;\n}\n\n.preview-file {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 32px 40px;\n text-align: center;\n color: var(--np-text);\n}\n\n.preview-file svg {\n color: var(--np-primary);\n}\n\n.preview-file .preview-file-name {\n font-size: 14px;\n font-weight: 600;\n word-break: break-all;\n}\n\n.preview-file a {\n color: var(--np-primary);\n font-size: 13px;\n font-weight: 600;\n text-decoration: none;\n}\n\n.preview-file a:hover {\n text-decoration: underline;\n}\n\n.actions {\n margin-top: 28px;\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n}\n\n.submit-feedback {\n margin: 18px 0 0;\n min-height: 20px;\n font-size: 13px;\n font-weight: 600;\n line-height: 1.4;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.submit-feedback.show {\n opacity: 1;\n}\n\n.submit-feedback.success {\n color: #15803d;\n}\n\n.submit-feedback.error {\n color: #dc2626;\n}\n\n.btn {\n border-radius: 10px;\n padding: 12px 26px;\n font-size: 15px;\n font-weight: 600;\n font-family: inherit;\n cursor: pointer;\n transition: all 0.18s ease;\n min-width: 120px;\n}\n\n.btn:active {\n transform: translateY(1px);\n}\n\n.btn-secondary {\n background: #ffffff;\n border: 1px solid #d5dde7;\n color: #334155;\n}\n\n.btn-secondary:hover {\n background: #f1f5f9;\n border-color: #b6c2d1;\n}\n\n.btn-primary {\n background: linear-gradient(\n 135deg,\n var(--np-primary),\n var(--np-primary-dark)\n );\n border: 1px solid var(--np-primary-dark);\n color: #ffffff;\n box-shadow: 0 6px 16px rgba(0, 60, 130, 0.28);\n}\n\n.btn-primary:hover {\n box-shadow: 0 8px 22px rgba(0, 60, 130, 0.38);\n filter: brightness(1.06);\n}\n\n@media (max-width: 480px) {\n .dialog {\n padding: 24px 20px 24px;\n border-radius: 16px;\n }\n\n .form-grid {\n grid-template-columns: 1fr;\n }\n\n .actions {\n justify-content: stretch;\n }\n\n .actions .btn {\n flex: 1;\n }\n}\n';
65
65
 
66
66
  // src/component/support-widget.template.html
67
- var support_widget_template_default = '<button\n id="open-btn"\n class="launcher"\n type="button"\n aria-label="Open support form"\n></button>\n\n<div id="modal" class="modal">\n <div\n class="dialog"\n role="dialog"\n aria-modal="true"\n aria-label="Support request form"\n >\n <div class="header">\n <h3 class="title">T\u1EA1o y\xEAu c\u1EA7u</h3>\n <button id="close-btn" class="close-btn" type="button" aria-label="Close">\n \xD7\n </button>\n </div>\n\n <div class="form-grid">\n <div class="field">\n <label for="requester"><span class="required">*</span> H\u1ECD v\xE0 t\xEAn</label>\n <div class="input-wrap">\n <input id="requester" type="text" placeholder="H\u1ECD v\xE0 t\xEAn" />\n <button type="button" class="btn-clear" aria-label="X\xF3a">\xD7</button>\n </div>\n </div>\n\n <div class="field">\n <label for="phone-number"\n ><span class="required">*</span> S\u1ED1 \u0111i\u1EC7n tho\u1EA1i</label\n >\n <div class="input-wrap">\n <input id="phone-number" type="text" placeholder="S\u1ED1 \u0111i\u1EC7n tho\u1EA1i" />\n <button type="button" class="btn-clear" aria-label="X\xF3a">\xD7</button>\n </div>\n </div>\n\n <div class="field full">\n <label for="email"><span class="required">*</span> Email</label>\n <div class="input-wrap">\n <input id="email" type="email" placeholder="Email" />\n <button type="button" class="btn-clear" aria-label="X\xF3a">\xD7</button>\n </div>\n </div>\n\n <div class="field full">\n <label for="content"><span class="required">*</span> N\u1ED9i dung</label>\n <div class="input-wrap input-wrap--textarea">\n <textarea\n id="content"\n placeholder="Anh/Ch\u1ECB vui l\xF2ng nh\u1EADp th\xF4ng tin c\u1EA7n h\u1ED7 tr\u1EE3"\n ></textarea>\n <button type="button" class="btn-clear" aria-label="X\xF3a">\xD7</button>\n </div>\n </div>\n\n <div class="field full">\n <label>File \u0111\xEDnh k\xE8m</label>\n <div id="upload-trigger" class="upload-zone" role="button" tabindex="0" aria-label="T\u1EA3i l\xEAn t\u1EC7p">\n <input id="file-input" type="file" multiple style="display: none" />\n <div class="upload-icon-wrapper">\n <svg\n class="upload-icon"\n xmlns="http://www.w3.org/2000/svg"\n width="20"\n height="20"\n viewBox="0 0 24 24"\n fill="none"\n stroke="currentColor"\n stroke-width="2.2"\n stroke-linecap="round"\n stroke-linejoin="round"\n >\n <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>\n <polyline points="17 8 12 3 7 8"></polyline>\n <line x1="12" y1="3" x2="12" y2="15"></line>\n </svg>\n </div>\n <div class="upload-text-container">\n <span class="upload-main-text">Ch\u1ECDn t\u1EC7p t\u1EA3i l\xEAn ho\u1EB7c k\xE9o th\u1EA3 v\xE0o \u0111\xE2y</span>\n <span class="upload-sub-text">H\u1ED7 tr\u1EE3 d\xE1n \u1EA3nh ho\u1EB7c t\u1EC7p (Ctrl+V / Cmd+V) \u0111\u1EC3 \u0111\xEDnh k\xE8m nhanh</span>\n </div>\n </div>\n <div id="file-list" class="file-list"></div>\n </div>\n </div>\n\n <div id="preview-overlay" class="preview-overlay">\n <div\n class="preview-box"\n role="dialog"\n aria-modal="true"\n aria-label="Xem tr\u01B0\u1EDBc t\u1EC7p"\n >\n <button\n id="preview-close"\n class="preview-close"\n type="button"\n aria-label="\u0110\xF3ng"\n >\n \xD7\n </button>\n <div id="preview-body" class="preview-body"></div>\n </div>\n </div>\n\n <div class="actions">\n <button id="cancel-btn" class="btn btn-secondary" type="button">\n H\u1EE7y\n </button>\n <button id="submit-btn" class="btn btn-primary" type="button">\n T\u1EA1o y\xEAu c\u1EA7u\n </button>\n </div>\n </div>\n</div>\n';
67
+ var support_widget_template_default = '<button\n id="open-btn"\n class="launcher"\n type="button"\n aria-label="Open support form"\n></button>\n\n<div id="modal" class="modal">\n <div\n class="dialog"\n role="dialog"\n aria-modal="true"\n aria-label="Support request form"\n >\n <div class="header">\n <h3 class="title">T\u1EA1o y\xEAu c\u1EA7u</h3>\n <button id="close-btn" class="close-btn" type="button" aria-label="Close">\n \xD7\n </button>\n </div>\n\n <div class="form-grid">\n <div class="field">\n <label for="requester"><span class="required">*</span> H\u1ECD v\xE0 t\xEAn</label>\n <div class="input-wrap">\n <input id="requester" type="text" placeholder="H\u1ECD v\xE0 t\xEAn" />\n <button type="button" class="btn-clear" aria-label="X\xF3a">\xD7</button>\n </div>\n <p id="requester-error" class="field-error" aria-live="polite"></p>\n </div>\n\n <div class="field">\n <label for="phone-number"\n ><span class="required">*</span> S\u1ED1 \u0111i\u1EC7n tho\u1EA1i</label\n >\n <div class="input-wrap">\n <input id="phone-number" type="text" placeholder="S\u1ED1 \u0111i\u1EC7n tho\u1EA1i" />\n <button type="button" class="btn-clear" aria-label="X\xF3a">\xD7</button>\n </div>\n <p id="phone-number-error" class="field-error" aria-live="polite"></p>\n </div>\n\n <div class="field full">\n <label for="email"><span class="required">*</span> Email</label>\n <div class="input-wrap">\n <input id="email" type="email" placeholder="Email" />\n <button type="button" class="btn-clear" aria-label="X\xF3a">\xD7</button>\n </div>\n <p id="email-error" class="field-error" aria-live="polite"></p>\n </div>\n\n <div class="field full">\n <label for="content"><span class="required">*</span> N\u1ED9i dung</label>\n <div class="input-wrap input-wrap--textarea">\n <textarea\n id="content"\n placeholder="Anh/Ch\u1ECB vui l\xF2ng nh\u1EADp th\xF4ng tin c\u1EA7n h\u1ED7 tr\u1EE3"\n ></textarea>\n <button type="button" class="btn-clear" aria-label="X\xF3a">\xD7</button>\n </div>\n <p id="content-error" class="field-error" aria-live="polite"></p>\n </div>\n\n <div class="field full">\n <label>File \u0111\xEDnh k\xE8m</label>\n <div id="upload-trigger" class="upload-zone" role="button" tabindex="0" aria-label="T\u1EA3i l\xEAn t\u1EC7p">\n <input id="file-input" type="file" multiple style="display: none" />\n <div class="upload-icon-wrapper">\n <svg\n class="upload-icon"\n xmlns="http://www.w3.org/2000/svg"\n width="20"\n height="20"\n viewBox="0 0 24 24"\n fill="none"\n stroke="currentColor"\n stroke-width="2.2"\n stroke-linecap="round"\n stroke-linejoin="round"\n >\n <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>\n <polyline points="17 8 12 3 7 8"></polyline>\n <line x1="12" y1="3" x2="12" y2="15"></line>\n </svg>\n </div>\n <div class="upload-text-container">\n <span class="upload-main-text">Ch\u1ECDn t\u1EC7p t\u1EA3i l\xEAn ho\u1EB7c k\xE9o th\u1EA3 v\xE0o \u0111\xE2y</span>\n <span class="upload-sub-text">H\u1ED7 tr\u1EE3 d\xE1n \u1EA3nh ho\u1EB7c t\u1EC7p (Ctrl+V / Cmd+V) \u0111\u1EC3 \u0111\xEDnh k\xE8m nhanh</span>\n </div>\n </div>\n <div id="file-list" class="file-list"></div>\n </div>\n </div>\n\n <div id="preview-overlay" class="preview-overlay">\n <div\n class="preview-box"\n role="dialog"\n aria-modal="true"\n aria-label="Xem tr\u01B0\u1EDBc t\u1EC7p"\n >\n <button\n id="preview-close"\n class="preview-close"\n type="button"\n aria-label="\u0110\xF3ng"\n >\n \xD7\n </button>\n <div id="preview-body" class="preview-body"></div>\n </div>\n </div>\n\n <p id="submit-feedback" class="submit-feedback" aria-live="polite"></p>\n\n <div class="actions">\n <button id="cancel-btn" class="btn btn-secondary" type="button">\n H\u1EE7y\n </button>\n <button id="submit-btn" class="btn btn-primary" type="button">\n T\u1EA1o y\xEAu c\u1EA7u\n </button>\n </div>\n </div>\n</div>\n';
68
68
 
69
69
  // src/component/support-widget.element.ts
70
70
  var sharedTemplate = null;
@@ -98,6 +98,7 @@ var SupportWidgetElement = class extends HTMLElement {
98
98
  this.selectedFiles = [];
99
99
  this.prefilledAttachments = [];
100
100
  this.previewUrls = [];
101
+ this.closeAfterSuccessTimer = null;
101
102
  this.priority = 0;
102
103
  this.coordinators = [];
103
104
  this.emailContacts = [];
@@ -121,6 +122,7 @@ var SupportWidgetElement = class extends HTMLElement {
121
122
  }
122
123
  disconnectedCallback() {
123
124
  window.removeEventListener("resize", this.handleResize);
125
+ this.clearCloseAfterSuccessTimer();
124
126
  }
125
127
  attributeChangedCallback() {
126
128
  this.syncConfigFromAttributes();
@@ -169,6 +171,8 @@ var SupportWidgetElement = class extends HTMLElement {
169
171
  }
170
172
  close() {
171
173
  var _a, _b;
174
+ this.clearCloseAfterSuccessTimer();
175
+ this.resetFormData();
172
176
  (_b = (_a = this.shadowRoot) == null ? void 0 : _a.getElementById("modal")) == null ? void 0 : _b.classList.remove("show");
173
177
  this.dispatchEvent(new CustomEvent(WIDGET_EVENTS.CLOSE, { bubbles: true }));
174
178
  }
@@ -466,10 +470,12 @@ var SupportWidgetElement = class extends HTMLElement {
466
470
  if (!input || !clearBtn) return;
467
471
  const updateVisibility = () => this.updateClearButton(input);
468
472
  input.addEventListener("input", updateVisibility);
473
+ input.addEventListener("input", () => this.clearFieldError(input.id));
469
474
  clearBtn.addEventListener("click", () => {
470
475
  input.value = "";
471
476
  input.focus();
472
477
  updateVisibility();
478
+ this.clearFieldError(input.id);
473
479
  });
474
480
  updateVisibility();
475
481
  });
@@ -492,8 +498,108 @@ var SupportWidgetElement = class extends HTMLElement {
492
498
  const el = (_a = this.shadowRoot) == null ? void 0 : _a.getElementById(id);
493
499
  return (_c = (_b = el == null ? void 0 : el.value) == null ? void 0 : _b.trim()) != null ? _c : "";
494
500
  }
501
+ setFieldError(id, message) {
502
+ var _a, _b;
503
+ const errorEl = (_a = this.shadowRoot) == null ? void 0 : _a.getElementById(`${id}-error`);
504
+ if (errorEl) {
505
+ errorEl.textContent = message;
506
+ }
507
+ const input = (_b = this.shadowRoot) == null ? void 0 : _b.getElementById(id);
508
+ const wrap = input == null ? void 0 : input.parentElement;
509
+ if (wrap == null ? void 0 : wrap.classList.contains("input-wrap")) {
510
+ wrap.classList.add("has-error");
511
+ }
512
+ }
513
+ clearFieldError(id) {
514
+ var _a, _b;
515
+ const errorEl = (_a = this.shadowRoot) == null ? void 0 : _a.getElementById(`${id}-error`);
516
+ if (errorEl) {
517
+ errorEl.textContent = "";
518
+ }
519
+ const input = (_b = this.shadowRoot) == null ? void 0 : _b.getElementById(id);
520
+ const wrap = input == null ? void 0 : input.parentElement;
521
+ if (wrap == null ? void 0 : wrap.classList.contains("input-wrap")) {
522
+ wrap.classList.remove("has-error");
523
+ }
524
+ }
525
+ clearAllFieldErrors() {
526
+ this.clearFieldError("requester");
527
+ this.clearFieldError("phone-number");
528
+ this.clearFieldError("email");
529
+ this.clearFieldError("content");
530
+ }
531
+ setSubmitFeedback(type, message) {
532
+ var _a;
533
+ const feedbackEl = (_a = this.shadowRoot) == null ? void 0 : _a.getElementById("submit-feedback");
534
+ if (!feedbackEl) return;
535
+ feedbackEl.textContent = message;
536
+ feedbackEl.classList.remove("success", "error");
537
+ feedbackEl.classList.add(type, "show");
538
+ }
539
+ clearSubmitFeedback() {
540
+ var _a;
541
+ const feedbackEl = (_a = this.shadowRoot) == null ? void 0 : _a.getElementById("submit-feedback");
542
+ if (!feedbackEl) return;
543
+ feedbackEl.textContent = "";
544
+ feedbackEl.classList.remove("success", "error", "show");
545
+ }
546
+ clearCloseAfterSuccessTimer() {
547
+ if (this.closeAfterSuccessTimer !== null) {
548
+ window.clearTimeout(this.closeAfterSuccessTimer);
549
+ this.closeAfterSuccessTimer = null;
550
+ }
551
+ }
552
+ validateRequiredFields() {
553
+ var _a;
554
+ this.clearAllFieldErrors();
555
+ const requiredFields = [
556
+ { id: "requester", message: "Vui l\xF2ng nh\u1EADp h\u1ECD v\xE0 t\xEAn." },
557
+ { id: "phone-number", message: "Vui l\xF2ng nh\u1EADp s\u1ED1 \u0111i\u1EC7n tho\u1EA1i." },
558
+ { id: "email", message: "Vui l\xF2ng nh\u1EADp email." },
559
+ { id: "content", message: "Vui l\xF2ng nh\u1EADp n\u1ED9i dung." }
560
+ ];
561
+ let firstInvalidId = null;
562
+ requiredFields.forEach(({ id, message }) => {
563
+ if (!this.getInputValue(id)) {
564
+ this.setFieldError(id, message);
565
+ if (!firstInvalidId) {
566
+ firstInvalidId = id;
567
+ }
568
+ }
569
+ });
570
+ if (firstInvalidId) {
571
+ const firstInvalid = (_a = this.shadowRoot) == null ? void 0 : _a.getElementById(firstInvalidId);
572
+ firstInvalid == null ? void 0 : firstInvalid.focus();
573
+ return false;
574
+ }
575
+ return true;
576
+ }
577
+ resetFormData() {
578
+ this.setInputValue("requester", "");
579
+ this.setInputValue("email", "");
580
+ this.setInputValue("phone-number", "");
581
+ this.setInputValue("content", "");
582
+ this.clearAllFieldErrors();
583
+ this.clearSubmitFeedback();
584
+ this.selectedFiles = [];
585
+ this.prefilledAttachments = [];
586
+ this.renderFileList();
587
+ this.closePreview();
588
+ }
495
589
  async submit() {
496
590
  try {
591
+ this.clearCloseAfterSuccessTimer();
592
+ this.clearSubmitFeedback();
593
+ if (!this.validateRequiredFields()) {
594
+ this.setSubmitFeedback("error", "Vui l\xF2ng nh\u1EADp \u0111\u1EA7y \u0111\u1EE7 th\xF4ng tin b\u1EAFt bu\u1ED9c.");
595
+ this.dispatchEvent(
596
+ new CustomEvent(WIDGET_EVENTS.SUBMIT_ERROR, {
597
+ bubbles: true,
598
+ detail: { message: "Please fill in all required fields." }
599
+ })
600
+ );
601
+ return;
602
+ }
497
603
  const user = {
498
604
  name: this.getInputValue("requester"),
499
605
  email: this.getInputValue("email"),
@@ -533,15 +639,19 @@ var SupportWidgetElement = class extends HTMLElement {
533
639
  );
534
640
  const baseUrl = resolveBaseUrl(this.config);
535
641
  const result = await createSupportRequest(baseUrl, formData);
642
+ this.setSubmitFeedback("success", "G\u1EEDi y\xEAu c\u1EA7u th\xE0nh c\xF4ng.");
536
643
  this.dispatchEvent(
537
644
  new CustomEvent(WIDGET_EVENTS.SUBMIT_SUCCESS, {
538
645
  bubbles: true,
539
646
  detail: result
540
647
  })
541
648
  );
542
- this.close();
649
+ this.closeAfterSuccessTimer = window.setTimeout(() => {
650
+ this.close();
651
+ }, 1200);
543
652
  } catch (error) {
544
653
  const message = error instanceof Error ? error.message : "Unknown error";
654
+ this.setSubmitFeedback("error", message);
545
655
  this.dispatchEvent(
546
656
  new CustomEvent(WIDGET_EVENTS.SUBMIT_ERROR, {
547
657
  bubbles: true,
@@ -646,4 +756,4 @@ export {
646
756
  SupportWidgetElement,
647
757
  registerSupportWidget
648
758
  };
649
- //# sourceMappingURL=chunk-5BULJCA4.js.map
759
+ //# sourceMappingURL=chunk-ZZQ7CSFN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/config/endpoints.ts","../src/core/validation/request-validator.ts","../src/services/api/http-client.ts","../src/services/api/support-api.ts","../src/component/events/widget-events.ts","../src/component/support-widget.styles.css","../src/component/support-widget.template.html","../src/component/support-widget.element.ts","../src/register.ts"],"sourcesContent":["export const PROD_API_URL = \"https://namphuong-api.azurewebsites.net\";\nexport const DEV_API_URL = \"https://namphuong-api-dev.azurewebsites.net\";\n\nexport function resolveBaseUrl(input: { isDev?: boolean }): string {\n return input.isDev ? DEV_API_URL : PROD_API_URL;\n}\n","import type {\n SupportSubmissionInput,\n SupportUser,\n SupportWidgetConfig,\n} from \"../../types/public\";\n\nexport function validateWidgetConfig(config: SupportWidgetConfig): void {\n if (!config.projectId || config.projectId.trim().length === 0) {\n throw new Error(\"projectId is required.\");\n }\n}\n\nexport function validateUser(user: SupportUser): void {\n if (!user.name?.trim()) {\n throw new Error(\"user.name is required.\");\n }\n if (!user.email?.trim()) {\n throw new Error(\"user.email is required.\");\n }\n if (!user.phoneNumber?.trim()) {\n throw new Error(\"user.phoneNumber is required.\");\n }\n}\n\nexport function validateSubmission(input: SupportSubmissionInput): void {\n if (!input.content?.trim()) {\n throw new Error(\"Content is required.\");\n }\n}\n","export async function postFormData<TResponse>(\n url: string,\n body: FormData,\n): Promise<TResponse> {\n const response = await fetch(url, {\n method: \"POST\",\n body,\n });\n\n if (!response.ok) {\n const message = await response.text();\n throw new Error(`Request failed (${response.status}): ${message}`);\n }\n\n return (await response.json()) as TResponse;\n}\n","import { postFormData } from \"./http-client\";\n\ninterface CreateRequestResponse {\n statusCode?: number;\n message?: string;\n data?: {\n url?: string;\n requestCode?: string;\n };\n}\n\nexport async function createSupportRequest(\n baseUrl: string,\n formData: FormData,\n): Promise<CreateRequestResponse> {\n const endpoint = `${baseUrl.replace(/\\/$/, \"\")}/api/supportcenter/create-request-anonymous`;\n return postFormData<CreateRequestResponse>(endpoint, formData);\n}\n\n","export const WIDGET_EVENTS = {\n OPEN: \"np-hub-open\",\n CLOSE: \"np-hub-close\",\n SUBMIT_SUCCESS: \"np-hub-submit-success\",\n SUBMIT_ERROR: \"np-hub-submit-error\",\n} as const;\n","@import url(\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap\");\n\n:host {\n --np-primary: #003c82;\n --np-primary-dark: #002a5c;\n --np-primary-soft: rgba(0, 60, 130, 0.08);\n --np-border: #e2e8f0;\n --np-text: #0f172a;\n --np-text-muted: #64748b;\n font-family: \"Outfit\", sans-serif;\n display: block;\n position: fixed;\n right: 20px;\n bottom: 20px;\n z-index: 10000;\n}\n\n.launcher {\n width: var(--np-hub-width, 72px);\n height: var(--np-hub-height, 72px);\n border: none;\n border-radius: 50%;\n cursor: grab;\n box-shadow: 0 8px 28px rgba(0, 60, 130, 0.2);\n background-color: #ffffff;\n background-image: var(--np-hub-icon);\n background-position: center;\n background-repeat: no-repeat;\n background-size: 75%;\n transition:\n transform 0.2s ease,\n box-shadow 0.2s ease;\n}\n\n.launcher:hover {\n transform: scale(1.05);\n box-shadow: 0 12px 32px rgba(0, 60, 130, 0.3);\n}\n\n.launcher:active {\n cursor: grabbing;\n}\n\n.modal {\n position: fixed;\n inset: 0;\n background: rgba(15, 23, 42, 0.55);\n backdrop-filter: blur(6px);\n display: none;\n align-items: center;\n justify-content: center;\n padding: 16px;\n opacity: 0;\n transition: opacity 0.25s ease-out;\n}\n\n.modal.show {\n display: flex;\n opacity: 1;\n}\n\n.dialog {\n width: min(540px, 100%);\n max-height: calc(100vh - 32px);\n overflow-y: auto;\n background: #ffffff;\n border-radius: 20px;\n box-shadow: 0 24px 60px rgba(15, 23, 42, 0.22);\n padding: 28px 32px 32px;\n box-sizing: border-box;\n position: relative;\n transform: translateY(24px) scale(0.98);\n transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.modal.show .dialog {\n transform: translateY(0) scale(1);\n}\n\n.dialog::-webkit-scrollbar {\n width: 8px;\n}\n\n.dialog::-webkit-scrollbar-thumb {\n background: #cbd5e1;\n border-radius: 8px;\n}\n\n.header {\n display: flex;\n align-items: center;\n justify-content: center;\n padding-bottom: 18px;\n margin-bottom: 22px;\n border-bottom: 1px solid var(--np-border);\n position: relative;\n}\n\n.title {\n margin: 0;\n font-size: 22px;\n font-weight: 700;\n color: var(--np-primary);\n text-align: center;\n letter-spacing: -0.01em;\n}\n\n.close-btn {\n border: none;\n background: #f1f5f9;\n color: #64748b;\n font-size: 20px;\n line-height: 1;\n cursor: pointer;\n position: absolute;\n right: 0;\n top: 0;\n bottom: 18px;\n margin: auto 0;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n transition:\n background 0.15s ease,\n color 0.15s ease,\n transform 0.15s ease;\n}\n\n.close-btn:hover {\n background: #e2e8f0;\n color: #0f172a;\n transform: rotate(90deg);\n}\n\n.form-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 18px;\n}\n\n.field {\n display: flex;\n flex-direction: column;\n gap: 7px;\n}\n\n.field-error {\n margin: 0;\n min-height: 16px;\n font-size: 12px;\n line-height: 1.35;\n color: #dc2626;\n}\n\n.field.full {\n grid-column: 1 / -1;\n}\n\nlabel {\n font-size: 13.5px;\n font-weight: 600;\n color: #334155;\n}\n\n.required {\n color: #ef4444;\n margin-right: 3px;\n}\n\ninput,\ntextarea {\n width: 100%;\n box-sizing: border-box;\n border: 1px solid #d5dde7;\n border-radius: 10px;\n font-size: 14px;\n padding: 12px 14px;\n color: var(--np-text);\n outline: none;\n font-family: inherit;\n background: #fbfcfe;\n transition:\n border-color 0.15s ease,\n box-shadow 0.15s ease,\n background 0.15s ease;\n}\n\ntextarea {\n min-height: 120px;\n resize: vertical;\n line-height: 1.5;\n}\n\ninput::placeholder,\ntextarea::placeholder {\n color: #94a3b8;\n}\n\ninput:hover,\ntextarea:hover {\n border-color: #b6c2d1;\n}\n\ninput:focus,\ntextarea:focus {\n border-color: var(--np-primary);\n background: #ffffff;\n box-shadow: 0 0 0 4px var(--np-primary-soft);\n}\n\n.input-wrap.has-error input,\n.input-wrap.has-error textarea {\n border-color: #ef4444;\n background: #fff7f7;\n}\n\n.input-wrap.has-error input:focus,\n.input-wrap.has-error textarea:focus {\n border-color: #ef4444;\n box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.15);\n}\n\n.input-wrap {\n position: relative;\n}\n\n.input-wrap input,\n.input-wrap textarea {\n padding-right: 40px;\n}\n\n.btn-clear {\n position: absolute;\n right: 10px;\n top: 50%;\n transform: translateY(-50%);\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 50%;\n background: #e2e8f0;\n color: #64748b;\n font-size: 16px;\n line-height: 1;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n opacity: 0;\n pointer-events: none;\n transition:\n opacity 0.15s ease,\n background 0.15s ease,\n color 0.15s ease;\n}\n\n.input-wrap.has-value:hover .btn-clear,\n.input-wrap.has-value:focus-within .btn-clear {\n opacity: 1;\n pointer-events: auto;\n}\n\n.btn-clear:hover {\n background: #cbd5e1;\n color: #0f172a;\n}\n\n.input-wrap--textarea .btn-clear {\n top: 12px;\n transform: none;\n}\n\n/* File upload styling */\n.upload-zone {\n display: flex;\n align-items: center;\n gap: 16px;\n background: #f8fafc;\n border: 1.5px dashed #cbd5e1;\n padding: 16px 20px;\n border-radius: 12px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n user-select: none;\n outline: none;\n}\n\n.upload-zone:hover {\n background: var(--np-primary-soft);\n border-color: var(--np-primary);\n}\n\n.upload-zone:focus-visible {\n border-color: var(--np-primary);\n box-shadow: 0 0 0 4px var(--np-primary-soft);\n}\n\n.upload-zone.dragover {\n background: rgba(0, 60, 130, 0.08);\n border-color: var(--np-primary);\n transform: scale(1.005);\n}\n\n.upload-icon-wrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: 10px;\n background: #ffffff;\n border: 1px solid #e2e8f0;\n color: #64748b;\n box-shadow: 0 2px 4px rgba(15, 23, 42, 0.04);\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.upload-zone:hover .upload-icon-wrapper,\n.upload-zone.dragover .upload-icon-wrapper {\n color: var(--np-primary);\n border-color: rgba(0, 60, 130, 0.15);\n box-shadow: 0 4px 8px rgba(0, 60, 130, 0.08);\n}\n\n.upload-text-container {\n display: flex;\n flex-direction: column;\n gap: 3px;\n flex: 1;\n}\n\n.upload-main-text {\n font-size: 13px;\n font-weight: 600;\n color: #334155;\n transition: color 0.2s ease;\n}\n\n.upload-zone:hover .upload-main-text {\n color: var(--np-primary);\n}\n\n.upload-sub-text {\n font-size: 11px;\n color: #64748b;\n line-height: 1.4;\n}\n\n.file-list {\n margin-top: 14px;\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));\n gap: 12px;\n}\n\n.file-item {\n position: relative;\n display: flex;\n flex-direction: column;\n background: #ffffff;\n border: 1px solid #e2e8f0;\n border-radius: 12px;\n font-size: 11px;\n color: #475569;\n box-shadow: 0 2px 5px rgba(15, 23, 42, 0.03);\n animation: file-in 0.2s cubic-bezier(0.16, 1, 0.3, 1);\n transition: all 0.2s ease;\n overflow: hidden;\n}\n\n.file-item:hover {\n border-color: #cbd5e1;\n box-shadow: 0 4px 12px rgba(15, 23, 42, 0.08);\n transform: translateY(-2px);\n}\n\n.file-preview-trigger {\n border: none;\n background: none;\n padding: 0;\n margin: 0;\n cursor: pointer;\n display: flex;\n flex-direction: column;\n width: 100%;\n color: inherit;\n font: inherit;\n}\n\n.file-thumb {\n width: 100%;\n aspect-ratio: 1 / 1;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #f8fafc;\n border-bottom: 1px solid #f1f5f9;\n position: relative;\n overflow: hidden;\n transition: background 0.2s ease;\n}\n\n.file-thumb img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n transition: transform 0.25s ease;\n}\n\n.file-item:hover .file-thumb img {\n transform: scale(1.06);\n}\n\n.file-thumb--icon {\n color: #64748b;\n background: #f1f5f9;\n}\n\n.file-item:hover .file-thumb--icon {\n background: #e2e8f0;\n color: var(--np-primary);\n}\n\n@keyframes file-in {\n from {\n opacity: 0;\n transform: translateY(6px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.file-info-container {\n padding: 8px 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n box-sizing: border-box;\n}\n\n.file-item .file-name {\n width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n line-height: 1.2;\n color: #334155;\n font-size: 11px;\n font-weight: 500;\n text-align: center;\n}\n\n.file-badge {\n position: absolute;\n top: 6px;\n left: 6px;\n z-index: 2;\n padding: 3px 6px;\n border-radius: 6px;\n font-size: 9px;\n font-weight: 600;\n line-height: 1;\n color: #0369a1;\n background: rgba(224, 242, 254, 0.9);\n border: 1px solid rgba(186, 230, 253, 0.8);\n backdrop-filter: blur(4px);\n box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05);\n}\n\n.file-item .btn-remove {\n position: absolute;\n top: 6px;\n right: 6px;\n z-index: 2;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(255, 255, 255, 0.9);\n border: 1px solid #e2e8f0;\n border-radius: 50%;\n color: #64748b;\n cursor: pointer;\n padding: 0;\n box-shadow: 0 2px 4px rgba(15, 23, 42, 0.06);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n backdrop-filter: blur(4px);\n}\n\n.file-item .btn-remove svg {\n width: 8px;\n height: 8px;\n stroke-width: 3px;\n transition: transform 0.2s ease;\n}\n\n.file-item .btn-remove:hover {\n color: #ffffff;\n background: #ef4444;\n border-color: #ef4444;\n transform: scale(1.1);\n box-shadow: 0 3px 8px rgba(239, 68, 68, 0.25);\n}\n\n.file-item .btn-remove:hover svg {\n transform: rotate(90deg);\n}\n\n/* File preview popup */\n.preview-overlay {\n position: fixed;\n inset: 0;\n z-index: 20;\n display: none;\n align-items: center;\n justify-content: center;\n padding: 24px;\n background: rgba(15, 23, 42, 0.72);\n backdrop-filter: blur(4px);\n opacity: 0;\n transition: opacity 0.2s ease-out;\n}\n\n.preview-overlay.show {\n display: flex;\n opacity: 1;\n}\n\n.preview-box {\n position: relative;\n max-width: min(720px, 100%);\n max-height: calc(100vh - 96px);\n background: #ffffff;\n border-radius: 16px;\n padding: 16px;\n box-shadow: 0 24px 60px rgba(15, 23, 42, 0.35);\n display: flex;\n flex-direction: column;\n}\n\n.preview-close {\n position: absolute;\n top: -14px;\n right: -14px;\n width: 34px;\n height: 34px;\n border-radius: 50%;\n border: none;\n background: #ffffff;\n color: #334155;\n font-size: 22px;\n line-height: 1;\n cursor: pointer;\n box-shadow: 0 4px 12px rgba(15, 23, 42, 0.25);\n transition:\n color 0.15s ease,\n transform 0.15s ease;\n}\n\n.preview-close:hover {\n color: #ef4444;\n transform: scale(1.05);\n}\n\n.preview-body {\n overflow: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.preview-body img {\n max-width: 100%;\n max-height: calc(100vh - 140px);\n object-fit: contain;\n border-radius: 8px;\n display: block;\n}\n\n.preview-file {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 32px 40px;\n text-align: center;\n color: var(--np-text);\n}\n\n.preview-file svg {\n color: var(--np-primary);\n}\n\n.preview-file .preview-file-name {\n font-size: 14px;\n font-weight: 600;\n word-break: break-all;\n}\n\n.preview-file a {\n color: var(--np-primary);\n font-size: 13px;\n font-weight: 600;\n text-decoration: none;\n}\n\n.preview-file a:hover {\n text-decoration: underline;\n}\n\n.actions {\n margin-top: 28px;\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n}\n\n.submit-feedback {\n margin: 18px 0 0;\n min-height: 20px;\n font-size: 13px;\n font-weight: 600;\n line-height: 1.4;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.submit-feedback.show {\n opacity: 1;\n}\n\n.submit-feedback.success {\n color: #15803d;\n}\n\n.submit-feedback.error {\n color: #dc2626;\n}\n\n.btn {\n border-radius: 10px;\n padding: 12px 26px;\n font-size: 15px;\n font-weight: 600;\n font-family: inherit;\n cursor: pointer;\n transition: all 0.18s ease;\n min-width: 120px;\n}\n\n.btn:active {\n transform: translateY(1px);\n}\n\n.btn-secondary {\n background: #ffffff;\n border: 1px solid #d5dde7;\n color: #334155;\n}\n\n.btn-secondary:hover {\n background: #f1f5f9;\n border-color: #b6c2d1;\n}\n\n.btn-primary {\n background: linear-gradient(\n 135deg,\n var(--np-primary),\n var(--np-primary-dark)\n );\n border: 1px solid var(--np-primary-dark);\n color: #ffffff;\n box-shadow: 0 6px 16px rgba(0, 60, 130, 0.28);\n}\n\n.btn-primary:hover {\n box-shadow: 0 8px 22px rgba(0, 60, 130, 0.38);\n filter: brightness(1.06);\n}\n\n@media (max-width: 480px) {\n .dialog {\n padding: 24px 20px 24px;\n border-radius: 16px;\n }\n\n .form-grid {\n grid-template-columns: 1fr;\n }\n\n .actions {\n justify-content: stretch;\n }\n\n .actions .btn {\n flex: 1;\n }\n}\n","<button\n id=\"open-btn\"\n class=\"launcher\"\n type=\"button\"\n aria-label=\"Open support form\"\n></button>\n\n<div id=\"modal\" class=\"modal\">\n <div\n class=\"dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Support request form\"\n >\n <div class=\"header\">\n <h3 class=\"title\">Tạo yêu cầu</h3>\n <button id=\"close-btn\" class=\"close-btn\" type=\"button\" aria-label=\"Close\">\n ×\n </button>\n </div>\n\n <div class=\"form-grid\">\n <div class=\"field\">\n <label for=\"requester\"><span class=\"required\">*</span> Họ và tên</label>\n <div class=\"input-wrap\">\n <input id=\"requester\" type=\"text\" placeholder=\"Họ và tên\" />\n <button type=\"button\" class=\"btn-clear\" aria-label=\"Xóa\">×</button>\n </div>\n <p id=\"requester-error\" class=\"field-error\" aria-live=\"polite\"></p>\n </div>\n\n <div class=\"field\">\n <label for=\"phone-number\"\n ><span class=\"required\">*</span> Số điện thoại</label\n >\n <div class=\"input-wrap\">\n <input id=\"phone-number\" type=\"text\" placeholder=\"Số điện thoại\" />\n <button type=\"button\" class=\"btn-clear\" aria-label=\"Xóa\">×</button>\n </div>\n <p id=\"phone-number-error\" class=\"field-error\" aria-live=\"polite\"></p>\n </div>\n\n <div class=\"field full\">\n <label for=\"email\"><span class=\"required\">*</span> Email</label>\n <div class=\"input-wrap\">\n <input id=\"email\" type=\"email\" placeholder=\"Email\" />\n <button type=\"button\" class=\"btn-clear\" aria-label=\"Xóa\">×</button>\n </div>\n <p id=\"email-error\" class=\"field-error\" aria-live=\"polite\"></p>\n </div>\n\n <div class=\"field full\">\n <label for=\"content\"><span class=\"required\">*</span> Nội dung</label>\n <div class=\"input-wrap input-wrap--textarea\">\n <textarea\n id=\"content\"\n placeholder=\"Anh/Chị vui lòng nhập thông tin cần hỗ trợ\"\n ></textarea>\n <button type=\"button\" class=\"btn-clear\" aria-label=\"Xóa\">×</button>\n </div>\n <p id=\"content-error\" class=\"field-error\" aria-live=\"polite\"></p>\n </div>\n\n <div class=\"field full\">\n <label>File đính kèm</label>\n <div id=\"upload-trigger\" class=\"upload-zone\" role=\"button\" tabindex=\"0\" aria-label=\"Tải lên tệp\">\n <input id=\"file-input\" type=\"file\" multiple style=\"display: none\" />\n <div class=\"upload-icon-wrapper\">\n <svg\n class=\"upload-icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"></path>\n <polyline points=\"17 8 12 3 7 8\"></polyline>\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"></line>\n </svg>\n </div>\n <div class=\"upload-text-container\">\n <span class=\"upload-main-text\">Chọn tệp tải lên hoặc kéo thả vào đây</span>\n <span class=\"upload-sub-text\">Hỗ trợ dán ảnh hoặc tệp (Ctrl+V / Cmd+V) để đính kèm nhanh</span>\n </div>\n </div>\n <div id=\"file-list\" class=\"file-list\"></div>\n </div>\n </div>\n\n <div id=\"preview-overlay\" class=\"preview-overlay\">\n <div\n class=\"preview-box\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Xem trước tệp\"\n >\n <button\n id=\"preview-close\"\n class=\"preview-close\"\n type=\"button\"\n aria-label=\"Đóng\"\n >\n ×\n </button>\n <div id=\"preview-body\" class=\"preview-body\"></div>\n </div>\n </div>\n\n <p id=\"submit-feedback\" class=\"submit-feedback\" aria-live=\"polite\"></p>\n\n <div class=\"actions\">\n <button id=\"cancel-btn\" class=\"btn btn-secondary\" type=\"button\">\n Hủy\n </button>\n <button id=\"submit-btn\" class=\"btn btn-primary\" type=\"button\">\n Tạo yêu cầu\n </button>\n </div>\n </div>\n</div>\n","import { resolveBaseUrl } from \"../core/config/endpoints\";\nimport {\n validateSubmission,\n validateUser,\n validateWidgetConfig,\n} from \"../core/validation/request-validator\";\nimport { createSupportRequest } from \"../services/api/support-api\";\nimport type {\n SupportSubmissionInput,\n SupportUser,\n SupportUserPrefill,\n SupportWidgetConfig,\n} from \"../types/public\";\nimport { WIDGET_EVENTS } from \"./events/widget-events\";\nimport npSupportLogo from \"./assets/np-support-logo.png\";\nimport styles from \"./support-widget.styles.css\";\nimport markup from \"./support-widget.template.html\";\n\nlet sharedTemplate: HTMLTemplateElement | null = null;\n\nfunction getTemplate(): HTMLTemplateElement {\n if (!sharedTemplate) {\n sharedTemplate = document.createElement(\"template\");\n sharedTemplate.innerHTML = `<style>${styles}</style>${markup}`;\n }\n return sharedTemplate;\n}\n\nasync function urlToFile(url: string): Promise<File | null> {\n try {\n const response = await fetch(url);\n if (!response.ok) return null;\n const blob = await response.blob();\n const name = url.substring(url.lastIndexOf(\"/\") + 1) || \"attachment\";\n return new File([blob], name, { type: blob.type });\n } catch (e) {\n console.warn(\"Failed to fetch prefilled attachment\", url, e);\n return null;\n }\n}\n\ninterface FormPrefillInput {\n content?: string;\n attachments?: string[];\n}\n\ntype RequiredFieldId = \"requester\" | \"phone-number\" | \"email\" | \"content\";\n\nexport class SupportWidgetElement extends HTMLElement {\n static observedAttributes = [\"project-id\", \"is-dev\", \"width\", \"height\"];\n\n private config: SupportWidgetConfig = {\n projectId: \"\",\n };\n\n private user?: SupportUserPrefill;\n private dragOccurred = false;\n\n // Internal states for fields mapped behind the scenes\n private selectedFiles: File[] = [];\n private prefilledAttachments: string[] = [];\n private previewUrls: string[] = [];\n private closeAfterSuccessTimer: number | null = null;\n public priority = 0;\n public coordinators: string[] = [];\n public emailContacts: string[] = [];\n\n constructor() {\n super();\n const root = this.attachShadow({ mode: \"open\" });\n root.appendChild(getTemplate().content.cloneNode(true));\n this.bindActions();\n }\n\n connectedCallback(): void {\n this.syncConfigFromAttributes();\n this.prefillFromState();\n this.applyLauncherStyle();\n this.restorePosition();\n window.addEventListener(\"resize\", this.handleResize);\n }\n\n disconnectedCallback(): void {\n window.removeEventListener(\"resize\", this.handleResize);\n this.clearCloseAfterSuccessTimer();\n }\n\n attributeChangedCallback(): void {\n this.syncConfigFromAttributes();\n this.prefillFromState();\n this.applyLauncherStyle();\n }\n\n setUser(user: SupportUserPrefill): void {\n this.user = user;\n this.prefillFromState();\n }\n\n setConfig(config: Partial<SupportWidgetConfig>): void {\n this.config = {\n ...this.config,\n ...config,\n };\n if (config.projectId !== undefined) {\n this.setAttribute(\"project-id\", config.projectId);\n }\n if (config.isDev !== undefined) {\n if (config.isDev) {\n this.setAttribute(\"is-dev\", \"\");\n } else {\n this.removeAttribute(\"is-dev\");\n }\n }\n if (config.priority !== undefined) {\n this.priority = config.priority;\n }\n if (config.coordinators !== undefined) {\n this.coordinators = config.coordinators;\n }\n if (config.emailContacts !== undefined) {\n this.emailContacts = config.emailContacts;\n }\n }\n\n setFormPrefill(data: FormPrefillInput): void {\n this.setInputValue(\"content\", data.content ?? \"\");\n this.prefilledAttachments = data.attachments ?? [];\n this.renderFileList();\n }\n\n open(): void {\n this.shadowRoot?.getElementById(\"modal\")?.classList.add(\"show\");\n this.dispatchEvent(new CustomEvent(WIDGET_EVENTS.OPEN, { bubbles: true }));\n }\n\n close(): void {\n this.clearCloseAfterSuccessTimer();\n this.resetFormData();\n this.shadowRoot?.getElementById(\"modal\")?.classList.remove(\"show\");\n this.dispatchEvent(new CustomEvent(WIDGET_EVENTS.CLOSE, { bubbles: true }));\n }\n\n private syncConfigFromAttributes(): void {\n this.config = {\n ...this.config,\n projectId: this.getAttribute(\"project-id\") ?? \"\",\n isDev: this.hasAttribute(\"is-dev\"),\n };\n }\n\n private bindActions(): void {\n const root = this.shadowRoot;\n if (!root) return;\n\n const launcher = root.getElementById(\"open-btn\");\n if (launcher) {\n launcher.addEventListener(\"click\", () => {\n if (this.dragOccurred) {\n this.dragOccurred = false;\n return;\n }\n this.open();\n });\n this.setupDrag(launcher);\n }\n\n root\n .getElementById(\"close-btn\")\n ?.addEventListener(\"click\", () => this.close());\n root\n .getElementById(\"cancel-btn\")\n ?.addEventListener(\"click\", () => this.close());\n root\n .getElementById(\"submit-btn\")\n ?.addEventListener(\"click\", () => void this.submit());\n\n this.setupClearableInputs();\n\n // File selection UI handlers\n const uploadTrigger = root.getElementById(\"upload-trigger\");\n const fileInput = root.getElementById(\n \"file-input\",\n ) as HTMLInputElement | null;\n\n if (uploadTrigger && fileInput) {\n uploadTrigger.addEventListener(\"click\", () => {\n fileInput.click();\n });\n\n uploadTrigger.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n fileInput.click();\n }\n });\n\n uploadTrigger.addEventListener(\"dragover\", (e: DragEvent) => {\n e.preventDefault();\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"copy\";\n }\n uploadTrigger.classList.add(\"dragover\");\n });\n\n uploadTrigger.addEventListener(\"dragleave\", () => {\n uploadTrigger.classList.remove(\"dragover\");\n });\n\n uploadTrigger.addEventListener(\"drop\", (e: DragEvent) => {\n e.preventDefault();\n uploadTrigger.classList.remove(\"dragover\");\n if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {\n this.addSelectedFiles(Array.from(e.dataTransfer.files));\n }\n });\n\n fileInput.addEventListener(\"change\", () => {\n if (fileInput.files) {\n this.addSelectedFiles(Array.from(fileInput.files));\n // Reset file input value to allow selecting the same file again\n fileInput.value = \"\";\n }\n });\n }\n\n this.setupClipboardPaste();\n this.setupPreviewControls();\n }\n\n private setupPreviewControls(): void {\n const root = this.shadowRoot;\n if (!root) return;\n\n const overlay = root.getElementById(\"preview-overlay\");\n root\n .getElementById(\"preview-close\")\n ?.addEventListener(\"click\", () => this.closePreview());\n\n overlay?.addEventListener(\"click\", (event) => {\n if (event.target === overlay) this.closePreview();\n });\n\n root.addEventListener(\"keydown\", (event) => {\n if ((event as KeyboardEvent).key === \"Escape\") this.closePreview();\n });\n }\n\n private setupClipboardPaste(): void {\n const dialog = this.shadowRoot?.querySelector(\".dialog\");\n if (!dialog) return;\n\n dialog.addEventListener(\"paste\", (event) => {\n const clipboard = (event as ClipboardEvent).clipboardData;\n if (!clipboard) return;\n\n const files = Array.from(clipboard.items)\n .filter((item: DataTransferItem) => item.kind === \"file\")\n .map((item: DataTransferItem) => item.getAsFile())\n .filter((file): file is File => file !== null);\n\n if (files.length === 0) return;\n\n event.preventDefault();\n this.addSelectedFiles(files);\n });\n }\n\n private addSelectedFiles(files: File[]): void {\n if (files.length === 0) return;\n this.selectedFiles.push(...files);\n this.renderFileList();\n }\n\n private renderFileList(): void {\n const fileListEl = this.shadowRoot?.getElementById(\"file-list\");\n if (!fileListEl) return;\n fileListEl.innerHTML = \"\";\n\n // Release object URLs created in the previous render to avoid leaks\n this.previewUrls.forEach((url) => URL.revokeObjectURL(url));\n this.previewUrls = [];\n\n // Prefilled URLs\n this.prefilledAttachments.forEach((url, index) => {\n const name = url.substring(url.lastIndexOf(\"/\") + 1) || url;\n const isImage = this.isImageName(name);\n const previewUrl = isImage ? url : null;\n fileListEl.appendChild(\n this.buildFileItem({\n name,\n title: url,\n previewUrl,\n type: \"prefilled\",\n index,\n isImage,\n openUrl: url,\n badge: \"Đã gán\",\n }),\n );\n });\n\n // Selected local files\n this.selectedFiles.forEach((file, index) => {\n let previewUrl: string | null = null;\n const isImage = file.type.startsWith(\"image/\");\n if (isImage) {\n previewUrl = URL.createObjectURL(file);\n this.previewUrls.push(previewUrl);\n }\n fileListEl.appendChild(\n this.buildFileItem({\n name: file.name,\n title: file.name,\n previewUrl,\n type: \"selected\",\n index,\n isImage,\n openUrl: null,\n badge: null,\n }),\n );\n });\n\n // Hook remove event\n fileListEl.querySelectorAll(\".btn-remove\").forEach((btn) => {\n btn.addEventListener(\"click\", (e) => {\n const target = e.currentTarget as HTMLElement;\n const type = target.getAttribute(\"data-type\");\n const index = parseInt(target.getAttribute(\"data-index\") || \"0\", 10);\n if (type === \"prefilled\") {\n this.prefilledAttachments.splice(index, 1);\n } else {\n this.selectedFiles.splice(index, 1);\n }\n this.renderFileList();\n });\n });\n }\n\n private buildFileItem(opts: {\n name: string;\n title: string;\n previewUrl: string | null;\n type: \"prefilled\" | \"selected\";\n index: number;\n isImage: boolean;\n openUrl: string | null;\n badge: string | null;\n }): HTMLDivElement {\n const item = document.createElement(\"div\");\n item.className = \"file-item\";\n\n const trigger = document.createElement(\"button\");\n trigger.type = \"button\";\n trigger.className = \"file-preview-trigger\";\n trigger.title = \"Nhấn để xem trước\";\n trigger.addEventListener(\"click\", () => {\n this.openPreview({\n name: opts.title,\n previewUrl: opts.previewUrl,\n isImage: opts.isImage,\n openUrl: opts.openUrl,\n });\n });\n\n const thumb = document.createElement(\"div\");\n thumb.className = \"file-thumb\";\n if (opts.previewUrl) {\n const img = document.createElement(\"img\");\n img.src = opts.previewUrl;\n img.alt = opts.name;\n // Fall back to a file icon if the image fails to load\n img.addEventListener(\"error\", () => this.fillWithFileIcon(thumb));\n thumb.appendChild(img);\n } else {\n this.fillWithFileIcon(thumb);\n }\n\n const infoContainer = document.createElement(\"div\");\n infoContainer.className = \"file-info-container\";\n\n const name = document.createElement(\"span\");\n name.className = \"file-name\";\n name.title = opts.title;\n name.textContent = opts.name;\n\n infoContainer.appendChild(name);\n trigger.append(thumb, infoContainer);\n\n const removeBtn = document.createElement(\"button\");\n removeBtn.type = \"button\";\n removeBtn.className = \"btn-remove\";\n removeBtn.setAttribute(\"aria-label\", \"Xóa tệp\");\n removeBtn.setAttribute(\"data-type\", opts.type);\n removeBtn.setAttribute(\"data-index\", String(opts.index));\n removeBtn.innerHTML = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n `;\n\n item.append(trigger, removeBtn);\n\n if (opts.badge) {\n const badge = document.createElement(\"span\");\n badge.className = \"file-badge\";\n badge.textContent = opts.badge;\n item.appendChild(badge);\n }\n\n return item;\n }\n\n private fillWithFileIcon(thumb: HTMLElement): void {\n thumb.innerHTML = \"\";\n thumb.classList.add(\"file-thumb--icon\");\n thumb.innerHTML = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"></path>\n <polyline points=\"14 2 14 8 20 8\"></polyline>\n </svg>`;\n }\n\n private openPreview(opts: {\n name: string;\n previewUrl: string | null;\n isImage: boolean;\n openUrl: string | null;\n }): void {\n const overlay = this.shadowRoot?.getElementById(\"preview-overlay\");\n const body = this.shadowRoot?.getElementById(\"preview-body\");\n if (!overlay || !body) return;\n\n body.innerHTML = \"\";\n\n if (opts.isImage && opts.previewUrl) {\n const img = document.createElement(\"img\");\n img.src = opts.previewUrl;\n img.alt = opts.name;\n body.appendChild(img);\n } else {\n const info = document.createElement(\"div\");\n info.className = \"preview-file\";\n const openLink = opts.openUrl\n ? `<a href=\"${opts.openUrl}\" target=\"_blank\" rel=\"noopener noreferrer\">Mở trong tab mới</a>`\n : `<span>Không có bản xem trước cho tệp này</span>`;\n info.innerHTML = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"56\" height=\"56\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"></path>\n <polyline points=\"14 2 14 8 20 8\"></polyline>\n </svg>\n <span class=\"preview-file-name\"></span>\n ${openLink}`;\n const nameEl = info.querySelector(\".preview-file-name\");\n if (nameEl) nameEl.textContent = opts.name;\n body.appendChild(info);\n }\n\n overlay.classList.add(\"show\");\n }\n\n private closePreview(): void {\n const overlay = this.shadowRoot?.getElementById(\"preview-overlay\");\n if (!overlay) return;\n overlay.classList.remove(\"show\");\n const body = this.shadowRoot?.getElementById(\"preview-body\");\n if (body) body.innerHTML = \"\";\n }\n\n private isImageName(name: string): boolean {\n return /\\.(png|jpe?g|gif|webp|bmp|svg|avif)$/i.test(name);\n }\n\n private prefillFromState(): void {\n this.setInputValue(\"requester\", this.user?.name ?? \"\");\n this.setInputValue(\"email\", this.user?.email ?? \"\");\n this.setInputValue(\"phone-number\", this.user?.phoneNumber ?? \"\");\n }\n\n private applyLauncherStyle(): void {\n const launcher = this.shadowRoot?.getElementById(\"open-btn\");\n if (!launcher) return;\n\n const launcherStyles = [`--np-hub-icon: url(\"${npSupportLogo}\")`];\n const width = this.normalizeSize(this.getAttribute(\"width\"));\n const height = this.normalizeSize(this.getAttribute(\"height\"));\n if (width) launcherStyles.push(`--np-hub-width: ${width}`);\n if (height) launcherStyles.push(`--np-hub-height: ${height}`);\n\n launcher.setAttribute(\"style\", `${launcherStyles.join(\"; \")};`);\n }\n\n private normalizeSize(value: string | null): string | null {\n const trimmed = value?.trim();\n if (!trimmed) return null;\n return /^\\d+(\\.\\d+)?$/.test(trimmed) ? `${trimmed}px` : trimmed;\n }\n\n private setupClearableInputs(): void {\n const root = this.shadowRoot;\n if (!root) return;\n\n root.querySelectorAll(\".input-wrap\").forEach((wrap) => {\n const input = wrap.querySelector(\"input, textarea\") as\n | HTMLInputElement\n | HTMLTextAreaElement\n | null;\n const clearBtn = wrap.querySelector(\n \".btn-clear\",\n ) as HTMLButtonElement | null;\n if (!input || !clearBtn) return;\n\n const updateVisibility = () => this.updateClearButton(input);\n\n input.addEventListener(\"input\", updateVisibility);\n input.addEventListener(\"input\", () => this.clearFieldError(input.id));\n clearBtn.addEventListener(\"click\", () => {\n input.value = \"\";\n input.focus();\n updateVisibility();\n this.clearFieldError(input.id);\n });\n\n updateVisibility();\n });\n }\n\n private updateClearButton(\n input: HTMLInputElement | HTMLTextAreaElement,\n ): void {\n const wrap = input.parentElement;\n if (wrap?.classList.contains(\"input-wrap\")) {\n wrap.classList.toggle(\"has-value\", input.value.length > 0);\n }\n }\n\n private setInputValue(id: string, value: string): void {\n const el = this.shadowRoot?.getElementById(id) as\n | HTMLInputElement\n | HTMLTextAreaElement\n | null;\n if (!el) return;\n el.value = value;\n this.updateClearButton(el);\n }\n\n private getInputValue(id: string): string {\n const el = this.shadowRoot?.getElementById(id) as\n | HTMLInputElement\n | HTMLTextAreaElement\n | null;\n return el?.value?.trim() ?? \"\";\n }\n\n private setFieldError(id: RequiredFieldId, message: string): void {\n const errorEl = this.shadowRoot?.getElementById(`${id}-error`);\n if (errorEl) {\n errorEl.textContent = message;\n }\n\n const input = this.shadowRoot?.getElementById(id) as\n | HTMLInputElement\n | HTMLTextAreaElement\n | null;\n const wrap = input?.parentElement;\n if (wrap?.classList.contains(\"input-wrap\")) {\n wrap.classList.add(\"has-error\");\n }\n }\n\n private clearFieldError(id: string): void {\n const errorEl = this.shadowRoot?.getElementById(`${id}-error`);\n if (errorEl) {\n errorEl.textContent = \"\";\n }\n\n const input = this.shadowRoot?.getElementById(id) as\n | HTMLInputElement\n | HTMLTextAreaElement\n | null;\n const wrap = input?.parentElement;\n if (wrap?.classList.contains(\"input-wrap\")) {\n wrap.classList.remove(\"has-error\");\n }\n }\n\n private clearAllFieldErrors(): void {\n this.clearFieldError(\"requester\");\n this.clearFieldError(\"phone-number\");\n this.clearFieldError(\"email\");\n this.clearFieldError(\"content\");\n }\n\n private setSubmitFeedback(\n type: \"success\" | \"error\",\n message: string,\n ): void {\n const feedbackEl = this.shadowRoot?.getElementById(\"submit-feedback\");\n if (!feedbackEl) return;\n\n feedbackEl.textContent = message;\n feedbackEl.classList.remove(\"success\", \"error\");\n feedbackEl.classList.add(type, \"show\");\n }\n\n private clearSubmitFeedback(): void {\n const feedbackEl = this.shadowRoot?.getElementById(\"submit-feedback\");\n if (!feedbackEl) return;\n\n feedbackEl.textContent = \"\";\n feedbackEl.classList.remove(\"success\", \"error\", \"show\");\n }\n\n private clearCloseAfterSuccessTimer(): void {\n if (this.closeAfterSuccessTimer !== null) {\n window.clearTimeout(this.closeAfterSuccessTimer);\n this.closeAfterSuccessTimer = null;\n }\n }\n\n private validateRequiredFields(): boolean {\n this.clearAllFieldErrors();\n\n const requiredFields: Array<{\n id: RequiredFieldId;\n message: string;\n }> = [\n { id: \"requester\", message: \"Vui lòng nhập họ và tên.\" },\n { id: \"phone-number\", message: \"Vui lòng nhập số điện thoại.\" },\n { id: \"email\", message: \"Vui lòng nhập email.\" },\n { id: \"content\", message: \"Vui lòng nhập nội dung.\" },\n ];\n\n let firstInvalidId: RequiredFieldId | null = null;\n\n requiredFields.forEach(({ id, message }) => {\n if (!this.getInputValue(id)) {\n this.setFieldError(id, message);\n if (!firstInvalidId) {\n firstInvalidId = id;\n }\n }\n });\n\n if (firstInvalidId) {\n const firstInvalid = this.shadowRoot?.getElementById(firstInvalidId) as\n | HTMLInputElement\n | HTMLTextAreaElement\n | null;\n firstInvalid?.focus();\n return false;\n }\n\n return true;\n }\n\n private resetFormData(): void {\n this.setInputValue(\"requester\", \"\");\n this.setInputValue(\"email\", \"\");\n this.setInputValue(\"phone-number\", \"\");\n this.setInputValue(\"content\", \"\");\n this.clearAllFieldErrors();\n this.clearSubmitFeedback();\n\n this.selectedFiles = [];\n this.prefilledAttachments = [];\n this.renderFileList();\n this.closePreview();\n }\n\n private async submit(): Promise<void> {\n try {\n this.clearCloseAfterSuccessTimer();\n this.clearSubmitFeedback();\n\n if (!this.validateRequiredFields()) {\n this.setSubmitFeedback(\"error\", \"Vui lòng nhập đầy đủ thông tin bắt buộc.\");\n this.dispatchEvent(\n new CustomEvent(WIDGET_EVENTS.SUBMIT_ERROR, {\n bubbles: true,\n detail: { message: \"Please fill in all required fields.\" },\n }),\n );\n return;\n }\n\n const user: SupportUser = {\n name: this.getInputValue(\"requester\"),\n email: this.getInputValue(\"email\"),\n phoneNumber: this.getInputValue(\"phone-number\"),\n };\n\n this.user = user;\n\n validateWidgetConfig(this.config);\n validateUser(user);\n\n const content = this.getInputValue(\"content\");\n const submission: SupportSubmissionInput = {\n content,\n attachments: [], // dummy value for local validation of required content field\n };\n validateSubmission(submission);\n\n // Create FormData to send request as multipart/form-data\n const formData = new FormData();\n formData.append(\"Requester\", user.name);\n formData.append(\"PhoneNumber\", user.phoneNumber);\n formData.append(\"Email\", user.email);\n formData.append(\"Content\", content);\n formData.append(\"ProjectId\", this.config.projectId);\n formData.append(\"Priority\", String(this.priority));\n\n // Fetch prefilled attachments and convert them to Files\n for (const url of this.prefilledAttachments) {\n const file = await urlToFile(url);\n if (file) {\n formData.append(\"Attachments\", file);\n }\n }\n\n // Add newly selected files\n for (const file of this.selectedFiles) {\n formData.append(\"Attachments\", file);\n }\n\n // Add coordinators and emailContacts\n this.coordinators.forEach((coord) =>\n formData.append(\"Coordinators\", coord),\n );\n this.emailContacts.forEach((contact) =>\n formData.append(\"EmailContacts\", contact),\n );\n\n const baseUrl = resolveBaseUrl(this.config);\n const result = await createSupportRequest(baseUrl, formData);\n\n this.setSubmitFeedback(\"success\", \"Gửi yêu cầu thành công.\");\n\n this.dispatchEvent(\n new CustomEvent(WIDGET_EVENTS.SUBMIT_SUCCESS, {\n bubbles: true,\n detail: result,\n }),\n );\n this.closeAfterSuccessTimer = window.setTimeout(() => {\n this.close();\n }, 1200);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n this.setSubmitFeedback(\"error\", message);\n this.dispatchEvent(\n new CustomEvent(WIDGET_EVENTS.SUBMIT_ERROR, {\n bubbles: true,\n detail: { message },\n }),\n );\n }\n }\n\n private setupDrag(launcher: HTMLElement): void {\n launcher.addEventListener(\"pointerdown\", (e: PointerEvent) => {\n if (e.button !== 0) return;\n\n this.dragOccurred = false;\n const rect = this.getBoundingClientRect();\n const startX = e.clientX;\n const startY = e.clientY;\n const initialLeft = rect.left;\n const initialTop = rect.top;\n\n try {\n launcher.setPointerCapture(e.pointerId);\n } catch {\n // ignore if pointer capture fails\n }\n\n const onPointerMove = (moveEvent: PointerEvent) => {\n const dx = moveEvent.clientX - startX;\n const dy = moveEvent.clientY - startY;\n\n if (!this.dragOccurred && (Math.abs(dx) > 4 || Math.abs(dy) > 4)) {\n this.dragOccurred = true;\n launcher.style.cursor = \"grabbing\";\n }\n\n if (this.dragOccurred) {\n const leftVal = initialLeft + dx;\n const topVal = initialTop + dy;\n this.adjustPosition(leftVal, topVal);\n }\n };\n\n const onPointerUp = (upEvent: PointerEvent) => {\n try {\n launcher.releasePointerCapture(upEvent.pointerId);\n } catch {\n // ignore\n }\n launcher.removeEventListener(\"pointermove\", onPointerMove);\n launcher.removeEventListener(\"pointerup\", onPointerUp);\n launcher.removeEventListener(\"pointercancel\", onPointerUp);\n launcher.style.cursor = \"\";\n\n if (this.dragOccurred) {\n localStorage.setItem(\n \"np-hub-widget-position\",\n JSON.stringify({\n left: this.style.left,\n top: this.style.top,\n }),\n );\n }\n };\n\n launcher.addEventListener(\"pointermove\", onPointerMove);\n launcher.addEventListener(\"pointerup\", onPointerUp);\n launcher.addEventListener(\"pointercancel\", onPointerUp);\n });\n }\n\n private adjustPosition(leftVal: number, topVal: number): void {\n const rect = this.getBoundingClientRect();\n const width = rect.width || 72;\n const height = rect.height || 72;\n\n const minLeft = 0;\n const maxLeft = window.innerWidth - width;\n const minTop = 0;\n const maxTop = window.innerHeight - height;\n\n const clampedLeft = Math.max(minLeft, Math.min(maxLeft, leftVal));\n const clampedTop = Math.max(minTop, Math.min(maxTop, topVal));\n\n this.style.right = \"auto\";\n this.style.bottom = \"auto\";\n this.style.left = `${clampedLeft}px`;\n this.style.top = `${clampedTop}px`;\n }\n\n private restorePosition(): void {\n const savedPosition = localStorage.getItem(\"np-hub-widget-position\");\n if (savedPosition) {\n try {\n const { left, top } = JSON.parse(savedPosition);\n if (left && top) {\n const leftVal = parseFloat(left);\n const topVal = parseFloat(top);\n this.adjustPosition(leftVal, topVal);\n }\n } catch {\n // Ignore parsing errors\n }\n }\n }\n\n private handleResize = (): void => {\n if (this.style.left && this.style.top) {\n const leftVal = parseFloat(this.style.left);\n const topVal = parseFloat(this.style.top);\n this.adjustPosition(leftVal, topVal);\n }\n };\n}\n","import { SupportWidgetElement } from \"./component/support-widget.element\";\n\nconst TAG_NAME = \"np-hub\";\n\nexport function registerSupportWidget(): void {\n if (!customElements.get(TAG_NAME)) {\n customElements.define(TAG_NAME, SupportWidgetElement);\n }\n}\n\nregisterSupportWidget();\n"],"mappings":"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","names":["_a","e"]}