JSFiddle - React, Tailwind, and code Playground
by Josh Pullen
JavaScript
// User data
const goal = {
days: ["mon", "tue"],
startDate: new Date("May 22, 2020").getTime()
};
const logs = [
{ date: new Date("May 25, 2020").getTime() },
{ date: new Date("May 26, 2020").getTime() },
{ date: new Date("May 27, 2020").getTime() },
{ date: new Date("May 28, 2020").getTime() }
];
const today = new Date("May 28, 2020");
// Functions
function completedDay(day) {
const sameDay = (dateA, dateB) => (
dateA.getFullYear() === dateB.getFullYear() &&
dateA.getMonth() === dateB.getMonth() &&
dateA.getDate() === dateB.getDate()
);
return logs.some(log => sameDay(new Date(log.date), day));
}
function isDayOff(day) {
const dayNames = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
const dayName = dayNames[day.getDay()];
return !goal.days.includes(dayName);
}
function getStreak(beforeDay) {
let day = new Date(beforeDay); // Copy so we don't modify the original
day.setDate(day.getDate() - 1);
let streakType = null;
let streakDays = 0;
while (day.getTime() >= goal.startDate) {
if (!isDayOff(day)) {
if (streakType === null) {
streakType = completedDay(day) ? "good" : "bad";
}
if (completedDay(day) === (streakType === "good")) {
// This day matches the streak!
streakDays++;
} else {
// This day doesn't match. We've hit the end of the streak.
break;
}
}
day.setDate(day.getDate() - 1);
}
// If it's a bad streak and you haven't done anything today,
// that doesn't count against you (because the outcome of today
// is still undecided). But if you have a good streak going and
// you succeed today, that should add to your streak.
if (streakType === "good" && completedDay(today) && !isDayOff(today)) {
streakDays++;
}
return {
type: streakType,
days: streakDays
}
}
// Code
console.log("Completed today?", completedDay(today));
const streak = getStreak(today);
console.log("Streak:", streak.days,...