From 7de4c555e0a47d4cc2c8e1c2643041f02f5764da Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Thu, 3 Jun 2021 01:31:53 +0200 Subject: [PATCH 01/11] start work --- src/features/timeline/Calendar/Entry.js | 39 +++++++++ src/features/timeline/Calendar/Header.js | 54 +++++++++++++ src/features/timeline/Calendar/Info.js | 47 +++++++++++ src/features/timeline/Calendar/Tags.js | 81 +++++++++++++++++++ src/features/timeline/Calendar/index.js | 94 ++++++++++++++++++++++ src/features/timeline/TimelineIndexPage.js | 63 ++++++++++++--- src/features/timeline/temp.css | 15 ++++ 7 files changed, 381 insertions(+), 12 deletions(-) create mode 100644 src/features/timeline/Calendar/Entry.js create mode 100644 src/features/timeline/Calendar/Header.js create mode 100644 src/features/timeline/Calendar/Info.js create mode 100644 src/features/timeline/Calendar/Tags.js create mode 100644 src/features/timeline/Calendar/index.js create mode 100644 src/features/timeline/temp.css diff --git a/src/features/timeline/Calendar/Entry.js b/src/features/timeline/Calendar/Entry.js new file mode 100644 index 00000000..aa6e1a51 --- /dev/null +++ b/src/features/timeline/Calendar/Entry.js @@ -0,0 +1,39 @@ +import React from "react" +import PropTypes from "prop-types" +import { Link } from "gatsby" +import { useSelector } from "react-redux" +import { Typography, ButtonBase, Paper, Box } from "@material-ui/core" +import { Add as AddNoteIcon } from "@material-ui/icons" + +import { entryIdFromDate } from "../../utils/days" +import { selectEntryNote } from "../../entries" + +const Entry = ({ date, isPast, isToday, className }) => { + const entryId = entryIdFromDate(date) + const editPath = `/timeline/${entryId}/edit` + const entryNote = useSelector((state) => selectEntryNote(state, { date })) + const isEditable = isPast || isToday + + if (!isEditable) return null + + return ( + + {entryNote ? ( + {entryNote} + ) : ( + + + Add note + + )} + + ) +} + +Entry.propTypes = { + date: PropTypes.instanceOf(Date), + isPast: PropTypes.bool.isRequired, + isToday: PropTypes.bool.isRequired, +} + +export default Entry diff --git a/src/features/timeline/Calendar/Header.js b/src/features/timeline/Calendar/Header.js new file mode 100644 index 00000000..bf44eae0 --- /dev/null +++ b/src/features/timeline/Calendar/Header.js @@ -0,0 +1,54 @@ +import React from "react" +import PropTypes from "prop-types" +import { useSelector } from "react-redux" +import { format } from "date-fns" +import { Typography } from "@material-ui/core" + +import { + selectCycleDayForDate, + selectPredictedMenstruationForDate, +} from "../../cycle" + +const TimelineHeader = ({ date, isSelected, isToday, isFuture, className }) => { + const cycleDay = useSelector((state) => + selectCycleDayForDate(state, { date }) + ) + + const isPredictedMenstruation = useSelector((state) => + selectPredictedMenstruationForDate(state, { date }) + ) + + const isMenstruation = isPredictedMenstruation + + const textColor = isToday || isFuture ? "textPrimary" : "textSecondary" + + return ( +
+ + {isToday ? "Today" : date.getDate()} + + + Day {cycleDay} + +
+ ) +} + +TimelineHeader.propTypes = { + date: PropTypes.instanceOf(Date), + isSelected: PropTypes.bool.isRequired, + isToday: PropTypes.bool.isRequired, + isFuture: PropTypes.bool.isRequired, +} + +export default TimelineHeader diff --git a/src/features/timeline/Calendar/Info.js b/src/features/timeline/Calendar/Info.js new file mode 100644 index 00000000..21e55c02 --- /dev/null +++ b/src/features/timeline/Calendar/Info.js @@ -0,0 +1,47 @@ +import React from "react" +import { useSelector } from "react-redux" +import PropTypes from "prop-types" +import { format } from "date-fns" +import { Paper, Typography } from "@material-ui/core" + +import { + selectDaysBetween, + selectIsDaysBetweenCalculated, + selectIsDateCurrentCycle, + selectNextStartDate, +} from "../../cycle" +import { useSettings } from "../../settings" +import getMonth from "date-fns/getMonth" + +const Info = ({ date }) => { + const { mainMensesTag } = useSettings() + + const daysBetween = useSelector(selectDaysBetween) + const isDaysBetweenCalculated = useSelector(selectIsDaysBetweenCalculated) + + const isCurrentCycle = useSelector((state) => + selectIsDateCurrentCycle(state, { date }) + ) + const nextStartDate = useSelector((state) => + selectNextStartDate(state, { date }) + ) + const isNextPeriodThisMonth = getMonth(nextStartDate) === getMonth(date) + + if (!nextStartDate || !isNextPeriodThisMonth) return null + + return ( + + Next {mainMensesTag} {!isCurrentCycle && "was"} estimated + to arrive {format(nextStartDate, "EEEE, MMMM do")}, based + on {isDaysBetweenCalculated ? "your average" : "a default"}{" "} + {daysBetween || "?"}-day cycle.{" "} + + ) +} + +Info.propTypes = { + date: PropTypes.instanceOf(Date), + isToday: PropTypes.bool, +} + +export default Info diff --git a/src/features/timeline/Calendar/Tags.js b/src/features/timeline/Calendar/Tags.js new file mode 100644 index 00000000..87635321 --- /dev/null +++ b/src/features/timeline/Calendar/Tags.js @@ -0,0 +1,81 @@ +import React from "react" +import PropTypes from "prop-types" +import classNames from "classnames" +import { useSelector, useDispatch } from "react-redux" +import { Chip, makeStyles } from "@material-ui/core" +import { AddCircle as AddIcon } from "@material-ui/icons" + +import { selectTagsForDate } from "../../cycle" +import { selectEntryNote, upsertEntry } from "../../entries" +import { textEndsWithTag } from "../../utils/tags" + +const useStyles = makeStyles((theme) => ({ + tag: { + borderStyle: "dashed", + borderColor: "transparent", + color: theme.palette.text.primary, + }, + predictedTag: { + borderColor: "rgba(0, 0, 0, 0.23)", + }, + loggedTag: { + fontWeight: theme.typography.fontWeightMedium, + backgroundColor: theme.palette.background.paper, + }, +})) + +const Tags = ({ date, isFuture, className }) => { + const classes = useStyles() + + const dispatch = useDispatch() + const entryNote = useSelector((state) => selectEntryNote(state, { date })) + const tags = useSelector((state) => selectTagsForDate(state, { date })) + + const handleAddTag = (tag) => (event) => { + event.preventDefault() + + let note = entryNote || "" + if (!note || textEndsWithTag(note)) { + note = `${entryNote} #${tag}` + } else { + note = `${entryNote} \n\n #${tag}` + } + dispatch(upsertEntry({ date, note })) + } + + if (tags.length === 0) return null + + return ( + + ) +} + +Tags.propTypes = { + date: PropTypes.instanceOf(Date), +} + +export default Tags diff --git a/src/features/timeline/Calendar/index.js b/src/features/timeline/Calendar/index.js new file mode 100644 index 00000000..f3f8d863 --- /dev/null +++ b/src/features/timeline/Calendar/index.js @@ -0,0 +1,94 @@ +import { getDay, getDaysInMonth, getYear } from "date-fns" +import React, { useEffect, useState } from "react" +import { useSelector } from "react-redux" +import { + format, + addDays, + isFuture as dateIsFuture, + isToday as dateIsToday, + isPast as dateIsPast, + isSameDay as dateIsSameDay, +} from "date-fns" +import { selectHasPredictionsForDate } from "../../cycle" +import Info from "./Info" +import Header from "./Header" +import Entry from "./Entry" +import Tags from "./Tags" +import { entryIdFromDate } from "../../utils/days" +import { Box, Typography } from "@material-ui/core" + +const Calendar = ({ dates }) => { + console.log(dates) + return ( +
+ + + {dates[0].toLocaleString("default", { month: "long" })}{" "} + {getYear(dates[0])}{" "} + + + +
    + {dates.map((date) => ( + + ))} +
+
+ ) +} + +const Item = ({ date, ...props }) => { + const hasPredictions = useSelector((state) => + selectHasPredictionsForDate(state, { date }) + ) + + const isPast = dateIsPast(date) + const isFuture = dateIsFuture(date) + const isToday = dateIsToday(date) + const itemProps = { date, isFuture, isToday, isPast, isSelected: false } + const scrollToId = `scrollTo-${entryIdFromDate(addDays(date, 1))}` + + return ( + <> + +
+ + {isFuture && !hasPredictions ? ( + + {date.getDate()} + + ) : ( + <> +
+ + + + )} + + + + ) +} + +export default Calendar diff --git a/src/features/timeline/TimelineIndexPage.js b/src/features/timeline/TimelineIndexPage.js index 9bc86672..f33c08c7 100644 --- a/src/features/timeline/TimelineIndexPage.js +++ b/src/features/timeline/TimelineIndexPage.js @@ -1,15 +1,24 @@ -import React, { useEffect } from "react" +import React, { useEffect, useState } from "react" import { useSelector } from "react-redux" import { navigate } from "gatsby" import { List, IconButton, makeStyles } from "@material-ui/core" -import { Today } from "@material-ui/icons" -import { eachDayOfInterval, addDays, isToday } from "date-fns" +import { Today, CalendarViewDay } from "@material-ui/icons" +import { + eachDayOfInterval, + addDays, + isToday, + getMonth, + getYear, + getDaysInMonth, +} from "date-fns" import { makeDate, entryIdFromDate } from "../utils/days" import { AppLayout, AppMainToolbar, AppPage } from "../app" import { Welcome } from "../onboarding" import { selectDaysBetween } from "../cycle" import TimelineItem from "./TimelineItem" import DatePicker from "./DatePicker" +import "./temp.css" +import Calendar from "./Calendar" const useStyles = makeStyles((theme) => ({ timeline: { @@ -21,6 +30,7 @@ const useStyles = makeStyles((theme) => ({ const CycleIndexPage = ({ entryId }) => { const classes = useStyles() + const [calendarView, setCalendarView] = useState() const selectedDate = makeDate(entryId) const calculatedDaysBetween = useSelector(selectDaysBetween) @@ -40,6 +50,18 @@ const CycleIndexPage = ({ entryId }) => { }) }, [selectedDate]) + const a = range.reduce((acc, curr) => { + const month = getMonth(curr) + if (acc[month]) { + acc[month] = [...acc[month], curr] + } else { + acc[month] = [curr] + } + return acc + }, {}) + + console.log(a) + return ( @@ -52,16 +74,33 @@ const CycleIndexPage = ({ entryId }) => { > + setCalendarView((c) => !c)} + style={{ marginLeft: "auto" }} + > + + - - {range.map((date) => { - return ( - - {isToday(date) && } - - ) - })} - + {calendarView ? ( + Object.keys(a).map((monthNumber) => ( + + )) + ) : ( + + {range.map((date) => { + return ( + + {isToday(date) && } + + ) + })} + + )} ) diff --git a/src/features/timeline/temp.css b/src/features/timeline/temp.css new file mode 100644 index 00000000..c5849fdb --- /dev/null +++ b/src/features/timeline/temp.css @@ -0,0 +1,15 @@ +.calendar ul, +.calendar ol { + display: grid; + grid-template-columns: repeat(7, calc(14.2% - 0.5em)); + grid-gap: 1em; + margin: 0 auto; + padding: 5px; +} + +@media all and (max-width: 800px) { + .calendar ul, + .calendar ol { + grid-gap: 0.25em; + } +} From ae374e817e507beb8a21b0f406e07a78adf66b73 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Thu, 3 Jun 2021 01:36:30 +0200 Subject: [PATCH 02/11] lint fixes --- src/features/timeline/Calendar/Day.js | 63 ++++++++++++++++++++ src/features/timeline/Calendar/Entry.js | 2 +- src/features/timeline/Calendar/Header.js | 1 - src/features/timeline/Calendar/Info.js | 5 +- src/features/timeline/Calendar/index.js | 69 ++-------------------- src/features/timeline/TimelineIndexPage.js | 12 +--- 6 files changed, 73 insertions(+), 79 deletions(-) create mode 100644 src/features/timeline/Calendar/Day.js diff --git a/src/features/timeline/Calendar/Day.js b/src/features/timeline/Calendar/Day.js new file mode 100644 index 00000000..a18c867b --- /dev/null +++ b/src/features/timeline/Calendar/Day.js @@ -0,0 +1,63 @@ +import { useSelector } from "react-redux" +import { Box, Typography } from "@material-ui/core" +import { + addDays, + isFuture as dateIsFuture, + isToday as dateIsToday, + isPast as dateIsPast, +} from "date-fns" +import { selectHasPredictionsForDate } from "../../cycle" +import React from "react" +import { entryIdFromDate } from "../../utils/days" +import Header from "./Header" +import Entry from "./Entry" +import Tags from "./Tags" + +const Day = ({ date, ...props }) => { + const hasPredictions = useSelector((state) => + selectHasPredictionsForDate(state, { date }) + ) + + const isPast = dateIsPast(date) + const isFuture = dateIsFuture(date) + const isToday = dateIsToday(date) + const itemProps = { date, isFuture, isToday, isPast, isSelected: false } + const scrollToId = `scrollTo-${entryIdFromDate(addDays(date, 1))}` + + return ( + <> + +
+ + {isFuture && !hasPredictions ? ( + + {date.getDate()} + + ) : ( + <> +
+ + + + )} + + + + ) +} + +export default Day diff --git a/src/features/timeline/Calendar/Entry.js b/src/features/timeline/Calendar/Entry.js index aa6e1a51..3f4c7d97 100644 --- a/src/features/timeline/Calendar/Entry.js +++ b/src/features/timeline/Calendar/Entry.js @@ -2,7 +2,7 @@ import React from "react" import PropTypes from "prop-types" import { Link } from "gatsby" import { useSelector } from "react-redux" -import { Typography, ButtonBase, Paper, Box } from "@material-ui/core" +import { Typography, ButtonBase, Box } from "@material-ui/core" import { Add as AddNoteIcon } from "@material-ui/icons" import { entryIdFromDate } from "../../utils/days" diff --git a/src/features/timeline/Calendar/Header.js b/src/features/timeline/Calendar/Header.js index bf44eae0..b41b0060 100644 --- a/src/features/timeline/Calendar/Header.js +++ b/src/features/timeline/Calendar/Header.js @@ -1,7 +1,6 @@ import React from "react" import PropTypes from "prop-types" import { useSelector } from "react-redux" -import { format } from "date-fns" import { Typography } from "@material-ui/core" import { diff --git a/src/features/timeline/Calendar/Info.js b/src/features/timeline/Calendar/Info.js index 21e55c02..942237b3 100644 --- a/src/features/timeline/Calendar/Info.js +++ b/src/features/timeline/Calendar/Info.js @@ -2,8 +2,8 @@ import React from "react" import { useSelector } from "react-redux" import PropTypes from "prop-types" import { format } from "date-fns" -import { Paper, Typography } from "@material-ui/core" - +import { Typography } from "@material-ui/core" +import getMonth from "date-fns/getMonth" import { selectDaysBetween, selectIsDaysBetweenCalculated, @@ -11,7 +11,6 @@ import { selectNextStartDate, } from "../../cycle" import { useSettings } from "../../settings" -import getMonth from "date-fns/getMonth" const Info = ({ date }) => { const { mainMensesTag } = useSettings() diff --git a/src/features/timeline/Calendar/index.js b/src/features/timeline/Calendar/index.js index f3f8d863..c4e1943a 100644 --- a/src/features/timeline/Calendar/index.js +++ b/src/features/timeline/Calendar/index.js @@ -1,24 +1,10 @@ -import { getDay, getDaysInMonth, getYear } from "date-fns" -import React, { useEffect, useState } from "react" -import { useSelector } from "react-redux" -import { - format, - addDays, - isFuture as dateIsFuture, - isToday as dateIsToday, - isPast as dateIsPast, - isSameDay as dateIsSameDay, -} from "date-fns" -import { selectHasPredictionsForDate } from "../../cycle" +import { getYear } from "date-fns" +import React from "react" import Info from "./Info" -import Header from "./Header" -import Entry from "./Entry" -import Tags from "./Tags" -import { entryIdFromDate } from "../../utils/days" import { Box, Typography } from "@material-ui/core" +import Day from "./Day" const Calendar = ({ dates }) => { - console.log(dates) return (
{
    {dates.map((date) => ( - + ))}
) } -const Item = ({ date, ...props }) => { - const hasPredictions = useSelector((state) => - selectHasPredictionsForDate(state, { date }) - ) - - const isPast = dateIsPast(date) - const isFuture = dateIsFuture(date) - const isToday = dateIsToday(date) - const itemProps = { date, isFuture, isToday, isPast, isSelected: false } - const scrollToId = `scrollTo-${entryIdFromDate(addDays(date, 1))}` - - return ( - <> - -
- - {isFuture && !hasPredictions ? ( - - {date.getDate()} - - ) : ( - <> -
- - - - )} - - - - ) -} - export default Calendar diff --git a/src/features/timeline/TimelineIndexPage.js b/src/features/timeline/TimelineIndexPage.js index f33c08c7..14bc7b68 100644 --- a/src/features/timeline/TimelineIndexPage.js +++ b/src/features/timeline/TimelineIndexPage.js @@ -3,23 +3,17 @@ import { useSelector } from "react-redux" import { navigate } from "gatsby" import { List, IconButton, makeStyles } from "@material-ui/core" import { Today, CalendarViewDay } from "@material-ui/icons" -import { - eachDayOfInterval, - addDays, - isToday, - getMonth, - getYear, - getDaysInMonth, -} from "date-fns" +import { eachDayOfInterval, addDays, isToday, getMonth } from "date-fns" import { makeDate, entryIdFromDate } from "../utils/days" import { AppLayout, AppMainToolbar, AppPage } from "../app" import { Welcome } from "../onboarding" import { selectDaysBetween } from "../cycle" import TimelineItem from "./TimelineItem" import DatePicker from "./DatePicker" -import "./temp.css" import Calendar from "./Calendar" +import "./temp.css" + const useStyles = makeStyles((theme) => ({ timeline: { "& > *": { From 35665c979f471b5844dcaebc53200f938dbed785 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Thu, 3 Jun 2021 01:39:21 +0200 Subject: [PATCH 03/11] mobile --- src/features/timeline/temp.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/features/timeline/temp.css b/src/features/timeline/temp.css index c5849fdb..0d2de98c 100644 --- a/src/features/timeline/temp.css +++ b/src/features/timeline/temp.css @@ -1,15 +1,15 @@ .calendar ul, .calendar ol { display: grid; - grid-template-columns: repeat(7, calc(14.2% - 0.5em)); + grid-template-columns: repeat(7, calc(14.2% - 1em)); grid-gap: 1em; margin: 0 auto; padding: 5px; } @media all and (max-width: 800px) { - .calendar ul, .calendar ol { grid-gap: 0.25em; + grid-template-columns: repeat(7, calc(14.2% - 0.25em)); } } From eca2d76e9687efd3cfb72e68c4ad26a9adc3aa26 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Thu, 3 Jun 2021 20:14:38 +0200 Subject: [PATCH 04/11] add redirect uris --- src/features/timeline/Calendar/Day.js | 3 +- src/features/timeline/Calendar/Entry.js | 4 +- src/features/timeline/Calendar/Tags.js | 81 ---------------------- src/features/timeline/TimelineEditPage.js | 10 +-- src/features/timeline/TimelineIndexPage.js | 19 +++-- src/pages/timeline.js | 3 + 6 files changed, 26 insertions(+), 94 deletions(-) delete mode 100644 src/features/timeline/Calendar/Tags.js diff --git a/src/features/timeline/Calendar/Day.js b/src/features/timeline/Calendar/Day.js index a18c867b..82c49971 100644 --- a/src/features/timeline/Calendar/Day.js +++ b/src/features/timeline/Calendar/Day.js @@ -11,7 +11,6 @@ import React from "react" import { entryIdFromDate } from "../../utils/days" import Header from "./Header" import Entry from "./Entry" -import Tags from "./Tags" const Day = ({ date, ...props }) => { const hasPredictions = useSelector((state) => @@ -49,9 +48,9 @@ const Day = ({ date, ...props }) => { ) : ( <> + {" "}
- )} diff --git a/src/features/timeline/Calendar/Entry.js b/src/features/timeline/Calendar/Entry.js index 3f4c7d97..89aae2bf 100644 --- a/src/features/timeline/Calendar/Entry.js +++ b/src/features/timeline/Calendar/Entry.js @@ -10,7 +10,7 @@ import { selectEntryNote } from "../../entries" const Entry = ({ date, isPast, isToday, className }) => { const entryId = entryIdFromDate(date) - const editPath = `/timeline/${entryId}/edit` + const editPath = `/timeline/calendar/${entryId}/edit` const entryNote = useSelector((state) => selectEntryNote(state, { date })) const isEditable = isPast || isToday @@ -21,7 +21,7 @@ const Entry = ({ date, isPast, isToday, className }) => { {entryNote ? ( {entryNote} ) : ( - + Add note diff --git a/src/features/timeline/Calendar/Tags.js b/src/features/timeline/Calendar/Tags.js deleted file mode 100644 index 87635321..00000000 --- a/src/features/timeline/Calendar/Tags.js +++ /dev/null @@ -1,81 +0,0 @@ -import React from "react" -import PropTypes from "prop-types" -import classNames from "classnames" -import { useSelector, useDispatch } from "react-redux" -import { Chip, makeStyles } from "@material-ui/core" -import { AddCircle as AddIcon } from "@material-ui/icons" - -import { selectTagsForDate } from "../../cycle" -import { selectEntryNote, upsertEntry } from "../../entries" -import { textEndsWithTag } from "../../utils/tags" - -const useStyles = makeStyles((theme) => ({ - tag: { - borderStyle: "dashed", - borderColor: "transparent", - color: theme.palette.text.primary, - }, - predictedTag: { - borderColor: "rgba(0, 0, 0, 0.23)", - }, - loggedTag: { - fontWeight: theme.typography.fontWeightMedium, - backgroundColor: theme.palette.background.paper, - }, -})) - -const Tags = ({ date, isFuture, className }) => { - const classes = useStyles() - - const dispatch = useDispatch() - const entryNote = useSelector((state) => selectEntryNote(state, { date })) - const tags = useSelector((state) => selectTagsForDate(state, { date })) - - const handleAddTag = (tag) => (event) => { - event.preventDefault() - - let note = entryNote || "" - if (!note || textEndsWithTag(note)) { - note = `${entryNote} #${tag}` - } else { - note = `${entryNote} \n\n #${tag}` - } - dispatch(upsertEntry({ date, note })) - } - - if (tags.length === 0) return null - - return ( - - ) -} - -Tags.propTypes = { - date: PropTypes.instanceOf(Date), -} - -export default Tags diff --git a/src/features/timeline/TimelineEditPage.js b/src/features/timeline/TimelineEditPage.js index 879d96b9..1be8e185 100644 --- a/src/features/timeline/TimelineEditPage.js +++ b/src/features/timeline/TimelineEditPage.js @@ -30,10 +30,12 @@ const useStyles = makeStyles((theme) => ({ }, })) -const CycleEditPage = ({ entryId }) => { +const CycleEditPage = ({ entryId, path }) => { const classes = useStyles() const date = makeDate(entryId) - + const redirectTo = path.includes("/calendar") + ? `/timeline/calendar/${entryId}` + : `/timeline/${entryId}` const dispatch = useDispatch() const entryNote = useSelector((state) => selectEntryNote(state, { entryId })) const [note, setNote] = useState(entryNote) @@ -45,13 +47,13 @@ const CycleEditPage = ({ entryId }) => { const handleReset = (event) => { event.preventDefault() setNote(entryNote) - navigate(`/timeline/${entryId}`) + navigate(redirectTo) } const handleSubmit = (event) => { event.preventDefault() dispatch(upsertEntry({ date, note })) - navigate(`/timeline/${entryId}`) + navigate(redirectTo) } return ( diff --git a/src/features/timeline/TimelineIndexPage.js b/src/features/timeline/TimelineIndexPage.js index 14bc7b68..44635994 100644 --- a/src/features/timeline/TimelineIndexPage.js +++ b/src/features/timeline/TimelineIndexPage.js @@ -3,6 +3,7 @@ import { useSelector } from "react-redux" import { navigate } from "gatsby" import { List, IconButton, makeStyles } from "@material-ui/core" import { Today, CalendarViewDay } from "@material-ui/icons" +import AppsIcon from "@material-ui/icons/Apps" import { eachDayOfInterval, addDays, isToday, getMonth } from "date-fns" import { makeDate, entryIdFromDate } from "../utils/days" import { AppLayout, AppMainToolbar, AppPage } from "../app" @@ -22,9 +23,9 @@ const useStyles = makeStyles((theme) => ({ }, })) -const CycleIndexPage = ({ entryId }) => { +const CycleIndexPage = ({ entryId, path }) => { const classes = useStyles() - const [calendarView, setCalendarView] = useState() + const [calendarView] = useState(path.includes("/calendar")) const selectedDate = makeDate(entryId) const calculatedDaysBetween = useSelector(selectDaysBetween) @@ -63,17 +64,25 @@ const CycleIndexPage = ({ entryId }) => { navigate(`/timeline/${entryIdFromDate(new Date())}`)} + onClick={() => + navigate( + `/timeline/${calendarView ? "" : "calendar/"}${entryIdFromDate( + new Date() + )}` + ) + } style={{ marginLeft: "auto" }} > setCalendarView((c) => !c)} + onClick={() => + navigate(`/timeline/${calendarView ? "" : "calendar/"}`) + } style={{ marginLeft: "auto" }} > - + {calendarView ? : } {calendarView ? ( diff --git a/src/pages/timeline.js b/src/pages/timeline.js index 96b54d41..9e6c6ea6 100644 --- a/src/pages/timeline.js +++ b/src/pages/timeline.js @@ -44,6 +44,9 @@ const CyclePage = () => { + + + From 6628578c28630575b67d6f80d80607536b5cc116 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Thu, 3 Jun 2021 20:25:53 +0200 Subject: [PATCH 05/11] remove css file --- src/features/timeline/Calendar/index.js | 25 +++++++++++++++++----- src/features/timeline/TimelineIndexPage.js | 2 -- src/features/timeline/temp.css | 15 ------------- 3 files changed, 20 insertions(+), 22 deletions(-) delete mode 100644 src/features/timeline/temp.css diff --git a/src/features/timeline/Calendar/index.js b/src/features/timeline/Calendar/index.js index c4e1943a..e0ffc55a 100644 --- a/src/features/timeline/Calendar/index.js +++ b/src/features/timeline/Calendar/index.js @@ -1,12 +1,27 @@ import { getYear } from "date-fns" import React from "react" import Info from "./Info" -import { Box, Typography } from "@material-ui/core" +import { Box, Typography, makeStyles } from "@material-ui/core" import Day from "./Day" +const useStyles = makeStyles((theme) => ({ + calendar: { + display: "grid", + gridTemplateColumns: `repeat(7, calc(14.2% - ${theme.spacing(2)}px))`, + gridGap: theme.spacing(2), + padding: theme.spacing(1), + + [theme.breakpoints.down("sm")]: { + gridTemplateColumns: `repeat(7, calc(14.2% - ${theme.spacing(1)}px))`, + gridGap: theme.spacing(1), + }, + }, +})) + const Calendar = ({ dates }) => { + const classes = useStyles() return ( -
+ { -
    + {dates.map((date) => ( ))} -
-
+
+ ) } diff --git a/src/features/timeline/TimelineIndexPage.js b/src/features/timeline/TimelineIndexPage.js index 44635994..ca8afb83 100644 --- a/src/features/timeline/TimelineIndexPage.js +++ b/src/features/timeline/TimelineIndexPage.js @@ -13,8 +13,6 @@ import TimelineItem from "./TimelineItem" import DatePicker from "./DatePicker" import Calendar from "./Calendar" -import "./temp.css" - const useStyles = makeStyles((theme) => ({ timeline: { "& > *": { diff --git a/src/features/timeline/temp.css b/src/features/timeline/temp.css deleted file mode 100644 index 0d2de98c..00000000 --- a/src/features/timeline/temp.css +++ /dev/null @@ -1,15 +0,0 @@ -.calendar ul, -.calendar ol { - display: grid; - grid-template-columns: repeat(7, calc(14.2% - 1em)); - grid-gap: 1em; - margin: 0 auto; - padding: 5px; -} - -@media all and (max-width: 800px) { - .calendar ol { - grid-gap: 0.25em; - grid-template-columns: repeat(7, calc(14.2% - 0.25em)); - } -} From cee69703d011f49fa32f8cf49b294c44ec9d7b81 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Thu, 3 Jun 2021 20:29:16 +0200 Subject: [PATCH 06/11] remove log --- src/features/timeline/TimelineIndexPage.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/features/timeline/TimelineIndexPage.js b/src/features/timeline/TimelineIndexPage.js index ca8afb83..04847c82 100644 --- a/src/features/timeline/TimelineIndexPage.js +++ b/src/features/timeline/TimelineIndexPage.js @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react" +import React, { useEffect } from "react" import { useSelector } from "react-redux" import { navigate } from "gatsby" import { List, IconButton, makeStyles } from "@material-ui/core" @@ -23,7 +23,7 @@ const useStyles = makeStyles((theme) => ({ const CycleIndexPage = ({ entryId, path }) => { const classes = useStyles() - const [calendarView] = useState(path.includes("/calendar")) + const calendarView = path.includes("/calendar") const selectedDate = makeDate(entryId) const calculatedDaysBetween = useSelector(selectDaysBetween) @@ -43,7 +43,7 @@ const CycleIndexPage = ({ entryId, path }) => { }) }, [selectedDate]) - const a = range.reduce((acc, curr) => { + const daysInMonths = range.reduce((acc, curr) => { const month = getMonth(curr) if (acc[month]) { acc[month] = [...acc[month], curr] @@ -53,8 +53,6 @@ const CycleIndexPage = ({ entryId, path }) => { return acc }, {}) - console.log(a) - return ( @@ -84,8 +82,8 @@ const CycleIndexPage = ({ entryId, path }) => { {calendarView ? ( - Object.keys(a).map((monthNumber) => ( - + Object.keys(daysInMonths).map((monthNumber) => ( + )) ) : ( From 94fa97b3a75ea44e9f967e19e75cdbba27a1f2b0 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Fri, 4 Jun 2021 14:04:56 +0200 Subject: [PATCH 07/11] make new page --- gatsby-browser.js | 2 +- gatsby-node.js | 3 ++ src/features/timeline/Calendar/Entry.js | 2 +- src/features/timeline/TimelineEditPage.js | 6 +-- src/features/timeline/TimelineIndexPage.js | 19 +++----- src/pages/calendar.js | 53 ++++++++++++++++++++++ src/pages/timeline.js | 3 -- 7 files changed, 67 insertions(+), 21 deletions(-) create mode 100644 src/pages/calendar.js diff --git a/gatsby-browser.js b/gatsby-browser.js index 4fb7c8ae..ef60d670 100644 --- a/gatsby-browser.js +++ b/gatsby-browser.js @@ -10,7 +10,7 @@ export const wrapRootElement = ({ element }) => { } export const shouldUpdateScroll = ({ routerProps: { location } }) => { - const regex = /timeline\/?(\d\d\d\d-\d\d-\d\d)?$/ + const regex = /(timeline|calendar)\/?(\d\d\d\d-\d\d-\d\d)?$/ const results = location.pathname.match(regex) if (results) { diff --git a/gatsby-node.js b/gatsby-node.js index d52502b7..388e689a 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -4,6 +4,9 @@ exports.onCreatePage = async ({ page, actions }) => { if (page.path === "/timeline/") { page.matchPath = "/timeline/*" createPage(page) + } else if (page.path === "/calendar/") { + page.matchPath = "/calendar/*" + createPage(page) } else if (page.path === "/profile/") { page.matchPath = "/profile/*" createPage(page) diff --git a/src/features/timeline/Calendar/Entry.js b/src/features/timeline/Calendar/Entry.js index 89aae2bf..fc332169 100644 --- a/src/features/timeline/Calendar/Entry.js +++ b/src/features/timeline/Calendar/Entry.js @@ -10,7 +10,7 @@ import { selectEntryNote } from "../../entries" const Entry = ({ date, isPast, isToday, className }) => { const entryId = entryIdFromDate(date) - const editPath = `/timeline/calendar/${entryId}/edit` + const editPath = `/calendar/${entryId}/edit` const entryNote = useSelector((state) => selectEntryNote(state, { date })) const isEditable = isPast || isToday diff --git a/src/features/timeline/TimelineEditPage.js b/src/features/timeline/TimelineEditPage.js index 1be8e185..34c28a68 100644 --- a/src/features/timeline/TimelineEditPage.js +++ b/src/features/timeline/TimelineEditPage.js @@ -30,12 +30,10 @@ const useStyles = makeStyles((theme) => ({ }, })) -const CycleEditPage = ({ entryId, path }) => { +const CycleEditPage = ({ entryId, calendar }) => { const classes = useStyles() const date = makeDate(entryId) - const redirectTo = path.includes("/calendar") - ? `/timeline/calendar/${entryId}` - : `/timeline/${entryId}` + const redirectTo = calendar ? `/calendar/${entryId}` : `/${entryId}` const dispatch = useDispatch() const entryNote = useSelector((state) => selectEntryNote(state, { entryId })) const [note, setNote] = useState(entryNote) diff --git a/src/features/timeline/TimelineIndexPage.js b/src/features/timeline/TimelineIndexPage.js index 04847c82..5fc95c54 100644 --- a/src/features/timeline/TimelineIndexPage.js +++ b/src/features/timeline/TimelineIndexPage.js @@ -21,10 +21,8 @@ const useStyles = makeStyles((theme) => ({ }, })) -const CycleIndexPage = ({ entryId, path }) => { +const CycleIndexPage = ({ entryId, calendar: calendarView }) => { const classes = useStyles() - const calendarView = path.includes("/calendar") - const selectedDate = makeDate(entryId) const calculatedDaysBetween = useSelector(selectDaysBetween) @@ -60,21 +58,18 @@ const CycleIndexPage = ({ entryId, path }) => { - navigate( - `/timeline/${calendarView ? "" : "calendar/"}${entryIdFromDate( - new Date() - )}` - ) - } + onClick={() => { + const link = calendarView ? "/calendar" : "/timeline" + navigate(`${link}/${entryIdFromDate(new Date())}`) + }} style={{ marginLeft: "auto" }} > - navigate(`/timeline/${calendarView ? "" : "calendar/"}`) + navigate(`/${calendarView ? "timeline/" : "calendar/"}`) } style={{ marginLeft: "auto" }} > diff --git a/src/pages/calendar.js b/src/pages/calendar.js new file mode 100644 index 00000000..7a04ca70 --- /dev/null +++ b/src/pages/calendar.js @@ -0,0 +1,53 @@ +import React, { useEffect } from "react" +import { useSelector } from "react-redux" +import { navigate } from "gatsby" +import { Router } from "@reach/router" + +import { useAuth } from "../features/auth" +import { useSubscription } from "../features/user" +import { selectAreEntriesLoading } from "../features/entries" +import { useSettings } from "../features/settings" +import { TimelineIndexPage, TimelineEditPage } from "../features/timeline" +import { selectHasMensesStartDate } from "../features/cycle" +import { Seo, Loading } from "../features/app" +import { INCOMPLETE } from "../features/navigation" + +const CalendarView = () => { + const { isAuthenticated, isAuthPending } = useAuth() + const { isSubscribed } = useSubscription() + const { isLoading: settingsIsLoading } = useSettings() + + const entriesAreLoading = useSelector(selectAreEntriesLoading) + const hasMensesStartDate = useSelector(selectHasMensesStartDate) + + const dataIsLoading = entriesAreLoading || settingsIsLoading + const isIncomplete = !hasMensesStartDate || !isSubscribed + + useEffect(() => { + if (isAuthenticated && !dataIsLoading && isIncomplete) { + navigate(INCOMPLETE.to) + } + }, [isAuthenticated, dataIsLoading, isIncomplete]) + + if (isAuthPending || dataIsLoading) { + return ( + <> + + + + ) + } + + return ( + <> + + + + + + + + ) +} + +export default CalendarView diff --git a/src/pages/timeline.js b/src/pages/timeline.js index 9e6c6ea6..96b54d41 100644 --- a/src/pages/timeline.js +++ b/src/pages/timeline.js @@ -44,9 +44,6 @@ const CyclePage = () => { - - - From 230a0189a61523cd3bd1e63844b99e45bddb7301 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Wed, 9 Jun 2021 12:08:30 +0200 Subject: [PATCH 08/11] add border to first period day --- src/features/timeline/Calendar/Day.js | 34 ++++++++++++------ src/features/timeline/Calendar/Info.js | 46 ------------------------- src/features/timeline/Calendar/index.js | 2 -- 3 files changed, 24 insertions(+), 58 deletions(-) delete mode 100644 src/features/timeline/Calendar/Info.js diff --git a/src/features/timeline/Calendar/Day.js b/src/features/timeline/Calendar/Day.js index 82c49971..72bb3e8a 100644 --- a/src/features/timeline/Calendar/Day.js +++ b/src/features/timeline/Calendar/Day.js @@ -1,18 +1,37 @@ import { useSelector } from "react-redux" -import { Box, Typography } from "@material-ui/core" +import { Box, makeStyles, Typography } from "@material-ui/core" import { addDays, isFuture as dateIsFuture, isToday as dateIsToday, isPast as dateIsPast, } from "date-fns" -import { selectHasPredictionsForDate } from "../../cycle" +import { + selectHasPredictionsForDate, + selectPredictedMenstruationForDate, +} from "../../cycle" import React from "react" import { entryIdFromDate } from "../../utils/days" import Header from "./Header" import Entry from "./Entry" +const useStyles = makeStyles((theme) => ({ + list: { listStyle: "none" }, + day: { + minHeight: 100, + background: theme.palette.grey[200], + border: (props) => + props.isPeriod + ? `2px solid ${theme.palette.error.light}` + : `2px solid ${theme.palette.grey[200]}`, + }, +})) + const Day = ({ date, ...props }) => { + const isPredictedMenstruation = useSelector((state) => + selectPredictedMenstruationForDate(state, { date }) + ) + const classes = useStyles({ isPeriod: isPredictedMenstruation }) const hasPredictions = useSelector((state) => selectHasPredictionsForDate(state, { date }) ) @@ -25,13 +44,7 @@ const Day = ({ date, ...props }) => { return ( <> - +
{ justifyContent={ isFuture && !hasPredictions ? "center" : "space-between" } + className={classes.day} flexDirection="column" height={"100%"} + borderRadius={4} > {isFuture && !hasPredictions ? ( @@ -48,7 +63,6 @@ const Day = ({ date, ...props }) => { ) : ( <> - {" "}
diff --git a/src/features/timeline/Calendar/Info.js b/src/features/timeline/Calendar/Info.js deleted file mode 100644 index 942237b3..00000000 --- a/src/features/timeline/Calendar/Info.js +++ /dev/null @@ -1,46 +0,0 @@ -import React from "react" -import { useSelector } from "react-redux" -import PropTypes from "prop-types" -import { format } from "date-fns" -import { Typography } from "@material-ui/core" -import getMonth from "date-fns/getMonth" -import { - selectDaysBetween, - selectIsDaysBetweenCalculated, - selectIsDateCurrentCycle, - selectNextStartDate, -} from "../../cycle" -import { useSettings } from "../../settings" - -const Info = ({ date }) => { - const { mainMensesTag } = useSettings() - - const daysBetween = useSelector(selectDaysBetween) - const isDaysBetweenCalculated = useSelector(selectIsDaysBetweenCalculated) - - const isCurrentCycle = useSelector((state) => - selectIsDateCurrentCycle(state, { date }) - ) - const nextStartDate = useSelector((state) => - selectNextStartDate(state, { date }) - ) - const isNextPeriodThisMonth = getMonth(nextStartDate) === getMonth(date) - - if (!nextStartDate || !isNextPeriodThisMonth) return null - - return ( - - Next {mainMensesTag} {!isCurrentCycle && "was"} estimated - to arrive {format(nextStartDate, "EEEE, MMMM do")}, based - on {isDaysBetweenCalculated ? "your average" : "a default"}{" "} - {daysBetween || "?"}-day cycle.{" "} - - ) -} - -Info.propTypes = { - date: PropTypes.instanceOf(Date), - isToday: PropTypes.bool, -} - -export default Info diff --git a/src/features/timeline/Calendar/index.js b/src/features/timeline/Calendar/index.js index e0ffc55a..e09b3533 100644 --- a/src/features/timeline/Calendar/index.js +++ b/src/features/timeline/Calendar/index.js @@ -1,6 +1,5 @@ import { getYear } from "date-fns" import React from "react" -import Info from "./Info" import { Box, Typography, makeStyles } from "@material-ui/core" import Day from "./Day" @@ -34,7 +33,6 @@ const Calendar = ({ dates }) => { {dates[0].toLocaleString("default", { month: "long" })}{" "} {getYear(dates[0])}{" "} - {dates.map((date) => ( From 4fc9e9ca32ea625a13157dca85c8332373f00a0c Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Wed, 9 Jun 2021 23:41:42 +0200 Subject: [PATCH 09/11] start week at mondy --- src/features/timeline/Calendar/Day.js | 23 ++++++++++++++++++++++- src/features/timeline/Calendar/index.js | 25 +++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/features/timeline/Calendar/Day.js b/src/features/timeline/Calendar/Day.js index 72bb3e8a..3184f933 100644 --- a/src/features/timeline/Calendar/Day.js +++ b/src/features/timeline/Calendar/Day.js @@ -2,6 +2,7 @@ import { useSelector } from "react-redux" import { Box, makeStyles, Typography } from "@material-ui/core" import { addDays, + getDay, isFuture as dateIsFuture, isToday as dateIsToday, isPast as dateIsPast, @@ -41,10 +42,30 @@ const Day = ({ date, ...props }) => { const isToday = dateIsToday(date) const itemProps = { date, isFuture, isToday, isPast, isSelected: false } const scrollToId = `scrollTo-${entryIdFromDate(addDays(date, 1))}` + const weekDay = props.isFirstOfMonth ? getDay(date) : null + + const columnsForFirstDay = { + 0: 7, + 1: 0, + 2: 2, + 3: 3, + 4: 4, + 5: 5, + 6: 6, + } return ( <> - +
({ gridGap: theme.spacing(1), }, }, + weekDays: { + display: "grid", + gridTemplateColumns: `repeat(7, calc(14.2% - ${theme.spacing(2)}px))`, + listStyle: "none", + gridGap: theme.spacing(2), + padding: theme.spacing(1), + "& li": { + textAlign: "center", + }, + }, })) const Calendar = ({ dates }) => { @@ -34,9 +44,20 @@ const Calendar = ({ dates }) => { {getYear(dates[0])}{" "} + <> + +
  • Mon
  • +
  • Tues
  • +
  • Wed
  • +
  • Thurs
  • +
  • Fri
  • +
  • Sat
  • +
  • Sun
  • +
    + - {dates.map((date) => ( - + {dates.map((date, i) => ( + ))} From d000aa0ed4eba49e4d8e8ae75085c15ca7794dd3 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Wed, 9 Jun 2021 23:50:25 +0200 Subject: [PATCH 10/11] add dots when there are tags --- src/features/timeline/Calendar/Entry.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/features/timeline/Calendar/Entry.js b/src/features/timeline/Calendar/Entry.js index fc332169..be55f60b 100644 --- a/src/features/timeline/Calendar/Entry.js +++ b/src/features/timeline/Calendar/Entry.js @@ -1,14 +1,16 @@ import React from "react" import PropTypes from "prop-types" import { Link } from "gatsby" -import { useSelector } from "react-redux" -import { Typography, ButtonBase, Box } from "@material-ui/core" -import { Add as AddNoteIcon } from "@material-ui/icons" +import { useSelector } from "react-redux" +import { ButtonBase, Tooltip } from "@material-ui/core" +import { Brightness1 as BrightnessIcon } from "@material-ui/icons" +import { useTheme } from "@material-ui/core/styles" import { entryIdFromDate } from "../../utils/days" import { selectEntryNote } from "../../entries" const Entry = ({ date, isPast, isToday, className }) => { + const theme = useTheme() const entryId = entryIdFromDate(date) const editPath = `/calendar/${entryId}/edit` const entryNote = useSelector((state) => selectEntryNote(state, { date })) @@ -19,13 +21,10 @@ const Entry = ({ date, isPast, isToday, className }) => { return ( {entryNote ? ( - {entryNote} - ) : ( - - - Add note - - )} + + + + ) : null} ) } From 18627cc7634d731b98266d3354bc5a90067dac15 Mon Sep 17 00:00:00 2001 From: Sara Vieira Date: Wed, 9 Jun 2021 23:56:09 +0200 Subject: [PATCH 11/11] make one per hashtag --- src/features/timeline/Calendar/Entry.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/features/timeline/Calendar/Entry.js b/src/features/timeline/Calendar/Entry.js index be55f60b..e5d4af7f 100644 --- a/src/features/timeline/Calendar/Entry.js +++ b/src/features/timeline/Calendar/Entry.js @@ -20,11 +20,15 @@ const Entry = ({ date, isPast, isToday, className }) => { return ( - {entryNote ? ( - - - - ) : null} + {entryNote + ? entryNote.split(" ").map((note) => ( + + + + )) + : null} ) }