diff --git a/forgettable-frontend/package.json b/forgettable-frontend/package.json
index a396b79a..47113dff 100644
--- a/forgettable-frontend/package.json
+++ b/forgettable-frontend/package.json
@@ -15,6 +15,7 @@
"firebase": "^9.6.8",
"image-to-base64": "^2.2.0",
"react": "^17.0.2",
+ "react-calendar-heatmap": "^1.8.1",
"react-dom": "^17.0.2",
"react-firebase-hooks": "^5.0.3",
"react-google-autocomplete": "^2.6.1",
@@ -23,6 +24,7 @@
"react-scripts": "^5.0.0",
"react-test-renderer": "^17.0.2",
"react-toastify": "^8.2.0",
+ "react-tooltip": "^4.2.21",
"typescript": "^4.6.2",
"web-vitals": "^2.1.4"
},
diff --git a/forgettable-frontend/src/components/Streaks/Streaks.js b/forgettable-frontend/src/components/Streaks/Streaks.js
new file mode 100644
index 00000000..1b2cedb6
--- /dev/null
+++ b/forgettable-frontend/src/components/Streaks/Streaks.js
@@ -0,0 +1,105 @@
+
+import React, {useState, useEffect} from 'react';
+import CalendarHeatmap from 'react-calendar-heatmap';
+import ReactTooltip from 'react-tooltip';
+import classes from './Streaks.module.css';
+import './react-calendar-heatmap/dist/styles.css';
+import {getLongDateStringWithSlashes} from '../../functions/dateFormatter';
+import {getAllEncounters} from '../../services';
+import {unmarshalEncounters} from '../../functions/dataUnmarshaller';
+import {Avatar, Card} from '@mui/material';
+
+const today = new Date();
+
+function Streaks(encounter) {
+ const [dates, setDates]=useState([]);
+ async function getDate() {
+ const encountersResult = await getAllEncounters();
+
+ const unmarshalledEncounters = encountersResult.map((encounter) =>
+ unmarshalEncounters(encounter),
+ );
+ setDates(unmarshalledEncounters.map((a) =>a.date));
+ }
+ useEffect(()=>{
+ try {
+ getDate();
+ } catch (err) {
+ console.log(err);
+ }
+ }, [encounter]);
+ // count the occurrences of the date
+ const occurrences = dates.reduce(function(acc, curr) {
+ return acc[curr] ? ++acc[curr] : acc[curr] = 1, acc;
+ }, {});
+ // set useful Array
+ const resultDate = Object.keys(occurrences);
+ const resultCount = Object.values(occurrences);
+ // use for the values props of the CalendarHeatmap
+ const data = getRange(resultCount.length).map((d) => (
+ {
+ date: resultDate[d],
+ count: resultCount[d],
+ }));
+ return (
+
+
+
+
+ {
+ if (!value) {
+ return 'color-streaks-0';
+ }
+ return `${value.count}` <= 10 ?
+ `color-streaks-${value.count}` :
+ `color-streaks-10`;
+ }}
+ tooltipDataAttrs={(value) => {
+ if (!value.date) {
+ return {'data-tip':
+ `None encounter at this date`};
+ }
+ return {
+ 'data-tip': `${getLongDateStringWithSlashes(value.date)}
+ has count:
+ ${value.count }`,
+ };
+ }
+ }
+ showWeekdayLabels={true}
+ />
+
+
+ );
+}
+// use for the startDate props of the CalendarHeatmap
+function shiftDate(date, numDays) {
+ const newDate = new Date(date);
+ newDate.setDate(newDate.getDate() + numDays);
+ return newDate;
+}
+function getRange(count) {
+ return Array.from({length: count}, (_, i) => i);
+}
+export default Streaks;
diff --git a/forgettable-frontend/src/components/Streaks/Streaks.module.css b/forgettable-frontend/src/components/Streaks/Streaks.module.css
new file mode 100644
index 00000000..e52b76f8
--- /dev/null
+++ b/forgettable-frontend/src/components/Streaks/Streaks.module.css
@@ -0,0 +1,69 @@
+.scales {
+ display: flex;
+ margin-left: auto;
+ margin-right: 0;
+ }
+ .description {
+ width: 915px;
+ margin-left: 29px;
+ color: #313131;
+ display: flex;
+ justify-content: space-between;
+}
+
+.descriptionScales {
+ display: flex;
+}
+
+.streaks0 {
+ background: #eeeeee;
+ fill: #eeeeee;
+ width: 14px;
+ height: 14px;
+ margin: 5px;
+ border-radius: 50%;
+}
+
+.streaks1 {
+ background:#F3D58A ;
+ fill: #F3D58A;
+ width: 14px;
+ height: 14px;
+ margin: 5px;
+ border-radius: 50%;
+}
+
+.streaks2 {
+ width: 14px;
+ height: 14px;
+ margin: 5px;
+ border-radius: 50%;
+ fill: #ecc769;
+ background: #ecc769;
+}
+
+.streaks3 {
+ width: 14px;
+ height: 14px;
+ margin: 5px;
+ border-radius: 50%;
+ fill: #ebb429;
+ background: #ebb429;
+}
+
+.streaks4 {
+ width: 14px;
+ height: 14px;
+ margin: 5px;
+ border-radius: 50%;
+ fill: #d89d07;
+ background: #d89d07;
+}
+.streaks5 {
+ width: 14px;
+ height: 14px;
+ margin: 5px;
+ border-radius: 50%;
+ fill: #d80707;
+ background:#d80707;
+}
diff --git a/forgettable-frontend/src/components/Streaks/react-calendar-heatmap/dist/styles.css b/forgettable-frontend/src/components/Streaks/react-calendar-heatmap/dist/styles.css
new file mode 100644
index 00000000..1fe99ca8
--- /dev/null
+++ b/forgettable-frontend/src/components/Streaks/react-calendar-heatmap/dist/styles.css
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+ .react-calendar-heatmap text {
+ font-size: 5px;
+ fill: #aaa;
+ }
+
+ .react-calendar-heatmap .react-calendar-heatmap-small-text {
+ font-size: 5px;
+ }
+
+ .react-calendar-heatmap rect:hover {
+ stroke: #555;
+ stroke-width: 1px;
+ }
+
+
+ .color-streaks-0 {
+ fill: #eeeeee;
+ }
+
+ .color-streaks-1 {
+ fill: #F3D58A;
+ }
+
+ .color-streaks-2 {
+ fill: #ecc769;
+ }
+
+ .color-streaks-3 {
+ fill: #ebb429;
+ }
+
+ .color-streaks-4 {
+ fill: #e9a804;
+ }
+ .color-streaks-5 {
+ fill: #d89d07;
+ }
+ .color-streaks-6 {
+ fill: #8f6804;
+ }
+ .color-streaks-7 {
+ fill: #7b5902;
+ }
+ .color-streaks-8 {
+ fill: #4b3600;
+ }
+ .color-streaks-9 {
+ fill: #463200;
+ }
+ .color-streaks-10 {
+ fill: #d80707;
+ }
\ No newline at end of file
diff --git a/forgettable-frontend/src/pages/home/Home.js b/forgettable-frontend/src/pages/home/Home.js
index 2ee10724..5aab23ea 100644
--- a/forgettable-frontend/src/pages/home/Home.js
+++ b/forgettable-frontend/src/pages/home/Home.js
@@ -19,6 +19,7 @@ import { useNavigate } from 'react-router-dom';
import { unmarshalPerson, unmarshalEncounters } from '../../functions/dataUnmarshaller';
import UpcomingBirthdaySummary from '../../components/UpcomingBirthdaySummary/UpcomingBirthdaySummary';
import SearchFilterModal from '../../components/SearchFilterModal/SearchFilterModal';
+import Streaks from '../../components/Streaks/Streaks';
function Home() {
const [isHover, setIsHover] = useState(false);
@@ -162,6 +163,9 @@ function Home() {
+
+
+
Recently Updated
diff --git a/forgettable-frontend/src/pages/home/Home.module.css b/forgettable-frontend/src/pages/home/Home.module.css
index 50287596..e25a7975 100644
--- a/forgettable-frontend/src/pages/home/Home.module.css
+++ b/forgettable-frontend/src/pages/home/Home.module.css
@@ -13,7 +13,16 @@
font-size: var(--text-xxlarge);
font-weight: var(--font-semibold);
}
-
+.streaks_container {
+ display: flex;
+ flex-direction: column;
+ margin-left: 35px;
+ margin-top: flex;
+ margin-bottom: 20px;
+ margin-right: 490px; /* accounts for summary panel + margin */
+ min-width: 805px;
+ max-width: 1565px;
+}
.home_searchArea {
width: 100%;
display: flex;