Plugin Directory

Changeset 3410996


Ignore:
Timestamp:
12/04/2025 01:31:17 PM (3 months ago)
Author:
dekode
Message:

Tagging 2.3.1

Location:
dekode-fundraising
Files:
20 edited
11 copied

Legend:

Unmodified
Added
Removed
  • dekode-fundraising/tags/2.3.1/CHANGELOG.txt

    r3408236 r3410996  
    1 = 2.2.1 (2025-08-22) =
    2 * Initial wordpress.org release.
     1= 2.3.1 (2025-12-04) =
     2* Bundle languages dir in zip.
    33
    44= 2.3.0 (2025-12-02) =
    55* Reintroduce translation files.
     6
     7= 2.2.1 (2025-08-22) =
     8* Initial WordPress.org release.
  • dekode-fundraising/tags/2.3.1/README.txt

    r3408236 r3410996  
    44Requires PHP: 8.1
    55Tested up to: 6.8
    6 Stable tag: 2.3.0
     6Stable tag: 2.3.1
    77License: GPLv3 or later
    88License URI: https://www.gnu.org/licenses/gpl-3.0.html
     
    4646== Changelog ==
    4747
    48 = 2.2.1 (2025-08-22) =
    49 * Initial WordPress.org release.
     48= 2.3.1 (2025-12-04) =
     49* Bundle languages dir in zip.
    5050
    5151= 2.3.0 (2025-12-02) =
    5252* Reintroduce translation files.
     53
     54= 2.2.1 (2025-08-22) =
     55* Initial WordPress.org release.
  • dekode-fundraising/tags/2.3.1/build/blocks/donation-form/editor.asset.php

    r3382635 r3410996  
    1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '59d96ee1fd27a6d10057');
     1<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '916a72b70b315aff448b');
  • dekode-fundraising/tags/2.3.1/build/blocks/donation-form/editor.js

    r3382635 r3410996  
    1 (()=>{"use strict";const e=window.wp.blocks,n=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-form","title":"Donation Form","description":"Displays a donation form.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true}},"attributes":{"formId":{"type":"number","default":0},"urlParams":{"type":"array","default":[],"items":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}}}},"editorScript":"file:./editor.js","viewScript":"fundy-form-script","viewStyle":"fundy-form-style"}'),r=window.wp.blockEditor,o=window.wp.element,i=window.wp.components,t=window.wp.i18n,a=window.ReactJSXRuntime;(0,e.registerBlockType)(n,{edit:function({attributes:{formId:e,urlParams:n=[]},setAttributes:s}){var d,l;const[u,c]=(0,o.useReducer)((e,n)=>({...e,...n}),{isInitialized:!1,isLoaded:!1,apiToken:null!==(d=window.fundySettings.apiToken)&&void 0!==d?d:"",baseURL:null!==(l=window.fundySettings.baseURL)&&void 0!==l?l:"",forms:!1,error:null}),{isInitialized:p,isLoaded:m,apiToken:f,baseURL:h,forms:g,error:k}=u;if((0,o.useEffect)(()=>{!1===p&&f&&h&&c({isInitialized:!0})},[p,f,h]),(0,o.useEffect)(()=>{h&&f&&fetch(`${h}/api/v1/organization/forms`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:"Bearer "+f}}).then(e=>{if(!e.ok)throw new Error("Network response was not ok.");return e.json()}).then(n=>{const r=n.map(e=>({value:e.id,label:e.name}));c({isLoaded:!0,forms:r,error:null}),!e&&r.length&&s({formId:parseInt(r[0].value,10)})}).catch(e=>{c({error:"There has been a problem with your fetch operation: "+e})})},[h,f,e,s]),!f)return(0,a.jsx)("div",{...(0,r.useBlockProps)(),children:(0,a.jsx)(i.Placeholder,{instructions:(0,t.__)("Please set an API Token on the plugin settings page.","dekode-fundraising")})});const w=g&&g.length>0,y=(e,r,o)=>{const i=n.map((n,i)=>i===e?{...n,[r]:o}:n);s({urlParams:i})};return(0,a.jsx)("div",{...(0,r.useBlockProps)(),children:(0,a.jsxs)(i.Placeholder,{label:(0,t.__)("Dekode Fundraising Form","dekode-fundraising"),isColumnLayout:!0,children:[(0,a.jsx)(i.SelectControl,{label:(0,t.__)("Select a Form","dekode-fundraising"),value:e,className:"fundy-form",options:g||[{label:"",value:""}],onChange:e=>s({formId:parseInt(e,10)}),disabled:!m}),!w&&(0,a.jsx)("p",{children:(0,t.__)("No forms found. Please create a Form on your Dekode Fundraising account first.","dekode-fundraising")}),!m&&(0,a.jsx)("p",{children:(0,t.__)("Loading…","dekode-fundraising")}),k&&(0,a.jsx)("p",{children:"Error: "+k}),(0,a.jsxs)("div",{className:"fundy-form-params",children:[(0,a.jsx)("h4",{children:(0,t.__)("Default URL Parameters (Optional)","dekode-fundraising")}),(0,a.jsxs)("div",{style:{marginTop:"1em"},children:[n.map((e,r)=>(0,a.jsxs)(i.Flex,{children:[(0,a.jsx)(i.FlexBlock,{children:(0,a.jsx)(i.TextControl,{label:(0,t.__)("Key","dekode-fundraising"),value:e.key,onChange:e=>y(r,"key",e)})}),(0,a.jsx)(i.FlexBlock,{children:(0,a.jsx)(i.TextControl,{label:(0,t.__)("Value","dekode-fundraising"),value:e.value,onChange:e=>y(r,"value",e)})}),(0,a.jsx)(i.FlexItem,{children:(0,a.jsx)(i.Button,{isDestructive:!0,onClick:()=>(e=>{const r=n.filter((n,r)=>r!==e);s({urlParams:r})})(r),style:{marginTop:"14px"},children:(0,t.__)("Remove","dekode-fundraising")})})]},`param-${r}`)),(0,a.jsx)(i.Button,{variant:"link",onClick:()=>{s({urlParams:[...n,{key:"",value:""}]})},children:(0,t.__)("Add Parameter","dekode-fundraising")})]})]})]})})},save:()=>null})})();
     1/******/ (() => { // webpackBootstrap
     2/******/    "use strict";
     3/******/    var __webpack_modules__ = ({
     4
     5/***/ "./src/blocks/donation-form/block.json":
     6/*!*********************************************!*\
     7  !*** ./src/blocks/donation-form/block.json ***!
     8  \*********************************************/
     9/***/ ((module) => {
     10
     11module.exports = /*#__PURE__*/JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-form","title":"Donation Form","description":"Displays a donation form.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true}},"attributes":{"formId":{"type":"number","default":0},"urlParams":{"type":"array","default":[],"items":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}}}},"editorScript":"file:./editor.js","viewScript":"fundy-form-script","viewStyle":"fundy-form-style"}');
     12
     13/***/ }),
     14
     15/***/ "./src/blocks/donation-form/edit.js":
     16/*!******************************************!*\
     17  !*** ./src/blocks/donation-form/edit.js ***!
     18  \******************************************/
     19/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
     20
     21__webpack_require__.r(__webpack_exports__);
     22/* harmony export */ __webpack_require__.d(__webpack_exports__, {
     23/* harmony export */   "default": () => (/* binding */ Edit)
     24/* harmony export */ });
     25/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/block-editor */ "@wordpress/block-editor");
     26/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0__);
     27/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
     28/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__);
     29/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/components */ "@wordpress/components");
     30/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__);
     31/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n");
     32/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__);
     33/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! react/jsx-runtime */ "react/jsx-runtime");
     34/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__);
     35/**
     36 * WordPress dependencies
     37 */
     38
     39
     40
     41
     42
     43/**
     44 * Render the content generation block.
     45 */
     46
     47function Edit({
     48  attributes: {
     49    formId,
     50    urlParams = []
     51  },
     52  setAttributes
     53}) {
     54  var _window$fundySettings, _window$fundySettings2;
     55  const [state, setState] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_1__.useReducer)((s, a) => ({
     56    ...s,
     57    ...a
     58  }), {
     59    isInitialized: false,
     60    isLoaded: false,
     61    apiToken: (_window$fundySettings = window.fundySettings.apiToken) !== null && _window$fundySettings !== void 0 ? _window$fundySettings : '',
     62    baseURL: (_window$fundySettings2 = window.fundySettings.baseURL) !== null && _window$fundySettings2 !== void 0 ? _window$fundySettings2 : '',
     63    forms: false,
     64    error: null
     65  });
     66  const {
     67    isInitialized,
     68    isLoaded,
     69    apiToken,
     70    baseURL,
     71    forms,
     72    error
     73  } = state;
     74
     75  // Initialize
     76  (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_1__.useEffect)(() => {
     77    if (false === isInitialized && apiToken && baseURL) {
     78      setState({
     79        isInitialized: true
     80      });
     81    }
     82  }, [isInitialized, apiToken, baseURL]);
     83
     84  // Fetch forms
     85  (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_1__.useEffect)(() => {
     86    if (baseURL && apiToken) {
     87      fetch(`${baseURL}/api/v1/organization/forms`, {
     88        method: 'GET',
     89        headers: {
     90          'Content-Type': 'application/json',
     91          Authorization: 'Bearer ' + apiToken
     92        }
     93      }).then(response => {
     94        if (!response.ok) {
     95          throw new Error('Network response was not ok.');
     96        }
     97        return response.json();
     98      }).then(data => {
     99        const options = data.map(form => ({
     100          value: form.id,
     101          label: form.name
     102        }));
     103        setState({
     104          isLoaded: true,
     105          forms: options,
     106          error: null
     107        });
     108
     109        // If no form is saved, set first form as selected.
     110        if (!formId && options.length) {
     111          setAttributes({
     112            formId: parseInt(options[0].value, 10)
     113          });
     114        }
     115      }).catch(err => {
     116        setState({
     117          error: 'There has been a problem with your fetch operation: ' + err
     118        });
     119      });
     120    }
     121  }, [baseURL, apiToken, formId, setAttributes]);
     122
     123  /* eslint-disable react-hooks/rules-of-hooks */
     124  if (!apiToken) {
     125    return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
     126      ...(0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0__.useBlockProps)(),
     127      children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.Placeholder, {
     128        instructions: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Please set an API Token on the plugin settings page.', 'dekode-fundraising')
     129      })
     130    });
     131  }
     132  const hasForms = forms && forms.length > 0;
     133
     134  /**
     135   * Repeater handlers
     136   */
     137  const addParam = () => {
     138    setAttributes({
     139      urlParams: [...urlParams, {
     140        key: '',
     141        value: ''
     142      }]
     143    });
     144  };
     145  const updateParam = (index, field, newValue) => {
     146    const updated = urlParams.map((item, i) => i === index ? {
     147      ...item,
     148      [field]: newValue
     149    } : item);
     150    setAttributes({
     151      urlParams: updated
     152    });
     153  };
     154  const removeParam = index => {
     155    const updated = urlParams.filter((_, i) => i !== index);
     156    setAttributes({
     157      urlParams: updated
     158    });
     159  };
     160  return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
     161    ...(0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0__.useBlockProps)(),
     162    children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.Placeholder, {
     163      label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Dekode Fundraising Form', 'dekode-fundraising'),
     164      isColumnLayout: true,
     165      children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.SelectControl, {
     166        label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Select a Form', 'dekode-fundraising'),
     167        value: formId,
     168        className: "fundy-form",
     169        options: forms || [{
     170          label: '',
     171          value: ''
     172        }],
     173        onChange: value => setAttributes({
     174          formId: parseInt(value, 10)
     175        }),
     176        disabled: !isLoaded
     177      }), !hasForms && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("p", {
     178        children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('No forms found. Please create a Form on your Dekode Fundraising account first.', 'dekode-fundraising')
     179      }), !isLoaded && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("p", {
     180        children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Loading…', 'dekode-fundraising')
     181      }), error && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("p", {
     182        children: 'Error: ' + error
     183      }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
     184        className: "fundy-form-params",
     185        children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("h4", {
     186          children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Default URL Parameters (Optional)', 'dekode-fundraising')
     187        }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
     188          style: {
     189            marginTop: '1em'
     190          },
     191          children: [urlParams.map((param, index) => /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.Flex, {
     192            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.FlexBlock, {
     193              children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.TextControl, {
     194                label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Key', 'dekode-fundraising'),
     195                value: param.key,
     196                onChange: val => updateParam(index, 'key', val)
     197              })
     198            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.FlexBlock, {
     199              children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.TextControl, {
     200                label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Value', 'dekode-fundraising'),
     201                value: param.value,
     202                onChange: val => updateParam(index, 'value', val)
     203              })
     204            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.FlexItem, {
     205              children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.Button, {
     206                isDestructive: true,
     207                onClick: () => removeParam(index),
     208                style: {
     209                  marginTop: '14px'
     210                },
     211                children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Remove', 'dekode-fundraising')
     212              })
     213            })]
     214          }, `param-${index}`)), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.Button, {
     215            variant: "link",
     216            onClick: addParam,
     217            children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Add Parameter', 'dekode-fundraising')
     218          })]
     219        })]
     220      })]
     221    })
     222  });
     223  /* eslint-enable react-hooks/rules-of-hooks */
     224}
     225
     226/***/ }),
     227
     228/***/ "@wordpress/block-editor":
     229/*!*************************************!*\
     230  !*** external ["wp","blockEditor"] ***!
     231  \*************************************/
     232/***/ ((module) => {
     233
     234module.exports = window["wp"]["blockEditor"];
     235
     236/***/ }),
     237
     238/***/ "@wordpress/blocks":
     239/*!********************************!*\
     240  !*** external ["wp","blocks"] ***!
     241  \********************************/
     242/***/ ((module) => {
     243
     244module.exports = window["wp"]["blocks"];
     245
     246/***/ }),
     247
     248/***/ "@wordpress/components":
     249/*!************************************!*\
     250  !*** external ["wp","components"] ***!
     251  \************************************/
     252/***/ ((module) => {
     253
     254module.exports = window["wp"]["components"];
     255
     256/***/ }),
     257
     258/***/ "@wordpress/element":
     259/*!*********************************!*\
     260  !*** external ["wp","element"] ***!
     261  \*********************************/
     262/***/ ((module) => {
     263
     264module.exports = window["wp"]["element"];
     265
     266/***/ }),
     267
     268/***/ "@wordpress/i18n":
     269/*!******************************!*\
     270  !*** external ["wp","i18n"] ***!
     271  \******************************/
     272/***/ ((module) => {
     273
     274module.exports = window["wp"]["i18n"];
     275
     276/***/ }),
     277
     278/***/ "react/jsx-runtime":
     279/*!**********************************!*\
     280  !*** external "ReactJSXRuntime" ***!
     281  \**********************************/
     282/***/ ((module) => {
     283
     284module.exports = window["ReactJSXRuntime"];
     285
     286/***/ })
     287
     288/******/    });
     289/************************************************************************/
     290/******/    // The module cache
     291/******/    var __webpack_module_cache__ = {};
     292/******/   
     293/******/    // The require function
     294/******/    function __webpack_require__(moduleId) {
     295/******/        // Check if module is in cache
     296/******/        var cachedModule = __webpack_module_cache__[moduleId];
     297/******/        if (cachedModule !== undefined) {
     298/******/            return cachedModule.exports;
     299/******/        }
     300/******/        // Create a new module (and put it into the cache)
     301/******/        var module = __webpack_module_cache__[moduleId] = {
     302/******/            // no module.id needed
     303/******/            // no module.loaded needed
     304/******/            exports: {}
     305/******/        };
     306/******/   
     307/******/        // Execute the module function
     308/******/        __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
     309/******/   
     310/******/        // Return the exports of the module
     311/******/        return module.exports;
     312/******/    }
     313/******/   
     314/************************************************************************/
     315/******/    /* webpack/runtime/compat get default export */
     316/******/    (() => {
     317/******/        // getDefaultExport function for compatibility with non-harmony modules
     318/******/        __webpack_require__.n = (module) => {
     319/******/            var getter = module && module.__esModule ?
     320/******/                () => (module['default']) :
     321/******/                () => (module);
     322/******/            __webpack_require__.d(getter, { a: getter });
     323/******/            return getter;
     324/******/        };
     325/******/    })();
     326/******/   
     327/******/    /* webpack/runtime/define property getters */
     328/******/    (() => {
     329/******/        // define getter functions for harmony exports
     330/******/        __webpack_require__.d = (exports, definition) => {
     331/******/            for(var key in definition) {
     332/******/                if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
     333/******/                    Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
     334/******/                }
     335/******/            }
     336/******/        };
     337/******/    })();
     338/******/   
     339/******/    /* webpack/runtime/hasOwnProperty shorthand */
     340/******/    (() => {
     341/******/        __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
     342/******/    })();
     343/******/   
     344/******/    /* webpack/runtime/make namespace object */
     345/******/    (() => {
     346/******/        // define __esModule on exports
     347/******/        __webpack_require__.r = (exports) => {
     348/******/            if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
     349/******/                Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
     350/******/            }
     351/******/            Object.defineProperty(exports, '__esModule', { value: true });
     352/******/        };
     353/******/    })();
     354/******/   
     355/************************************************************************/
     356var __webpack_exports__ = {};
     357// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
     358(() => {
     359/*!********************************************!*\
     360  !*** ./src/blocks/donation-form/editor.js ***!
     361  \********************************************/
     362__webpack_require__.r(__webpack_exports__);
     363/* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/blocks */ "@wordpress/blocks");
     364/* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_blocks__WEBPACK_IMPORTED_MODULE_0__);
     365/* harmony import */ var _block_json__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./block.json */ "./src/blocks/donation-form/block.json");
     366/* harmony import */ var _edit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./edit */ "./src/blocks/donation-form/edit.js");
     367/**
     368 * WordPress dependencies
     369 */
     370
     371
     372/**
     373 * Internal dependencies
     374 */
     375
     376
     377(0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_0__.registerBlockType)(_block_json__WEBPACK_IMPORTED_MODULE_1__, {
     378  edit: _edit__WEBPACK_IMPORTED_MODULE_2__["default"],
     379  save: () => null
     380});
     381})();
     382
     383/******/ })()
     384;
     385//# sourceMappingURL=editor.js.map
  • dekode-fundraising/tags/2.3.1/build/blocks/donation-receipt/editor.asset.php

    r3382635 r3410996  
    1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-i18n'), 'version' => '7b5f3ffebaab90c2ba48');
     1<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-i18n'), 'version' => 'fb5c7ccc9c7d5bea9f70');
  • dekode-fundraising/tags/2.3.1/build/blocks/donation-receipt/editor.js

    r3382635 r3410996  
    1 (()=>{"use strict";const e=window.wp.blocks,i=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-receipt","title":"Donation Receipt","description":"Displays a donation receipt on a thank you page.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true},"multiple":false},"attributes":{},"editorScript":"file:editor.js","script":"file:frontend.js"}'),t=window.wp.blockEditor,n=window.wp.i18n,d=window.ReactJSXRuntime;(0,e.registerBlockType)(i,{edit:function(){return(0,d.jsx)("div",{...(0,t.useBlockProps)(),children:(0,d.jsx)("table",{children:(0,d.jsxs)("tbody",{children:[(0,d.jsxs)("tr",{children:[(0,d.jsx)("td",{children:(0,n.__)("Name","dekode-fundraising")}),(0,d.jsx)("td",{children:"John Smith"})]}),(0,d.jsxs)("tr",{children:[(0,d.jsx)("td",{children:(0,n.__)("Date","dekode-fundraising")}),(0,d.jsx)("td",{children:"name@email.no"})]}),(0,d.jsxs)("tr",{children:[(0,d.jsx)("td",{children:(0,n.__)("Total amount","dekode-fundraising")}),(0,d.jsx)("td",{children:"400 kr"})]})]})})})},save:()=>null})})();
     1/******/ (() => { // webpackBootstrap
     2/******/    "use strict";
     3/******/    var __webpack_modules__ = ({
     4
     5/***/ "./src/blocks/donation-receipt/block.json":
     6/*!************************************************!*\
     7  !*** ./src/blocks/donation-receipt/block.json ***!
     8  \************************************************/
     9/***/ ((module) => {
     10
     11module.exports = /*#__PURE__*/JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-receipt","title":"Donation Receipt","description":"Displays a donation receipt on a thank you page.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true},"multiple":false},"attributes":{},"editorScript":"file:editor.js","script":"file:frontend.js"}');
     12
     13/***/ }),
     14
     15/***/ "./src/blocks/donation-receipt/edit.js":
     16/*!*********************************************!*\
     17  !*** ./src/blocks/donation-receipt/edit.js ***!
     18  \*********************************************/
     19/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
     20
     21__webpack_require__.r(__webpack_exports__);
     22/* harmony export */ __webpack_require__.d(__webpack_exports__, {
     23/* harmony export */   "default": () => (/* binding */ Edit)
     24/* harmony export */ });
     25/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/block-editor */ "@wordpress/block-editor");
     26/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0__);
     27/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n");
     28/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__);
     29/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react/jsx-runtime */ "react/jsx-runtime");
     30/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__);
     31/**
     32 * WordPress dependencies
     33 */
     34
     35
     36
     37/**
     38 * Render the content generation block.
     39 */
     40
     41function Edit() {
     42  return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("div", {
     43    ...(0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0__.useBlockProps)(),
     44    children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("table", {
     45      children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tbody", {
     46        children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     47          children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     48            children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Name', 'dekode-fundraising')
     49          }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     50            children: "John Smith"
     51          })]
     52        }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     53          children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     54            children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Date', 'dekode-fundraising')
     55          }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     56            children: "name@email.no"
     57          })]
     58        }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     59          children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     60            children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Total amount', 'dekode-fundraising')
     61          }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     62            children: "400 kr"
     63          })]
     64        })]
     65      })
     66    })
     67  });
     68}
     69
     70/***/ }),
     71
     72/***/ "@wordpress/block-editor":
     73/*!*************************************!*\
     74  !*** external ["wp","blockEditor"] ***!
     75  \*************************************/
     76/***/ ((module) => {
     77
     78module.exports = window["wp"]["blockEditor"];
     79
     80/***/ }),
     81
     82/***/ "@wordpress/blocks":
     83/*!********************************!*\
     84  !*** external ["wp","blocks"] ***!
     85  \********************************/
     86/***/ ((module) => {
     87
     88module.exports = window["wp"]["blocks"];
     89
     90/***/ }),
     91
     92/***/ "@wordpress/i18n":
     93/*!******************************!*\
     94  !*** external ["wp","i18n"] ***!
     95  \******************************/
     96/***/ ((module) => {
     97
     98module.exports = window["wp"]["i18n"];
     99
     100/***/ }),
     101
     102/***/ "react/jsx-runtime":
     103/*!**********************************!*\
     104  !*** external "ReactJSXRuntime" ***!
     105  \**********************************/
     106/***/ ((module) => {
     107
     108module.exports = window["ReactJSXRuntime"];
     109
     110/***/ })
     111
     112/******/    });
     113/************************************************************************/
     114/******/    // The module cache
     115/******/    var __webpack_module_cache__ = {};
     116/******/   
     117/******/    // The require function
     118/******/    function __webpack_require__(moduleId) {
     119/******/        // Check if module is in cache
     120/******/        var cachedModule = __webpack_module_cache__[moduleId];
     121/******/        if (cachedModule !== undefined) {
     122/******/            return cachedModule.exports;
     123/******/        }
     124/******/        // Create a new module (and put it into the cache)
     125/******/        var module = __webpack_module_cache__[moduleId] = {
     126/******/            // no module.id needed
     127/******/            // no module.loaded needed
     128/******/            exports: {}
     129/******/        };
     130/******/   
     131/******/        // Execute the module function
     132/******/        __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
     133/******/   
     134/******/        // Return the exports of the module
     135/******/        return module.exports;
     136/******/    }
     137/******/   
     138/************************************************************************/
     139/******/    /* webpack/runtime/compat get default export */
     140/******/    (() => {
     141/******/        // getDefaultExport function for compatibility with non-harmony modules
     142/******/        __webpack_require__.n = (module) => {
     143/******/            var getter = module && module.__esModule ?
     144/******/                () => (module['default']) :
     145/******/                () => (module);
     146/******/            __webpack_require__.d(getter, { a: getter });
     147/******/            return getter;
     148/******/        };
     149/******/    })();
     150/******/   
     151/******/    /* webpack/runtime/define property getters */
     152/******/    (() => {
     153/******/        // define getter functions for harmony exports
     154/******/        __webpack_require__.d = (exports, definition) => {
     155/******/            for(var key in definition) {
     156/******/                if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
     157/******/                    Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
     158/******/                }
     159/******/            }
     160/******/        };
     161/******/    })();
     162/******/   
     163/******/    /* webpack/runtime/hasOwnProperty shorthand */
     164/******/    (() => {
     165/******/        __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
     166/******/    })();
     167/******/   
     168/******/    /* webpack/runtime/make namespace object */
     169/******/    (() => {
     170/******/        // define __esModule on exports
     171/******/        __webpack_require__.r = (exports) => {
     172/******/            if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
     173/******/                Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
     174/******/            }
     175/******/            Object.defineProperty(exports, '__esModule', { value: true });
     176/******/        };
     177/******/    })();
     178/******/   
     179/************************************************************************/
     180var __webpack_exports__ = {};
     181// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
     182(() => {
     183/*!***********************************************!*\
     184  !*** ./src/blocks/donation-receipt/editor.js ***!
     185  \***********************************************/
     186__webpack_require__.r(__webpack_exports__);
     187/* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/blocks */ "@wordpress/blocks");
     188/* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_blocks__WEBPACK_IMPORTED_MODULE_0__);
     189/* harmony import */ var _block_json__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./block.json */ "./src/blocks/donation-receipt/block.json");
     190/* harmony import */ var _edit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./edit */ "./src/blocks/donation-receipt/edit.js");
     191/**
     192 * WordPress dependencies
     193 */
     194
     195
     196/**
     197 * Internal dependencies
     198 */
     199
     200
     201(0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_0__.registerBlockType)(_block_json__WEBPACK_IMPORTED_MODULE_1__, {
     202  edit: _edit__WEBPACK_IMPORTED_MODULE_2__["default"],
     203  save: () => null
     204});
     205})();
     206
     207/******/ })()
     208;
     209//# sourceMappingURL=editor.js.map
  • dekode-fundraising/tags/2.3.1/build/blocks/donation-receipt/frontend.asset.php

    r3382635 r3410996  
    1 <?php return array('dependencies' => array('react-dom', 'react-jsx-runtime', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '9e529a7d822ecdbcbcef');
     1<?php return array('dependencies' => array('react-dom', 'react-jsx-runtime', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '7e045c998b07105a18a6');
  • dekode-fundraising/tags/2.3.1/build/blocks/donation-receipt/frontend.js

    r3382635 r3410996  
    1 (()=>{"use strict";var e={338:(e,n,r)=>{var t=r(795);n.H=t.createRoot,t.hydrateRoot},795:e=>{e.exports=window.ReactDOM}},n={};function r(t){var d=n[t];if(void 0!==d)return d.exports;var o=n[t]={exports:{}};return e[t](o,o.exports,r),o.exports}r.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return r.d(n,{a:n}),n},r.d=(e,n)=>{for(var t in n)r.o(n,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},r.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n);var t=r(338);const d=window.wp.domReady;var o=r.n(d);const i=window.wp.element,a=window.wp.i18n,s=window.ReactJSXRuntime;function c(e){return new Date(e).toLocaleDateString()}const l=()=>{var e;const[n,r]=(0,i.useReducer)((e,n)=>({...e,...n}),{isLoaded:!1,isError:!1,baseURL:null!==(e=window.fundySettings.baseURL)&&void 0!==e?e:null,donation:null}),{isLoaded:t,isError:d,baseURL:o,donation:l}=n;return(0,i.useEffect)(()=>{const e=function(){const e=new URLSearchParams(window.location.search);return{donationId:e.get("donation_id")||null,token:e.get("token")||null,expiry:e.get("expiry")||null}}();e.donationId&&e.token&&e.expiry&&o||r({isLoaded:!0,isError:!0});const n={donation_id:e.donationId,token:e.token,expiry:e.expiry},t=new URLSearchParams(n).toString();fetch(o+"/api/v1/donation/receipt?"+t,{method:"GET",headers:{"Content-Type":"application/json"}}).then(e=>{if(e.ok)return e.json();throw new Error("Network response was not ok.")}).then(e=>{r({isLoaded:!0,isError:!1,donation:e})}).catch(()=>{r({isLoaded:!0,isError:!0})})},[o]),t?d||!l?(0,s.jsx)(i.Fragment,{children:(0,s.jsx)("p",{children:(0,a.__)("Unfortunately, we were unable to load the details for the donation at this moment; the link may have expired.","dekode-fundraising")})}):(0,s.jsx)(i.Fragment,{children:(0,s.jsx)("table",{children:(0,s.jsx)("tbody",{children:l&&l.company_name?(0,s.jsxs)(i.Fragment,{children:[l.company_name&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Company name","dekode-fundraising")}),(0,s.jsx)("td",{children:l.company_name})]}),l.first_name&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Contact person","dekode-fundraising")}),(0,s.jsx)("td",{children:l.first_name+" "+l?.last_name})]}),l.created_at&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Date","dekode-fundraising")}),(0,s.jsx)("td",{children:c(l.created_at)})]}),l.amount&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Total amount","dekode-fundraising")}),(0,s.jsx)("td",{children:l.amount})]}),l.invoice_url&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Invoice","dekode-fundraising")}),(0,s.jsx)("td",{children:(0,s.jsxs)("a",{href:l.invoice_url,children:[(0,a.__)("Download invoice","dekode-fundraising")," ","⇒"]})})]})]}):(0,s.jsxs)(i.Fragment,{children:[l.first_name&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Name","dekode-fundraising")}),(0,s.jsx)("td",{children:l.first_name+" "+l?.last_name})]}),l.created_at&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Date","dekode-fundraising")}),(0,s.jsx)("td",{children:c(l.created_at)})]}),l.amount&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Total amount","dekode-fundraising")}),(0,s.jsx)("td",{children:l.amount})]})]})})})}):null};o()(function(){document.querySelectorAll(".fundy-receipt").forEach(e=>{(0,t.H)(e).render((0,s.jsx)(l,{}))})})})();
     1/******/ (() => { // webpackBootstrap
     2/******/    "use strict";
     3/******/    var __webpack_modules__ = ({
     4
     5/***/ "./node_modules/react-dom/client.js":
     6/*!******************************************!*\
     7  !*** ./node_modules/react-dom/client.js ***!
     8  \******************************************/
     9/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
     10
     11
     12
     13var m = __webpack_require__(/*! react-dom */ "react-dom");
     14if (false) // removed by dead control flow
     15{} else {
     16  var i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
     17  exports.createRoot = function(c, o) {
     18    i.usingClientEntryPoint = true;
     19    try {
     20      return m.createRoot(c, o);
     21    } finally {
     22      i.usingClientEntryPoint = false;
     23    }
     24  };
     25  exports.hydrateRoot = function(c, h, o) {
     26    i.usingClientEntryPoint = true;
     27    try {
     28      return m.hydrateRoot(c, h, o);
     29    } finally {
     30      i.usingClientEntryPoint = false;
     31    }
     32  };
     33}
     34
     35
     36/***/ }),
     37
     38/***/ "./src/blocks/donation-receipt/components/Receipt/Receipt.jsx":
     39/*!********************************************************************!*\
     40  !*** ./src/blocks/donation-receipt/components/Receipt/Receipt.jsx ***!
     41  \********************************************************************/
     42/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
     43
     44__webpack_require__.r(__webpack_exports__);
     45/* harmony export */ __webpack_require__.d(__webpack_exports__, {
     46/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
     47/* harmony export */   formatDateTime: () => (/* binding */ formatDateTime)
     48/* harmony export */ });
     49/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
     50/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
     51/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n");
     52/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__);
     53/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react/jsx-runtime */ "react/jsx-runtime");
     54/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__);
     55/**
     56 * External dependencies
     57 */
     58
     59/**
     60 * WordPress dependencies
     61 */
     62
     63
     64
     65const Receipt = () => {
     66  var _window$fundySettings;
     67  const [state, setState] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useReducer)((s, a) => ({
     68    ...s,
     69    ...a
     70  }), {
     71    isLoaded: false,
     72    isError: false,
     73    baseURL: (_window$fundySettings = window.fundySettings.baseURL) !== null && _window$fundySettings !== void 0 ? _window$fundySettings : null,
     74    donation: null
     75  });
     76  const {
     77    isLoaded,
     78    isError,
     79    baseURL,
     80    donation
     81  } = state;
     82  (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
     83    const queryParams = getQueryParams();
     84    if (!queryParams.donationId || !queryParams.token || !queryParams.expiry || !baseURL) {
     85      setState({
     86        isLoaded: true,
     87        isError: true
     88      });
     89    }
     90    const params = {
     91      donation_id: queryParams.donationId,
     92      token: queryParams.token,
     93      expiry: queryParams.expiry
     94    };
     95    const queryString = new URLSearchParams(params).toString();
     96    fetch(baseURL + '/api/v1/donation/receipt?' + queryString, {
     97      method: 'GET',
     98      headers: {
     99        'Content-Type': 'application/json'
     100      }
     101    }).then(response => {
     102      if (response.ok) {
     103        return response.json();
     104      }
     105      throw new Error('Network response was not ok.');
     106    }).then(data => {
     107      setState({
     108        isLoaded: true,
     109        isError: false,
     110        donation: data
     111      });
     112    }).catch(() => {
     113      setState({
     114        isLoaded: true,
     115        isError: true
     116      });
     117    });
     118  }, [baseURL]);
     119  if (!isLoaded) {
     120    return null;
     121  }
     122  if (isError || !donation) {
     123    return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
     124      children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("p", {
     125        children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Unfortunately, we were unable to load the details for the donation at this moment; the link may have expired.', 'dekode-fundraising')
     126      })
     127    });
     128  }
     129  return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
     130    children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("table", {
     131      children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("tbody", {
     132        children: donation && donation.company_name ? /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
     133          children: [donation.company_name && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     134            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     135              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Company name', 'dekode-fundraising')
     136            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     137              children: donation.company_name
     138            })]
     139          }), donation.first_name && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     140            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     141              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Contact person', 'dekode-fundraising')
     142            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     143              children: donation.first_name + ' ' + donation?.last_name
     144            })]
     145          }), donation.created_at && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     146            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     147              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Date', 'dekode-fundraising')
     148            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     149              children: formatDateTime(donation.created_at)
     150            })]
     151          }), donation.amount && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     152            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     153              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Total amount', 'dekode-fundraising')
     154            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     155              children: donation.amount
     156            })]
     157          }), donation.invoice_url && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     158            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     159              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Invoice', 'dekode-fundraising')
     160            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     161              children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("a", {
     162                href: donation.invoice_url,
     163                children: [(0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Download invoice', 'dekode-fundraising'), ' ', "\u21D2"]
     164              })
     165            })]
     166          })]
     167        }) : /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
     168          children: [donation.first_name && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     169            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     170              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Name', 'dekode-fundraising')
     171            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     172              children: donation.first_name + ' ' + donation?.last_name
     173            })]
     174          }), donation.created_at && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     175            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     176              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Date', 'dekode-fundraising')
     177            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     178              children: formatDateTime(donation.created_at)
     179            })]
     180          }), donation.amount && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     181            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     182              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Total amount', 'dekode-fundraising')
     183            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     184              children: donation.amount
     185            })]
     186          })]
     187        })
     188      })
     189    })
     190  });
     191};
     192
     193/**
     194 * Format a datetime value as a date string in the user's locale.
     195 *
     196 * @param {string|Date|null|undefined} dateTime
     197 *
     198 * @returns {string} Formatted date or empty string if invalid.
     199 */
     200function formatDateTime(dateTime) {
     201  if (!dateTime) return 'unknown';
     202  const date = dateTime instanceof Date ? dateTime : new Date(dateTime);
     203  if (Number.isNaN(date.getTime())) {
     204    return 'unknown';
     205  }
     206  const locales = typeof navigator !== 'undefined' ? navigator.languages || navigator.language : undefined;
     207  return date.toLocaleDateString(locales, {
     208    year: 'numeric',
     209    month: 'numeric',
     210    day: 'numeric'
     211  });
     212}
     213
     214/**
     215 * Return the required query params from the page URL.
     216 */
     217function getQueryParams() {
     218  const params = new URLSearchParams(window.location.search);
     219  return {
     220    donationId: params.get('donation_id') || null,
     221    token: params.get('token') || null,
     222    expiry: params.get('expiry') || null
     223  };
     224}
     225/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Receipt);
     226
     227/***/ }),
     228
     229/***/ "./src/blocks/donation-receipt/components/Receipt/index.js":
     230/*!*****************************************************************!*\
     231  !*** ./src/blocks/donation-receipt/components/Receipt/index.js ***!
     232  \*****************************************************************/
     233/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
     234
     235__webpack_require__.r(__webpack_exports__);
     236/* harmony export */ __webpack_require__.d(__webpack_exports__, {
     237/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
     238/* harmony export */ });
     239/* harmony import */ var _Receipt__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Receipt */ "./src/blocks/donation-receipt/components/Receipt/Receipt.jsx");
     240/**
     241 * Internal dependencies
     242 */
     243
     244/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_Receipt__WEBPACK_IMPORTED_MODULE_0__["default"]);
     245
     246/***/ }),
     247
     248/***/ "@wordpress/dom-ready":
     249/*!**********************************!*\
     250  !*** external ["wp","domReady"] ***!
     251  \**********************************/
     252/***/ ((module) => {
     253
     254module.exports = window["wp"]["domReady"];
     255
     256/***/ }),
     257
     258/***/ "@wordpress/element":
     259/*!*********************************!*\
     260  !*** external ["wp","element"] ***!
     261  \*********************************/
     262/***/ ((module) => {
     263
     264module.exports = window["wp"]["element"];
     265
     266/***/ }),
     267
     268/***/ "@wordpress/i18n":
     269/*!******************************!*\
     270  !*** external ["wp","i18n"] ***!
     271  \******************************/
     272/***/ ((module) => {
     273
     274module.exports = window["wp"]["i18n"];
     275
     276/***/ }),
     277
     278/***/ "react-dom":
     279/*!***************************!*\
     280  !*** external "ReactDOM" ***!
     281  \***************************/
     282/***/ ((module) => {
     283
     284module.exports = window["ReactDOM"];
     285
     286/***/ }),
     287
     288/***/ "react/jsx-runtime":
     289/*!**********************************!*\
     290  !*** external "ReactJSXRuntime" ***!
     291  \**********************************/
     292/***/ ((module) => {
     293
     294module.exports = window["ReactJSXRuntime"];
     295
     296/***/ })
     297
     298/******/    });
     299/************************************************************************/
     300/******/    // The module cache
     301/******/    var __webpack_module_cache__ = {};
     302/******/   
     303/******/    // The require function
     304/******/    function __webpack_require__(moduleId) {
     305/******/        // Check if module is in cache
     306/******/        var cachedModule = __webpack_module_cache__[moduleId];
     307/******/        if (cachedModule !== undefined) {
     308/******/            return cachedModule.exports;
     309/******/        }
     310/******/        // Create a new module (and put it into the cache)
     311/******/        var module = __webpack_module_cache__[moduleId] = {
     312/******/            // no module.id needed
     313/******/            // no module.loaded needed
     314/******/            exports: {}
     315/******/        };
     316/******/   
     317/******/        // Execute the module function
     318/******/        __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
     319/******/   
     320/******/        // Return the exports of the module
     321/******/        return module.exports;
     322/******/    }
     323/******/   
     324/************************************************************************/
     325/******/    /* webpack/runtime/compat get default export */
     326/******/    (() => {
     327/******/        // getDefaultExport function for compatibility with non-harmony modules
     328/******/        __webpack_require__.n = (module) => {
     329/******/            var getter = module && module.__esModule ?
     330/******/                () => (module['default']) :
     331/******/                () => (module);
     332/******/            __webpack_require__.d(getter, { a: getter });
     333/******/            return getter;
     334/******/        };
     335/******/    })();
     336/******/   
     337/******/    /* webpack/runtime/define property getters */
     338/******/    (() => {
     339/******/        // define getter functions for harmony exports
     340/******/        __webpack_require__.d = (exports, definition) => {
     341/******/            for(var key in definition) {
     342/******/                if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
     343/******/                    Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
     344/******/                }
     345/******/            }
     346/******/        };
     347/******/    })();
     348/******/   
     349/******/    /* webpack/runtime/hasOwnProperty shorthand */
     350/******/    (() => {
     351/******/        __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
     352/******/    })();
     353/******/   
     354/******/    /* webpack/runtime/make namespace object */
     355/******/    (() => {
     356/******/        // define __esModule on exports
     357/******/        __webpack_require__.r = (exports) => {
     358/******/            if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
     359/******/                Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
     360/******/            }
     361/******/            Object.defineProperty(exports, '__esModule', { value: true });
     362/******/        };
     363/******/    })();
     364/******/   
     365/************************************************************************/
     366var __webpack_exports__ = {};
     367// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
     368(() => {
     369/*!*************************************************!*\
     370  !*** ./src/blocks/donation-receipt/frontend.js ***!
     371  \*************************************************/
     372__webpack_require__.r(__webpack_exports__);
     373/* harmony import */ var react_dom_client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react-dom/client */ "./node_modules/react-dom/client.js");
     374/* harmony import */ var _wordpress_dom_ready__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/dom-ready */ "@wordpress/dom-ready");
     375/* harmony import */ var _wordpress_dom_ready__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_dom_ready__WEBPACK_IMPORTED_MODULE_1__);
     376/* harmony import */ var _components_Receipt__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/Receipt */ "./src/blocks/donation-receipt/components/Receipt/index.js");
     377/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react/jsx-runtime */ "react/jsx-runtime");
     378/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__);
     379/**
     380 * External dependencies
     381 */
     382
     383/**
     384 * WordPress dependencies
     385 */
     386 // eslint-disable-line import/no-extraneous-dependencies
     387
     388
     389/**
     390 * Internal dependencies
     391 */
     392
     393
     394/**
     395 * Render the donation receipt component.
     396 */
     397
     398_wordpress_dom_ready__WEBPACK_IMPORTED_MODULE_1___default()(function () {
     399  const receiptBlocks = document.querySelectorAll('.fundy-receipt');
     400  receiptBlocks.forEach(block => {
     401    (0,react_dom_client__WEBPACK_IMPORTED_MODULE_0__.createRoot)(block).render(/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)(_components_Receipt__WEBPACK_IMPORTED_MODULE_2__["default"], {}));
     402  });
     403});
     404})();
     405
     406/******/ })()
     407;
     408//# sourceMappingURL=frontend.js.map
  • dekode-fundraising/tags/2.3.1/composer.json

    r3408236 r3410996  
    2626    "scripts": {
    2727        "lint": "./vendor/bin/phpcs .",
    28         "make-pot": "./vendor/bin/wp i18n make-pot . languages/dekode-fundraising.pot --exclude=\".github,.cache,node_modules,vendor,tests,src\" --slug=dekode-fundraising",
    29         "make-json": "./vendor/bin/wp i18n make-json languages --no-purge"
     28        "make-pot": "./vendor/bin/wp i18n make-pot . --slug=dekode-fundraising --domain=dekode-fundraising --exclude='.github,.cache,tests,src,node_modules,vendor'",
     29        "make-json": [
     30            "./vendor/bin/wp i18n make-json ./languages --no-purge",
     31            "./vendor/bin/wp i18n make-php ./languages"
     32        ]
    3033    },
    3134    "autoload-dev": {
  • dekode-fundraising/tags/2.3.1/dekode-fundraising.php

    r3408236 r3410996  
    44 * Plugin URI:        https://github.com/DekodeInteraktiv/fundy-extension-wp/
    55 * Description:       Integrates with Dekode Fundraising, making it easy to add donation forms to your website.
    6  * Version:           2.3.0
     6 * Version:           2.3.1
    77 * Author:            Dekode Interaktiv
    88 * Author URI:        https://dekode.no
     
    2525}
    2626
    27 \define( 'FUNDY_VERSION', '2.3.0' );
     27\define( 'FUNDY_VERSION', '2.3.1' );
    2828\define( 'FUNDY_PLUGIN_URL', \plugin_dir_url( __FILE__ ) );
    2929\define( 'FUNDY_PLUGIN_DIR', \plugin_dir_path( __FILE__ ) );
  • dekode-fundraising/tags/2.3.1/languages/dekode-fundraising.pot

    r3408236 r3410996  
    33msgid ""
    44msgstr ""
    5 "Project-Id-Version: Dekode Fundraising 2.2.1\n"
     5"Project-Id-Version: Dekode Fundraising 2.3.0\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/dekode-fundraising\n"
    77"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
     
    1010"Content-Type: text/plain; charset=UTF-8\n"
    1111"Content-Transfer-Encoding: 8bit\n"
    12 "POT-Creation-Date: 2025-12-02T15:15:59+00:00\n"
     12"POT-Creation-Date: 2025-12-04T12:57:20+00:00\n"
    1313"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
    1414"X-Generator: WP-CLI 2.13.0-alpha\n"
     
    112112msgstr ""
    113113
    114 #: build/blocks/donation-form/editor.js:1
     114#: build/blocks/donation-form/editor.js:128
     115#: build/blocks/donation-form/editor.js:92
    115116msgid "Please set an API Token on the plugin settings page."
    116117msgstr ""
    117118
    118 #: build/blocks/donation-form/editor.js:1
     119#: build/blocks/donation-form/editor.js:163
     120#: build/blocks/donation-form/editor.js:126
    119121msgid "Dekode Fundraising Form"
    120122msgstr ""
    121123
    122 #: build/blocks/donation-form/editor.js:1
     124#: build/blocks/donation-form/editor.js:166
     125#: build/blocks/donation-form/editor.js:128
    123126msgid "Select a Form"
    124127msgstr ""
    125128
    126 #: build/blocks/donation-form/editor.js:1
     129#: build/blocks/donation-form/editor.js:178
     130#: build/blocks/donation-form/editor.js:140
    127131msgid "No forms found. Please create a Form on your Dekode Fundraising account first."
    128132msgstr ""
    129133
    130 #: build/blocks/donation-form/editor.js:1
     134#: build/blocks/donation-form/editor.js:180
     135#: build/blocks/donation-form/editor.js:147
    131136msgid "Loading…"
    132137msgstr ""
    133138
    134 #: build/blocks/donation-form/editor.js:1
     139#: build/blocks/donation-form/editor.js:186
     140#: build/blocks/donation-form/editor.js:151
    135141msgid "Default URL Parameters (Optional)"
    136142msgstr ""
    137143
    138 #: build/blocks/donation-form/editor.js:1
     144#: build/blocks/donation-form/editor.js:194
     145#: build/blocks/donation-form/editor.js:158
    139146msgid "Key"
    140147msgstr ""
    141148
    142 #: build/blocks/donation-form/editor.js:1
     149#: build/blocks/donation-form/editor.js:200
     150#: build/blocks/donation-form/editor.js:167
    143151msgid "Value"
    144152msgstr ""
    145153
    146 #: build/blocks/donation-form/editor.js:1
     154#: build/blocks/donation-form/editor.js:211
     155#: build/blocks/donation-form/editor.js:180
    147156msgid "Remove"
    148157msgstr ""
    149158
    150 #: build/blocks/donation-form/editor.js:1
     159#: build/blocks/donation-form/editor.js:217
     160#: build/blocks/donation-form/editor.js:186
    151161msgid "Add Parameter"
    152162msgstr ""
    153163
    154 #: build/blocks/donation-receipt/editor.js:1
    155 #: build/blocks/donation-receipt/frontend.js:1
     164#: build/blocks/donation-receipt/editor.js:48
     165#: build/blocks/donation-receipt/frontend.js:170
     166#: build/blocks/donation-receipt/editor.js:16
     167#: build/blocks/donation-receipt/frontend.js:165
    156168msgid "Name"
    157169msgstr ""
    158170
    159 #: build/blocks/donation-receipt/editor.js:1
    160 #: build/blocks/donation-receipt/frontend.js:1
     171#: build/blocks/donation-receipt/editor.js:54
     172#: build/blocks/donation-receipt/frontend.js:147
     173#: build/blocks/donation-receipt/frontend.js:176
     174#: build/blocks/donation-receipt/editor.js:20
     175#: build/blocks/donation-receipt/frontend.js:137
     176#: build/blocks/donation-receipt/frontend.js:175
    161177msgid "Date"
    162178msgstr ""
    163179
    164 #: build/blocks/donation-receipt/editor.js:1
    165 #: build/blocks/donation-receipt/frontend.js:1
     180#: build/blocks/donation-receipt/editor.js:60
     181#: build/blocks/donation-receipt/frontend.js:153
     182#: build/blocks/donation-receipt/frontend.js:182
     183#: build/blocks/donation-receipt/editor.js:24
     184#: build/blocks/donation-receipt/frontend.js:145
     185#: build/blocks/donation-receipt/frontend.js:183
    166186msgid "Total amount"
    167187msgstr ""
    168188
    169 #: build/blocks/donation-receipt/frontend.js:1
     189#: build/blocks/donation-receipt/frontend.js:125
     190#: build/blocks/donation-receipt/frontend.js:104
    170191msgid "Unfortunately, we were unable to load the details for the donation at this moment; the link may have expired."
    171192msgstr ""
    172193
    173 #: build/blocks/donation-receipt/frontend.js:1
     194#: build/blocks/donation-receipt/frontend.js:135
     195#: build/blocks/donation-receipt/frontend.js:121
    174196msgid "Company name"
    175197msgstr ""
    176198
    177 #: build/blocks/donation-receipt/frontend.js:1
     199#: build/blocks/donation-receipt/frontend.js:141
     200#: build/blocks/donation-receipt/frontend.js:127
    178201msgid "Contact person"
    179202msgstr ""
    180203
    181 #: build/blocks/donation-receipt/frontend.js:1
     204#: build/blocks/donation-receipt/frontend.js:159
     205#: build/blocks/donation-receipt/frontend.js:151
    182206msgid "Invoice"
    183207msgstr ""
    184208
    185 #: build/blocks/donation-receipt/frontend.js:1
     209#: build/blocks/donation-receipt/frontend.js:163
     210#: build/blocks/donation-receipt/frontend.js:154
    186211msgid "Download invoice"
    187212msgstr ""
  • dekode-fundraising/tags/2.3.1/src/blocks/donation-receipt/components/Receipt/Receipt.jsx

    r3382635 r3410996  
    168168
    169169/**
    170  * Format the donation datetime for display.
    171  */
    172 function formatDateTime(dateTime) {
    173     const date = new Date(dateTime);
    174     return date.toLocaleDateString();
     170 * Format a datetime value as a date string in the user's locale.
     171 *
     172 * @param {string|Date|null|undefined} dateTime
     173 *
     174 * @returns {string} Formatted date or empty string if invalid.
     175 */
     176export function formatDateTime(dateTime) {
     177    if (!dateTime) return 'unknown';
     178
     179    const date = dateTime instanceof Date ? dateTime : new Date(dateTime);
     180
     181    if (Number.isNaN(date.getTime())) {
     182        return 'unknown';
     183    }
     184
     185    const locales =
     186        typeof navigator !== 'undefined'
     187        ? navigator.languages || navigator.language
     188        : undefined;
     189
     190    return date.toLocaleDateString(locales, {
     191        year:  'numeric',
     192        month: 'numeric',
     193        day:   'numeric',
     194    });
    175195}
    176196
  • dekode-fundraising/trunk/CHANGELOG.txt

    r3408236 r3410996  
    1 = 2.2.1 (2025-08-22) =
    2 * Initial wordpress.org release.
     1= 2.3.1 (2025-12-04) =
     2* Bundle languages dir in zip.
    33
    44= 2.3.0 (2025-12-02) =
    55* Reintroduce translation files.
     6
     7= 2.2.1 (2025-08-22) =
     8* Initial WordPress.org release.
  • dekode-fundraising/trunk/README.txt

    r3408236 r3410996  
    44Requires PHP: 8.1
    55Tested up to: 6.8
    6 Stable tag: 2.3.0
     6Stable tag: 2.3.1
    77License: GPLv3 or later
    88License URI: https://www.gnu.org/licenses/gpl-3.0.html
     
    4646== Changelog ==
    4747
    48 = 2.2.1 (2025-08-22) =
    49 * Initial WordPress.org release.
     48= 2.3.1 (2025-12-04) =
     49* Bundle languages dir in zip.
    5050
    5151= 2.3.0 (2025-12-02) =
    5252* Reintroduce translation files.
     53
     54= 2.2.1 (2025-08-22) =
     55* Initial WordPress.org release.
  • dekode-fundraising/trunk/build/blocks/donation-form/editor.asset.php

    r3382635 r3410996  
    1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '59d96ee1fd27a6d10057');
     1<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '916a72b70b315aff448b');
  • dekode-fundraising/trunk/build/blocks/donation-form/editor.js

    r3382635 r3410996  
    1 (()=>{"use strict";const e=window.wp.blocks,n=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-form","title":"Donation Form","description":"Displays a donation form.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true}},"attributes":{"formId":{"type":"number","default":0},"urlParams":{"type":"array","default":[],"items":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}}}},"editorScript":"file:./editor.js","viewScript":"fundy-form-script","viewStyle":"fundy-form-style"}'),r=window.wp.blockEditor,o=window.wp.element,i=window.wp.components,t=window.wp.i18n,a=window.ReactJSXRuntime;(0,e.registerBlockType)(n,{edit:function({attributes:{formId:e,urlParams:n=[]},setAttributes:s}){var d,l;const[u,c]=(0,o.useReducer)((e,n)=>({...e,...n}),{isInitialized:!1,isLoaded:!1,apiToken:null!==(d=window.fundySettings.apiToken)&&void 0!==d?d:"",baseURL:null!==(l=window.fundySettings.baseURL)&&void 0!==l?l:"",forms:!1,error:null}),{isInitialized:p,isLoaded:m,apiToken:f,baseURL:h,forms:g,error:k}=u;if((0,o.useEffect)(()=>{!1===p&&f&&h&&c({isInitialized:!0})},[p,f,h]),(0,o.useEffect)(()=>{h&&f&&fetch(`${h}/api/v1/organization/forms`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:"Bearer "+f}}).then(e=>{if(!e.ok)throw new Error("Network response was not ok.");return e.json()}).then(n=>{const r=n.map(e=>({value:e.id,label:e.name}));c({isLoaded:!0,forms:r,error:null}),!e&&r.length&&s({formId:parseInt(r[0].value,10)})}).catch(e=>{c({error:"There has been a problem with your fetch operation: "+e})})},[h,f,e,s]),!f)return(0,a.jsx)("div",{...(0,r.useBlockProps)(),children:(0,a.jsx)(i.Placeholder,{instructions:(0,t.__)("Please set an API Token on the plugin settings page.","dekode-fundraising")})});const w=g&&g.length>0,y=(e,r,o)=>{const i=n.map((n,i)=>i===e?{...n,[r]:o}:n);s({urlParams:i})};return(0,a.jsx)("div",{...(0,r.useBlockProps)(),children:(0,a.jsxs)(i.Placeholder,{label:(0,t.__)("Dekode Fundraising Form","dekode-fundraising"),isColumnLayout:!0,children:[(0,a.jsx)(i.SelectControl,{label:(0,t.__)("Select a Form","dekode-fundraising"),value:e,className:"fundy-form",options:g||[{label:"",value:""}],onChange:e=>s({formId:parseInt(e,10)}),disabled:!m}),!w&&(0,a.jsx)("p",{children:(0,t.__)("No forms found. Please create a Form on your Dekode Fundraising account first.","dekode-fundraising")}),!m&&(0,a.jsx)("p",{children:(0,t.__)("Loading…","dekode-fundraising")}),k&&(0,a.jsx)("p",{children:"Error: "+k}),(0,a.jsxs)("div",{className:"fundy-form-params",children:[(0,a.jsx)("h4",{children:(0,t.__)("Default URL Parameters (Optional)","dekode-fundraising")}),(0,a.jsxs)("div",{style:{marginTop:"1em"},children:[n.map((e,r)=>(0,a.jsxs)(i.Flex,{children:[(0,a.jsx)(i.FlexBlock,{children:(0,a.jsx)(i.TextControl,{label:(0,t.__)("Key","dekode-fundraising"),value:e.key,onChange:e=>y(r,"key",e)})}),(0,a.jsx)(i.FlexBlock,{children:(0,a.jsx)(i.TextControl,{label:(0,t.__)("Value","dekode-fundraising"),value:e.value,onChange:e=>y(r,"value",e)})}),(0,a.jsx)(i.FlexItem,{children:(0,a.jsx)(i.Button,{isDestructive:!0,onClick:()=>(e=>{const r=n.filter((n,r)=>r!==e);s({urlParams:r})})(r),style:{marginTop:"14px"},children:(0,t.__)("Remove","dekode-fundraising")})})]},`param-${r}`)),(0,a.jsx)(i.Button,{variant:"link",onClick:()=>{s({urlParams:[...n,{key:"",value:""}]})},children:(0,t.__)("Add Parameter","dekode-fundraising")})]})]})]})})},save:()=>null})})();
     1/******/ (() => { // webpackBootstrap
     2/******/    "use strict";
     3/******/    var __webpack_modules__ = ({
     4
     5/***/ "./src/blocks/donation-form/block.json":
     6/*!*********************************************!*\
     7  !*** ./src/blocks/donation-form/block.json ***!
     8  \*********************************************/
     9/***/ ((module) => {
     10
     11module.exports = /*#__PURE__*/JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-form","title":"Donation Form","description":"Displays a donation form.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true}},"attributes":{"formId":{"type":"number","default":0},"urlParams":{"type":"array","default":[],"items":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}}}},"editorScript":"file:./editor.js","viewScript":"fundy-form-script","viewStyle":"fundy-form-style"}');
     12
     13/***/ }),
     14
     15/***/ "./src/blocks/donation-form/edit.js":
     16/*!******************************************!*\
     17  !*** ./src/blocks/donation-form/edit.js ***!
     18  \******************************************/
     19/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
     20
     21__webpack_require__.r(__webpack_exports__);
     22/* harmony export */ __webpack_require__.d(__webpack_exports__, {
     23/* harmony export */   "default": () => (/* binding */ Edit)
     24/* harmony export */ });
     25/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/block-editor */ "@wordpress/block-editor");
     26/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0__);
     27/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
     28/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__);
     29/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/components */ "@wordpress/components");
     30/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__);
     31/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n");
     32/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__);
     33/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! react/jsx-runtime */ "react/jsx-runtime");
     34/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__);
     35/**
     36 * WordPress dependencies
     37 */
     38
     39
     40
     41
     42
     43/**
     44 * Render the content generation block.
     45 */
     46
     47function Edit({
     48  attributes: {
     49    formId,
     50    urlParams = []
     51  },
     52  setAttributes
     53}) {
     54  var _window$fundySettings, _window$fundySettings2;
     55  const [state, setState] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_1__.useReducer)((s, a) => ({
     56    ...s,
     57    ...a
     58  }), {
     59    isInitialized: false,
     60    isLoaded: false,
     61    apiToken: (_window$fundySettings = window.fundySettings.apiToken) !== null && _window$fundySettings !== void 0 ? _window$fundySettings : '',
     62    baseURL: (_window$fundySettings2 = window.fundySettings.baseURL) !== null && _window$fundySettings2 !== void 0 ? _window$fundySettings2 : '',
     63    forms: false,
     64    error: null
     65  });
     66  const {
     67    isInitialized,
     68    isLoaded,
     69    apiToken,
     70    baseURL,
     71    forms,
     72    error
     73  } = state;
     74
     75  // Initialize
     76  (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_1__.useEffect)(() => {
     77    if (false === isInitialized && apiToken && baseURL) {
     78      setState({
     79        isInitialized: true
     80      });
     81    }
     82  }, [isInitialized, apiToken, baseURL]);
     83
     84  // Fetch forms
     85  (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_1__.useEffect)(() => {
     86    if (baseURL && apiToken) {
     87      fetch(`${baseURL}/api/v1/organization/forms`, {
     88        method: 'GET',
     89        headers: {
     90          'Content-Type': 'application/json',
     91          Authorization: 'Bearer ' + apiToken
     92        }
     93      }).then(response => {
     94        if (!response.ok) {
     95          throw new Error('Network response was not ok.');
     96        }
     97        return response.json();
     98      }).then(data => {
     99        const options = data.map(form => ({
     100          value: form.id,
     101          label: form.name
     102        }));
     103        setState({
     104          isLoaded: true,
     105          forms: options,
     106          error: null
     107        });
     108
     109        // If no form is saved, set first form as selected.
     110        if (!formId && options.length) {
     111          setAttributes({
     112            formId: parseInt(options[0].value, 10)
     113          });
     114        }
     115      }).catch(err => {
     116        setState({
     117          error: 'There has been a problem with your fetch operation: ' + err
     118        });
     119      });
     120    }
     121  }, [baseURL, apiToken, formId, setAttributes]);
     122
     123  /* eslint-disable react-hooks/rules-of-hooks */
     124  if (!apiToken) {
     125    return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
     126      ...(0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0__.useBlockProps)(),
     127      children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.Placeholder, {
     128        instructions: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Please set an API Token on the plugin settings page.', 'dekode-fundraising')
     129      })
     130    });
     131  }
     132  const hasForms = forms && forms.length > 0;
     133
     134  /**
     135   * Repeater handlers
     136   */
     137  const addParam = () => {
     138    setAttributes({
     139      urlParams: [...urlParams, {
     140        key: '',
     141        value: ''
     142      }]
     143    });
     144  };
     145  const updateParam = (index, field, newValue) => {
     146    const updated = urlParams.map((item, i) => i === index ? {
     147      ...item,
     148      [field]: newValue
     149    } : item);
     150    setAttributes({
     151      urlParams: updated
     152    });
     153  };
     154  const removeParam = index => {
     155    const updated = urlParams.filter((_, i) => i !== index);
     156    setAttributes({
     157      urlParams: updated
     158    });
     159  };
     160  return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
     161    ...(0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0__.useBlockProps)(),
     162    children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.Placeholder, {
     163      label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Dekode Fundraising Form', 'dekode-fundraising'),
     164      isColumnLayout: true,
     165      children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.SelectControl, {
     166        label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Select a Form', 'dekode-fundraising'),
     167        value: formId,
     168        className: "fundy-form",
     169        options: forms || [{
     170          label: '',
     171          value: ''
     172        }],
     173        onChange: value => setAttributes({
     174          formId: parseInt(value, 10)
     175        }),
     176        disabled: !isLoaded
     177      }), !hasForms && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("p", {
     178        children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('No forms found. Please create a Form on your Dekode Fundraising account first.', 'dekode-fundraising')
     179      }), !isLoaded && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("p", {
     180        children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Loading…', 'dekode-fundraising')
     181      }), error && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("p", {
     182        children: 'Error: ' + error
     183      }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
     184        className: "fundy-form-params",
     185        children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("h4", {
     186          children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Default URL Parameters (Optional)', 'dekode-fundraising')
     187        }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
     188          style: {
     189            marginTop: '1em'
     190          },
     191          children: [urlParams.map((param, index) => /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.Flex, {
     192            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.FlexBlock, {
     193              children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.TextControl, {
     194                label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Key', 'dekode-fundraising'),
     195                value: param.key,
     196                onChange: val => updateParam(index, 'key', val)
     197              })
     198            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.FlexBlock, {
     199              children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.TextControl, {
     200                label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Value', 'dekode-fundraising'),
     201                value: param.value,
     202                onChange: val => updateParam(index, 'value', val)
     203              })
     204            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.FlexItem, {
     205              children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.Button, {
     206                isDestructive: true,
     207                onClick: () => removeParam(index),
     208                style: {
     209                  marginTop: '14px'
     210                },
     211                children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Remove', 'dekode-fundraising')
     212              })
     213            })]
     214          }, `param-${index}`)), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.Button, {
     215            variant: "link",
     216            onClick: addParam,
     217            children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_3__.__)('Add Parameter', 'dekode-fundraising')
     218          })]
     219        })]
     220      })]
     221    })
     222  });
     223  /* eslint-enable react-hooks/rules-of-hooks */
     224}
     225
     226/***/ }),
     227
     228/***/ "@wordpress/block-editor":
     229/*!*************************************!*\
     230  !*** external ["wp","blockEditor"] ***!
     231  \*************************************/
     232/***/ ((module) => {
     233
     234module.exports = window["wp"]["blockEditor"];
     235
     236/***/ }),
     237
     238/***/ "@wordpress/blocks":
     239/*!********************************!*\
     240  !*** external ["wp","blocks"] ***!
     241  \********************************/
     242/***/ ((module) => {
     243
     244module.exports = window["wp"]["blocks"];
     245
     246/***/ }),
     247
     248/***/ "@wordpress/components":
     249/*!************************************!*\
     250  !*** external ["wp","components"] ***!
     251  \************************************/
     252/***/ ((module) => {
     253
     254module.exports = window["wp"]["components"];
     255
     256/***/ }),
     257
     258/***/ "@wordpress/element":
     259/*!*********************************!*\
     260  !*** external ["wp","element"] ***!
     261  \*********************************/
     262/***/ ((module) => {
     263
     264module.exports = window["wp"]["element"];
     265
     266/***/ }),
     267
     268/***/ "@wordpress/i18n":
     269/*!******************************!*\
     270  !*** external ["wp","i18n"] ***!
     271  \******************************/
     272/***/ ((module) => {
     273
     274module.exports = window["wp"]["i18n"];
     275
     276/***/ }),
     277
     278/***/ "react/jsx-runtime":
     279/*!**********************************!*\
     280  !*** external "ReactJSXRuntime" ***!
     281  \**********************************/
     282/***/ ((module) => {
     283
     284module.exports = window["ReactJSXRuntime"];
     285
     286/***/ })
     287
     288/******/    });
     289/************************************************************************/
     290/******/    // The module cache
     291/******/    var __webpack_module_cache__ = {};
     292/******/   
     293/******/    // The require function
     294/******/    function __webpack_require__(moduleId) {
     295/******/        // Check if module is in cache
     296/******/        var cachedModule = __webpack_module_cache__[moduleId];
     297/******/        if (cachedModule !== undefined) {
     298/******/            return cachedModule.exports;
     299/******/        }
     300/******/        // Create a new module (and put it into the cache)
     301/******/        var module = __webpack_module_cache__[moduleId] = {
     302/******/            // no module.id needed
     303/******/            // no module.loaded needed
     304/******/            exports: {}
     305/******/        };
     306/******/   
     307/******/        // Execute the module function
     308/******/        __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
     309/******/   
     310/******/        // Return the exports of the module
     311/******/        return module.exports;
     312/******/    }
     313/******/   
     314/************************************************************************/
     315/******/    /* webpack/runtime/compat get default export */
     316/******/    (() => {
     317/******/        // getDefaultExport function for compatibility with non-harmony modules
     318/******/        __webpack_require__.n = (module) => {
     319/******/            var getter = module && module.__esModule ?
     320/******/                () => (module['default']) :
     321/******/                () => (module);
     322/******/            __webpack_require__.d(getter, { a: getter });
     323/******/            return getter;
     324/******/        };
     325/******/    })();
     326/******/   
     327/******/    /* webpack/runtime/define property getters */
     328/******/    (() => {
     329/******/        // define getter functions for harmony exports
     330/******/        __webpack_require__.d = (exports, definition) => {
     331/******/            for(var key in definition) {
     332/******/                if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
     333/******/                    Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
     334/******/                }
     335/******/            }
     336/******/        };
     337/******/    })();
     338/******/   
     339/******/    /* webpack/runtime/hasOwnProperty shorthand */
     340/******/    (() => {
     341/******/        __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
     342/******/    })();
     343/******/   
     344/******/    /* webpack/runtime/make namespace object */
     345/******/    (() => {
     346/******/        // define __esModule on exports
     347/******/        __webpack_require__.r = (exports) => {
     348/******/            if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
     349/******/                Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
     350/******/            }
     351/******/            Object.defineProperty(exports, '__esModule', { value: true });
     352/******/        };
     353/******/    })();
     354/******/   
     355/************************************************************************/
     356var __webpack_exports__ = {};
     357// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
     358(() => {
     359/*!********************************************!*\
     360  !*** ./src/blocks/donation-form/editor.js ***!
     361  \********************************************/
     362__webpack_require__.r(__webpack_exports__);
     363/* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/blocks */ "@wordpress/blocks");
     364/* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_blocks__WEBPACK_IMPORTED_MODULE_0__);
     365/* harmony import */ var _block_json__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./block.json */ "./src/blocks/donation-form/block.json");
     366/* harmony import */ var _edit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./edit */ "./src/blocks/donation-form/edit.js");
     367/**
     368 * WordPress dependencies
     369 */
     370
     371
     372/**
     373 * Internal dependencies
     374 */
     375
     376
     377(0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_0__.registerBlockType)(_block_json__WEBPACK_IMPORTED_MODULE_1__, {
     378  edit: _edit__WEBPACK_IMPORTED_MODULE_2__["default"],
     379  save: () => null
     380});
     381})();
     382
     383/******/ })()
     384;
     385//# sourceMappingURL=editor.js.map
  • dekode-fundraising/trunk/build/blocks/donation-receipt/editor.asset.php

    r3382635 r3410996  
    1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-i18n'), 'version' => '7b5f3ffebaab90c2ba48');
     1<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-i18n'), 'version' => 'fb5c7ccc9c7d5bea9f70');
  • dekode-fundraising/trunk/build/blocks/donation-receipt/editor.js

    r3382635 r3410996  
    1 (()=>{"use strict";const e=window.wp.blocks,i=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-receipt","title":"Donation Receipt","description":"Displays a donation receipt on a thank you page.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true},"multiple":false},"attributes":{},"editorScript":"file:editor.js","script":"file:frontend.js"}'),t=window.wp.blockEditor,n=window.wp.i18n,d=window.ReactJSXRuntime;(0,e.registerBlockType)(i,{edit:function(){return(0,d.jsx)("div",{...(0,t.useBlockProps)(),children:(0,d.jsx)("table",{children:(0,d.jsxs)("tbody",{children:[(0,d.jsxs)("tr",{children:[(0,d.jsx)("td",{children:(0,n.__)("Name","dekode-fundraising")}),(0,d.jsx)("td",{children:"John Smith"})]}),(0,d.jsxs)("tr",{children:[(0,d.jsx)("td",{children:(0,n.__)("Date","dekode-fundraising")}),(0,d.jsx)("td",{children:"name@email.no"})]}),(0,d.jsxs)("tr",{children:[(0,d.jsx)("td",{children:(0,n.__)("Total amount","dekode-fundraising")}),(0,d.jsx)("td",{children:"400 kr"})]})]})})})},save:()=>null})})();
     1/******/ (() => { // webpackBootstrap
     2/******/    "use strict";
     3/******/    var __webpack_modules__ = ({
     4
     5/***/ "./src/blocks/donation-receipt/block.json":
     6/*!************************************************!*\
     7  !*** ./src/blocks/donation-receipt/block.json ***!
     8  \************************************************/
     9/***/ ((module) => {
     10
     11module.exports = /*#__PURE__*/JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-receipt","title":"Donation Receipt","description":"Displays a donation receipt on a thank you page.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true},"multiple":false},"attributes":{},"editorScript":"file:editor.js","script":"file:frontend.js"}');
     12
     13/***/ }),
     14
     15/***/ "./src/blocks/donation-receipt/edit.js":
     16/*!*********************************************!*\
     17  !*** ./src/blocks/donation-receipt/edit.js ***!
     18  \*********************************************/
     19/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
     20
     21__webpack_require__.r(__webpack_exports__);
     22/* harmony export */ __webpack_require__.d(__webpack_exports__, {
     23/* harmony export */   "default": () => (/* binding */ Edit)
     24/* harmony export */ });
     25/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/block-editor */ "@wordpress/block-editor");
     26/* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0__);
     27/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n");
     28/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__);
     29/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react/jsx-runtime */ "react/jsx-runtime");
     30/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__);
     31/**
     32 * WordPress dependencies
     33 */
     34
     35
     36
     37/**
     38 * Render the content generation block.
     39 */
     40
     41function Edit() {
     42  return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("div", {
     43    ...(0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_0__.useBlockProps)(),
     44    children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("table", {
     45      children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tbody", {
     46        children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     47          children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     48            children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Name', 'dekode-fundraising')
     49          }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     50            children: "John Smith"
     51          })]
     52        }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     53          children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     54            children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Date', 'dekode-fundraising')
     55          }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     56            children: "name@email.no"
     57          })]
     58        }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     59          children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     60            children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Total amount', 'dekode-fundraising')
     61          }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     62            children: "400 kr"
     63          })]
     64        })]
     65      })
     66    })
     67  });
     68}
     69
     70/***/ }),
     71
     72/***/ "@wordpress/block-editor":
     73/*!*************************************!*\
     74  !*** external ["wp","blockEditor"] ***!
     75  \*************************************/
     76/***/ ((module) => {
     77
     78module.exports = window["wp"]["blockEditor"];
     79
     80/***/ }),
     81
     82/***/ "@wordpress/blocks":
     83/*!********************************!*\
     84  !*** external ["wp","blocks"] ***!
     85  \********************************/
     86/***/ ((module) => {
     87
     88module.exports = window["wp"]["blocks"];
     89
     90/***/ }),
     91
     92/***/ "@wordpress/i18n":
     93/*!******************************!*\
     94  !*** external ["wp","i18n"] ***!
     95  \******************************/
     96/***/ ((module) => {
     97
     98module.exports = window["wp"]["i18n"];
     99
     100/***/ }),
     101
     102/***/ "react/jsx-runtime":
     103/*!**********************************!*\
     104  !*** external "ReactJSXRuntime" ***!
     105  \**********************************/
     106/***/ ((module) => {
     107
     108module.exports = window["ReactJSXRuntime"];
     109
     110/***/ })
     111
     112/******/    });
     113/************************************************************************/
     114/******/    // The module cache
     115/******/    var __webpack_module_cache__ = {};
     116/******/   
     117/******/    // The require function
     118/******/    function __webpack_require__(moduleId) {
     119/******/        // Check if module is in cache
     120/******/        var cachedModule = __webpack_module_cache__[moduleId];
     121/******/        if (cachedModule !== undefined) {
     122/******/            return cachedModule.exports;
     123/******/        }
     124/******/        // Create a new module (and put it into the cache)
     125/******/        var module = __webpack_module_cache__[moduleId] = {
     126/******/            // no module.id needed
     127/******/            // no module.loaded needed
     128/******/            exports: {}
     129/******/        };
     130/******/   
     131/******/        // Execute the module function
     132/******/        __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
     133/******/   
     134/******/        // Return the exports of the module
     135/******/        return module.exports;
     136/******/    }
     137/******/   
     138/************************************************************************/
     139/******/    /* webpack/runtime/compat get default export */
     140/******/    (() => {
     141/******/        // getDefaultExport function for compatibility with non-harmony modules
     142/******/        __webpack_require__.n = (module) => {
     143/******/            var getter = module && module.__esModule ?
     144/******/                () => (module['default']) :
     145/******/                () => (module);
     146/******/            __webpack_require__.d(getter, { a: getter });
     147/******/            return getter;
     148/******/        };
     149/******/    })();
     150/******/   
     151/******/    /* webpack/runtime/define property getters */
     152/******/    (() => {
     153/******/        // define getter functions for harmony exports
     154/******/        __webpack_require__.d = (exports, definition) => {
     155/******/            for(var key in definition) {
     156/******/                if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
     157/******/                    Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
     158/******/                }
     159/******/            }
     160/******/        };
     161/******/    })();
     162/******/   
     163/******/    /* webpack/runtime/hasOwnProperty shorthand */
     164/******/    (() => {
     165/******/        __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
     166/******/    })();
     167/******/   
     168/******/    /* webpack/runtime/make namespace object */
     169/******/    (() => {
     170/******/        // define __esModule on exports
     171/******/        __webpack_require__.r = (exports) => {
     172/******/            if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
     173/******/                Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
     174/******/            }
     175/******/            Object.defineProperty(exports, '__esModule', { value: true });
     176/******/        };
     177/******/    })();
     178/******/   
     179/************************************************************************/
     180var __webpack_exports__ = {};
     181// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
     182(() => {
     183/*!***********************************************!*\
     184  !*** ./src/blocks/donation-receipt/editor.js ***!
     185  \***********************************************/
     186__webpack_require__.r(__webpack_exports__);
     187/* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/blocks */ "@wordpress/blocks");
     188/* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_blocks__WEBPACK_IMPORTED_MODULE_0__);
     189/* harmony import */ var _block_json__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./block.json */ "./src/blocks/donation-receipt/block.json");
     190/* harmony import */ var _edit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./edit */ "./src/blocks/donation-receipt/edit.js");
     191/**
     192 * WordPress dependencies
     193 */
     194
     195
     196/**
     197 * Internal dependencies
     198 */
     199
     200
     201(0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_0__.registerBlockType)(_block_json__WEBPACK_IMPORTED_MODULE_1__, {
     202  edit: _edit__WEBPACK_IMPORTED_MODULE_2__["default"],
     203  save: () => null
     204});
     205})();
     206
     207/******/ })()
     208;
     209//# sourceMappingURL=editor.js.map
  • dekode-fundraising/trunk/build/blocks/donation-receipt/frontend.asset.php

    r3382635 r3410996  
    1 <?php return array('dependencies' => array('react-dom', 'react-jsx-runtime', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '9e529a7d822ecdbcbcef');
     1<?php return array('dependencies' => array('react-dom', 'react-jsx-runtime', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '7e045c998b07105a18a6');
  • dekode-fundraising/trunk/build/blocks/donation-receipt/frontend.js

    r3382635 r3410996  
    1 (()=>{"use strict";var e={338:(e,n,r)=>{var t=r(795);n.H=t.createRoot,t.hydrateRoot},795:e=>{e.exports=window.ReactDOM}},n={};function r(t){var d=n[t];if(void 0!==d)return d.exports;var o=n[t]={exports:{}};return e[t](o,o.exports,r),o.exports}r.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return r.d(n,{a:n}),n},r.d=(e,n)=>{for(var t in n)r.o(n,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},r.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n);var t=r(338);const d=window.wp.domReady;var o=r.n(d);const i=window.wp.element,a=window.wp.i18n,s=window.ReactJSXRuntime;function c(e){return new Date(e).toLocaleDateString()}const l=()=>{var e;const[n,r]=(0,i.useReducer)((e,n)=>({...e,...n}),{isLoaded:!1,isError:!1,baseURL:null!==(e=window.fundySettings.baseURL)&&void 0!==e?e:null,donation:null}),{isLoaded:t,isError:d,baseURL:o,donation:l}=n;return(0,i.useEffect)(()=>{const e=function(){const e=new URLSearchParams(window.location.search);return{donationId:e.get("donation_id")||null,token:e.get("token")||null,expiry:e.get("expiry")||null}}();e.donationId&&e.token&&e.expiry&&o||r({isLoaded:!0,isError:!0});const n={donation_id:e.donationId,token:e.token,expiry:e.expiry},t=new URLSearchParams(n).toString();fetch(o+"/api/v1/donation/receipt?"+t,{method:"GET",headers:{"Content-Type":"application/json"}}).then(e=>{if(e.ok)return e.json();throw new Error("Network response was not ok.")}).then(e=>{r({isLoaded:!0,isError:!1,donation:e})}).catch(()=>{r({isLoaded:!0,isError:!0})})},[o]),t?d||!l?(0,s.jsx)(i.Fragment,{children:(0,s.jsx)("p",{children:(0,a.__)("Unfortunately, we were unable to load the details for the donation at this moment; the link may have expired.","dekode-fundraising")})}):(0,s.jsx)(i.Fragment,{children:(0,s.jsx)("table",{children:(0,s.jsx)("tbody",{children:l&&l.company_name?(0,s.jsxs)(i.Fragment,{children:[l.company_name&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Company name","dekode-fundraising")}),(0,s.jsx)("td",{children:l.company_name})]}),l.first_name&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Contact person","dekode-fundraising")}),(0,s.jsx)("td",{children:l.first_name+" "+l?.last_name})]}),l.created_at&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Date","dekode-fundraising")}),(0,s.jsx)("td",{children:c(l.created_at)})]}),l.amount&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Total amount","dekode-fundraising")}),(0,s.jsx)("td",{children:l.amount})]}),l.invoice_url&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Invoice","dekode-fundraising")}),(0,s.jsx)("td",{children:(0,s.jsxs)("a",{href:l.invoice_url,children:[(0,a.__)("Download invoice","dekode-fundraising")," ","⇒"]})})]})]}):(0,s.jsxs)(i.Fragment,{children:[l.first_name&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Name","dekode-fundraising")}),(0,s.jsx)("td",{children:l.first_name+" "+l?.last_name})]}),l.created_at&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Date","dekode-fundraising")}),(0,s.jsx)("td",{children:c(l.created_at)})]}),l.amount&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Total amount","dekode-fundraising")}),(0,s.jsx)("td",{children:l.amount})]})]})})})}):null};o()(function(){document.querySelectorAll(".fundy-receipt").forEach(e=>{(0,t.H)(e).render((0,s.jsx)(l,{}))})})})();
     1/******/ (() => { // webpackBootstrap
     2/******/    "use strict";
     3/******/    var __webpack_modules__ = ({
     4
     5/***/ "./node_modules/react-dom/client.js":
     6/*!******************************************!*\
     7  !*** ./node_modules/react-dom/client.js ***!
     8  \******************************************/
     9/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
     10
     11
     12
     13var m = __webpack_require__(/*! react-dom */ "react-dom");
     14if (false) // removed by dead control flow
     15{} else {
     16  var i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
     17  exports.createRoot = function(c, o) {
     18    i.usingClientEntryPoint = true;
     19    try {
     20      return m.createRoot(c, o);
     21    } finally {
     22      i.usingClientEntryPoint = false;
     23    }
     24  };
     25  exports.hydrateRoot = function(c, h, o) {
     26    i.usingClientEntryPoint = true;
     27    try {
     28      return m.hydrateRoot(c, h, o);
     29    } finally {
     30      i.usingClientEntryPoint = false;
     31    }
     32  };
     33}
     34
     35
     36/***/ }),
     37
     38/***/ "./src/blocks/donation-receipt/components/Receipt/Receipt.jsx":
     39/*!********************************************************************!*\
     40  !*** ./src/blocks/donation-receipt/components/Receipt/Receipt.jsx ***!
     41  \********************************************************************/
     42/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
     43
     44__webpack_require__.r(__webpack_exports__);
     45/* harmony export */ __webpack_require__.d(__webpack_exports__, {
     46/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
     47/* harmony export */   formatDateTime: () => (/* binding */ formatDateTime)
     48/* harmony export */ });
     49/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
     50/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
     51/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n");
     52/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__);
     53/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react/jsx-runtime */ "react/jsx-runtime");
     54/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__);
     55/**
     56 * External dependencies
     57 */
     58
     59/**
     60 * WordPress dependencies
     61 */
     62
     63
     64
     65const Receipt = () => {
     66  var _window$fundySettings;
     67  const [state, setState] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useReducer)((s, a) => ({
     68    ...s,
     69    ...a
     70  }), {
     71    isLoaded: false,
     72    isError: false,
     73    baseURL: (_window$fundySettings = window.fundySettings.baseURL) !== null && _window$fundySettings !== void 0 ? _window$fundySettings : null,
     74    donation: null
     75  });
     76  const {
     77    isLoaded,
     78    isError,
     79    baseURL,
     80    donation
     81  } = state;
     82  (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
     83    const queryParams = getQueryParams();
     84    if (!queryParams.donationId || !queryParams.token || !queryParams.expiry || !baseURL) {
     85      setState({
     86        isLoaded: true,
     87        isError: true
     88      });
     89    }
     90    const params = {
     91      donation_id: queryParams.donationId,
     92      token: queryParams.token,
     93      expiry: queryParams.expiry
     94    };
     95    const queryString = new URLSearchParams(params).toString();
     96    fetch(baseURL + '/api/v1/donation/receipt?' + queryString, {
     97      method: 'GET',
     98      headers: {
     99        'Content-Type': 'application/json'
     100      }
     101    }).then(response => {
     102      if (response.ok) {
     103        return response.json();
     104      }
     105      throw new Error('Network response was not ok.');
     106    }).then(data => {
     107      setState({
     108        isLoaded: true,
     109        isError: false,
     110        donation: data
     111      });
     112    }).catch(() => {
     113      setState({
     114        isLoaded: true,
     115        isError: true
     116      });
     117    });
     118  }, [baseURL]);
     119  if (!isLoaded) {
     120    return null;
     121  }
     122  if (isError || !donation) {
     123    return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
     124      children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("p", {
     125        children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Unfortunately, we were unable to load the details for the donation at this moment; the link may have expired.', 'dekode-fundraising')
     126      })
     127    });
     128  }
     129  return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
     130    children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("table", {
     131      children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("tbody", {
     132        children: donation && donation.company_name ? /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
     133          children: [donation.company_name && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     134            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     135              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Company name', 'dekode-fundraising')
     136            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     137              children: donation.company_name
     138            })]
     139          }), donation.first_name && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     140            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     141              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Contact person', 'dekode-fundraising')
     142            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     143              children: donation.first_name + ' ' + donation?.last_name
     144            })]
     145          }), donation.created_at && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     146            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     147              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Date', 'dekode-fundraising')
     148            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     149              children: formatDateTime(donation.created_at)
     150            })]
     151          }), donation.amount && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     152            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     153              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Total amount', 'dekode-fundraising')
     154            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     155              children: donation.amount
     156            })]
     157          }), donation.invoice_url && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     158            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     159              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Invoice', 'dekode-fundraising')
     160            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     161              children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("a", {
     162                href: donation.invoice_url,
     163                children: [(0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Download invoice', 'dekode-fundraising'), ' ', "\u21D2"]
     164              })
     165            })]
     166          })]
     167        }) : /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
     168          children: [donation.first_name && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     169            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     170              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Name', 'dekode-fundraising')
     171            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     172              children: donation.first_name + ' ' + donation?.last_name
     173            })]
     174          }), donation.created_at && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     175            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     176              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Date', 'dekode-fundraising')
     177            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     178              children: formatDateTime(donation.created_at)
     179            })]
     180          }), donation.amount && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxs)("tr", {
     181            children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     182              children: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Total amount', 'dekode-fundraising')
     183            }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_2__.jsx)("td", {
     184              children: donation.amount
     185            })]
     186          })]
     187        })
     188      })
     189    })
     190  });
     191};
     192
     193/**
     194 * Format a datetime value as a date string in the user's locale.
     195 *
     196 * @param {string|Date|null|undefined} dateTime
     197 *
     198 * @returns {string} Formatted date or empty string if invalid.
     199 */
     200function formatDateTime(dateTime) {
     201  if (!dateTime) return 'unknown';
     202  const date = dateTime instanceof Date ? dateTime : new Date(dateTime);
     203  if (Number.isNaN(date.getTime())) {
     204    return 'unknown';
     205  }
     206  const locales = typeof navigator !== 'undefined' ? navigator.languages || navigator.language : undefined;
     207  return date.toLocaleDateString(locales, {
     208    year: 'numeric',
     209    month: 'numeric',
     210    day: 'numeric'
     211  });
     212}
     213
     214/**
     215 * Return the required query params from the page URL.
     216 */
     217function getQueryParams() {
     218  const params = new URLSearchParams(window.location.search);
     219  return {
     220    donationId: params.get('donation_id') || null,
     221    token: params.get('token') || null,
     222    expiry: params.get('expiry') || null
     223  };
     224}
     225/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Receipt);
     226
     227/***/ }),
     228
     229/***/ "./src/blocks/donation-receipt/components/Receipt/index.js":
     230/*!*****************************************************************!*\
     231  !*** ./src/blocks/donation-receipt/components/Receipt/index.js ***!
     232  \*****************************************************************/
     233/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
     234
     235__webpack_require__.r(__webpack_exports__);
     236/* harmony export */ __webpack_require__.d(__webpack_exports__, {
     237/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
     238/* harmony export */ });
     239/* harmony import */ var _Receipt__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Receipt */ "./src/blocks/donation-receipt/components/Receipt/Receipt.jsx");
     240/**
     241 * Internal dependencies
     242 */
     243
     244/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_Receipt__WEBPACK_IMPORTED_MODULE_0__["default"]);
     245
     246/***/ }),
     247
     248/***/ "@wordpress/dom-ready":
     249/*!**********************************!*\
     250  !*** external ["wp","domReady"] ***!
     251  \**********************************/
     252/***/ ((module) => {
     253
     254module.exports = window["wp"]["domReady"];
     255
     256/***/ }),
     257
     258/***/ "@wordpress/element":
     259/*!*********************************!*\
     260  !*** external ["wp","element"] ***!
     261  \*********************************/
     262/***/ ((module) => {
     263
     264module.exports = window["wp"]["element"];
     265
     266/***/ }),
     267
     268/***/ "@wordpress/i18n":
     269/*!******************************!*\
     270  !*** external ["wp","i18n"] ***!
     271  \******************************/
     272/***/ ((module) => {
     273
     274module.exports = window["wp"]["i18n"];
     275
     276/***/ }),
     277
     278/***/ "react-dom":
     279/*!***************************!*\
     280  !*** external "ReactDOM" ***!
     281  \***************************/
     282/***/ ((module) => {
     283
     284module.exports = window["ReactDOM"];
     285
     286/***/ }),
     287
     288/***/ "react/jsx-runtime":
     289/*!**********************************!*\
     290  !*** external "ReactJSXRuntime" ***!
     291  \**********************************/
     292/***/ ((module) => {
     293
     294module.exports = window["ReactJSXRuntime"];
     295
     296/***/ })
     297
     298/******/    });
     299/************************************************************************/
     300/******/    // The module cache
     301/******/    var __webpack_module_cache__ = {};
     302/******/   
     303/******/    // The require function
     304/******/    function __webpack_require__(moduleId) {
     305/******/        // Check if module is in cache
     306/******/        var cachedModule = __webpack_module_cache__[moduleId];
     307/******/        if (cachedModule !== undefined) {
     308/******/            return cachedModule.exports;
     309/******/        }
     310/******/        // Create a new module (and put it into the cache)
     311/******/        var module = __webpack_module_cache__[moduleId] = {
     312/******/            // no module.id needed
     313/******/            // no module.loaded needed
     314/******/            exports: {}
     315/******/        };
     316/******/   
     317/******/        // Execute the module function
     318/******/        __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
     319/******/   
     320/******/        // Return the exports of the module
     321/******/        return module.exports;
     322/******/    }
     323/******/   
     324/************************************************************************/
     325/******/    /* webpack/runtime/compat get default export */
     326/******/    (() => {
     327/******/        // getDefaultExport function for compatibility with non-harmony modules
     328/******/        __webpack_require__.n = (module) => {
     329/******/            var getter = module && module.__esModule ?
     330/******/                () => (module['default']) :
     331/******/                () => (module);
     332/******/            __webpack_require__.d(getter, { a: getter });
     333/******/            return getter;
     334/******/        };
     335/******/    })();
     336/******/   
     337/******/    /* webpack/runtime/define property getters */
     338/******/    (() => {
     339/******/        // define getter functions for harmony exports
     340/******/        __webpack_require__.d = (exports, definition) => {
     341/******/            for(var key in definition) {
     342/******/                if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
     343/******/                    Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
     344/******/                }
     345/******/            }
     346/******/        };
     347/******/    })();
     348/******/   
     349/******/    /* webpack/runtime/hasOwnProperty shorthand */
     350/******/    (() => {
     351/******/        __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
     352/******/    })();
     353/******/   
     354/******/    /* webpack/runtime/make namespace object */
     355/******/    (() => {
     356/******/        // define __esModule on exports
     357/******/        __webpack_require__.r = (exports) => {
     358/******/            if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
     359/******/                Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
     360/******/            }
     361/******/            Object.defineProperty(exports, '__esModule', { value: true });
     362/******/        };
     363/******/    })();
     364/******/   
     365/************************************************************************/
     366var __webpack_exports__ = {};
     367// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
     368(() => {
     369/*!*************************************************!*\
     370  !*** ./src/blocks/donation-receipt/frontend.js ***!
     371  \*************************************************/
     372__webpack_require__.r(__webpack_exports__);
     373/* harmony import */ var react_dom_client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react-dom/client */ "./node_modules/react-dom/client.js");
     374/* harmony import */ var _wordpress_dom_ready__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/dom-ready */ "@wordpress/dom-ready");
     375/* harmony import */ var _wordpress_dom_ready__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_dom_ready__WEBPACK_IMPORTED_MODULE_1__);
     376/* harmony import */ var _components_Receipt__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/Receipt */ "./src/blocks/donation-receipt/components/Receipt/index.js");
     377/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react/jsx-runtime */ "react/jsx-runtime");
     378/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__);
     379/**
     380 * External dependencies
     381 */
     382
     383/**
     384 * WordPress dependencies
     385 */
     386 // eslint-disable-line import/no-extraneous-dependencies
     387
     388
     389/**
     390 * Internal dependencies
     391 */
     392
     393
     394/**
     395 * Render the donation receipt component.
     396 */
     397
     398_wordpress_dom_ready__WEBPACK_IMPORTED_MODULE_1___default()(function () {
     399  const receiptBlocks = document.querySelectorAll('.fundy-receipt');
     400  receiptBlocks.forEach(block => {
     401    (0,react_dom_client__WEBPACK_IMPORTED_MODULE_0__.createRoot)(block).render(/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)(_components_Receipt__WEBPACK_IMPORTED_MODULE_2__["default"], {}));
     402  });
     403});
     404})();
     405
     406/******/ })()
     407;
     408//# sourceMappingURL=frontend.js.map
  • dekode-fundraising/trunk/composer.json

    r3408236 r3410996  
    2626    "scripts": {
    2727        "lint": "./vendor/bin/phpcs .",
    28         "make-pot": "./vendor/bin/wp i18n make-pot . languages/dekode-fundraising.pot --exclude=\".github,.cache,node_modules,vendor,tests,src\" --slug=dekode-fundraising",
    29         "make-json": "./vendor/bin/wp i18n make-json languages --no-purge"
     28        "make-pot": "./vendor/bin/wp i18n make-pot . --slug=dekode-fundraising --domain=dekode-fundraising --exclude='.github,.cache,tests,src,node_modules,vendor'",
     29        "make-json": [
     30            "./vendor/bin/wp i18n make-json ./languages --no-purge",
     31            "./vendor/bin/wp i18n make-php ./languages"
     32        ]
    3033    },
    3134    "autoload-dev": {
  • dekode-fundraising/trunk/dekode-fundraising.php

    r3408236 r3410996  
    44 * Plugin URI:        https://github.com/DekodeInteraktiv/fundy-extension-wp/
    55 * Description:       Integrates with Dekode Fundraising, making it easy to add donation forms to your website.
    6  * Version:           2.3.0
     6 * Version:           2.3.1
    77 * Author:            Dekode Interaktiv
    88 * Author URI:        https://dekode.no
     
    2525}
    2626
    27 \define( 'FUNDY_VERSION', '2.3.0' );
     27\define( 'FUNDY_VERSION', '2.3.1' );
    2828\define( 'FUNDY_PLUGIN_URL', \plugin_dir_url( __FILE__ ) );
    2929\define( 'FUNDY_PLUGIN_DIR', \plugin_dir_path( __FILE__ ) );
  • dekode-fundraising/trunk/languages/dekode-fundraising.pot

    r3408236 r3410996  
    33msgid ""
    44msgstr ""
    5 "Project-Id-Version: Dekode Fundraising 2.2.1\n"
     5"Project-Id-Version: Dekode Fundraising 2.3.0\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/dekode-fundraising\n"
    77"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
     
    1010"Content-Type: text/plain; charset=UTF-8\n"
    1111"Content-Transfer-Encoding: 8bit\n"
    12 "POT-Creation-Date: 2025-12-02T15:15:59+00:00\n"
     12"POT-Creation-Date: 2025-12-04T12:57:20+00:00\n"
    1313"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
    1414"X-Generator: WP-CLI 2.13.0-alpha\n"
     
    112112msgstr ""
    113113
    114 #: build/blocks/donation-form/editor.js:1
     114#: build/blocks/donation-form/editor.js:128
     115#: build/blocks/donation-form/editor.js:92
    115116msgid "Please set an API Token on the plugin settings page."
    116117msgstr ""
    117118
    118 #: build/blocks/donation-form/editor.js:1
     119#: build/blocks/donation-form/editor.js:163
     120#: build/blocks/donation-form/editor.js:126
    119121msgid "Dekode Fundraising Form"
    120122msgstr ""
    121123
    122 #: build/blocks/donation-form/editor.js:1
     124#: build/blocks/donation-form/editor.js:166
     125#: build/blocks/donation-form/editor.js:128
    123126msgid "Select a Form"
    124127msgstr ""
    125128
    126 #: build/blocks/donation-form/editor.js:1
     129#: build/blocks/donation-form/editor.js:178
     130#: build/blocks/donation-form/editor.js:140
    127131msgid "No forms found. Please create a Form on your Dekode Fundraising account first."
    128132msgstr ""
    129133
    130 #: build/blocks/donation-form/editor.js:1
     134#: build/blocks/donation-form/editor.js:180
     135#: build/blocks/donation-form/editor.js:147
    131136msgid "Loading…"
    132137msgstr ""
    133138
    134 #: build/blocks/donation-form/editor.js:1
     139#: build/blocks/donation-form/editor.js:186
     140#: build/blocks/donation-form/editor.js:151
    135141msgid "Default URL Parameters (Optional)"
    136142msgstr ""
    137143
    138 #: build/blocks/donation-form/editor.js:1
     144#: build/blocks/donation-form/editor.js:194
     145#: build/blocks/donation-form/editor.js:158
    139146msgid "Key"
    140147msgstr ""
    141148
    142 #: build/blocks/donation-form/editor.js:1
     149#: build/blocks/donation-form/editor.js:200
     150#: build/blocks/donation-form/editor.js:167
    143151msgid "Value"
    144152msgstr ""
    145153
    146 #: build/blocks/donation-form/editor.js:1
     154#: build/blocks/donation-form/editor.js:211
     155#: build/blocks/donation-form/editor.js:180
    147156msgid "Remove"
    148157msgstr ""
    149158
    150 #: build/blocks/donation-form/editor.js:1
     159#: build/blocks/donation-form/editor.js:217
     160#: build/blocks/donation-form/editor.js:186
    151161msgid "Add Parameter"
    152162msgstr ""
    153163
    154 #: build/blocks/donation-receipt/editor.js:1
    155 #: build/blocks/donation-receipt/frontend.js:1
     164#: build/blocks/donation-receipt/editor.js:48
     165#: build/blocks/donation-receipt/frontend.js:170
     166#: build/blocks/donation-receipt/editor.js:16
     167#: build/blocks/donation-receipt/frontend.js:165
    156168msgid "Name"
    157169msgstr ""
    158170
    159 #: build/blocks/donation-receipt/editor.js:1
    160 #: build/blocks/donation-receipt/frontend.js:1
     171#: build/blocks/donation-receipt/editor.js:54
     172#: build/blocks/donation-receipt/frontend.js:147
     173#: build/blocks/donation-receipt/frontend.js:176
     174#: build/blocks/donation-receipt/editor.js:20
     175#: build/blocks/donation-receipt/frontend.js:137
     176#: build/blocks/donation-receipt/frontend.js:175
    161177msgid "Date"
    162178msgstr ""
    163179
    164 #: build/blocks/donation-receipt/editor.js:1
    165 #: build/blocks/donation-receipt/frontend.js:1
     180#: build/blocks/donation-receipt/editor.js:60
     181#: build/blocks/donation-receipt/frontend.js:153
     182#: build/blocks/donation-receipt/frontend.js:182
     183#: build/blocks/donation-receipt/editor.js:24
     184#: build/blocks/donation-receipt/frontend.js:145
     185#: build/blocks/donation-receipt/frontend.js:183
    166186msgid "Total amount"
    167187msgstr ""
    168188
    169 #: build/blocks/donation-receipt/frontend.js:1
     189#: build/blocks/donation-receipt/frontend.js:125
     190#: build/blocks/donation-receipt/frontend.js:104
    170191msgid "Unfortunately, we were unable to load the details for the donation at this moment; the link may have expired."
    171192msgstr ""
    172193
    173 #: build/blocks/donation-receipt/frontend.js:1
     194#: build/blocks/donation-receipt/frontend.js:135
     195#: build/blocks/donation-receipt/frontend.js:121
    174196msgid "Company name"
    175197msgstr ""
    176198
    177 #: build/blocks/donation-receipt/frontend.js:1
     199#: build/blocks/donation-receipt/frontend.js:141
     200#: build/blocks/donation-receipt/frontend.js:127
    178201msgid "Contact person"
    179202msgstr ""
    180203
    181 #: build/blocks/donation-receipt/frontend.js:1
     204#: build/blocks/donation-receipt/frontend.js:159
     205#: build/blocks/donation-receipt/frontend.js:151
    182206msgid "Invoice"
    183207msgstr ""
    184208
    185 #: build/blocks/donation-receipt/frontend.js:1
     209#: build/blocks/donation-receipt/frontend.js:163
     210#: build/blocks/donation-receipt/frontend.js:154
    186211msgid "Download invoice"
    187212msgstr ""
  • dekode-fundraising/trunk/src/blocks/donation-receipt/components/Receipt/Receipt.jsx

    r3382635 r3410996  
    168168
    169169/**
    170  * Format the donation datetime for display.
    171  */
    172 function formatDateTime(dateTime) {
    173     const date = new Date(dateTime);
    174     return date.toLocaleDateString();
     170 * Format a datetime value as a date string in the user's locale.
     171 *
     172 * @param {string|Date|null|undefined} dateTime
     173 *
     174 * @returns {string} Formatted date or empty string if invalid.
     175 */
     176export function formatDateTime(dateTime) {
     177    if (!dateTime) return 'unknown';
     178
     179    const date = dateTime instanceof Date ? dateTime : new Date(dateTime);
     180
     181    if (Number.isNaN(date.getTime())) {
     182        return 'unknown';
     183    }
     184
     185    const locales =
     186        typeof navigator !== 'undefined'
     187        ? navigator.languages || navigator.language
     188        : undefined;
     189
     190    return date.toLocaleDateString(locales, {
     191        year:  'numeric',
     192        month: 'numeric',
     193        day:   'numeric',
     194    });
    175195}
    176196
Note: See TracChangeset for help on using the changeset viewer.