@netlib/widerrufsbutton 1.0.6 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -57,17 +57,17 @@ Content-Type: application/json
57
57
 
58
58
  ## Konfigurationsparameter
59
59
 
60
- | Parameter | Typ | Pflicht | Beschreibung |
61
- |---|---|---|---|
62
- | `apiUrl` | string | ja | PATCH-Endpunkt |
63
- | `action` | string | ja | Action-Name, Default: `widerruf_submit` |
64
- | `introText` | string | – | Einleitungstext im Modal |
60
+ | Parameter | Typ | Pflicht | Beschreibung |
61
+ |---------------|---|---|---|
62
+ | `apiUrl` | string | ja | PATCH-Endpunkt |
63
+ | `action` | string | ja | Action-Name, Default: `widerruf_submit` |
64
+ | `introText` | string | – | Einleitungstext im Modal |
65
65
  | `companyName` | string | – | Firmenname im Modal-Titel |
66
66
  | `buttonLabel` | string | – | Button-Beschriftung, Default: `Vertrag widerrufen` |
67
67
  | `cancelLabel` | string | – | Abbrechen-Button, Default: `Abbrechen` |
68
68
  | `submitLabel` | string | – | Absenden-Button, Default: `Widerruf bestätigen` |
69
69
  | `buttonClass` | string | – | Zusätzliche CSS-Klassen am Button |
70
- | `authToken` | string | – | Bearer-Token für `Authorization`-Header |
70
+ | `cl` | string | – | Bearer-Token für `Authorization`-Header |
71
71
 
72
72
  ## Einbindung
73
73
 
