Plugin Directory

Changeset 3165470


Ignore:
Timestamp:
10/09/2024 07:26:59 AM (18 months ago)
Author:
fapi
Message:

Added average churn rate periods graph

Location:
fapi-member
Files:
412 added
9 edited

Legend:

Unmodified
Added
Removed
  • fapi-member/trunk/app/dist/src_Components_Content_Members_Members_js.bundle.js

    r3161406 r3165470  
    1616/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    1717
    18 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ StatisticsClient)\n/* harmony export */ });\n/* harmony import */ var _Client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Client */ \"./src/Clients/Client.js\");\n/* harmony import */ var Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! Enums/RequestMethodType */ \"./src/Enums/RequestMethodType.js\");\n/* harmony import */ var Models_MembershipChange__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! Models/MembershipChange */ \"./src/Models/MembershipChange.js\");\n\n\n\nclass StatisticsClient extends _Client__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\n  constructor() {\n    super('statistics');\n  }\n  async getMembershipChangesForUser(userId) {\n    var changesData = await this.sendRequest('getMembershipChangesForUser', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, {\n      user_id: userId\n    });\n    var changes = [];\n    if (changesData) {\n      changesData.forEach(changeData => {\n        changes.push(new Models_MembershipChange__WEBPACK_IMPORTED_MODULE_2__[\"default\"](changeData));\n      });\n    }\n    return changes;\n  }\n  async getMemberCountsForPeriod(filterData) {\n    return await this.sendRequest('getMemberCountsForPeriod', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getMemberCountChangesForPeriod(filterData) {\n    return await this.sendRequest('getMemberCountChangesForPeriod', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getChurnRate(filterData) {\n    return await this.sendRequest('getChurnRate', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getAcquisitionRate(filterData) {\n    return await this.sendRequest('getAcquisitionRate', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getActiveCountsForPeriod(filterData) {\n    return await this.sendRequest('getActiveCountsForPeriod', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n}\n\n//# sourceURL=webpack://app/./src/Clients/StatisticsClient.js?");
     18eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ StatisticsClient)\n/* harmony export */ });\n/* harmony import */ var _Client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Client */ \"./src/Clients/Client.js\");\n/* harmony import */ var Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! Enums/RequestMethodType */ \"./src/Enums/RequestMethodType.js\");\n/* harmony import */ var Models_MembershipChange__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! Models/MembershipChange */ \"./src/Models/MembershipChange.js\");\n\n\n\nclass StatisticsClient extends _Client__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\n  constructor() {\n    super('statistics');\n  }\n  async getMembershipChangesForUser(userId) {\n    var changesData = await this.sendRequest('getMembershipChangesForUser', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, {\n      user_id: userId\n    });\n    var changes = [];\n    if (changesData) {\n      changesData.forEach(changeData => {\n        changes.push(new Models_MembershipChange__WEBPACK_IMPORTED_MODULE_2__[\"default\"](changeData));\n      });\n    }\n    return changes;\n  }\n  async getMemberCountsForPeriod(filterData) {\n    return await this.sendRequest('getMemberCountsForPeriod', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getMemberCountChangesForPeriod(filterData) {\n    return await this.sendRequest('getMemberCountChangesForPeriod', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getChurnRate(filterData) {\n    return await this.sendRequest('getChurnRate', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getAcquisitionRate(filterData) {\n    return await this.sendRequest('getAcquisitionRate', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getActiveCountsForPeriod(filterData) {\n    return await this.sendRequest('getActiveCountsForPeriod', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getAverageChurnRatePeriods(filterData) {\n    return await this.sendRequest('getAverageChurnRatePeriods', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n}\n\n//# sourceURL=webpack://app/./src/Clients/StatisticsClient.js?");
    1919
    2020/***/ }),
  • fapi-member/trunk/app/dist/src_Components_Content_Overview_Statistics_js.bundle.js

    r3161406 r3165470  
    1616/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    1717
    18 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ StatisticsClient)\n/* harmony export */ });\n/* harmony import */ var _Client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Client */ \"./src/Clients/Client.js\");\n/* harmony import */ var Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! Enums/RequestMethodType */ \"./src/Enums/RequestMethodType.js\");\n/* harmony import */ var Models_MembershipChange__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! Models/MembershipChange */ \"./src/Models/MembershipChange.js\");\n\n\n\nclass StatisticsClient extends _Client__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\n  constructor() {\n    super('statistics');\n  }\n  async getMembershipChangesForUser(userId) {\n    var changesData = await this.sendRequest('getMembershipChangesForUser', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, {\n      user_id: userId\n    });\n    var changes = [];\n    if (changesData) {\n      changesData.forEach(changeData => {\n        changes.push(new Models_MembershipChange__WEBPACK_IMPORTED_MODULE_2__[\"default\"](changeData));\n      });\n    }\n    return changes;\n  }\n  async getMemberCountsForPeriod(filterData) {\n    return await this.sendRequest('getMemberCountsForPeriod', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getMemberCountChangesForPeriod(filterData) {\n    return await this.sendRequest('getMemberCountChangesForPeriod', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getChurnRate(filterData) {\n    return await this.sendRequest('getChurnRate', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getAcquisitionRate(filterData) {\n    return await this.sendRequest('getAcquisitionRate', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getActiveCountsForPeriod(filterData) {\n    return await this.sendRequest('getActiveCountsForPeriod', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n}\n\n//# sourceURL=webpack://app/./src/Clients/StatisticsClient.js?");
     18eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ StatisticsClient)\n/* harmony export */ });\n/* harmony import */ var _Client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Client */ \"./src/Clients/Client.js\");\n/* harmony import */ var Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! Enums/RequestMethodType */ \"./src/Enums/RequestMethodType.js\");\n/* harmony import */ var Models_MembershipChange__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! Models/MembershipChange */ \"./src/Models/MembershipChange.js\");\n\n\n\nclass StatisticsClient extends _Client__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\n  constructor() {\n    super('statistics');\n  }\n  async getMembershipChangesForUser(userId) {\n    var changesData = await this.sendRequest('getMembershipChangesForUser', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, {\n      user_id: userId\n    });\n    var changes = [];\n    if (changesData) {\n      changesData.forEach(changeData => {\n        changes.push(new Models_MembershipChange__WEBPACK_IMPORTED_MODULE_2__[\"default\"](changeData));\n      });\n    }\n    return changes;\n  }\n  async getMemberCountsForPeriod(filterData) {\n    return await this.sendRequest('getMemberCountsForPeriod', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getMemberCountChangesForPeriod(filterData) {\n    return await this.sendRequest('getMemberCountChangesForPeriod', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getChurnRate(filterData) {\n    return await this.sendRequest('getChurnRate', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getAcquisitionRate(filterData) {\n    return await this.sendRequest('getAcquisitionRate', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getActiveCountsForPeriod(filterData) {\n    return await this.sendRequest('getActiveCountsForPeriod', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n  async getAverageChurnRatePeriods(filterData) {\n    return await this.sendRequest('getAverageChurnRatePeriods', Enums_RequestMethodType__WEBPACK_IMPORTED_MODULE_1__.RequestMethodType.POST, filterData);\n  }\n}\n\n//# sourceURL=webpack://app/./src/Clients/StatisticsClient.js?");
    1919
    2020/***/ }),
     
    2626/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    2727
    28 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var Components_Content_Overview_StatisticsFilter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! Components/Content/Overview/StatisticsFilter */ \"./src/Components/Content/Overview/StatisticsFilter.js\");\n/* harmony import */ var Clients_StatisticsClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! Clients/StatisticsClient */ \"./src/Clients/StatisticsClient.js\");\n/* harmony import */ var Clients_MemberSectionClient__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! Clients/MemberSectionClient */ \"./src/Clients/MemberSectionClient.js\");\n/* harmony import */ var Components_Elements_Loading__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! Components/Elements/Loading */ \"./src/Components/Elements/Loading.js\");\n/* harmony import */ var Components_Content_Overview_StatisticsCharts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! Components/Content/Overview/StatisticsCharts */ \"./src/Components/Content/Overview/StatisticsCharts.js\");\n\n\n\n\n\n\nfunction Statistics() {\n  const statisticsClient = new Clients_StatisticsClient__WEBPACK_IMPORTED_MODULE_2__[\"default\"]();\n  const sectionClient = new Clients_MemberSectionClient__WEBPACK_IMPORTED_MODULE_3__[\"default\"]();\n  const [loadStatistics, setLoadStatistics] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(true);\n  const [levels, setLevels] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n  const [filterData, setFilterData] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n  const [memberCounts, setMemberCounts] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n  const [activeCounts, setActiveCounts] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n  const [memberCountChanges, setMemberCountChanges] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n  const [churnRates, setChurnRates] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n  const [acquisitionRates, setAcquisitionRates] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n  const [showingGroupedLevels, setShowingGroupedLevels] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(true);\n  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {\n    const reloadStatistics = async () => {\n      await sectionClient.getAllAsLevels().then(data => {\n        setLevels(data);\n      });\n      if (filterData !== null) {\n        statisticsClient.getMemberCountsForPeriod(filterData).then(data => {\n          setMemberCounts(data);\n        });\n        statisticsClient.getMemberCountChangesForPeriod(filterData).then(data => {\n          setMemberCountChanges(data);\n        });\n        statisticsClient.getChurnRate(filterData).then(data => {\n          setChurnRates(data);\n        });\n        statisticsClient.getAcquisitionRate(filterData).then(data => {\n          setAcquisitionRates(data);\n        });\n        statisticsClient.getActiveCountsForPeriod(filterData).then(data => {\n          setActiveCounts(data);\n        });\n        setShowingGroupedLevels(filterData.group_levels);\n      }\n      setLoadStatistics(false);\n    };\n    if (loadStatistics) {\n      reloadStatistics();\n    }\n  }, [loadStatistics]);\n  if (levels === null) {\n    return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_Loading__WEBPACK_IMPORTED_MODULE_4__[\"default\"], null);\n  }\n  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n    className: \"content-statistics\"\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Content_Overview_StatisticsFilter__WEBPACK_IMPORTED_MODULE_1__[\"default\"], {\n    levels: levels,\n    setFilterData: setFilterData,\n    setLoadStatistics: setLoadStatistics,\n    loadStatistics: loadStatistics,\n    filterData: filterData\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Content_Overview_StatisticsCharts__WEBPACK_IMPORTED_MODULE_5__[\"default\"], {\n    showingGroupedLevels: showingGroupedLevels,\n    memberCounts: memberCounts,\n    memberCountChanges: memberCountChanges,\n    churnRates: churnRates,\n    acquisitionRates: acquisitionRates,\n    activeCounts: activeCounts,\n    resetStatsToNull: () => {\n      setMemberCounts(null);\n      setMemberCountChanges(null);\n      setChurnRates(null);\n      setAcquisitionRates(null);\n    }\n  }));\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Statistics);\n\n//# sourceURL=webpack://app/./src/Components/Content/Overview/Statistics.js?");
     28eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var Components_Content_Overview_StatisticsFilter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! Components/Content/Overview/StatisticsFilter */ \"./src/Components/Content/Overview/StatisticsFilter.js\");\n/* harmony import */ var Clients_StatisticsClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! Clients/StatisticsClient */ \"./src/Clients/StatisticsClient.js\");\n/* harmony import */ var Clients_MemberSectionClient__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! Clients/MemberSectionClient */ \"./src/Clients/MemberSectionClient.js\");\n/* harmony import */ var Components_Elements_Loading__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! Components/Elements/Loading */ \"./src/Components/Elements/Loading.js\");\n/* harmony import */ var Components_Content_Overview_StatisticsCharts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! Components/Content/Overview/StatisticsCharts */ \"./src/Components/Content/Overview/StatisticsCharts.js\");\n\n\n\n\n\n\nfunction Statistics() {\n  const statisticsClient = new Clients_StatisticsClient__WEBPACK_IMPORTED_MODULE_2__[\"default\"]();\n  const sectionClient = new Clients_MemberSectionClient__WEBPACK_IMPORTED_MODULE_3__[\"default\"]();\n  const [loadStatistics, setLoadStatistics] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(true);\n  const [levels, setLevels] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n  const [filterData, setFilterData] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n  const [memberCounts, setMemberCounts] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n  const [activeCounts, setActiveCounts] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n  const [memberCountChanges, setMemberCountChanges] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n  const [churnRates, setChurnRates] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n  const [acquisitionRates, setAcquisitionRates] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n  const [averageChurnRatePeriods, setAverageChurnRatePeriods] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n  const [showingGroupedLevels, setShowingGroupedLevels] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(true);\n  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {\n    const reloadStatistics = async () => {\n      await sectionClient.getAllAsLevels().then(data => {\n        setLevels(data);\n      });\n      if (filterData !== null) {\n        statisticsClient.getMemberCountsForPeriod(filterData).then(data => {\n          setMemberCounts(data);\n        });\n        statisticsClient.getMemberCountChangesForPeriod(filterData).then(data => {\n          setMemberCountChanges(data);\n        });\n        statisticsClient.getChurnRate(filterData).then(data => {\n          setChurnRates(data);\n        });\n        statisticsClient.getAcquisitionRate(filterData).then(data => {\n          setAcquisitionRates(data);\n        });\n        statisticsClient.getActiveCountsForPeriod(filterData).then(data => {\n          setActiveCounts(data);\n        });\n        statisticsClient.getAverageChurnRatePeriods(filterData).then(data => {\n          setAverageChurnRatePeriods(data);\n        });\n        setShowingGroupedLevels(filterData.group_levels);\n      }\n      setLoadStatistics(false);\n    };\n    if (loadStatistics) {\n      reloadStatistics();\n    }\n  }, [loadStatistics]);\n  if (levels === null) {\n    return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_Loading__WEBPACK_IMPORTED_MODULE_4__[\"default\"], null);\n  }\n  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n    className: \"content-statistics\"\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Content_Overview_StatisticsFilter__WEBPACK_IMPORTED_MODULE_1__[\"default\"], {\n    levels: levels,\n    setFilterData: setFilterData,\n    setLoadStatistics: setLoadStatistics,\n    loadStatistics: loadStatistics,\n    filterData: filterData\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Content_Overview_StatisticsCharts__WEBPACK_IMPORTED_MODULE_5__[\"default\"], {\n    filterData: filterData,\n    showingGroupedLevels: showingGroupedLevels,\n    memberCounts: memberCounts,\n    memberCountChanges: memberCountChanges,\n    churnRates: churnRates,\n    acquisitionRates: acquisitionRates,\n    activeCounts: activeCounts,\n    averageChurnRatePeriods: averageChurnRatePeriods,\n    resetStatsToNull: () => {\n      setMemberCounts(null);\n      setMemberCountChanges(null);\n      setChurnRates(null);\n      setAcquisitionRates(null);\n      setActiveCounts(null);\n      setAverageChurnRatePeriods(null);\n    }\n  }));\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Statistics);\n\n//# sourceURL=webpack://app/./src/Components/Content/Overview/Statistics.js?");
    2929
    3030/***/ }),
     
    3636/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    3737
    38 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var Components_Elements_Loading__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! Components/Elements/Loading */ \"./src/Components/Elements/Loading.js\");\n/* harmony import */ var Components_Elements_BarChartWidget__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! Components/Elements/BarChartWidget */ \"./src/Components/Elements/BarChartWidget.js\");\n/* harmony import */ var Components_Elements_LineChartWidget__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! Components/Elements/LineChartWidget */ \"./src/Components/Elements/LineChartWidget.js\");\n\n\n\n\nfunction StatisticsCharts(_ref) {\n  let {\n    showingGroupedLevels,\n    memberCounts,\n    activeCounts,\n    memberCountChanges,\n    churnRates,\n    acquisitionRates,\n    resetStatsToNull\n  } = _ref;\n  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {\n    resetStatsToNull();\n  }, [showingGroupedLevels]);\n  if (memberCounts === null || memberCountChanges === null || acquisitionRates === null || churnRates === null || activeCounts === null) {\n    return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_Loading__WEBPACK_IMPORTED_MODULE_1__[\"default\"], {\n      height: '400px'\n    });\n  }\n  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n    className: \"statistics-charts\"\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_BarChartWidget__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n    data: memberCounts,\n    colors: showingGroupedLevels ? ['#0074e2'] : null,\n    title: 'Počet členství'\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_LineChartWidget__WEBPACK_IMPORTED_MODULE_3__[\"default\"], {\n    data: memberCountChanges,\n    colors: showingGroupedLevels ? ['#aad20e', 'rgb(250, 83, 41)'] : null,\n    title: 'Vzniklých/zaniklých členství'\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_BarChartWidget__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n    data: activeCounts,\n    colors: ['#aad20e'],\n    title: 'Aktivních členů'\n  }), showingGroupedLevels ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_BarChartWidget__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n    data: {\n      ...churnRates,\n      ...acquisitionRates\n    },\n    colors: showingGroupedLevels ? ['rgb(250, 83, 41)', '#aad20e'] : null,\n    isPercentage: true\n  }) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n    style: {\n      display: 'grid',\n      gap: '20px',\n      gridTemplateColumns: 'auto auto'\n    }\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_BarChartWidget__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n    data: churnRates,\n    colors: showingGroupedLevels ? ['rgb(250, 83, 41)'] : null,\n    title: 'Churn rate',\n    isPercentage: true\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_BarChartWidget__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n    data: acquisitionRates,\n    colors: showingGroupedLevels ? ['#aad20e'] : null,\n    title: 'Acquisition rate',\n    isPercentage: true\n  })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n    className: \"fm-chart no-data\",\n    style: {\n      width: '100%'\n    }\n  }, \"Data vygenerovan\\xE1 p\\u0159ed sta\\u017Een\\xEDm FAPI Member verze 2.2.0 nejsou p\\u0159esn\\xE1.\"));\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (StatisticsCharts);\n\n//# sourceURL=webpack://app/./src/Components/Content/Overview/StatisticsCharts.js?");
     38eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var Components_Elements_Loading__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! Components/Elements/Loading */ \"./src/Components/Elements/Loading.js\");\n/* harmony import */ var Components_Elements_BarChartWidget__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! Components/Elements/BarChartWidget */ \"./src/Components/Elements/BarChartWidget.js\");\n/* harmony import */ var Components_Elements_LineChartWidget__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! Components/Elements/LineChartWidget */ \"./src/Components/Elements/LineChartWidget.js\");\n\n\n\n\nfunction StatisticsCharts(_ref) {\n  let {\n    filterData,\n    showingGroupedLevels,\n    memberCounts,\n    activeCounts,\n    memberCountChanges,\n    churnRates,\n    acquisitionRates,\n    averageChurnRatePeriods,\n    resetStatsToNull\n  } = _ref;\n  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {\n    resetStatsToNull();\n  }, [showingGroupedLevels]);\n  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n    className: \"statistics-charts\"\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_BarChartWidget__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n    data: memberCounts,\n    colors: showingGroupedLevels ? ['#0074e2'] : null,\n    title: 'Počet členství'\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_LineChartWidget__WEBPACK_IMPORTED_MODULE_3__[\"default\"], {\n    data: memberCountChanges,\n    colors: showingGroupedLevels ? ['#aad20e', 'rgb(250, 83, 41)'] : null,\n    title: 'Vzniklých/zaniklých členství'\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_BarChartWidget__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n    data: activeCounts,\n    colors: ['#aad20e'],\n    title: 'Aktivních členů'\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_BarChartWidget__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n    data: averageChurnRatePeriods,\n    colors: showingGroupedLevels ? ['rgb(250, 83, 41)'] : null,\n    title: 'Churn rate od data registrace',\n    isPercentage: true\n  }), showingGroupedLevels ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_BarChartWidget__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n    data: {\n      ...churnRates,\n      ...acquisitionRates\n    },\n    colors: showingGroupedLevels ? ['rgb(250, 83, 41)', '#aad20e'] : null,\n    isPercentage: true,\n    title: 'Churn/Acquisition rate' + (filterData !== null ? ' - od ' + filterData.date_from + ' do ' + filterData.date_to : '')\n  }) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n    style: {\n      display: 'grid',\n      gap: '20px',\n      gridTemplateColumns: 'auto auto'\n    }\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_BarChartWidget__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n    data: churnRates,\n    colors: showingGroupedLevels ? ['rgb(250, 83, 41)'] : null,\n    isPercentage: true,\n    title: 'Churn rate' + (filterData !== null ? ' - od ' + filterData.date_from + ' do ' + filterData.date_to : '')\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_BarChartWidget__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n    data: acquisitionRates,\n    colors: showingGroupedLevels ? ['#aad20e'] : null,\n    isPercentage: true,\n    title: 'Acquisition rate' + (filterData !== null ? ' - od ' + filterData.date_from + ' do ' + filterData.date_to : '')\n  })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n    className: \"fm-chart no-data\",\n    style: {\n      width: '100%'\n    }\n  }, \"Data vygenerovan\\xE1 p\\u0159ed sta\\u017Een\\xEDm FAPI Member verze 2.2.0 nejsou p\\u0159esn\\xE1.\"));\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (StatisticsCharts);\n\n//# sourceURL=webpack://app/./src/Components/Content/Overview/StatisticsCharts.js?");
    3939
    4040/***/ }),
     
    5656/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    5757
    58 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/component/ResponsiveContainer.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/chart/BarChart.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/CartesianGrid.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/XAxis.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/YAxis.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/component/Tooltip.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/component/Legend.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/Bar.js\");\n/* harmony import */ var Helpers_StringHelper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! Helpers/StringHelper */ \"./src/Helpers/StringHelper.js\");\n\n\n\nfunction BarChartWidget(_ref) {\n  let {\n    data,\n    keys = [],\n    width = '100%',\n    height = 400,\n    title = '',\n    colors = null,\n    isPercentage = false\n  } = _ref;\n  let totalSum = 0;\n  Object.values(data).forEach(dataPoint => {\n    Object.keys(dataPoint).forEach(key => {\n      keys[key] = key;\n    });\n  });\n  keys = Object.keys(keys);\n  data = Object.entries(data).map(_ref2 => {\n    let [date, value] = _ref2;\n    return {\n      'fm-date': date,\n      ...value\n    };\n  });\n  data.forEach(dataPoint => {\n    keys.forEach(key => {\n      totalSum += dataPoint[key] || 0;\n    });\n  });\n  if (totalSum === 0 || data === null) {\n    return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n      className: \"fm-chart no-data\",\n      style: {\n        width: width\n      }\n    }, \"\\u017D\\xE1dn\\xE1 data\");\n  }\n  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n    className: 'fm-chart',\n    style: {\n      width: width\n    }\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"h4\", {\n    style: {\n      textAlign: 'center'\n    }\n  }, title), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_2__.ResponsiveContainer, {\n    width: '100%',\n    height: height\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_3__.BarChart, {\n    data: data,\n    margin: {\n      top: 20,\n      right: 30,\n      left: 20,\n      bottom: 5\n    }\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_4__.CartesianGrid, {\n    strokeDasharray: \"3 3\"\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_5__.XAxis, {\n    dataKey: \"fm-date\",\n    tickFomatter: value => value.toFixed(2)\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_6__.YAxis, {\n    tickFormatter: isPercentage ? value => \"\".concat(value.toFixed(0), \"%\") : value => \"\".concat(value)\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_7__.Tooltip, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_8__.Legend, null), keys.map((key, index) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_9__.Bar, {\n    key: key,\n    dataKey: key,\n    stackId: \"a\",\n    fill: colors === null ? Helpers_StringHelper__WEBPACK_IMPORTED_MODULE_1__.StringHelper.stringToColor(key) : colors[index],\n    animationBegin: 0,\n    animationDuration: 500,\n    animationEasing: \"ease-out\"\n  })))));\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (BarChartWidget);\n\n//# sourceURL=webpack://app/./src/Components/Elements/BarChartWidget.js?");
     58eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/component/ResponsiveContainer.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/chart/BarChart.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/CartesianGrid.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/XAxis.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/YAxis.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/component/Tooltip.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/component/Legend.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/Bar.js\");\n/* harmony import */ var Helpers_StringHelper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! Helpers/StringHelper */ \"./src/Helpers/StringHelper.js\");\n/* harmony import */ var Components_Elements_Loading__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! Components/Elements/Loading */ \"./src/Components/Elements/Loading.js\");\n\n\n\n\nfunction BarChartWidget(_ref) {\n  let {\n    data,\n    keys = [],\n    width = '100%',\n    height = 400,\n    title = '',\n    colors = null,\n    isPercentage = false\n  } = _ref;\n  let totalSum = 0;\n  if (data === null) {\n    return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n      className: \"fm-chart\",\n      style: {\n        width: '100%'\n      }\n    }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_Loading__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n      height: height + 'px'\n    }));\n  }\n  Object.values(data).forEach(dataPoint => {\n    Object.keys(dataPoint).forEach(key => {\n      keys[key] = key;\n    });\n  });\n  keys = Object.keys(keys);\n  data = Object.entries(data).map(_ref2 => {\n    let [date, value] = _ref2;\n    return {\n      'fm-date': date,\n      ...value\n    };\n  });\n  data.forEach(dataPoint => {\n    keys.forEach(key => {\n      totalSum += dataPoint[key] || 0;\n    });\n  });\n  if (totalSum === 0) {\n    return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n      className: \"fm-chart no-data\",\n      style: {\n        width: width\n      }\n    }, \"\\u017D\\xE1dn\\xE1 data\");\n  }\n  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n    className: 'fm-chart',\n    style: {\n      width: width\n    }\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"h4\", {\n    style: {\n      textAlign: 'center'\n    }\n  }, title), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_3__.ResponsiveContainer, {\n    width: '100%',\n    height: height\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_4__.BarChart, {\n    data: data,\n    margin: {\n      top: 20,\n      right: 30,\n      left: 20,\n      bottom: 5\n    }\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_5__.CartesianGrid, {\n    strokeDasharray: \"3 3\"\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_6__.XAxis, {\n    dataKey: \"fm-date\",\n    tickFomatter: value => value.toFixed(2)\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_7__.YAxis, {\n    tickFormatter: isPercentage ? value => \"\".concat(value.toFixed(0), \"%\") : value => \"\".concat(value)\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_8__.Tooltip, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_9__.Legend, null), keys.map((key, index) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_10__.Bar, {\n    key: key,\n    dataKey: key,\n    stackId: \"a\",\n    fill: colors === null ? Helpers_StringHelper__WEBPACK_IMPORTED_MODULE_1__.StringHelper.stringToColor(key) : colors[index],\n    animationBegin: 0,\n    animationDuration: 500,\n    animationEasing: \"ease-out\"\n  })))));\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (BarChartWidget);\n\n//# sourceURL=webpack://app/./src/Components/Elements/BarChartWidget.js?");
    5959
    6060/***/ }),
     
    6666/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    6767
    68 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/component/ResponsiveContainer.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/chart/LineChart.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/CartesianGrid.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/XAxis.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/YAxis.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/component/Tooltip.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/component/Legend.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/Line.js\");\n/* harmony import */ var Helpers_StringHelper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! Helpers/StringHelper */ \"./src/Helpers/StringHelper.js\");\n\n\n\nfunction LineChartWidget(_ref) {\n  let {\n    data,\n    keys = [],\n    width = '100%',\n    height = 400,\n    title = '',\n    colors = null\n  } = _ref;\n  let totalSum = 0;\n  Object.values(data).forEach(dataPoint => {\n    Object.keys(dataPoint).forEach(key => {\n      keys[key] = key;\n    });\n  });\n  keys = Object.keys(keys);\n  data = Object.entries(data).map(_ref2 => {\n    let [date, value] = _ref2;\n    return {\n      'fm-date': date,\n      ...value\n    };\n  });\n  data.forEach(dataPoint => {\n    keys.forEach(key => {\n      totalSum += dataPoint[key] || 0;\n    });\n  });\n  if (totalSum === 0 || data === null) {\n    return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n      className: \"fm-chart no-data\",\n      style: {\n        width: width\n      }\n    }, \"\\u017D\\xE1dn\\xE1 data\");\n  }\n  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n    className: 'fm-chart',\n    style: {\n      width: width\n    }\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"h4\", {\n    style: {\n      textAlign: 'center'\n    }\n  }, title), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_2__.ResponsiveContainer, {\n    width: '100%',\n    height: height\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_3__.LineChart, {\n    data: data,\n    margin: {\n      top: 20,\n      right: 30,\n      left: 20,\n      bottom: 5\n    }\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_4__.CartesianGrid, {\n    strokeDasharray: \"3 3\"\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_5__.XAxis, {\n    dataKey: \"fm-date\"\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_6__.YAxis, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_7__.Tooltip, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_8__.Legend, null), keys.map((key, index) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_9__.Line, {\n    key: key,\n    type: \"monotone\",\n    dataKey: key,\n    stroke: colors === null ? Helpers_StringHelper__WEBPACK_IMPORTED_MODULE_1__.StringHelper.stringToColor(key) : colors[index],\n    strokeWidth: 2.5,\n    animationBegin: 0,\n    animationDuration: 500,\n    animationEasing: \"ease-out\"\n  })))));\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (LineChartWidget);\n\n//# sourceURL=webpack://app/./src/Components/Elements/LineChartWidget.js?");
     68eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/component/ResponsiveContainer.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/chart/LineChart.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/CartesianGrid.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/XAxis.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/YAxis.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/component/Tooltip.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/component/Legend.js\");\n/* harmony import */ var recharts__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! recharts */ \"./node_modules/recharts/es6/cartesian/Line.js\");\n/* harmony import */ var Helpers_StringHelper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! Helpers/StringHelper */ \"./src/Helpers/StringHelper.js\");\n/* harmony import */ var Components_Elements_Loading__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! Components/Elements/Loading */ \"./src/Components/Elements/Loading.js\");\n\n\n\n\nfunction LineChartWidget(_ref) {\n  let {\n    data,\n    keys = [],\n    width = '100%',\n    height = 400,\n    title = '',\n    colors = null\n  } = _ref;\n  let totalSum = 0;\n  if (data === null) {\n    return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n      className: \"fm-chart\",\n      style: {\n        width: '100%'\n      }\n    }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Components_Elements_Loading__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n      height: height + 'px'\n    }));\n  }\n  Object.values(data).forEach(dataPoint => {\n    Object.keys(dataPoint).forEach(key => {\n      keys[key] = key;\n    });\n  });\n  keys = Object.keys(keys);\n  data = Object.entries(data).map(_ref2 => {\n    let [date, value] = _ref2;\n    return {\n      'fm-date': date,\n      ...value\n    };\n  });\n  data.forEach(dataPoint => {\n    keys.forEach(key => {\n      totalSum += dataPoint[key] || 0;\n    });\n  });\n  if (totalSum === 0) {\n    return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n      className: \"fm-chart no-data\",\n      style: {\n        width: width\n      }\n    }, \"\\u017D\\xE1dn\\xE1 data\");\n  }\n  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"div\", {\n    className: 'fm-chart',\n    style: {\n      width: width\n    }\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(\"h4\", {\n    style: {\n      textAlign: 'center'\n    }\n  }, title), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_3__.ResponsiveContainer, {\n    width: '100%',\n    height: height\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_4__.LineChart, {\n    data: data,\n    margin: {\n      top: 20,\n      right: 30,\n      left: 20,\n      bottom: 5\n    }\n  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_5__.CartesianGrid, {\n    strokeDasharray: \"3 3\"\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_6__.XAxis, {\n    dataKey: \"fm-date\"\n  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_7__.YAxis, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_8__.Tooltip, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_9__.Legend, null), keys.map((key, index) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(recharts__WEBPACK_IMPORTED_MODULE_10__.Line, {\n    key: key,\n    type: \"monotone\",\n    dataKey: key,\n    stroke: colors === null ? Helpers_StringHelper__WEBPACK_IMPORTED_MODULE_1__.StringHelper.stringToColor(key) : colors[index],\n    strokeWidth: 2.5,\n    animationBegin: 0,\n    animationDuration: 500,\n    animationEasing: \"ease-out\"\n  })))));\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (LineChartWidget);\n\n//# sourceURL=webpack://app/./src/Components/Elements/LineChartWidget.js?");
    6969
    7070/***/ }),
  • fapi-member/trunk/fapi-member.php

    r3161406 r3165470  
    1515 * Plugin URI:        https://fapi.cz/
    1616 * Description:       Plugin FAPI pro jednoduchou správu členských sekcí na webu.
    17  * Version:           2.2.0
     17 * Version:           2.2.1
    1818 * Requires at least: 5.9
    1919 * Requires PHP:      8.1
     
    3030require __DIR__ . '/src/Utils/functions.php';
    3131
    32 define('FAPI_MEMBER_PLUGIN_VERSION', '2.2.0');
     32define('FAPI_MEMBER_PLUGIN_VERSION', '2.2.1');
    3333
    3434$FapiPlugin = new FapiMemberPlugin();
  • fapi-member/trunk/readme.txt

    r3161406 r3165470  
    66Requires PHP: 8.1
    77License: GPLv2 or later
    8 Stable tag: 2.2.0
     8Stable tag: 2.2.1
    99
    1010Plugin FAPI pro jednoduchou správu členských sekcí na webu.
     
    2626
    2727== Changelog ==
     28
     29= 2.2.1 =
     30* Fapi Member Pro
     31    * Added average churn rate period graph
    2832
    2933= 2.2.0 =
  • fapi-member/trunk/src/Api/V2/Endpoints/StatisticsController.php

    r3161406 r3165470  
    147147        return $this->statisticsService->getActiveCountsForPeriod($dateFrom, $dateTo);
    148148    }
     149
     150    public function getAverageChurnRatePeriods(WP_REST_Request $request): array
     151    {
     152        $this->apiController->checkRequestMethod($request, RequestMethodType::POST);
     153        $body = json_decode($request->get_body(), true);
     154        $groupLevels = $this->apiController->extractParam($body, 'group_levels', BoolType::class);
     155
     156        $levelIds = [];
     157
     158        foreach ($body['level_ids'] as $levelId) {
     159            $levelIds[] = (int) $levelId;
     160        }
     161
     162        return $this->statisticsService->getAverageChurnRatePeriodsForLevels($groupLevels, $levelIds);
     163    }
    149164}
  • fapi-member/trunk/src/Model/MembershipChange.php

    r3161406 r3165470  
    6262    }
    6363
     64
     65    public function getTimestamp(): DateTimeImmutable|null
     66    {
     67        return $this->timestamp;
     68    }
     69
    6470    public function isActive(): bool
    6571    {
  • fapi-member/trunk/src/Repository/MembershipChangeRepository.php

    r3161406 r3165470  
    144144    }
    145145
     146    /** @return array<MembershipChange> */
     147    public function getFirstCreatedForLevels(
     148        array $levelIds,
     149    ): array
     150    {
     151        $levelIdsPlaceholder = implode(',', array_fill(0, count($levelIds), '%d'));
     152
     153        $queryParams = $levelIds === []
     154            ? ''
     155            :'AND level_id IN (' . $levelIdsPlaceholder . ')';
     156
     157        $query = $this->wpdb->prepare("
     158            SELECT t1.*
     159            FROM $this->tableName t1
     160            JOIN (
     161                SELECT user_id, level_id, MIN(timestamp) as min_timestamp
     162                FROM $this->tableName
     163                WHERE type = 'created'
     164                " . $queryParams . "
     165                GROUP BY user_id, level_id
     166            ) t2
     167            ON t1.user_id = t2.user_id
     168            AND t1.level_id = t2.level_id
     169            AND t1.timestamp = t2.min_timestamp
     170            ORDER BY t1.user_id, t1.level_id, t1.id DESC;
     171        ",
     172        $levelIds
     173        );
     174
     175        $results = $this->wpdb->get_results($query, ARRAY_A);
     176
     177        return $this->toEntities($results);
     178    }
     179
    146180    /** @return array<MembershipChange>*/
    147181    private function toEntities(array|null $results, bool $allowMultiple = false): array
  • fapi-member/trunk/src/Service/StatisticsService.php

    r3161406 r3165470  
    264264    }
    265265
     266    public function getAverageChurnRatePeriodsForLevels(
     267        bool $groupLevels,
     268        array $levelIds,
     269    ): array
     270    {
     271        $firstCreatedChanges = $this->membershipChangeRepository
     272            ->getFirstCreatedForLevels($levelIds);
     273
     274        $totalCount = count($firstCreatedChanges);
     275
     276        if ($totalCount === 0) {
     277            return [];
     278        }
     279
     280        $graphColumns = [
     281            'Měsíc' => '+1 month',
     282            '2 Měsíce' => '+2 months',
     283            '3 Měsíce' => '+3 months',
     284            '4 Měsíce' => '+4 months',
     285            '5 Měsíců' => '+5 months',
     286            'Půl roku' => '+6 months',
     287            'Rok' => '+1 year',
     288            '2 Roky' => '+2 years',
     289        ];
     290
     291        $churnedOutCounts = [];
     292
     293        foreach ($firstCreatedChanges as $firstCreatedChange) {
     294            $startDate = $firstCreatedChange->getTimestamp();
     295            $levelKey = $groupLevels
     296                    ? 'Churn rate'
     297                    : $this->levelRepository
     298                        ->getLevelById($firstCreatedChange->getLevelId())
     299                        ?->getName();
     300
     301            foreach ($graphColumns as $key => $value) {
     302                if (!isset($churnedOutCounts[$key][$levelKey])) {
     303                    $churnedOutCounts[$key][$levelKey] = 0;
     304                }
     305
     306                $endDate = $startDate->modify($value)->modify('-1 day');
     307
     308                if ($endDate > DateTimeHelper::getNow()) {
     309                    break;
     310                }
     311
     312                $lastChange = $this->membershipChangeRepository->findLastChange(
     313                    $firstCreatedChange->getUserId(),
     314                    $firstCreatedChange->getLevelId(),
     315                    $endDate,
     316                );
     317
     318                if ($firstCreatedChange->isActive() && !$lastChange->isActive()) {
     319                    $churnedOutCounts[$key][$levelKey]++;
     320                    break;
     321                }
     322            }
     323        }
     324
     325        $churnedOutRates = [];
     326
     327        foreach ($churnedOutCounts as $key => $churnedOutPeriod) {
     328            foreach ($churnedOutPeriod as $levelKey => $churnedOutLevel) {
     329                $churnedOutRates[$key][$levelKey] = number_format(($churnedOutLevel) / $totalCount * 100, 2);
     330            }
     331        }
     332
     333        return $churnedOutRates;
     334    }
     335
    266336    /** @param array<MembershipChange> $changes */
    267337    private function calculateActiveMembershipCounts(array $changes, array $levelIds): array
  • fapi-member/trunk/vendor/composer/installed.php

    r3161406 r3165470  
    44        'pretty_version' => 'dev-master',
    55        'version' => 'dev-master',
    6         'reference' => '4d9b686efbdc8c2972cf36ef708e93d22c64d481',
     6        'reference' => '6dcfee417299f2cbeb6bacde790da9205239561a',
    77        'type' => 'library',
    88        'install_path' => __DIR__ . '/../../',
     
    1414            'pretty_version' => 'dev-master',
    1515            'version' => 'dev-master',
    16             'reference' => '4d9b686efbdc8c2972cf36ef708e93d22c64d481',
     16            'reference' => '6dcfee417299f2cbeb6bacde790da9205239561a',
    1717            'type' => 'library',
    1818            'install_path' => __DIR__ . '/../../',
Note: See TracChangeset for help on using the changeset viewer.