diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php
index afd8201..a937999 100644
--- a/app/Http/Controllers/PageController.php
+++ b/app/Http/Controllers/PageController.php
@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
+use DateInterval;
use DateTime;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@@ -47,6 +48,7 @@ class PageController extends Controller
$user = Auth::user();
return view('pages.index', [
+ 'start_date'=> min((new DateTime())->sub(new DateInterval('P1Y')), $user->created_at),
'checkword' => $user->checkword,
'pages' => $pages,
]);
diff --git a/public/js/app.js b/public/js/app.js
index 653a9da..60ba339 100644
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -36044,6 +36044,387 @@ __webpack_require__(/*! ./components/user/First */ "./resources/js/components/us
/***/ }),
+/***/ "./resources/js/components/calendar/CalendarHeatmap.tsx":
+/*!**************************************************************!*\
+ !*** ./resources/js/components/calendar/CalendarHeatmap.tsx ***!
+ \**************************************************************/
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
+/* harmony export */ });
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js");
+/* harmony import */ var _constants_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./constants.js */ "./resources/js/components/calendar/constants.js");
+/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../utils */ "./resources/js/utils.ts");
+function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
+
+function _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."); }
+
+function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
+
+function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
+
+function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
+
+function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
+
+
+
+
+var SQUARE_SIZE = 10;
+var MONTH_LABEL_GUTTER_SIZE = 4;
+var CSS_PSEUDO_NAMESPACE = 'react-calendar-heatmap-';
+
+function CalendarHeatmap(_ref) {
+ var values = _ref.values,
+ startDate = _ref.startDate,
+ endDate = _ref.endDate,
+ gutterSize = _ref.gutterSize,
+ horizontal = _ref.horizontal,
+ showMonthLabels = _ref.showMonthLabels,
+ showWeekdayLabels = _ref.showWeekdayLabels,
+ showOutOfRangeDays = _ref.showOutOfRangeDays,
+ tooltipDataAttrs = _ref.tooltipDataAttrs,
+ onClick = _ref.onClick,
+ onMouseOver = _ref.onMouseOver,
+ onMouseLeave = _ref.onMouseLeave,
+ transformDayElement = _ref.transformDayElement;
+ var cachedValues = {};
+
+ for (var i in values) {
+ var value = values[i];
+ var date = (0,_utils__WEBPACK_IMPORTED_MODULE_2__.convertToDate)(value.date);
+ var index = Math.floor((date.getTime() - getStartDateWithEmptyDays().getTime()) / _constants_js__WEBPACK_IMPORTED_MODULE_1__.MILLISECONDS_IN_ONE_DAY);
+ cachedValues[index] = {
+ date: value.date,
+ event: value.event,
+ className: classForValue(value.id),
+ title: titleForValue(value.id),
+ tooltipDataAttrs: getTooltipDataAttrsForValue(value.id)
+ };
+ }
+
+ function getDateDifferenceInDays() {
+ var timeDiff = getEndDate().getTime() - (0,_utils__WEBPACK_IMPORTED_MODULE_2__.convertToDate)(startDate).getTime();
+ return Math.ceil(timeDiff / _constants_js__WEBPACK_IMPORTED_MODULE_1__.MILLISECONDS_IN_ONE_DAY);
+ }
+
+ function classForValue(value) {
+ return value ? 'color-filled' : 'color-empty';
+ }
+
+ function titleForValue(value) {
+ return value;
+ }
+
+ function getSquareSizeWithGutter() {
+ return SQUARE_SIZE + gutterSize;
+ }
+
+ function getMonthLabelSize() {
+ if (!showMonthLabels) {
+ return 0;
+ }
+
+ if (horizontal) {
+ return SQUARE_SIZE + MONTH_LABEL_GUTTER_SIZE;
+ }
+
+ return 2 * (SQUARE_SIZE + MONTH_LABEL_GUTTER_SIZE);
+ }
+
+ function getWeekdayLabelSize() {
+ if (!showWeekdayLabels) {
+ return 0;
+ }
+
+ if (horizontal) {
+ return 30;
+ }
+
+ return SQUARE_SIZE * 1.5;
+ }
+
+ function getStartDate() {
+ return (0,_utils__WEBPACK_IMPORTED_MODULE_2__.shiftDate)(getEndDate(), -getDateDifferenceInDays() + 1); // +1 because endDate is inclusive
+ }
+
+ function getEndDate() {
+ return (0,_utils__WEBPACK_IMPORTED_MODULE_2__.getBeginningTimeForDate)((0,_utils__WEBPACK_IMPORTED_MODULE_2__.convertToDate)(endDate));
+ }
+
+ function getStartDateWithEmptyDays() {
+ return (0,_utils__WEBPACK_IMPORTED_MODULE_2__.shiftDate)(getStartDate(), -getNumEmptyDaysAtStart());
+ }
+
+ function getNumEmptyDaysAtStart() {
+ return getStartDate().getDay();
+ }
+
+ function getNumEmptyDaysAtEnd() {
+ return _constants_js__WEBPACK_IMPORTED_MODULE_1__.DAYS_IN_WEEK - 1 - getEndDate().getDay();
+ }
+
+ function getWeekCount() {
+ var numDaysRoundedToWeek = getDateDifferenceInDays() + getNumEmptyDaysAtStart() + getNumEmptyDaysAtEnd();
+ return Math.ceil(numDaysRoundedToWeek / _constants_js__WEBPACK_IMPORTED_MODULE_1__.DAYS_IN_WEEK);
+ }
+
+ function getWeekWidth() {
+ return _constants_js__WEBPACK_IMPORTED_MODULE_1__.DAYS_IN_WEEK * getSquareSizeWithGutter();
+ }
+
+ function getWidth() {
+ return getWeekCount() * getSquareSizeWithGutter() - (gutterSize - getWeekdayLabelSize());
+ }
+
+ function getHeight() {
+ return getWeekWidth() + (getMonthLabelSize() - gutterSize) + getWeekdayLabelSize();
+ }
+
+ function getValueForIndex(index) {
+ if (cachedValues[index]) {
+ console.log(index, cachedValues);
+ return cachedValues[index].event;
+ }
+
+ return null;
+ }
+
+ function getClassNameForIndex(index) {
+ if (cachedValues[index]) {
+ return cachedValues[index].className;
+ }
+
+ return classForValue(null);
+ }
+
+ function getTitleForIndex(index) {
+ if (cachedValues[index]) {
+ return cachedValues[index].title;
+ }
+
+ return titleForValue ? titleForValue(null) : null;
+ }
+
+ function getTooltipDataAttrsForIndex(index) {
+ if (cachedValues[index]) {
+ return cachedValues[index].tooltipDataAttrs;
+ }
+
+ return getTooltipDataAttrsForValue({
+ date: null,
+ count: null
+ });
+ }
+
+ function getTooltipDataAttrsForValue(value) {
+ if (typeof tooltipDataAttrs === 'function') {
+ return tooltipDataAttrs(value);
+ }
+
+ return tooltipDataAttrs;
+ }
+
+ function getTransformForWeek(weekIndex) {
+ if (horizontal) {
+ return "translate(".concat(weekIndex * getSquareSizeWithGutter(), ", 0)");
+ }
+
+ return "translate(0, ".concat(weekIndex * getSquareSizeWithGutter(), ")");
+ }
+
+ function getTransformForWeekdayLabels() {
+ if (horizontal) {
+ return "translate(".concat(SQUARE_SIZE, ", ").concat(getMonthLabelSize(), ")");
+ }
+
+ return "";
+ }
+
+ function getTransformForMonthLabels() {
+ if (horizontal) {
+ return "translate(".concat(getWeekdayLabelSize(), ", 0)");
+ }
+
+ return "translate(".concat(getWeekWidth() + MONTH_LABEL_GUTTER_SIZE, ", ").concat(getWeekdayLabelSize(), ")");
+ }
+
+ function getTransformForAllWeeks() {
+ if (horizontal) {
+ return "translate(".concat(getWeekdayLabelSize(), ", ").concat(getMonthLabelSize(), ")");
+ }
+
+ return "translate(0, ".concat(getWeekdayLabelSize(), ")");
+ }
+
+ function getViewBox() {
+ if (horizontal) {
+ return "0 0 ".concat(getWidth(), " ").concat(getHeight());
+ }
+
+ return "0 0 ".concat(getHeight(), " ").concat(getWidth());
+ }
+
+ function getSquareCoordinates(dayIndex) {
+ if (horizontal) {
+ return [0, dayIndex * getSquareSizeWithGutter()];
+ }
+
+ return [dayIndex * getSquareSizeWithGutter(), 0];
+ }
+
+ function getWeekdayLabelCoordinates(dayIndex) {
+ if (horizontal) {
+ return [0, (dayIndex + 1) * SQUARE_SIZE + dayIndex * gutterSize];
+ }
+
+ return [dayIndex * SQUARE_SIZE + dayIndex * gutterSize, SQUARE_SIZE];
+ }
+
+ function getMonthLabelCoordinates(weekIndex) {
+ if (horizontal) {
+ return [weekIndex * getSquareSizeWithGutter(), getMonthLabelSize() - MONTH_LABEL_GUTTER_SIZE];
+ }
+
+ var verticalOffset = -2;
+ return [0, (weekIndex + 1) * getSquareSizeWithGutter() + verticalOffset];
+ }
+
+ function handleClick(value) {
+ if (onClick) {
+ onClick(value);
+ }
+ }
+
+ function handleMouseOver(e, value) {
+ if (onMouseOver) {
+ onMouseOver(e, value);
+ }
+ }
+
+ function handleMouseLeave(e, value) {
+ if (onMouseLeave) {
+ onMouseLeave(e, value);
+ }
+ }
+
+ function renderSquare(dayIndex, index) {
+ var indexOutOfRange = index < getNumEmptyDaysAtStart() || index >= getNumEmptyDaysAtStart() + getDateDifferenceInDays();
+
+ if (indexOutOfRange && !showOutOfRangeDays) {
+ return null;
+ }
+
+ var _getSquareCoordinates = getSquareCoordinates(dayIndex),
+ _getSquareCoordinates2 = _slicedToArray(_getSquareCoordinates, 2),
+ x = _getSquareCoordinates2[0],
+ y = _getSquareCoordinates2[1];
+
+ var value = getValueForIndex(index);
+ var rect = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("rect", Object.assign({
+ key: index,
+ width: SQUARE_SIZE,
+ height: SQUARE_SIZE,
+ x: x,
+ y: y,
+ className: getClassNameForIndex(index),
+ onClick: function onClick() {
+ return handleClick(value);
+ },
+ onMouseOver: function onMouseOver(e) {
+ return handleMouseOver(e, value);
+ },
+ onMouseLeave: function onMouseLeave(e) {
+ return handleMouseLeave(e, value);
+ }
+ }, getTooltipDataAttrsForIndex(index)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("title", null, getTitleForIndex(index)));
+ return transformDayElement ? transformDayElement(rect, value, index) : rect;
+ }
+
+ function renderWeek(weekIndex) {
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
+ key: weekIndex,
+ transform: getTransformForWeek(weekIndex),
+ className: "".concat(CSS_PSEUDO_NAMESPACE, "week")
+ }, (0,_utils__WEBPACK_IMPORTED_MODULE_2__.getRange)(_constants_js__WEBPACK_IMPORTED_MODULE_1__.DAYS_IN_WEEK).map(function (dayIndex) {
+ return renderSquare(dayIndex, weekIndex * _constants_js__WEBPACK_IMPORTED_MODULE_1__.DAYS_IN_WEEK + dayIndex);
+ }));
+ }
+
+ function renderAllWeeks() {
+ return (0,_utils__WEBPACK_IMPORTED_MODULE_2__.getRange)(getWeekCount()).map(function (weekIndex) {
+ return renderWeek(weekIndex);
+ });
+ }
+
+ function renderMonthLabels() {
+ if (!showMonthLabels) {
+ return null;
+ }
+
+ var weekRange = (0,_utils__WEBPACK_IMPORTED_MODULE_2__.getRange)(getWeekCount() - 1); // don't render for last week, because label will be cut off
+
+ return weekRange.map(function (weekIndex) {
+ var endOfWeek = (0,_utils__WEBPACK_IMPORTED_MODULE_2__.shiftDate)(getStartDateWithEmptyDays(), (weekIndex + 1) * _constants_js__WEBPACK_IMPORTED_MODULE_1__.DAYS_IN_WEEK);
+
+ var _getMonthLabelCoordin = getMonthLabelCoordinates(weekIndex),
+ _getMonthLabelCoordin2 = _slicedToArray(_getMonthLabelCoordin, 2),
+ x = _getMonthLabelCoordin2[0],
+ y = _getMonthLabelCoordin2[1];
+
+ return endOfWeek.getDate() >= 1 && endOfWeek.getDate() <= _constants_js__WEBPACK_IMPORTED_MODULE_1__.DAYS_IN_WEEK ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("text", {
+ key: weekIndex,
+ x: x,
+ y: y,
+ className: "".concat(CSS_PSEUDO_NAMESPACE, "month-label")
+ }, _constants_js__WEBPACK_IMPORTED_MODULE_1__.MONTH_LABELS[endOfWeek.getMonth()]) : null;
+ });
+ }
+
+ function renderWeekdayLabels() {
+ if (!showWeekdayLabels) {
+ return null;
+ }
+
+ return _constants_js__WEBPACK_IMPORTED_MODULE_1__.DAY_LABELS.map(function (weekdayLabel, dayIndex) {
+ var _getWeekdayLabelCoord = getWeekdayLabelCoordinates(dayIndex),
+ _getWeekdayLabelCoord2 = _slicedToArray(_getWeekdayLabelCoord, 2),
+ x = _getWeekdayLabelCoord2[0],
+ y = _getWeekdayLabelCoord2[1];
+
+ var cssClasses = "".concat(horizontal ? '' : "".concat(CSS_PSEUDO_NAMESPACE, "small-text"), " ").concat(CSS_PSEUDO_NAMESPACE, "weekday-label"); // eslint-disable-next-line no-bitwise
+
+ return dayIndex & 1 ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("text", {
+ key: "".concat(x).concat(y),
+ x: x,
+ y: y,
+ className: cssClasses
+ }, weekdayLabel) : null;
+ });
+ }
+
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", {
+ className: "react-calendar-heatmap",
+ viewBox: getViewBox()
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
+ transform: getTransformForMonthLabels(),
+ className: "".concat(CSS_PSEUDO_NAMESPACE, "month-labels")
+ }, renderMonthLabels()), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
+ transform: getTransformForAllWeeks(),
+ className: "".concat(CSS_PSEUDO_NAMESPACE, "all-weeks")
+ }, renderAllWeeks()), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
+ transform: getTransformForWeekdayLabels(),
+ className: "".concat(CSS_PSEUDO_NAMESPACE, "weekday-labels")
+ }, renderWeekdayLabels()));
+}
+
+/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (CalendarHeatmap);
+
+/***/ }),
+
/***/ "./resources/js/components/pages/App.tsx":
/*!***********************************************!*\
!*** ./resources/js/components/pages/App.tsx ***!
@@ -36059,15 +36440,16 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _List__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./List */ "./resources/js/components/pages/List.tsx");
/* harmony import */ var _Prompt__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Prompt */ "./resources/js/components/pages/Prompt.tsx");
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react */ "./node_modules/react/index.js");
-/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/Alert/Alert.js");
-/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/AlertTitle/AlertTitle.js");
-/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/Button/Button.js");
-/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/Divider/Divider.js");
+/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/Alert/Alert.js");
+/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/AlertTitle/AlertTitle.js");
+/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/Button/Button.js");
+/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/Divider/Divider.js");
/* harmony import */ var storage_encryption__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! storage-encryption */ "./node_modules/storage-encryption/build/index.js");
/* harmony import */ var storage_encryption__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(storage_encryption__WEBPACK_IMPORTED_MODULE_4__);
-/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! react-router-dom */ "./node_modules/react-router/esm/react-router.js");
-/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! react-router-dom */ "./node_modules/react-router-dom/esm/react-router-dom.js");
+/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! react-router-dom */ "./node_modules/react-router/esm/react-router.js");
+/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! react-router-dom */ "./node_modules/react-router-dom/esm/react-router-dom.js");
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../utils */ "./resources/js/utils.ts");
+/* harmony import */ var _calendar_CalendarHeatmap__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../calendar/CalendarHeatmap */ "./resources/js/components/calendar/CalendarHeatmap.tsx");
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _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."); }
@@ -36101,6 +36483,7 @@ var __rest = undefined && undefined.__rest || function (s, e) {
+
var app = document.getElementById('app');
var word = "shikiryu"; // FIXME should be in db and ≠ between users
@@ -36110,12 +36493,14 @@ var getPageContentUrl,
postUrl,
removeUrl,
checkword,
+ startDate,
csrf = "";
if (app) {
getPageContentUrl = "" + app.getAttribute('data-url');
pages = JSON.parse("" + app.getAttribute('data-list'));
postUrl = "" + app.getAttribute('data-post');
+ startDate = "" + app.getAttribute('data-start');
removeUrl = "" + app.getAttribute('data-remove');
csrf = "" + app.getAttribute('data-csrf');
checkword = "" + app.getAttribute('data-checkword');
@@ -36132,7 +36517,7 @@ function App() {
passphrase = _React$useState4[0],
setPassphrase = _React$useState4[1];
- var history = (0,react_router_dom__WEBPACK_IMPORTED_MODULE_6__.useHistory)();
+ var history = (0,react_router_dom__WEBPACK_IMPORTED_MODULE_7__.useHistory)();
var _React$useState5 = react__WEBPACK_IMPORTED_MODULE_3__.useState(checkPassphrase()),
_React$useState6 = _slicedToArray(_React$useState5, 2),
@@ -36192,16 +36577,16 @@ function App() {
var Error = function Error() {
if (error) {
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_mui_material__WEBPACK_IMPORTED_MODULE_7__["default"], {
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_mui_material__WEBPACK_IMPORTED_MODULE_8__["default"], {
severity: "error"
- }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_mui_material__WEBPACK_IMPORTED_MODULE_8__["default"], null, "Erreur"), "La phrase de passe ne correspond pas.");
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_mui_material__WEBPACK_IMPORTED_MODULE_9__["default"], null, "Erreur"), "La phrase de passe ne correspond pas.");
}
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement("div", null);
};
var LoadButton = function LoadButton() {
- return allLoaded ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(react__WEBPACK_IMPORTED_MODULE_3__.Fragment, null) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_mui_material__WEBPACK_IMPORTED_MODULE_9__["default"], {
+ return allLoaded ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(react__WEBPACK_IMPORTED_MODULE_3__.Fragment, null) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_mui_material__WEBPACK_IMPORTED_MODULE_10__["default"], {
variant: "outlined",
size: "small",
sx: {
@@ -36214,8 +36599,8 @@ function App() {
};
var AuthButton = function AuthButton() {
- var history = (0,react_router_dom__WEBPACK_IMPORTED_MODULE_6__.useHistory)();
- return user ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement("p", null, "Bienvenue !", " ", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_mui_material__WEBPACK_IMPORTED_MODULE_9__["default"], {
+ var history = (0,react_router_dom__WEBPACK_IMPORTED_MODULE_7__.useHistory)();
+ return user ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement("p", null, "Bienvenue !", " ", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_mui_material__WEBPACK_IMPORTED_MODULE_10__["default"], {
variant: "outlined",
size: "small",
sx: {
@@ -36226,7 +36611,7 @@ function App() {
return history.push("/diary/public");
});
}
- }, "Fermer mon carnet \xE0 clef")) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement("p", null, "Votre carnet est ferm\xE9.", " ", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_10__.Link, {
+ }, "Fermer mon carnet \xE0 clef")) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement("p", null, "Votre carnet est ferm\xE9.", " ", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_11__.Link, {
to: "/diary/public/pages"
}, "Voir vos pages"));
};
@@ -36251,10 +36636,10 @@ function App() {
var children = _a.children,
rest = __rest(_a, ["children"]);
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_6__.Route, Object.assign({}, rest, {
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_7__.Route, Object.assign({}, rest, {
render: function render(_ref) {
var location = _ref.location;
- return user ? children : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_6__.Redirect, {
+ return user ? children : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_7__.Redirect, {
to: {
pathname: "/diary/public/pass",
state: {
@@ -36273,10 +36658,40 @@ function App() {
});
}
+ function getCalendarValuesFromPagesList(pages) {
+ return pages.map(function (page) {
+ var _page$date$split = page.date.split(" "),
+ _page$date$split2 = _slicedToArray(_page$date$split, 1),
+ date = _page$date$split2[0];
+
+ var splittedDate = date.split("/").map(function (part) {
+ return parseInt(part, 10);
+ });
+ return {
+ id: page.id,
+ date: new Date(splittedDate[2], splittedDate[1] - 1, splittedDate[0]),
+ event: page.id
+ };
+ });
+ }
+
function ListPage() {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement("div", {
className: "col-md-12"
- }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_List__WEBPACK_IMPORTED_MODULE_1__["default"], {
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_calendar_CalendarHeatmap__WEBPACK_IMPORTED_MODULE_6__["default"], {
+ values: getCalendarValuesFromPagesList(listPages),
+ startDate: startDate,
+ endDate: new Date(),
+ showMonthLabels: true,
+ showWeekdayLabels: true,
+ showOutOfRangeDays: true,
+ horizontal: true,
+ gutterSize: 4,
+ onClick: function onClick(value) {
+ return alert(value);
+ },
+ tooltipDataAttrs: {}
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_List__WEBPACK_IMPORTED_MODULE_1__["default"], {
pages: listPages,
url: getPageContentUrl,
passphrase: passphrase,
@@ -36284,7 +36699,7 @@ function App() {
removeUrl: removeUrl,
loadPages: loadPages,
setAllLoaded: setAllLoaded
- }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_Form__WEBPACK_IMPORTED_MODULE_0__["default"], {
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_Form__WEBPACK_IMPORTED_MODULE_0__["default"], {
setListPages: setListPages,
csrf: csrf,
url: postUrl,
@@ -36292,20 +36707,20 @@ function App() {
}));
}
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement("div", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(AuthButton, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(LoadButton, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(Error, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], {
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement("div", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(AuthButton, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(LoadButton, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(Error, null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], {
sx: {
height: "20px",
mb: "20px",
mt: "10px"
}
- }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_6__.Switch, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_6__.Route, {
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_7__.Switch, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_7__.Route, {
path: "/diary/public/pass"
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(PromptPage, null)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(PrivateRoute, {
path: "/diary/public/pages"
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3__.createElement(ListPage, null))));
}
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((0,react_router_dom__WEBPACK_IMPORTED_MODULE_6__.withRouter)(App));
+/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((0,react_router_dom__WEBPACK_IMPORTED_MODULE_7__.withRouter)(App));
/***/ }),
@@ -36546,6 +36961,10 @@ function PageForm(_ref) {
}));
};
+ function updateContent(value) {
+ setContent(value);
+ }
+
if (isPassphraseSet) {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__.createElement("form", {
action: url,
@@ -37439,7 +37858,12 @@ function MobileMenu(_ref) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "isAllLoadedLocally": () => (/* binding */ isAllLoadedLocally)
+/* harmony export */ "isAllLoadedLocally": () => (/* binding */ isAllLoadedLocally),
+/* harmony export */ "shiftDate": () => (/* binding */ shiftDate),
+/* harmony export */ "getBeginningTimeForDate": () => (/* binding */ getBeginningTimeForDate),
+/* harmony export */ "convertToDate": () => (/* binding */ convertToDate),
+/* harmony export */ "dateNDaysAgo": () => (/* binding */ dateNDaysAgo),
+/* harmony export */ "getRange": () => (/* binding */ getRange)
/* harmony export */ });
var isAllLoadedLocally = function isAllLoadedLocally(pages) {
for (var i in pages) {
@@ -37452,6 +37876,40 @@ var isAllLoadedLocally = function isAllLoadedLocally(pages) {
return true;
};
+/** CALENDAR **/
+// returns a new date shifted a certain number of days (can be negative)
+
+
+var shiftDate = function shiftDate(date, numDays) {
+ var newDate = new Date(date);
+ newDate.setDate(newDate.getDate() + numDays);
+ return newDate;
+};
+
+var getBeginningTimeForDate = function getBeginningTimeForDate(date) {
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
+}; // obj can be a parseable string, a millisecond timestamp, or a Date object
+
+
+var convertToDate = function convertToDate(obj) {
+ return obj instanceof Date ? obj : new Date(obj);
+};
+
+var dateNDaysAgo = function dateNDaysAgo(numDaysAgo) {
+ return shiftDate(new Date(), -numDaysAgo);
+};
+
+var getRange = function getRange(count) {
+ var arr = [];
+
+ for (var idx = 0; idx < count; idx += 1) {
+ arr.push(idx);
+ }
+
+ return arr;
+};
+/** END CALENDAR **/
+
@@ -37491,6 +37949,28 @@ window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
// forceTLS: true
// });
+/***/ }),
+
+/***/ "./resources/js/components/calendar/constants.js":
+/*!*******************************************************!*\
+ !*** ./resources/js/components/calendar/constants.js ***!
+ \*******************************************************/
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ "MILLISECONDS_IN_ONE_DAY": () => (/* binding */ MILLISECONDS_IN_ONE_DAY),
+/* harmony export */ "DAYS_IN_WEEK": () => (/* binding */ DAYS_IN_WEEK),
+/* harmony export */ "MONTH_LABELS": () => (/* binding */ MONTH_LABELS),
+/* harmony export */ "DAY_LABELS": () => (/* binding */ DAY_LABELS)
+/* harmony export */ });
+var MILLISECONDS_IN_ONE_DAY = 24 * 60 * 60 * 1000;
+var DAYS_IN_WEEK = 7;
+var MONTH_LABELS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+var DAY_LABELS = ['', 'Mon', '', 'Wed', '', 'Fri', ''];
+
+
/***/ }),
/***/ "./node_modules/boolbase/index.js":
diff --git a/resources/js/components/calendar/CalendarHeatmap.tsx b/resources/js/components/calendar/CalendarHeatmap.tsx
new file mode 100644
index 0000000..0af56b6
--- /dev/null
+++ b/resources/js/components/calendar/CalendarHeatmap.tsx
@@ -0,0 +1,335 @@
+import React from 'react';
+import { DAYS_IN_WEEK, MILLISECONDS_IN_ONE_DAY, DAY_LABELS, MONTH_LABELS } from './constants.js';
+import {
+ shiftDate,
+ getBeginningTimeForDate,
+ convertToDate,
+ getRange,
+} from "../../utils";
+import {CalendarHeatmapProp} from "./CalendarHeatmapProp";
+
+const SQUARE_SIZE = 10;
+const MONTH_LABEL_GUTTER_SIZE = 4;
+const CSS_PSEUDO_NAMESPACE = 'react-calendar-heatmap-';
+
+function CalendarHeatmap({
+ values, startDate, endDate, gutterSize, horizontal,
+ showMonthLabels, showWeekdayLabels, showOutOfRangeDays, tooltipDataAttrs,
+ onClick, onMouseOver, onMouseLeave, transformDayElement
+ }: CalendarHeatmapProp) {
+
+ const cachedValues = {};
+ for (const i in values) {
+ const value = values[i];
+ const date = convertToDate(value.date);
+ const index = Math.floor((date.getTime() - getStartDateWithEmptyDays().getTime()) / MILLISECONDS_IN_ONE_DAY);
+ cachedValues[index] = {
+ date: value.date,
+ event: value.event,
+ className: classForValue(value.id),
+ title: titleForValue(value.id),
+ tooltipDataAttrs: getTooltipDataAttrsForValue(value.id),
+ };
+ }
+
+ function getDateDifferenceInDays() {
+ const timeDiff = getEndDate().getTime() - convertToDate(startDate).getTime();
+ return Math.ceil(timeDiff / MILLISECONDS_IN_ONE_DAY);
+ }
+
+ function classForValue(value) {
+ return value ? 'color-filled' : 'color-empty';
+ }
+
+ function titleForValue(value) {
+ return value;
+ }
+
+ function getSquareSizeWithGutter() {
+ return SQUARE_SIZE + gutterSize;
+ }
+
+ function getMonthLabelSize() {
+ if (!showMonthLabels) {
+ return 0;
+ }
+ if (horizontal) {
+ return SQUARE_SIZE + MONTH_LABEL_GUTTER_SIZE;
+ }
+ return 2 * (SQUARE_SIZE + MONTH_LABEL_GUTTER_SIZE);
+ }
+
+ function getWeekdayLabelSize() {
+ if (!showWeekdayLabels) {
+ return 0;
+ }
+ if (horizontal) {
+ return 30;
+ }
+ return SQUARE_SIZE * 1.5;
+ }
+
+ function getStartDate() {
+ return shiftDate(getEndDate(), -getDateDifferenceInDays() + 1); // +1 because endDate is inclusive
+ }
+
+ function getEndDate(): Date {
+ return getBeginningTimeForDate(convertToDate(endDate));
+ }
+
+ function getStartDateWithEmptyDays() {
+ return shiftDate(getStartDate(), -getNumEmptyDaysAtStart());
+ }
+
+ function getNumEmptyDaysAtStart() {
+ return getStartDate().getDay();
+ }
+
+ function getNumEmptyDaysAtEnd() {
+ return DAYS_IN_WEEK - 1 - getEndDate().getDay();
+ }
+
+ function getWeekCount() {
+ const numDaysRoundedToWeek =
+ getDateDifferenceInDays() + getNumEmptyDaysAtStart() + getNumEmptyDaysAtEnd();
+ return Math.ceil(numDaysRoundedToWeek / DAYS_IN_WEEK);
+ }
+
+ function getWeekWidth() {
+ return DAYS_IN_WEEK * getSquareSizeWithGutter();
+ }
+
+ function getWidth() {
+ return (
+ getWeekCount() * getSquareSizeWithGutter() -
+ (gutterSize - getWeekdayLabelSize())
+ );
+ }
+
+ function getHeight() {
+ return (
+ getWeekWidth() +
+ (getMonthLabelSize() - gutterSize) +
+ getWeekdayLabelSize()
+ );
+ }
+
+ function getValueForIndex(index) {
+ if (cachedValues[index]) {
+ console.log(index, cachedValues);
+ return cachedValues[index].event;
+ }
+ return null;
+ }
+
+ function getClassNameForIndex(index) {
+ if (cachedValues[index]) {
+ return cachedValues[index].className;
+ }
+ return classForValue(null);
+ }
+
+ function getTitleForIndex(index) {
+ if (cachedValues[index]) {
+ return cachedValues[index].title;
+ }
+ return titleForValue ? titleForValue(null) : null;
+ }
+
+ function getTooltipDataAttrsForIndex(index) {
+ if (cachedValues[index]) {
+ return cachedValues[index].tooltipDataAttrs;
+ }
+ return getTooltipDataAttrsForValue({ date: null, count: null });
+ }
+
+ function getTooltipDataAttrsForValue(value) {
+ if (typeof tooltipDataAttrs === 'function') {
+ return tooltipDataAttrs(value);
+ }
+ return tooltipDataAttrs;
+ }
+
+ function getTransformForWeek(weekIndex) {
+ if (horizontal) {
+ return `translate(${weekIndex * getSquareSizeWithGutter()}, 0)`;
+ }
+ return `translate(0, ${weekIndex * getSquareSizeWithGutter()})`;
+ }
+
+ function getTransformForWeekdayLabels() {
+ if (horizontal) {
+ return `translate(${SQUARE_SIZE}, ${getMonthLabelSize()})`;
+ }
+ return "";
+ }
+
+ function getTransformForMonthLabels() {
+ if (horizontal) {
+ return `translate(${getWeekdayLabelSize()}, 0)`;
+ }
+ return `translate(${getWeekWidth() + MONTH_LABEL_GUTTER_SIZE}, ${getWeekdayLabelSize()})`;
+ }
+
+ function getTransformForAllWeeks() {
+ if (horizontal) {
+ return `translate(${getWeekdayLabelSize()}, ${getMonthLabelSize()})`;
+ }
+ return `translate(0, ${getWeekdayLabelSize()})`;
+ }
+
+ function getViewBox() {
+ if (horizontal) {
+ return `0 0 ${getWidth()} ${getHeight()}`;
+ }
+ return `0 0 ${getHeight()} ${getWidth()}`;
+ }
+
+ function getSquareCoordinates(dayIndex) {
+ if (horizontal) {
+ return [0, dayIndex * getSquareSizeWithGutter()];
+ }
+ return [dayIndex * getSquareSizeWithGutter(), 0];
+ }
+
+ function getWeekdayLabelCoordinates(dayIndex) {
+ if (horizontal) {
+ return [0, (dayIndex + 1) * SQUARE_SIZE + dayIndex * gutterSize];
+ }
+ return [dayIndex * SQUARE_SIZE + dayIndex * gutterSize, SQUARE_SIZE];
+ }
+
+ function getMonthLabelCoordinates(weekIndex) {
+ if (horizontal) {
+ return [
+ weekIndex * getSquareSizeWithGutter(),
+ getMonthLabelSize() - MONTH_LABEL_GUTTER_SIZE,
+ ];
+ }
+ const verticalOffset = -2;
+ return [0, (weekIndex + 1) * getSquareSizeWithGutter() + verticalOffset];
+ }
+
+ function handleClick(value) {
+ if (onClick) {
+ onClick(value);
+ }
+ }
+
+ function handleMouseOver(e, value) {
+ if (onMouseOver) {
+ onMouseOver(e, value);
+ }
+ }
+
+ function handleMouseLeave(e, value) {
+ if (onMouseLeave) {
+ onMouseLeave(e, value);
+ }
+ }
+
+ function renderSquare(dayIndex, index) {
+ const indexOutOfRange =
+ index < getNumEmptyDaysAtStart() ||
+ index >= getNumEmptyDaysAtStart() + getDateDifferenceInDays();
+ if (indexOutOfRange && !showOutOfRangeDays) {
+ return null;
+ }
+ const [x, y] = getSquareCoordinates(dayIndex);
+ const value = getValueForIndex(index);
+ const rect = (
+ handleClick(value)}
+ onMouseOver={(e) => handleMouseOver(e, value)}
+ onMouseLeave={(e) => handleMouseLeave(e, value)}
+ {...getTooltipDataAttrsForIndex(index)}
+ >
+ {getTitleForIndex(index)}
+
+ );
+ return transformDayElement ? transformDayElement(rect, value as string, index) : rect;
+ }
+
+ function renderWeek(weekIndex) {
+ return (
+
+ {getRange(DAYS_IN_WEEK).map((dayIndex) =>
+ renderSquare(dayIndex, weekIndex * DAYS_IN_WEEK + dayIndex),
+ )}
+
+ );
+ }
+
+ function renderAllWeeks() {
+ return getRange(getWeekCount()).map((weekIndex) => renderWeek(weekIndex));
+ }
+
+ function renderMonthLabels() {
+ if (!showMonthLabels) {
+ return null;
+ }
+ const weekRange = getRange(getWeekCount() - 1); // don't render for last week, because label will be cut off
+ return weekRange.map((weekIndex) => {
+ const endOfWeek = shiftDate(getStartDateWithEmptyDays(), (weekIndex + 1) * DAYS_IN_WEEK);
+ const [x, y] = getMonthLabelCoordinates(weekIndex);
+ return endOfWeek.getDate() >= 1 && endOfWeek.getDate() <= DAYS_IN_WEEK ? (
+
+ {MONTH_LABELS[endOfWeek.getMonth()]}
+
+ ) : null;
+ });
+ }
+
+ function renderWeekdayLabels() {
+ if (!showWeekdayLabels) {
+ return null;
+ }
+ return DAY_LABELS.map((weekdayLabel, dayIndex) => {
+ const [x, y] = getWeekdayLabelCoordinates(dayIndex);
+ const cssClasses = `${
+ horizontal ? '' : `${CSS_PSEUDO_NAMESPACE}small-text`
+ } ${CSS_PSEUDO_NAMESPACE}weekday-label`;
+ // eslint-disable-next-line no-bitwise
+ return dayIndex & 1 ? (
+
+ {weekdayLabel}
+
+ ) : null;
+ });
+ }
+
+ return (
+
+ );
+}
+
+export default CalendarHeatmap;
diff --git a/resources/js/components/calendar/CalendarHeatmapProp.ts b/resources/js/components/calendar/CalendarHeatmapProp.ts
new file mode 100644
index 0000000..e308e6a
--- /dev/null
+++ b/resources/js/components/calendar/CalendarHeatmapProp.ts
@@ -0,0 +1,19 @@
+import {CalendarHeatmapValuesProp} from "./CalendarHeatmapValuesProp";
+import {ReactEventHandler} from "react";
+
+export interface CalendarHeatmapProp {
+ values: CalendarHeatmapValuesProp[]; // array of objects with date and arbitrary metadata
+ startDate: Date; // start of date range
+ endDate: Date; // end of date range
+ gutterSize: number; // size of space between squares
+ horizontal: boolean; // whether to orient horizontally or vertically
+ showMonthLabels: boolean; // whether to show month labels
+ showWeekdayLabels: boolean; // whether to show weekday labels
+ showOutOfRangeDays: boolean; // whether to render squares for extra days in week after endDate, and before start date
+ tooltipDataAttrs: object; // data attributes to add to square for setting 3rd party tooltips, e.g. { 'data-toggle': 'tooltip' } for bootstrap tooltips
+ onClick: (v:string) => void; // callback function when a square is clicked
+ onMouseOver?: (e:ReactEventHandler, v:string) => void; // callback function when mouse pointer is over a square
+ onMouseLeave?: (e:ReactEventHandler, v:string) => void; // callback function when mouse pointer is left a square
+ transformDayElement?: (element:JSX.Element, v:string, i:number) => void; // function to further transform the svg element for a single day
+}
+
diff --git a/resources/js/components/calendar/CalendarHeatmapValuesProp.ts b/resources/js/components/calendar/CalendarHeatmapValuesProp.ts
new file mode 100644
index 0000000..deb952e
--- /dev/null
+++ b/resources/js/components/calendar/CalendarHeatmapValuesProp.ts
@@ -0,0 +1,5 @@
+export interface CalendarHeatmapValuesProp {
+ id: string;
+ date: Date;
+ event: string;
+}
diff --git a/resources/js/components/calendar/constants.js b/resources/js/components/calendar/constants.js
new file mode 100644
index 0000000..380b5f7
--- /dev/null
+++ b/resources/js/components/calendar/constants.js
@@ -0,0 +1,22 @@
+const MILLISECONDS_IN_ONE_DAY = 24 * 60 * 60 * 1000;
+
+const DAYS_IN_WEEK = 7;
+
+const MONTH_LABELS = [
+ 'Jan',
+ 'Feb',
+ 'Mar',
+ 'Apr',
+ 'May',
+ 'Jun',
+ 'Jul',
+ 'Aug',
+ 'Sep',
+ 'Oct',
+ 'Nov',
+ 'Dec',
+];
+
+const DAY_LABELS = ['', 'Mon', '', 'Wed', '', 'Fri', ''];
+
+export { MILLISECONDS_IN_ONE_DAY, DAYS_IN_WEEK, MONTH_LABELS, DAY_LABELS };
diff --git a/resources/js/components/pages/App.tsx b/resources/js/components/pages/App.tsx
index 43a52da..dc919b4 100644
--- a/resources/js/components/pages/App.tsx
+++ b/resources/js/components/pages/App.tsx
@@ -14,6 +14,8 @@ import {
} from "react-router-dom";
import {IList} from "../../interfaces/IList";
import {isAllLoadedLocally} from "../../utils";
+import CalendarHeatmap from "../calendar/CalendarHeatmap";
+import {CalendarHeatmapValuesProp} from "../calendar/CalendarHeatmapValuesProp";
const app = document.getElementById('app');
const word = "shikiryu"; // FIXME should be in db and ≠ between users
@@ -24,12 +26,14 @@ let getPageContentUrl,
postUrl,
removeUrl,
checkword,
+ startDate,
csrf = "";
if (app) {
getPageContentUrl = "" + app.getAttribute('data-url');
pages = JSON.parse("" + app.getAttribute('data-list')) as IList[];
postUrl = "" + app.getAttribute('data-post');
+ startDate = "" + app.getAttribute('data-start');
removeUrl = "" + app.getAttribute('data-remove');
csrf = "" + app.getAttribute('data-csrf');
checkword = "" + app.getAttribute('data-checkword');
@@ -157,9 +161,33 @@ function App() {
return ();
}
+ function getCalendarValuesFromPagesList(pages: IList[]): CalendarHeatmapValuesProp[] {
+ return pages.map(page => {
+ const [date, ] = page.date.split(" ");
+ const splittedDate = date.split("/").map(part => { return parseInt(part, 10);});
+ return {
+ id: page.id,
+ date: new Date(splittedDate[2] as number, splittedDate[1] - 1, splittedDate[0] as number),
+ event: page.id
+ };
+ });
+ }
+
function ListPage() {
return (
+
alert(value)}
+ tooltipDataAttrs={{}}
+ />
("");
const onSubmit = async (event: React.FormEvent) => {
event.preventDefault();
encryptStorage = new EncryptStorage(passphrase);
@@ -56,6 +56,9 @@ export default function PageForm({setListPages, csrf, url, passphrase}) {
]);
}
}
+ function updateContent(value: string|undefined): void {
+ setContent(value as string);
+ }
if (isPassphraseSet) {
return (
@@ -73,7 +76,7 @@ export default function PageForm({setListPages, csrf, url, passphrase}) {
/>