@@ -0,0 +1,8 @@
1
+ import { WiderrufsConfig } from './types';
2
+ /**
3
+ * Generates a complete, self-contained HTML page for the Widerruf form.
4
+ * Works without JavaScript — the form submits via POST to config.formAction (or config.apiUrl).
5
+ * Integrators embed this via generateFallbackHtml(config) in Astro or serve the pre-built
6
+ * dist/widerruf.html from any web server (ColdFusion, nginx, etc.).
7
+ */
8
+ export declare function generateFallbackHtml(config: WiderrufsConfig): string;
package/dist/index.cjs.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),s=require("react"),I=require("react-dom");async function W(r,a){const n={"Content-Type":"application/json"};r.authToken&&(n.Authorization=`Bearer ${r.authToken}`);const d={action:r.action,payload:{...a,datum:new Date().toISOString()}},i=await fetch(r.apiUrl,{method:"PATCH",headers:n,body:JSON.stringify(d)});if(!i.ok)throw new Error(`Server antwortete mit Status ${i.status}`)}const k=new Date().toLocaleDateString("de-DE",{day:"2-digit",month:"2-digit",year:"numeric"}),B={name:"",email:"",vertragId:"",widerrufsgrund:"",datum:k};function h(r){const a={};return r.name.trim()||(a.name="Bitte geben Sie Ihren Namen an."),r.email.trim()?/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r.email)||(a.email="Bitte geben Sie eine gültige E-Mail-Adresse an."):a.email="Bitte geben Sie Ihre E-Mail-Adresse an.",r.vertragId.trim()||(a.vertragId="Bitte geben Sie die Bestellnummer oder Vertragsnummer an."),a}function N({config:r,onClose:a}){const[n,d]=s.useState(B),[i,x]=s.useState({}),[c,w]=s.useState({}),[p,f]=s.useState("idle"),[y,v]=s.useState(""),j=s.useRef(null);s.useEffect(()=>{var l;(l=j.current)==null||l.focus();const t=o=>o.key==="Escape"&&a();return document.addEventListener("keydown",t),()=>document.removeEventListener("keydown",t)},[a]);function m(t,l){const o={...n,[t]:l};if(d(o),c[t]){const b=h(o);x(z=>({...z,[t]:b[t]}))}}function g(t){w(o=>({...o,[t]:!0}));const l=h(n);x(o=>({...o,[t]:l[t]}))}async function S(t){t.preventDefault();const l=Object.fromEntries(Object.keys(n).map(b=>[b,!0]));w(l);const o=h(n);if(x(o),!(Object.keys(o).length>0)){f("loading"),v("");try{await W(r,n),f("success")}catch(b){v(b instanceof Error?b.message:"Ein unbekannter Fehler ist aufgetreten."),f("error")}}}const E=r.companyName?`Widerruf – ${r.companyName}`:"Widerrufsformular";return e.jsx("div",{className:"wrb-overlay",role:"dialog","aria-modal":"true","aria-labelledby":"wrb-title",onClick:t=>t.target===t.currentTarget&&a(),children:e.jsxs("div",{className:"wrb-modal",children:[e.jsxs("div",{className:"wrb-modal-header",children:[e.jsx("h2",{className:"wrb-modal-title",id:"wrb-title",children:E}),e.jsx("button",{className:"wrb-close-btn",onClick:a,"aria-label":"Schließen",type:"button",children:"✕"})]}),p==="success"?e.jsxs("div",{className:"wrb-success",children:[e.jsx("span",{className:"wrb-success-icon",children:"✓"}),e.jsx("h3",{children:"Widerruf eingegangen"}),e.jsxs("p",{children:["Ihr Widerruf wurde erfolgreich übermittelt. Sie erhalten in Kürze eine Bestätigung an ",e.jsx("strong",{children:n.email}),"."]})]}):e.jsxs("div",{className:"wrb-modal-body",children:[r.introText&&e.jsx("p",{className:"wrb-intro",children:r.introText}),p==="error"&&y&&e.jsx("div",{className:"wrb-alert wrb-alert-error",role:"alert",children:y}),e.jsxs("form",{onSubmit:S,noValidate:!0,children:[e.jsx(u,{label:"Name",required:!0,error:c.name?i.name:void 0,children:e.jsx("input",{ref:j,className:`wrb-input${c.name&&i.name?" wrb-error":""}`,type:"text",autoComplete:"name",value:n.name,onChange:t=>m("name",t.target.value),onBlur:()=>g("name"),placeholder:"Vor- und Nachname"})}),e.jsx(u,{label:"E-Mail-Adresse",required:!0,hint:"Hierüber erhalten Sie die Eingangsbestätigung.",error:c.email?i.email:void 0,children:e.jsx("input",{className:`wrb-input${c.email&&i.email?" wrb-error":""}`,type:"email",autoComplete:"email",value:n.email,onChange:t=>m("email",t.target.value),onBlur:()=>g("email"),placeholder:"name@beispiel.de"})}),e.jsx(u,{label:"Bestell- / Auftrags- / Vertragsnummer",required:!0,hint:"Zu finden in Ihrer Bestellbestätigung.",error:c.vertragId?i.vertragId:void 0,children:e.jsx("input",{className:`wrb-input${c.vertragId&&i.vertragId?" wrb-error":""}`,type:"text",value:n.vertragId,onChange:t=>m("vertragId",t.target.value),onBlur:()=>g("vertragId"),placeholder:"z.B. 10045678"})}),e.jsx(u,{label:"Widerrufsgrund",hint:"Freiwillige Angabe – ein Widerruf ist ohne Angabe von Gründen möglich.",children:e.jsx("textarea",{className:"wrb-textarea",value:n.widerrufsgrund,onChange:t=>m("widerrufsgrund",t.target.value),placeholder:"Optional",rows:3})}),e.jsx(u,{label:"Datum der Widerrufserklärung",children:e.jsx("div",{className:"wrb-date-display",children:k})}),e.jsxs("div",{className:"wrb-actions",children:[e.jsx("button",{type:"button",className:"wrb-cancel-btn",onClick:a,children:r.cancelLabel??"Abbrechen"}),e.jsx("button",{type:"submit",className:"wrb-submit-btn",disabled:p==="loading",children:p==="loading"?"Wird gesendet…":r.submitLabel??"Absenden"})]})]})]})]})})}function u({label:r,required:a,hint:n,error:d,children:i}){return e.jsxs("div",{className:"wrb-field",children:[e.jsxs("label",{className:"wrb-label",children:[r,a&&e.jsx("span",{className:"wrb-required","aria-hidden":"true",children:"*"})]}),i,n&&!d&&e.jsx("p",{className:"wrb-hint",children:n}),d&&e.jsx("p",{className:"wrb-field-error",role:"alert",children:d})]})}function C(){const r="wrb-styles";if(document.getElementById(r))return;const a=`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),b=require("react"),C=require("react-dom");async function L(e,t){const n={"Content-Type":"application/json"};e.authToken&&(n.Authorization=`Bearer ${e.authToken}`);const d={action:e.action,payload:{...t,datum:new Date().toISOString()}},i=await fetch(e.apiUrl,{method:"PATCH",headers:n,body:JSON.stringify(d)});let l;try{l=await i.json()}catch{if(!i.ok)throw new Error(`Server antwortete mit Status ${i.status}`);return}if(l!==null&&typeof l=="object"&&"ok"in l&&l.ok===!1){const s=l.message;throw new Error(typeof s=="string"&&s?s:`Server antwortete mit Status ${i.status}`)}if(!i.ok)throw new Error(`Server antwortete mit Status ${i.status}`)}const z=new Date().toLocaleDateString("de-DE",{day:"2-digit",month:"2-digit",year:"numeric"}),T={name:"",email:"",vertragId:"",widerrufsgrund:"",datum:z};function j(e){const t={};return e.name.trim()||(t.name="Bitte geben Sie Ihren Namen an."),e.email.trim()?/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e.email)||(t.email="Bitte geben Sie eine gültige E-Mail-Adresse an."):t.email="Bitte geben Sie Ihre E-Mail-Adresse an.",e.vertragId.trim()||(t.vertragId="Bitte geben Sie die Bestellnummer oder Vertragsnummer an."),t}function W({config:e,onClose:t}){const[n,d]=b.useState(T),[i,l]=b.useState({}),[s,p]=b.useState({}),[x,y]=b.useState("idle"),[k,N]=b.useState(""),S=b.useRef(null);b.useEffect(()=>{var c;(c=S.current)==null||c.focus();const a=o=>o.key==="Escape"&&t();return document.addEventListener("keydown",a),()=>document.removeEventListener("keydown",a)},[t]);function w(a,c){const o={...n,[a]:c};if(d(o),s[a]){const h=j(o);l(g=>({...g,[a]:h[a]}))}}function v(a){p(o=>({...o,[a]:!0}));const c=j(n);l(o=>({...o,[a]:c[a]}))}async function I(a){var h,g;a.preventDefault();const c=Object.fromEntries(Object.keys(n).map(f=>[f,!0]));p(c);const o=j(n);if(l(o),!(Object.keys(o).length>0)){y("loading"),N("");try{await L(e,n),y("success"),(h=e.onSuccess)==null||h.call(e)}catch(f){const E=f instanceof Error?f:new Error("Ein unbekannter Fehler ist aufgetreten.");N(E.message),y("error"),(g=e.onError)==null||g.call(e,E)}}}const A=e.companyName?`Widerruf – ${e.companyName}`:"Widerrufsformular";return r.jsx("div",{className:"wrb-overlay",role:"dialog","aria-modal":"true","aria-labelledby":"wrb-title",onClick:a=>a.target===a.currentTarget&&t(),children:r.jsxs("div",{className:"wrb-modal",children:[r.jsxs("div",{className:"wrb-modal-header",children:[r.jsx("h2",{className:"wrb-modal-title",id:"wrb-title",children:A}),r.jsx("button",{className:"wrb-close-btn",onClick:t,"aria-label":"Schließen",type:"button",children:"✕"})]}),x==="success"?r.jsxs("div",{className:"wrb-modal-body",children:[r.jsxs("div",{className:"wrb-success",children:[r.jsx("span",{className:"wrb-success-icon",children:"✓"}),r.jsx("h3",{children:"Widerruf eingegangen"}),r.jsxs("p",{children:["Ihr Widerruf wurde erfolgreich übermittelt. Sie erhalten in Kürze eine Bestätigung an ",r.jsx("strong",{children:n.email}),"."]})]}),r.jsx($,{links:e.legalLinks})]}):r.jsxs("div",{className:"wrb-modal-body",children:[e.introText&&r.jsx("p",{className:"wrb-intro",children:e.introText}),x==="error"&&k&&r.jsx("div",{className:"wrb-alert wrb-alert-error",role:"alert",children:k}),r.jsxs("form",{onSubmit:I,noValidate:!0,children:[r.jsx(m,{label:"Name",required:!0,error:s.name?i.name:void 0,children:r.jsx("input",{ref:S,className:`wrb-input${s.name&&i.name?" wrb-error":""}`,type:"text",autoComplete:"name",value:n.name,onChange:a=>w("name",a.target.value),onBlur:()=>v("name"),placeholder:"Vor- und Nachname"})}),r.jsx(m,{label:"E-Mail-Adresse",required:!0,hint:"Hierüber erhalten Sie die Eingangsbestätigung.",error:s.email?i.email:void 0,children:r.jsx("input",{className:`wrb-input${s.email&&i.email?" wrb-error":""}`,type:"email",autoComplete:"email",value:n.email,onChange:a=>w("email",a.target.value),onBlur:()=>v("email"),placeholder:"name@beispiel.de"})}),r.jsx(m,{label:"Bestell- / Auftrags- / Vertragsnummer",required:!0,hint:"Zu finden in Ihrer Bestellbestätigung.",error:s.vertragId?i.vertragId:void 0,children:r.jsx("input",{className:`wrb-input${s.vertragId&&i.vertragId?" wrb-error":""}`,type:"text",value:n.vertragId,onChange:a=>w("vertragId",a.target.value),onBlur:()=>v("vertragId"),placeholder:"z.B. 10045678"})}),r.jsx(m,{label:"Widerrufsgrund",hint:"Freiwillige Angabe – ein Widerruf ist ohne Angabe von Gründen möglich.",children:r.jsx("textarea",{className:"wrb-textarea",value:n.widerrufsgrund,onChange:a=>w("widerrufsgrund",a.target.value),placeholder:"Optional",rows:3})}),r.jsx(m,{label:"Datum der Widerrufserklärung",children:r.jsx("div",{className:"wrb-date-display",children:z})}),r.jsxs("div",{className:"wrb-actions",children:[r.jsx("button",{type:"button",className:"wrb-cancel-btn",onClick:t,children:e.cancelLabel??"Abbrechen"}),r.jsx("button",{type:"submit",className:"wrb-submit-btn",disabled:x==="loading",children:x==="loading"?"Wird gesendet…":e.submitLabel??"Absenden"})]})]}),r.jsx($,{links:e.legalLinks})]})]})})}function m({label:e,required:t,hint:n,error:d,children:i}){return r.jsxs("div",{className:"wrb-field",children:[r.jsxs("label",{className:"wrb-label",children:[e,t&&r.jsx("span",{className:"wrb-required","aria-hidden":"true",children:"*"})]}),i,n&&!d&&r.jsx("p",{className:"wrb-hint",children:n}),d&&r.jsx("p",{className:"wrb-field-error",role:"alert",children:d})]})}function $({links:e}){return e!=null&&e.length?r.jsx("div",{className:"wrb-legal-links",children:e.map(t=>r.jsx("a",{href:t.href,className:"wrb-legal-link",target:"_blank",rel:"noopener noreferrer",children:t.name},t.href))}):null}const B=`
2
2
  /* Widerrufsbutton widget — prefix: wrb- */
3
3
  .wrb-btn {
4
4
  display: inline-flex;
@@ -200,4 +200,128 @@
200
200
  font-size: 14px;
201
201
  }
202
202
  .wrb-alert-error { background: #fef2f2; border: 1px solid #fecaca; color: #991b1b; }
203
- `,n=document.createElement("style");n.id=r,n.textContent=a,document.head.appendChild(n)}function A({config:r}){const[a,n]=s.useState(!1);return s.useEffect(()=>{C()},[]),e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:`wrb-btn${r.buttonClass?` ${r.buttonClass}`:""}`,onClick:()=>n(!0),children:r.buttonLabel??"Vertrag widerrufen"}),a&&I.createPortal(e.jsx(N,{config:r,onClose:()=>n(!1)}),document.body)]})}exports.WiderrufsModal=N;exports.WiderrufsWidget=A;
203
+
204
+ /* Legal links */
205
+ .wrb-legal-links {
206
+ display: flex;
207
+ flex-wrap: wrap;
208
+ gap: 4px 16px;
209
+ margin-top: 16px;
210
+ padding-top: 12px;
211
+ border-top: 1px solid #e5e7eb;
212
+ }
213
+ .wrb-legal-link {
214
+ font-size: 12px;
215
+ color: #6b7280;
216
+ text-decoration: none;
217
+ }
218
+ .wrb-legal-link:hover {
219
+ color: #374151;
220
+ text-decoration: underline;
221
+ }
222
+ `;function q(){const e="wrb-styles";if(document.getElementById(e))return;const t=document.createElement("style");t.id=e,t.textContent=B,document.head.appendChild(t)}function O({config:e}){const[t,n]=b.useState(!1);return b.useEffect(()=>{q()},[]),r.jsxs(r.Fragment,{children:[r.jsx("button",{type:"button",className:`wrb-btn${e.buttonClass?` ${e.buttonClass}`:""}`,onClick:()=>n(!0),children:e.buttonLabel??"Vertrag widerrufen"}),t&&C.createPortal(r.jsx(W,{config:e,onClose:()=>n(!1)}),document.body)]})}function u(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function D(e){var s;const t=new Date().toLocaleDateString("de-DE",{day:"2-digit",month:"2-digit",year:"numeric"}),n=e.companyName?`Widerruf – ${u(e.companyName)}`:"Widerrufsformular",d=u(e.formAction??e.apiUrl??"/rest/v1/apiCancellation"),i=e.introText?`<p class="wrb-intro">${u(e.introText)}</p>`:"",l=(s=e.legalLinks)!=null&&s.length?`
223
+ <div class="wrb-legal-links">
224
+ ${e.legalLinks.map(p=>`<a href="${u(p.href)}" class="wrb-legal-link" rel="noopener noreferrer">${u(p.name)}</a>`).join(`
225
+ `)}
226
+ </div>`:"";return`<!DOCTYPE html>
227
+ <html lang="de">
228
+ <head>
229
+ <meta charset="UTF-8">
230
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
231
+ <title>${n}</title>
232
+ <style>
233
+ *, *::before, *::after { box-sizing: border-box; }
234
+ body { margin: 0; background: #f9fafb; }
235
+ .wrb-page {
236
+ min-height: 100vh;
237
+ display: flex;
238
+ align-items: flex-start;
239
+ justify-content: center;
240
+ padding: 40px 16px;
241
+ }
242
+ .wrb-page .wrb-modal { max-height: none; }
243
+ .wrb-page .wrb-modal-title { font-size: 20px; }
244
+ ${B}
245
+ </style>
246
+ </head>
247
+ <body>
248
+ <div class="wrb-page">
249
+ <div class="wrb-modal">
250
+ <div class="wrb-modal-header">
251
+ <h1 class="wrb-modal-title">${n}</h1>
252
+ </div>
253
+ <div class="wrb-modal-body">
254
+ ${i}
255
+ <form method="POST" action="${d}" novalidate>
256
+ <div class="wrb-field">
257
+ <label class="wrb-label">
258
+ Name <span class="wrb-required" aria-hidden="true">*</span>
259
+ </label>
260
+ <input
261
+ class="wrb-input"
262
+ type="text"
263
+ name="name"
264
+ autocomplete="name"
265
+ placeholder="Vor- und Nachname"
266
+ required
267
+ >
268
+ </div>
269
+ <div class="wrb-field">
270
+ <label class="wrb-label">
271
+ E-Mail-Adresse <span class="wrb-required" aria-hidden="true">*</span>
272
+ </label>
273
+ <input
274
+ class="wrb-input"
275
+ type="email"
276
+ name="email"
277
+ autocomplete="email"
278
+ placeholder="name@beispiel.de"
279
+ required
280
+ >
281
+ <p class="wrb-hint">Hierüber erhalten Sie die Eingangsbestätigung.</p>
282
+ </div>
283
+ <div class="wrb-field">
284
+ <label class="wrb-label">
285
+ Bestell- / Auftrags- / Vertragsnummer
286
+ <span class="wrb-required" aria-hidden="true">*</span>
287
+ </label>
288
+ <input
289
+ class="wrb-input"
290
+ type="text"
291
+ name="vertragId"
292
+ placeholder="z.B. 10045678"
293
+ required
294
+ >
295
+ <p class="wrb-hint">Zu finden in Ihrer Bestellbestätigung.</p>
296
+ </div>
297
+ <div class="wrb-field">
298
+ <label class="wrb-label">Widerrufsgrund</label>
299
+ <textarea
300
+ class="wrb-textarea"
301
+ name="widerrufsgrund"
302
+ placeholder="Optional"
303
+ rows="3"
304
+ ></textarea>
305
+ <p class="wrb-hint">
306
+ Freiwillige Angabe – ein Widerruf ist ohne Angabe von Gründen möglich.
307
+ </p>
308
+ </div>
309
+ <div class="wrb-field">
310
+ <label class="wrb-label">Datum der Widerrufserklärung</label>
311
+ <div class="wrb-date-display">${t}</div>
312
+ <input type="hidden" name="datum" value="${t}">
313
+ </div>
314
+ <input type="hidden" name="action" value="${u(e.action)}">
315
+ ${e.successUrl?`<input type="hidden" name="successUrl" value="${u(e.successUrl)}">`:""}
316
+ <div class="wrb-actions">
317
+ <button type="submit" class="wrb-submit-btn">
318
+ ${u(e.submitLabel??"Absenden")}
319
+ </button>
320
+ </div>
321
+ </form>
322
+ ${l}
323
+ </div>
324
+ </div>
325
+ </div>
326
+ </body>
327
+ </html>`}exports.WiderrufsModal=W;exports.WiderrufsWidget=O;exports.generateFallbackHtml=D;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { WiderrufsWidget } from './components/WiderrufsWidget';
2
2
  export { WiderrufsModal } from './components/WiderrufsModal';
3
- export type { WiderrufsConfig, WiderrufsFormData, SubmitStatus } from './types';
3
+ export { generateFallbackHtml } from './fallback';
4
+ export type { WiderrufsConfig, WiderrufsFormData, SubmitStatus, LegalLink } from './types';