Plugin Directory

Changeset 3256843


Ignore:
Timestamp:
03/17/2025 03:25:44 AM (13 months ago)
Author:
arraytics
Message:

release 1.0.30

Location:
timetics
Files:
232 added
13 edited

Legend:

Unmodified
Added
Removed
  • timetics/trunk/assets/js/dashboard.js

    r3186662 r3256843  
    117117/******/        __webpack_require__.u = (chunkId) => {
    118118/******/            // return url for filenames based on template
    119 /******/            return "chunk/" + {"vendors-node_modules_reduxjs_toolkit_dist_redux-toolkit_esm_js-node_modules_dayjs_dayjs_min_j-ca2e24":"7031216f899ff694d01a","assets_src_admin_index_js":"9debdb1f92e51928058f","vendors-node_modules_chart_js_auto_auto_js-node_modules_react-chartjs-2_dist_index_js":"283c7958d2ca191df6a7","assets_src_admin_pages_overview_index_js":"1e43603462f2d1467f31","assets_src_admin_pages_staff_index_js":"03b0e4d7106eb153aaf2","assets_src_admin_libs_staffLib_js":"01fad2ec7dc67eb56e84","assets_src_admin_hooks_useBulkDelete_js-assets_src_admin_services_exportImportApi_js":"00a8e54a5a09f572a7f0","assets_src_admin_hooks_useDebounceSearch_js":"f8193b183a4508eebca5","assets_src_admin_pages_staff_staffList_js":"42ac18fa7511c1562003","assets_src_admin_pages_staff_Create_js":"d5b658df3de6c137b3fa","assets_src_admin_pages_staff_Update_js":"9314603dd26e14bd556b","assets_src_admin_pages_meeting_index_js":"6986a4e1094f04a08935","vendors-node_modules_react-quill_lib_index_js-node_modules_react-quill_dist_quill_snow_css":"6f7a67601bc7774ca348","assets_src_admin_pages_settings_index_js":"ebdbae511295528c8021","assets_src_admin_pages_customers_index_js":"0a6d960d487e8cab55a5","assets_src_admin_pages_customers_CustomerList_js":"e2d7175438a882b21edc","assets_src_admin_pages_bookings_index_js":"7cac369bd95cb5cec561","assets_src_admin_pages_bookings_Create_js":"277562178b33a6c1970a","assets_src_admin_pages_bookings_Edit_js":"0858b12b12f4fb9660a8","vendors-node_modules_dayjs_plugin_isSameOrAfter_js-node_modules_dayjs_plugin_isToday_js-node_-97987c":"914e0865b9e4663e9d7d","assets_src_admin_pages_bookings_bookingLists_js":"9cc19297ce90352de77e","assets_src_admin_pages_meeting_CreateMeeting_js":"7e4f5762a7a530bbb112","assets_src_admin_pages_meeting_MeetingList_js":"bf99ea5fabbe3bfa36af","assets_src_admin_module_onboard_index_js":"d2461a5606c006aa5b73"}[chunkId] + ".chunk.js";
     119/******/            return "chunk/" + {"vendors-node_modules_reduxjs_toolkit_dist_redux-toolkit_esm_js-node_modules_dayjs_dayjs_min_j-ca2e24":"7031216f899ff694d01a","assets_src_admin_index_js":"80feda57d9155a54ebe9","vendors-node_modules_chart_js_auto_auto_js-node_modules_react-chartjs-2_dist_index_js":"283c7958d2ca191df6a7","assets_src_admin_pages_overview_index_js":"6e4c439aa0b83379596d","assets_src_admin_pages_staff_index_js":"03b0e4d7106eb153aaf2","assets_src_admin_libs_staffLib_js":"01fad2ec7dc67eb56e84","assets_src_admin_hooks_useBulkDelete_js-assets_src_admin_services_exportImportApi_js":"00a8e54a5a09f572a7f0","assets_src_admin_hooks_useDebounceSearch_js":"f8193b183a4508eebca5","assets_src_admin_pages_staff_staffList_js":"42ac18fa7511c1562003","assets_src_admin_pages_staff_Create_js":"d5b658df3de6c137b3fa","assets_src_admin_pages_staff_Update_js":"9314603dd26e14bd556b","assets_src_admin_pages_meeting_index_js":"6986a4e1094f04a08935","vendors-node_modules_react-quill_lib_index_js-node_modules_react-quill_dist_quill_snow_css":"6f7a67601bc7774ca348","assets_src_admin_pages_settings_index_js":"ebdbae511295528c8021","assets_src_admin_pages_customers_index_js":"0a6d960d487e8cab55a5","assets_src_admin_pages_customers_CustomerList_js":"e2d7175438a882b21edc","assets_src_admin_pages_bookings_index_js":"7cac369bd95cb5cec561","assets_src_admin_pages_bookings_Create_js":"277562178b33a6c1970a","assets_src_admin_pages_bookings_Edit_js":"0858b12b12f4fb9660a8","vendors-node_modules_dayjs_plugin_isSameOrAfter_js-node_modules_dayjs_plugin_isToday_js-node_-97987c":"914e0865b9e4663e9d7d","assets_src_admin_pages_bookings_bookingLists_js":"9cc19297ce90352de77e","assets_src_admin_pages_meeting_CreateMeeting_js":"7e4f5762a7a530bbb112","assets_src_admin_pages_meeting_MeetingList_js":"bf99ea5fabbe3bfa36af","assets_src_admin_module_onboard_index_js":"d2461a5606c006aa5b73"}[chunkId] + ".chunk.js";
    120120/******/        };
    121121/******/    })();
  • timetics/trunk/assets/js/frontend.js

    r3186662 r3256843  
    434434
    435435"use strict";
    436 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_redux__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var _common_icons_Icons__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../common/icons/Icons */ \"./assets/src/common/icons/Icons.js\");\n/* harmony import */ var _redux_slices_meetingSlice__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../redux/slices/meetingSlice */ \"./assets/src/frontend/redux/slices/meetingSlice.js\");\n/* harmony import */ var _SidebarInfo__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./SidebarInfo */ \"./assets/src/frontend/pages/bookings/SidebarInfo.js\");\n/* harmony import */ var _utils_helper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../utils/helper */ \"./assets/src/frontend/utils/helper.js\");\nfunction _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _iterableToArray(r) { if (\"undefined\" != typeof Symbol && null != r[Symbol.iterator] || null != r[\"@@iterator\"]) return Array.from(r); }\nfunction _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }\nfunction _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _unsupportedIterableToArray(r, a) { if (r) { if (\"string\" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return \"Object\" === t && r.constructor && (t = r.constructor.name), \"Map\" === t || \"Set\" === t ? Array.from(r) : \"Arguments\" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }\nfunction _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }\nfunction _iterableToArrayLimit(r, l) { var t = null == r ? null : \"undefined\" != typeof Symbol && r[Symbol.iterator] || r[\"@@iterator\"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t[\"return\"] && (u = t[\"return\"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }\nfunction _arrayWithHoles(r) { if (Array.isArray(r)) return r; }\n\n\n\n\n\nvar _window$React = window.React,\n  useState = _window$React.useState,\n  useEffect = _window$React.useEffect;\nvar __ = wp.i18n.__;\nvar _window$antd = window.antd,\n  Row = _window$antd.Row,\n  Col = _window$antd.Col,\n  Typography = _window$antd.Typography,\n  Space = _window$antd.Space,\n  Button = _window$antd.Button,\n  Alert = _window$antd.Alert,\n  Tooltip = _window$antd.Tooltip;\nvar Title = Typography.Title,\n  Text = Typography.Text;\nfunction SeatMap() {\n  var _wp;\n  var _useState = useState(false),\n    _useState2 = _slicedToArray(_useState, 2),\n    isApprovedQuantity = _useState2[0],\n    setIsApprovedQuantity = _useState2[1];\n  var _useState3 = useState(\"\"),\n    _useState4 = _slicedToArray(_useState3, 2),\n    validationMessage = _useState4[0],\n    setValidationMessage = _useState4[1];\n  var meetingReducer = (0,react_redux__WEBPACK_IMPORTED_MODULE_0__.useSelector)(function (state) {\n    return state.meetings;\n  });\n  var dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_0__.useDispatch)();\n  var step = meetingReducer.step,\n    meeting = meetingReducer.meeting,\n    currentSlot = meetingReducer.currentSlot,\n    _meetingReducer$selec = meetingReducer.selectedSeats,\n    selectedSeats = _meetingReducer$selec === void 0 ? [] : _meetingReducer$selec,\n    _meetingReducer$selec2 = meetingReducer.selectedSeat,\n    selectedSeat = _meetingReducer$selec2 === void 0 ? [] : _meetingReducer$selec2,\n    origin = meetingReducer.origin;\n  var onSelectHandler = function onSelectHandler(data) {\n    if (Array.isArray(data)) {\n      var filteredData = data.filter(function (dataObj) {\n        return selectedSeats.every(function (selectedSeatsObj) {\n          return selectedSeatsObj.id !== dataObj.id;\n        });\n      });\n      var _selectedSeat = filteredData === null || filteredData === void 0 ? void 0 : filteredData.map(function (chair) {\n        return (chair === null || chair === void 0 ? void 0 : chair.label) || \"\".concat(chair === null || chair === void 0 ? void 0 : chair.ticketType, \" - \").concat(chair === null || chair === void 0 ? void 0 : chair.number);\n      });\n      dispatch((0,_redux_slices_meetingSlice__WEBPACK_IMPORTED_MODULE_2__.setState)({\n        selectedSeats: [].concat(_toConsumableArray(selectedSeats), _toConsumableArray(filteredData)),\n        selectedSeat: [].concat(_toConsumableArray(selectedSeat), _toConsumableArray(_selectedSeat))\n      }));\n    } else {\n      var _selectedSeat2 = (data === null || data === void 0 ? void 0 : data.label) || \"\".concat(data === null || data === void 0 ? void 0 : data.ticketType, \" - \").concat(data === null || data === void 0 ? void 0 : data.number);\n      dispatch((0,_redux_slices_meetingSlice__WEBPACK_IMPORTED_MODULE_2__.setState)({\n        selectedSeats: [].concat(_toConsumableArray(selectedSeats), [data]),\n        selectedSeat: [].concat(_toConsumableArray(selectedSeat), [_selectedSeat2])\n      }));\n    }\n  };\n  var onUnselectHandler = function onUnselectHandler(data) {\n    if (Array.isArray(data)) {\n      var _selectedSeat = data === null || data === void 0 ? void 0 : data.map(function (chair) {\n        return (chair === null || chair === void 0 ? void 0 : chair.label) || \"\".concat(chair === null || chair === void 0 ? void 0 : chair.ticketType, \" - \").concat(chair === null || chair === void 0 ? void 0 : chair.number);\n      });\n      var _selectedSeats = data === null || data === void 0 ? void 0 : data.map(function (chair) {\n        return chair.id;\n      });\n      dispatch((0,_redux_slices_meetingSlice__WEBPACK_IMPORTED_MODULE_2__.setState)({\n        selectedSeats: _toConsumableArray(selectedSeats === null || selectedSeats === void 0 ? void 0 : selectedSeats.filter(function (seat) {\n          return !_selectedSeats.includes(seat.id);\n        })),\n        selectedSeat: _toConsumableArray(selectedSeat === null || selectedSeat === void 0 ? void 0 : selectedSeat.filter(function (seat) {\n          return !_selectedSeat.includes(seat);\n        }))\n      }));\n    } else {\n      var _selectedSeat3 = (data === null || data === void 0 ? void 0 : data.label) || \"\".concat(data === null || data === void 0 ? void 0 : data.ticketType, \" - \").concat(data === null || data === void 0 ? void 0 : data.number);\n      dispatch((0,_redux_slices_meetingSlice__WEBPACK_IMPORTED_MODULE_2__.setState)({\n        selectedSeats: selectedSeats === null || selectedSeats === void 0 ? void 0 : selectedSeats.filter(function (seat) {\n          return (seat === null || seat === void 0 ? void 0 : seat.id) !== (data === null || data === void 0 ? void 0 : data.id);\n        }),\n        selectedSeat: selectedSeat === null || selectedSeat === void 0 ? void 0 : selectedSeat.filter(function (seat) {\n          return seat !== _selectedSeat3;\n        })\n      }));\n    }\n  };\n  useEffect(function () {\n    var message = (0,_utils_helper__WEBPACK_IMPORTED_MODULE_4__.validateSelectedSeats)(selectedSeats, meeting === null || meeting === void 0 ? void 0 : meeting.price);\n    setValidationMessage(message);\n    message ? setIsApprovedQuantity(false) : setIsApprovedQuantity(true);\n  }, [selectedSeat]);\n  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Row, (origin === \"meeting\" || window.innerWidth < 768) && {\n    gutter: [24, 24]\n  }, /*#__PURE__*/React.createElement(Col, {\n    xs: 24,\n    sm: 24,\n    md: 8,\n    lg: 6\n  }, /*#__PURE__*/React.createElement(\"div\", {\n    className: origin === \"meeting\" ? \"tt-form-left-sidebar\" : \"tt-form-category-sidebar\"\n  }, /*#__PURE__*/React.createElement(Title, {\n    className: \"tt-meeting-name\",\n    level: 3\n  }, meeting === null || meeting === void 0 ? void 0 : meeting.name), /*#__PURE__*/React.createElement(Text, {\n    className: \"tt-meeting-description tt-mb-30\",\n    type: \"secondary\"\n  }, meeting === null || meeting === void 0 ? void 0 : meeting.description), /*#__PURE__*/React.createElement(_SidebarInfo__WEBPACK_IMPORTED_MODULE_3__[\"default\"], null))), /*#__PURE__*/React.createElement(Col, {\n    xs: 24,\n    sm: 24,\n    md: 16,\n    lg: 18\n  }, /*#__PURE__*/React.createElement(\"div\", {\n    className: origin === \"meeting\" ? \"tt-booking-body-wrap\" : \"tt-category-booking-wrap\"\n  }, /*#__PURE__*/React.createElement(\"div\", {\n    className: \"\"\n  }, !isApprovedQuantity && /*#__PURE__*/React.createElement(Alert, {\n    message: validationMessage,\n    type: \"warning\"\n  }), (_wp = wp) === null || _wp === void 0 || (_wp = _wp.hooks) === null || _wp === void 0 ? void 0 : _wp.applyFilters(\"seatMap\", meeting === null || meeting === void 0 ? void 0 : meeting.seat_plan, // an array of individual seat data\n  meeting === null || meeting === void 0 ? void 0 : meeting.seat_plan_settings,\n  // object regarding the canvas settings\n  currentSlot,\n  // an array of number id\n  onSelectHandler, onUnselectHandler)), /*#__PURE__*/React.createElement(Row, {\n    align: window.innerWidth > 767 ? \"end\" : \"center\"\n  }, /*#__PURE__*/React.createElement(Space, {\n    className: \"tt-seat-booking-button\"\n  }, /*#__PURE__*/React.createElement(Button, {\n    className: \"backbtn\",\n    size: \"large\",\n    type: \"primary\",\n    htmlType: \"button\",\n    ghost: true,\n    onClick: function onClick() {\n      dispatch((0,_redux_slices_meetingSlice__WEBPACK_IMPORTED_MODULE_2__.setState)({\n        step: step - 1,\n        selectedSeats: [],\n        selectedSeat: [],\n        allRecurringDates: null,\n        bookingTime: null\n      }));\n    }\n  }, /*#__PURE__*/React.createElement(_common_icons_Icons__WEBPACK_IMPORTED_MODULE_1__.ArrowLeftIcon, null), __(\"Go back\", \"timetics\")), /*#__PURE__*/React.createElement(Tooltip\n  // placement=\"topLeft\"\n  , {\n    className: \"toplevel_page_timetics\",\n    overlayClassName: \"tt-tooltip-card\",\n    title: !isApprovedQuantity ? validationMessage : null\n  }, /*#__PURE__*/React.createElement(\"div\", {\n    className: \"toplevel_page_timetics\"\n  }, /*#__PURE__*/React.createElement(Button, {\n    className: \"submit-btn\",\n    size: \"large\",\n    type: \"primary\",\n    htmlType: \"button\",\n    disabled: (selectedSeats === null || selectedSeats === void 0 ? void 0 : selectedSeats.length) === 0 || !isApprovedQuantity,\n    onClick: function onClick(e) {\n      e.preventDefault();\n      if ((selectedSeats === null || selectedSeats === void 0 ? void 0 : selectedSeats.length) === 0) return;\n      dispatch((0,_redux_slices_meetingSlice__WEBPACK_IMPORTED_MODULE_2__.setState)({\n        step: step + 1\n        // bookingSeat:\n      }));\n    }\n  }, __(\"Next\", \"timetics-pro\"), /*#__PURE__*/React.createElement(_common_icons_Icons__WEBPACK_IMPORTED_MODULE_1__.ArrowRightIcon2, null))))))))));\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (SeatMap);\n\n//# sourceURL=webpack://timetics/./assets/src/frontend/pages/bookings/SeatMap.js?");
     436eval("__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_redux__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react-redux */ \"./node_modules/react-redux/es/index.js\");\n/* harmony import */ var _common_icons_Icons__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../common/icons/Icons */ \"./assets/src/common/icons/Icons.js\");\n/* harmony import */ var _redux_slices_meetingSlice__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../redux/slices/meetingSlice */ \"./assets/src/frontend/redux/slices/meetingSlice.js\");\n/* harmony import */ var _SidebarInfo__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./SidebarInfo */ \"./assets/src/frontend/pages/bookings/SidebarInfo.js\");\n/* harmony import */ var _utils_helper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../utils/helper */ \"./assets/src/frontend/utils/helper.js\");\nfunction _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _iterableToArray(r) { if (\"undefined\" != typeof Symbol && null != r[Symbol.iterator] || null != r[\"@@iterator\"]) return Array.from(r); }\nfunction _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }\nfunction _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _unsupportedIterableToArray(r, a) { if (r) { if (\"string\" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return \"Object\" === t && r.constructor && (t = r.constructor.name), \"Map\" === t || \"Set\" === t ? Array.from(r) : \"Arguments\" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }\nfunction _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }\nfunction _iterableToArrayLimit(r, l) { var t = null == r ? null : \"undefined\" != typeof Symbol && r[Symbol.iterator] || r[\"@@iterator\"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t[\"return\"] && (u = t[\"return\"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }\nfunction _arrayWithHoles(r) { if (Array.isArray(r)) return r; }\n\n\n\n\n\nvar _window$React = window.React,\n  useState = _window$React.useState,\n  useEffect = _window$React.useEffect;\nvar __ = wp.i18n.__;\nvar _window$antd = window.antd,\n  Row = _window$antd.Row,\n  Col = _window$antd.Col,\n  Typography = _window$antd.Typography,\n  Space = _window$antd.Space,\n  Button = _window$antd.Button,\n  Alert = _window$antd.Alert,\n  Tooltip = _window$antd.Tooltip;\nvar Title = Typography.Title,\n  Text = Typography.Text;\nfunction SeatMap() {\n  var _wp;\n  var _useState = useState(false),\n    _useState2 = _slicedToArray(_useState, 2),\n    isApprovedQuantity = _useState2[0],\n    setIsApprovedQuantity = _useState2[1];\n  var _useState3 = useState(\"\"),\n    _useState4 = _slicedToArray(_useState3, 2),\n    validationMessage = _useState4[0],\n    setValidationMessage = _useState4[1];\n  var meetingReducer = (0,react_redux__WEBPACK_IMPORTED_MODULE_0__.useSelector)(function (state) {\n    return state.meetings;\n  });\n  var dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_0__.useDispatch)();\n  var step = meetingReducer.step,\n    meeting = meetingReducer.meeting,\n    currentSlot = meetingReducer.currentSlot,\n    _meetingReducer$selec = meetingReducer.selectedSeats,\n    selectedSeats = _meetingReducer$selec === void 0 ? [] : _meetingReducer$selec,\n    _meetingReducer$selec2 = meetingReducer.selectedSeat,\n    selectedSeat = _meetingReducer$selec2 === void 0 ? [] : _meetingReducer$selec2,\n    origin = meetingReducer.origin;\n  var onSelectHandler = function onSelectHandler(data) {\n    if (Array.isArray(data)) {\n      var filteredData = data.filter(function (dataObj) {\n        return selectedSeats.every(function (selectedSeatsObj) {\n          return selectedSeatsObj.id !== dataObj.id;\n        });\n      });\n      var _selectedSeat = filteredData === null || filteredData === void 0 ? void 0 : filteredData.map(function (chair) {\n        return (chair === null || chair === void 0 ? void 0 : chair.label) || \"\".concat(chair === null || chair === void 0 ? void 0 : chair.ticketType, \" - \").concat(chair === null || chair === void 0 ? void 0 : chair.number);\n      });\n      dispatch((0,_redux_slices_meetingSlice__WEBPACK_IMPORTED_MODULE_2__.setState)({\n        selectedSeats: [].concat(_toConsumableArray(selectedSeats), _toConsumableArray(filteredData)),\n        selectedSeat: [].concat(_toConsumableArray(selectedSeat), _toConsumableArray(_selectedSeat))\n      }));\n    } else {\n      var _selectedSeat2 = (data === null || data === void 0 ? void 0 : data.label) || \"\".concat(data === null || data === void 0 ? void 0 : data.ticketType, \" - \").concat(data === null || data === void 0 ? void 0 : data.number);\n      dispatch((0,_redux_slices_meetingSlice__WEBPACK_IMPORTED_MODULE_2__.setState)({\n        selectedSeats: [].concat(_toConsumableArray(selectedSeats), [data]),\n        selectedSeat: [].concat(_toConsumableArray(selectedSeat), [_selectedSeat2])\n      }));\n    }\n  };\n  var onUnselectHandler = function onUnselectHandler(data) {\n    if (Array.isArray(data)) {\n      var _selectedSeat = data === null || data === void 0 ? void 0 : data.map(function (chair) {\n        return (chair === null || chair === void 0 ? void 0 : chair.label) || \"\".concat(chair === null || chair === void 0 ? void 0 : chair.ticketType, \" - \").concat(chair === null || chair === void 0 ? void 0 : chair.number);\n      });\n      var _selectedSeats = data === null || data === void 0 ? void 0 : data.map(function (chair) {\n        return chair.id;\n      });\n      dispatch((0,_redux_slices_meetingSlice__WEBPACK_IMPORTED_MODULE_2__.setState)({\n        selectedSeats: _toConsumableArray(selectedSeats === null || selectedSeats === void 0 ? void 0 : selectedSeats.filter(function (seat) {\n          return !_selectedSeats.includes(seat.id);\n        })),\n        selectedSeat: _toConsumableArray(selectedSeat === null || selectedSeat === void 0 ? void 0 : selectedSeat.filter(function (seat) {\n          return !_selectedSeat.includes(seat);\n        }))\n      }));\n    } else {\n      var _selectedSeat3 = (data === null || data === void 0 ? void 0 : data.label) || \"\".concat(data === null || data === void 0 ? void 0 : data.ticketType, \" - \").concat(data === null || data === void 0 ? void 0 : data.number);\n      dispatch((0,_redux_slices_meetingSlice__WEBPACK_IMPORTED_MODULE_2__.setState)({\n        selectedSeats: selectedSeats === null || selectedSeats === void 0 ? void 0 : selectedSeats.filter(function (seat) {\n          return (seat === null || seat === void 0 ? void 0 : seat.id) !== (data === null || data === void 0 ? void 0 : data.id);\n        }),\n        selectedSeat: selectedSeat === null || selectedSeat === void 0 ? void 0 : selectedSeat.filter(function (seat) {\n          return seat !== _selectedSeat3;\n        })\n      }));\n    }\n  };\n  useEffect(function () {\n    var message = (0,_utils_helper__WEBPACK_IMPORTED_MODULE_4__.validateSelectedSeats)(selectedSeats, meeting === null || meeting === void 0 ? void 0 : meeting.price);\n    setValidationMessage(message);\n    message ? setIsApprovedQuantity(false) : setIsApprovedQuantity(true);\n  }, [selectedSeat]);\n  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Row, (origin === \"meeting\" || window.innerWidth < 768) && {\n    gutter: [24, 24]\n  }, /*#__PURE__*/React.createElement(Col, {\n    xs: 24,\n    sm: 24,\n    md: 8,\n    lg: 6\n  }, /*#__PURE__*/React.createElement(\"div\", {\n    className: origin === \"meeting\" ? \"tt-form-left-sidebar\" : \"tt-form-category-sidebar\"\n  }, /*#__PURE__*/React.createElement(Title, {\n    className: \"tt-meeting-name\",\n    level: 3\n  }, meeting === null || meeting === void 0 ? void 0 : meeting.name), /*#__PURE__*/React.createElement(Text, {\n    className: \"tt-meeting-description tt-mb-30\",\n    type: \"secondary\"\n  }, meeting === null || meeting === void 0 ? void 0 : meeting.description), /*#__PURE__*/React.createElement(_SidebarInfo__WEBPACK_IMPORTED_MODULE_3__[\"default\"], null))), /*#__PURE__*/React.createElement(Col, {\n    xs: 24,\n    sm: 24,\n    md: 16,\n    lg: 18\n  }, /*#__PURE__*/React.createElement(\"div\", {\n    className: origin === \"meeting\" ? \"tt-booking-body-wrap\" : \"tt-category-booking-wrap\"\n  }, /*#__PURE__*/React.createElement(\"div\", {\n    className: \"\"\n  }, !isApprovedQuantity && /*#__PURE__*/React.createElement(Alert, {\n    message: validationMessage,\n    type: \"warning\"\n  }), (_wp = wp) === null || _wp === void 0 || (_wp = _wp.hooks) === null || _wp === void 0 ? void 0 : _wp.applyFilters(\"seatMap\", {\n    data: meeting === null || meeting === void 0 ? void 0 : meeting.seat_plan,\n    settings: meeting === null || meeting === void 0 ? void 0 : meeting.seat_plan_settings,\n    currentSlot: currentSlot,\n    onSelectHandler: onSelectHandler,\n    onUnselectHandler: onUnselectHandler\n  })), /*#__PURE__*/React.createElement(Row, {\n    align: window.innerWidth > 767 ? \"end\" : \"center\"\n  }, /*#__PURE__*/React.createElement(Space, {\n    className: \"tt-seat-booking-button\"\n  }, /*#__PURE__*/React.createElement(Button, {\n    className: \"backbtn\",\n    size: \"large\",\n    type: \"primary\",\n    htmlType: \"button\",\n    ghost: true,\n    onClick: function onClick() {\n      dispatch((0,_redux_slices_meetingSlice__WEBPACK_IMPORTED_MODULE_2__.setState)({\n        step: step - 1,\n        selectedSeats: [],\n        selectedSeat: [],\n        allRecurringDates: null,\n        bookingTime: null\n      }));\n    }\n  }, /*#__PURE__*/React.createElement(_common_icons_Icons__WEBPACK_IMPORTED_MODULE_1__.ArrowLeftIcon, null), __(\"Go back\", \"timetics\")), /*#__PURE__*/React.createElement(Tooltip\n  // placement=\"topLeft\"\n  , {\n    className: \"toplevel_page_timetics\",\n    overlayClassName: \"tt-tooltip-card\",\n    title: !isApprovedQuantity ? validationMessage : null\n  }, /*#__PURE__*/React.createElement(\"div\", {\n    className: \"toplevel_page_timetics\"\n  }, /*#__PURE__*/React.createElement(Button, {\n    className: \"submit-btn\",\n    size: \"large\",\n    type: \"primary\",\n    htmlType: \"button\",\n    disabled: (selectedSeats === null || selectedSeats === void 0 ? void 0 : selectedSeats.length) === 0 || !isApprovedQuantity,\n    onClick: function onClick(e) {\n      e.preventDefault();\n      if ((selectedSeats === null || selectedSeats === void 0 ? void 0 : selectedSeats.length) === 0) return;\n      dispatch((0,_redux_slices_meetingSlice__WEBPACK_IMPORTED_MODULE_2__.setState)({\n        step: step + 1\n        // bookingSeat:\n      }));\n    }\n  }, __(\"Next\", \"timetics-pro\"), /*#__PURE__*/React.createElement(_common_icons_Icons__WEBPACK_IMPORTED_MODULE_1__.ArrowRightIcon2, null))))))))));\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (SeatMap);\n\n//# sourceURL=webpack://timetics/./assets/src/frontend/pages/bookings/SeatMap.js?");
    437437
    438438/***/ }),
  • timetics/trunk/bootstrap.php

    r3206505 r3256843  
    212212         */
    213213        require_once TIMETICS_PLUGIN_DIR . 'utils/global-helper.php';
     214        require_once TIMETICS_PLUGIN_DIR . 'core/staffs/calendars/CalendarSyncFacade.php';
     215        require_once TIMETICS_PLUGIN_DIR . 'core/staffs/calendars/CalendarSyncFactory.php';
     216        require_once TIMETICS_PLUGIN_DIR . 'core/staffs/calendars/CalendarSyncInterface.php';
     217        require_once TIMETICS_PLUGIN_DIR . 'core/staffs/calendars/GoogleCalendarSync.php';
    214218    }
    215219
     
    406410        }
    407411
    408  
     412
    409413        /**
    410414         * Show banner (codename: jhanda)
    411415         */
    412416        $filter_string = 'timetics,timetics-free-only';
    413        
     417
    414418        if( $this->has_pro ) {
    415            
     419
    416420            $filter_string .= ',timetics-pro';
    417421            $filter_string = str_replace(',timetics-free-only', '', $filter_string);
    418422
    419423        }
    420        
     424
    421425
    422426        \Wpmet\Libs\Banner::instance('timetics')
     
    425429            ->set_api_url('https://demo.themewinter.com/public/jhanda')
    426430            ->set_plugin_screens('timetics')
    427             ->set_plugin_screens('toplevel_page_timetics') 
     431            ->set_plugin_screens('toplevel_page_timetics')
    428432            ->call();
    429433        // show get-help and upgrade-to-premium menu.
  • timetics/trunk/core/appointments/api-appointment.php

    r3101489 r3256843  
    9595                'methods'             => \WP_REST_Server::EDITABLE,
    9696                'callback'            => [$this, 'update_item'],
    97                 'permission_callback' => function () {
    98                     return current_user_can( 'read_meeting' );
    99                 },
     97                'permission_callback' => [ $this, 'update_item_permissions_check' ],
    10098            ],
    10199            [
    102100                'methods'             => \WP_REST_Server::DELETABLE,
    103101                'callback'            => [$this, 'delete_item'],
    104                 'permission_callback' => function () {
    105                     return current_user_can( 'read_meeting' );
    106                 },
     102                'permission_callback' => [$this, 'delete_item_permissions_check' ],
    107103            ],
    108104        ] );
     
    374370     */
    375371    public function update_item( $request ) {
    376        
     372
    377373        $appointment_id = (int) $request['appointment_id'];
    378374        $appoint        = new Appointment( $appointment_id );
     
    441437
    442438    /**
     439     * Update permission check
     440     *
     441     * @param   WP_Rest_Request  $request
     442     *
     443     * @return  bool
     444     */
     445    public function update_item_permissions_check( $request ) {
     446        $appoinment_id = (int) $request['appointment_id'];
     447        $appointment   = new Appointment( $appoinment_id );
     448
     449        $staff_ids       = $appointment->get_staff_ids();
     450        $author          = $appointment->get_author();
     451        $current_user_id = get_current_user_id();
     452
     453        if (
     454            current_user_can( 'manage_options' )
     455            || current_user_can( 'read_meeting' )
     456            ||  in_array( $current_user_id, $staff_ids )
     457            || $author == $current_user_id
     458        ) {
     459            return true;
     460        }
     461
     462        return false;
     463    }
     464
     465    /**
    443466     * Get single appointment
    444467     *
     
    513536
    514537        return rest_ensure_response( $response );
     538    }
     539
     540    /**
     541     * Delete item permission check
     542     *
     543     * @param   WP_Rest_Request  $request
     544     *
     545     * @return  bool
     546     */
     547    public function delete_item_permissions_check( $request ) {
     548        $appoinment_id = (int) $request['appointment_id'];
     549        $appointment   = new Appointment( $appoinment_id );
     550
     551        $staff_ids       = $appointment->get_staff_ids();
     552        $author          = $appointment->get_author();
     553        $current_user_id = get_current_user_id();
     554
     555        if (
     556            current_user_can( 'manage_options' )
     557            || $author == $current_user_id
     558        ) {
     559            return true;
     560        }
     561
     562        return false;
    515563    }
    516564
     
    661709
    662710        if ( $id ) {
    663             $current_user_id = get_current_user_id();
    664711            $dulicate = $appoint->get_duplicate_nuber();
    665 
    666             if ( $appoint->get_author() != $current_user_id ) {
    667                 $data = [
    668                     'success' => 0,
    669                     'message' => __( 'You are not allowed to update this meeting.', 'timetics' ),
    670                 ];
    671 
    672                 return new WP_HTTP_Response( $data, 403 );
    673             }
    674 
    675712            if ( $dulicate && strpos( $name, '-Duplicate' ) == 0 ) {
    676713                $appoint->update([
  • timetics/trunk/core/appointments/appointment.php

    r3083828 r3256843  
    211211     */
    212212    public function get_staff_ids() {
    213         return $this->get_prop( 'staff' );
     213        $ids = $this->get_prop( 'staff' );
     214
     215        return is_array( $ids ) ? array_values( $ids ) : [];
    214216    }
    215217
     
    887889        return $datetime;
    888890    }
     891
     892    /**
     893     * Get appointmentt ids by author id
     894     *
     895     * @param   integer  $author_id  Appointment author id
     896     *
     897     * @return  array    Appointment ids
     898     */
     899    public static function get_appointment_ids_by_author( $author_id ) {
     900        $query = new WP_Query([
     901            'post_type'      => 'timetics-appointment',
     902            'post_status'    => 'any',
     903            'author'         => $author_id,
     904            'posts_per_page' => -1,
     905            'fields'         => 'ids'
     906        ]);
     907
     908        return $query->posts;
     909    }
    889910}
  • timetics/trunk/core/bookings/api-booking.php

    r3246999 r3256843  
    193193        }
    194194
    195         $appoint = Booking::all( $args );
    196 
     195        $bookings = Booking::all( $args );
    197196        $items = [];
    198         foreach ( $appoint['items'] as $item ) {
     197
     198        if ( ! current_user_can( 'manage_options' ) ) {
     199            $user_id         = get_current_user_id();
     200            $appointment_ids = Appointment::get_appointment_ids_by_author( $user_id );
     201            $bookings        = Booking::get_booking_ids_by_appointment( $appointment_ids, $per_page );
     202        }
     203
     204        foreach ( $bookings['items'] as $item ) {
    199205            $items[] = $this->prepare_item( $item->ID );
    200206        }
     
    209215            'status_code' => 200,
    210216            'data'        => [
    211                 'total' => $appoint['total'],
     217                'total' => $bookings['total'],
    212218                'items' => $items,
    213219            ],
     
    11741180        }
    11751181
    1176         // Check if the price is matched
    1177 
    1178         if ($total_price != $order_total) {
    1179             return $this->create_error_response(__('Pricing is not matched', 'timetics'), 403);
    1180         }
     1182        // // Check if the price is matched
     1183
     1184        // if ($total_price != $order_total) {
     1185        //     return $this->create_error_response(__('Pricing is not matched', 'timetics'), 403);
     1186        // }
    11811187
    11821188        // Check if the staff is matched
  • timetics/trunk/core/bookings/booking.php

    r3083828 r3256843  
    124124    public function get_customer_id() {
    125125        return $this->get_prop( 'customer' );
    126     }   
    127    
     126    }
     127
    128128    /**
    129129     * Get attendee id
     
    134134        $attendees = $this->get_prop( 'attendees' );
    135135        return $attendees ? $attendees : [];
    136     }   
    137    
     136    }
     137
    138138    /**
    139139     * Get custom url
     
    162162    public function get_speaker_id() {
    163163        return $this->get_prop( 'speaker' );
    164     }   
    165    
     164    }
     165
    166166    /**
    167167     * Get booking type
     
    180180    public function get_event_id() {
    181181        return $this->get_prop( 'event' );
    182     }   
     182    }
    183183
    184184    /**
     
    243243    public function get_location_type() {
    244244        return $this->get_prop( 'location_type' );
    245     }   
    246    
     245    }
     246
    247247    /**
    248248     * Get booking time
     
    738738            // @codingStandardsIgnoreEnd
    739739        }
    740        
     740
    741741        $post = new WP_Query( $args );
    742742
     
    964964        do_action( 'timetics_booking_notification', $this, $action );
    965965    }
     966
     967    /**
     968     * Get booking ids by appointment id
     969     *
     970     * @param   array  Collection of appointment ids
     971     *
     972     * @return  array Collection of booking ids
     973     */
     974    public static function get_booking_ids_by_appointment( $appointment_ids, $per_page = -1 ) {
     975        if ( empty( $appointment_ids ) ) {
     976            return [];
     977        }
     978
     979        $query = new WP_Query([
     980            'post_type'      => 'timetics-booking',
     981            'post_status'    => 'any',
     982            'posts_per_page' => $per_page,
     983            'meta_query'     => [
     984                [
     985                    'key'     => '_tt_booking_appointment',
     986                    'value'   => $appointment_ids,
     987                    'compare' => 'IN',
     988                ],
     989            ],
     990        ]);
     991
     992        return [
     993            'total' => $query->found_posts,
     994            'items' => $query->posts,
     995        ];
     996    }
     997
    966998}
  • timetics/trunk/core/customers/customer.php

    r3169771 r3256843  
    166166        return $quantities;
    167167
    168     }   
    169    
     168    }
     169
    170170    /**
    171171     * Get Attendees
     
    281281     */
    282282    public function save() {
    283         // Get the currently authenticated user
    284         $current_user = wp_get_current_user();
    285 
    286         // Ensure the user is logged in
    287         if ( ! $current_user->ID ) {
    288             $this->error = new \WP_Error( 'not_logged_in', 'You need to be logged in to update your profile.' );
    289             return  $this->error;
    290         }
    291 
    292         // Ensure the user can only update their own profile
    293         if ( $this->id && $this->id !== $current_user->ID ) {
    294             $this->error = new \WP_Error('unauthorized', 'You are not authorized to update this profile.' );
    295             return $this->error;
    296         }
    297 
    298283        $args = [
    299284            'first_name' => $this->data['first_name'],
  • timetics/trunk/core/integrations/google/service/calendar.php

    r3083828 r3256843  
    1313    const TIMETICS_TIMEZONE_URI   = 'https://www.googleapis.com/calendar/v3/users/me/settings/timezone';
    1414    const TIMETICS_CALENDAR_EVENT = 'https://www.googleapis.com/calendar/v3/calendars/primary/events/';
     15
     16
     17    /**
     18     * Get events from the calendar for the last 3 months.
     19     *
     20     * @param int $user_id Team member ID.
     21     *
     22     * @return array List of calendar events.
     23     */
     24    public function get_events($user_id) {
     25        $access_token = timetics_get_google_access_token($user_id);
     26
     27        if ( ! $access_token ) {
     28            return ['error' => 'Access token not found or expired.'];
     29        }
     30
     31        // Define the time range for the last 3 months
     32        $three_months_ago = date('c', strtotime('-3 months'));
     33        $now = date('c'); // Current date-time in RFC3339 format
     34
     35        // API URL with time range filter
     36        $api_url = add_query_arg([
     37            'timeMin' => $three_months_ago,
     38            'timeMax' => $now,
     39            'orderBy' => 'startTime',
     40            'singleEvents' => 'true',
     41        ], self::TIMETICS_CALENDAR_EVENT);
     42
     43        // Set headers
     44        $args = [
     45            'headers' => [
     46                'Authorization' => 'Bearer ' . $access_token,
     47                'Content-Type'  => 'application/json',
     48            ],
     49        ];
     50
     51        // Fetch data from Google Calendar API
     52        $response = wp_remote_get(self::TIMETICS_CALENDAR_EVENT, $args);
     53
     54        if ( is_wp_error( $response ) ) {
     55            return ['error' => $response->get_error_message()];
     56        }
     57
     58        $body   = wp_remote_retrieve_body( $response );
     59        $events = json_decode($body, true);
     60
     61        if ( empty( $events['items'] ) ) {
     62            return ['message' => 'No events found for the last 3 months.'];
     63        }
     64
     65        // Filter required fields
     66        $filtered_events = [];
     67        foreach ( $events['items'] as $event ) {
     68            if ( empty( $event['start'] ) ) {
     69                continue;
     70            }
     71            // error_log(print_r($event['start'], true));
     72            $start = ! empty($event['start']['dateTime']) ? $event['start']['dateTime'] : $event['start']['date'];
     73            $end = ! empty($event['end']['dateTime']) ? $event['end']['dateTime'] : $event['end']['date'];
     74
     75
     76            $filtered_events[] = [
     77                'start_date' => date('Y-m-d', strtotime($start)),
     78                'start_time' => date('H:i:s', strtotime($start)),
     79                'end_date'   => date('Y-m-d', strtotime($end)),
     80                'end_time'   => date('H:i:s', strtotime($end)),
     81                'summary'    => $event['summary'] ?? '',
     82                'description'=> $event['description'] ?? '',
     83            ];
     84        }
     85
     86        return $filtered_events;
     87    }
     88
    1589
    1690    /**
  • timetics/trunk/core/integrations/woocommerce/hooks.php

    r3101489 r3256843  
    318318        $meeting_id = $booking->get_appointment();
    319319        if( !empty($data['seats']) && is_array( $data['seats'])) {
    320             $quantity   = count( $data['seats'] ); 
     320            $quantity   = count( $data['seats'] );
    321321        }else {
    322             $quantity   = 1; 
     322            $quantity   = 1;
    323323        }
    324324        $price      = $booking->get_total();
     
    338338        $meeting    = new Appointment( $meeting_id );
    339339        $product_id = $meeting->get_wc_product_id();
    340        
     340
    341341
    342342        if ( ! $product_id ) {
     
    371371
    372372        return get_woocommerce_currency();
    373     }   
     373    }
    374374
    375375    /**
     
    391391        if ( (is_checkout() || is_cart()) && $session ) {
    392392            $timetics_data = $session->get('timetics_data');
    393             if( isset($timetics_data) ) { 
     393            if( isset($timetics_data) ) {
    394394            ?>
    395395            <style type="text/css">
  • timetics/trunk/readme.txt

    r3246999 r3256843  
    44Requires at least: 5.2
    55Tested up to: 6.7
    6 Stable tag: 1.0.29
     6Stable tag: 1.0.30
    77Requires PHP: 7.3
    88License: GPLv2 or later
     
    270270
    271271== Changelog ==
     272
     273= 1.0.30 ( March 13, 2025 ) =
     274Fix : Shortcode copy clip board couldn't work
     275Fix : Set booked seat color and other's booked seat different color
     276Fix : Dashboard filter couldn't work
     277Fix : Couldn't create customer when booking from frontend
     278Fix : Team member couldn't update assigned appointment
     279Fix : A staff can view another staff bookings
     280Fix : Admin unable to edit or delete staff meetings
     281
     282= 1.0.29 ( February 26, 2025 ) =
     283Fix: Calculate order total from meeting price.
     284
    272285= 1.0.28 ( December 11, 2024 ) =
    273286Fix: Resolved text domain compatibility issue with the latest WordPress.
     
    277290Fix: Resolved required field issue in booking questions.
    278291Tweak: WordPress 6.7 Compatibility.
    279 
    280 = 1.0.29 ( February 26, 2024 ) =
    281 Fix: Calculate order total from meeting price.
    282292
    283293= 1.0.27 ( November 12, 2024 ) =
  • timetics/trunk/timetics.php

    r3246999 r3256843  
    55 * Plugin URI:        https://arraytics.com/timetics/
    66 * Description:       Schedule, Appointment and Seat Booking plugin.
    7  * Version:           1.0.29
     7 * Version:           1.0.30
    88 * Requires at least: 5.2
    99 * Requires PHP:      7.3
     
    5757     */
    5858    public static function get_version() {
    59         return '1.0.29';
     59        return '1.0.30';
    6060    }
    6161
  • timetics/trunk/utils/global-helper.php

    r3031016 r3256843  
    726726    }
    727727}
     728
     729if ( ! function_exists( 'timetics_connected_platforms' ) ) {
     730
     731    /**
     732     * Get connected platforms
     733     *
     734     * @param   integer  $id
     735     *
     736     * @return  array       Connected platform lists
     737     */
     738    function timetics_connected_platforms( $id ) {
     739        $integrations = timetics_get_staff_integrations( $id );
     740        $integration_names = [];
     741
     742        if ( $integrations ) {
     743            foreach ( $integrations as $integration ) {
     744                if ( $integration['connected'] ) {
     745                    $integration_names[] = $integration['id'];
     746                }
     747            }
     748        }
     749
     750        return $integration_names;
     751    }
     752}
Note: See TracChangeset for help on using the changeset viewer.