🚧 Commence l'ajout de calendrier #8
@@ -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,
 | 
			
		||||
        ]);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										67
									
								
								public/css/app.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										67
									
								
								public/css/app.css
									
									
									
									
										vendored
									
									
								
							@@ -12385,6 +12385,73 @@ select {
 | 
			
		||||
.ease-in {
 | 
			
		||||
  transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
 * react-calendar-heatmap styles
 | 
			
		||||
 *
 | 
			
		||||
 * All of the styles in this file are optional and configurable!
 | 
			
		||||
 * The github and gitlab color scales are provided for reference.
 | 
			
		||||
 */
 | 
			
		||||
@media all and (max-width: 768px) {
 | 
			
		||||
    svg.react-calendar-heatmap {
 | 
			
		||||
        transform: rotate(90deg);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap text {
 | 
			
		||||
    font-size: 10px;
 | 
			
		||||
    fill: #aaa;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .react-calendar-heatmap-small-text {
 | 
			
		||||
    font-size: 5px;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap rect:hover {
 | 
			
		||||
    stroke: #555;
 | 
			
		||||
    stroke-width: 1px;
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
 * Default color scale
 | 
			
		||||
 */
 | 
			
		||||
.react-calendar-heatmap .color-empty {
 | 
			
		||||
    fill: #eeeeee;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-filled {
 | 
			
		||||
    fill: #8cc665;
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
 * Github color scale
 | 
			
		||||
 */
 | 
			
		||||
.react-calendar-heatmap .color-github-0 {
 | 
			
		||||
    fill: #eeeeee;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-github-1 {
 | 
			
		||||
    fill: #d6e685;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-github-2 {
 | 
			
		||||
    fill: #8cc665;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-github-3 {
 | 
			
		||||
    fill: #44a340;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-github-4 {
 | 
			
		||||
    fill: #1e6823;
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
 * Gitlab color scale
 | 
			
		||||
 */
 | 
			
		||||
.react-calendar-heatmap .color-gitlab-0 {
 | 
			
		||||
    fill: #ededed;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-gitlab-1 {
 | 
			
		||||
    fill: #acd5f2;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-gitlab-2 {
 | 
			
		||||
    fill: #7fa8d1;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-gitlab-3 {
 | 
			
		||||
    fill: #49729b;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-gitlab-4 {
 | 
			
		||||
    fill: #254e77;
 | 
			
		||||
}
 | 
			
		||||
.hover\:border-gray-300:hover {
 | 
			
		||||
  --tw-border-opacity: 1;
 | 
			
		||||
  border-color: rgb(209 213 219 / var(--tw-border-opacity));
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										524
									
								
								public/js/app.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										524
									
								
								public/js/app.js
									
									
									
									
										vendored
									
									
								
							@@ -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));
 | 
			
		||||
 | 
			
		||||
/***/ }),
 | 
			
		||||
 | 
			
		||||
@@ -36542,6 +36957,10 @@ function PageForm(_ref) {
 | 
			
		||||
    }));
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  function updateContent(value) {
 | 
			
		||||
    setContent(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (isPassphraseSet) {
 | 
			
		||||
    return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__.createElement("form", {
 | 
			
		||||
      action: url,
 | 
			
		||||
@@ -36559,7 +36978,7 @@ function PageForm(_ref) {
 | 
			
		||||
      size: "small"
 | 
			
		||||
    }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__.createElement(_uiw_react_md_editor__WEBPACK_IMPORTED_MODULE_3__["default"], {
 | 
			
		||||
      value: content,
 | 
			
		||||
      onChange: setContent
 | 
			
		||||
      onChange: updateContent
 | 
			
		||||
    }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__.createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], {
 | 
			
		||||
      variant: "contained",
 | 
			
		||||
      type: "submit"
 | 
			
		||||
@@ -37435,7 +37854,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) {
 | 
			
		||||
@@ -37448,6 +37872,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 **/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -37487,6 +37945,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":
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										79
									
								
								resources/css/app.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										79
									
								
								resources/css/app.css
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,82 @@
 | 
			
		||||
@import 'tailwindcss/base';
 | 
			
		||||
@import 'tailwindcss/components';
 | 
			
		||||
@import 'tailwindcss/utilities';
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * react-calendar-heatmap styles
 | 
			
		||||
 *
 | 
			
		||||
 * All of the styles in this file are optional and configurable!
 | 
			
		||||
 * The github and gitlab color scales are provided for reference.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@media all and (max-width: 768px) {
 | 
			
		||||
    svg.react-calendar-heatmap {
 | 
			
		||||
        transform: rotate(90deg);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.react-calendar-heatmap text {
 | 
			
		||||
    font-size: 10px;
 | 
			
		||||
    fill: #aaa;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.react-calendar-heatmap .react-calendar-heatmap-small-text {
 | 
			
		||||
    font-size: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.react-calendar-heatmap rect:hover {
 | 
			
		||||
    stroke: #555;
 | 
			
		||||
    stroke-width: 1px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Default color scale
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.react-calendar-heatmap .color-empty {
 | 
			
		||||
    fill: #eeeeee;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.react-calendar-heatmap .color-filled {
 | 
			
		||||
    fill: #8cc665;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Github color scale
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.react-calendar-heatmap .color-github-0 {
 | 
			
		||||
    fill: #eeeeee;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-github-1 {
 | 
			
		||||
    fill: #d6e685;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-github-2 {
 | 
			
		||||
    fill: #8cc665;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-github-3 {
 | 
			
		||||
    fill: #44a340;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-github-4 {
 | 
			
		||||
    fill: #1e6823;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Gitlab color scale
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.react-calendar-heatmap .color-gitlab-0 {
 | 
			
		||||
    fill: #ededed;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-gitlab-1 {
 | 
			
		||||
    fill: #acd5f2;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-gitlab-2 {
 | 
			
		||||
    fill: #7fa8d1;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-gitlab-3 {
 | 
			
		||||
    fill: #49729b;
 | 
			
		||||
}
 | 
			
		||||
.react-calendar-heatmap .color-gitlab-4 {
 | 
			
		||||
    fill: #254e77;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										335
									
								
								resources/js/components/calendar/CalendarHeatmap.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										335
									
								
								resources/js/components/calendar/CalendarHeatmap.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -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 = (
 | 
			
		||||
            <rect
 | 
			
		||||
                key={index}
 | 
			
		||||
                width={SQUARE_SIZE}
 | 
			
		||||
                height={SQUARE_SIZE}
 | 
			
		||||
                x={x}
 | 
			
		||||
                y={y}
 | 
			
		||||
                className={getClassNameForIndex(index)}
 | 
			
		||||
                onClick={() => handleClick(value)}
 | 
			
		||||
                onMouseOver={(e) => handleMouseOver(e, value)}
 | 
			
		||||
                onMouseLeave={(e) => handleMouseLeave(e, value)}
 | 
			
		||||
                {...getTooltipDataAttrsForIndex(index)}
 | 
			
		||||
            >
 | 
			
		||||
                <title>{getTitleForIndex(index)}</title>
 | 
			
		||||
            </rect>
 | 
			
		||||
        );
 | 
			
		||||
        return transformDayElement ? transformDayElement(rect, value as string, index) : rect;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function renderWeek(weekIndex) {
 | 
			
		||||
        return (
 | 
			
		||||
            <g
 | 
			
		||||
                key={weekIndex}
 | 
			
		||||
                transform={getTransformForWeek(weekIndex)}
 | 
			
		||||
                className={`${CSS_PSEUDO_NAMESPACE}week`}
 | 
			
		||||
            >
 | 
			
		||||
                {getRange(DAYS_IN_WEEK).map((dayIndex) =>
 | 
			
		||||
                    renderSquare(dayIndex, weekIndex * DAYS_IN_WEEK + dayIndex),
 | 
			
		||||
                )}
 | 
			
		||||
            </g>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 ? (
 | 
			
		||||
                <text key={weekIndex} x={x} y={y} className={`${CSS_PSEUDO_NAMESPACE}month-label`}>
 | 
			
		||||
            {MONTH_LABELS[endOfWeek.getMonth()]}
 | 
			
		||||
            </text>
 | 
			
		||||
        ) : 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 ? (
 | 
			
		||||
                <text key={`${x}${y}`} x={x} y={y} className={cssClasses}>
 | 
			
		||||
                {weekdayLabel}
 | 
			
		||||
                </text>
 | 
			
		||||
        ) : null;
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <svg className="react-calendar-heatmap" viewBox={getViewBox()}>
 | 
			
		||||
            <g
 | 
			
		||||
                transform={getTransformForMonthLabels()}
 | 
			
		||||
                className={`${CSS_PSEUDO_NAMESPACE}month-labels`}
 | 
			
		||||
            >
 | 
			
		||||
                {renderMonthLabels()}
 | 
			
		||||
            </g>
 | 
			
		||||
            <g
 | 
			
		||||
            transform={getTransformForAllWeeks()}
 | 
			
		||||
            className={`${CSS_PSEUDO_NAMESPACE}all-weeks`}
 | 
			
		||||
        >
 | 
			
		||||
            {renderAllWeeks()}
 | 
			
		||||
            </g>
 | 
			
		||||
            <g
 | 
			
		||||
            transform={getTransformForWeekdayLabels()}
 | 
			
		||||
            className={`${CSS_PSEUDO_NAMESPACE}weekday-labels`}
 | 
			
		||||
        >
 | 
			
		||||
            {renderWeekdayLabels()}
 | 
			
		||||
            </g>
 | 
			
		||||
        </svg>
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default CalendarHeatmap;
 | 
			
		||||
							
								
								
									
										19
									
								
								resources/js/components/calendar/CalendarHeatmapProp.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								resources/js/components/calendar/CalendarHeatmapProp.ts
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,5 @@
 | 
			
		||||
export interface CalendarHeatmapValuesProp {
 | 
			
		||||
    id: string;
 | 
			
		||||
    date: Date;
 | 
			
		||||
    event: string;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								resources/js/components/calendar/constants.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								resources/js/components/calendar/constants.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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 };
 | 
			
		||||
@@ -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 (<Prompt open={true} setOpen={updatePassphrase}/>);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 (
 | 
			
		||||
            <div className="col-md-12">
 | 
			
		||||
                <CalendarHeatmap
 | 
			
		||||
                    values={getCalendarValuesFromPagesList(listPages)}
 | 
			
		||||
                    startDate={startDate}
 | 
			
		||||
                    endDate={new Date()}
 | 
			
		||||
                    showMonthLabels={true}
 | 
			
		||||
                    showWeekdayLabels={true}
 | 
			
		||||
                    showOutOfRangeDays={true}
 | 
			
		||||
                    horizontal={true}
 | 
			
		||||
                    gutterSize={4}
 | 
			
		||||
                    onClick={(value) => alert(value)}
 | 
			
		||||
                    tooltipDataAttrs={{}}
 | 
			
		||||
                />
 | 
			
		||||
                <Pages
 | 
			
		||||
                    pages={listPages}
 | 
			
		||||
                    url={getPageContentUrl}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ let encryptStorage = new EncryptStorage('test'); // TODO la clef doit venir de l
 | 
			
		||||
 | 
			
		||||
export default function PageForm({setListPages, csrf, url, passphrase}) {
 | 
			
		||||
    const isPassphraseSet = passphrase !== null;
 | 
			
		||||
    const [content, setContent] = React.useState("");
 | 
			
		||||
    const [content, setContent] = React.useState<string>("");
 | 
			
		||||
    const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
 | 
			
		||||
        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}) {
 | 
			
		||||
                />
 | 
			
		||||
                <MDEditor
 | 
			
		||||
                    value={content}
 | 
			
		||||
                    onChange={setContent}
 | 
			
		||||
                    onChange={updateContent}
 | 
			
		||||
                  />
 | 
			
		||||
                <Button variant="contained" type={"submit"}>
 | 
			
		||||
                    Enregistrer
 | 
			
		||||
 
 | 
			
		||||
@@ -11,4 +11,36 @@ const isAllLoadedLocally = function(pages: IList[]) {
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { isAllLoadedLocally };
 | 
			
		||||
/** CALENDAR **/
 | 
			
		||||
// returns a new date shifted a certain number of days (can be negative)
 | 
			
		||||
const shiftDate = function(date, numDays) {
 | 
			
		||||
    const newDate = new Date(date);
 | 
			
		||||
    newDate.setDate(newDate.getDate() + numDays);
 | 
			
		||||
    return newDate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const getBeginningTimeForDate = function(date: Date): Date {
 | 
			
		||||
    return new Date(date.getFullYear(), date.getMonth(), date.getDate());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// obj can be a parseable string, a millisecond timestamp, or a Date object
 | 
			
		||||
const convertToDate = function(obj): Date {
 | 
			
		||||
    return obj instanceof Date ? obj : new Date(obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const dateNDaysAgo = function(numDaysAgo) {
 | 
			
		||||
    return shiftDate(new Date(), -numDaysAgo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const getRange = function(count) {
 | 
			
		||||
    const arr: number[] = [];
 | 
			
		||||
    for (let idx = 0; idx < count; idx += 1) {
 | 
			
		||||
        arr.push(idx);
 | 
			
		||||
    }
 | 
			
		||||
    return arr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** END CALENDAR **/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export { isAllLoadedLocally, shiftDate, getBeginningTimeForDate, convertToDate, dateNDaysAgo, getRange };
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@
 | 
			
		||||
            <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
 | 
			
		||||
                <div class="p-6 bg-white border-b border-gray-200">
 | 
			
		||||
                    <div id="app"
 | 
			
		||||
                         data-start="{{ $start_date->format('Y-m-d') }}"
 | 
			
		||||
                         data-list="{{json_encode($pages)}}"
 | 
			
		||||
                         data-url="{{ route('pages.show', ['page' => 'replace_me']) }}"
 | 
			
		||||
                         data-post="{{ route('pages.store') }}"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user