Skip to content

Commit a0cdd90

Browse files
committed
fix: relative dates in task builder, overdue tasks UI hint + more UI improvs
1 parent 0f7bf75 commit a0cdd90

File tree

7 files changed

+75
-32
lines changed

7 files changed

+75
-32
lines changed

apps/desktop-v2/app/page.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,8 @@ import * as Accordion from "@radix-ui/react-accordion";
1919
import React from "react";
2020

2121
function Home() {
22-
// get today's date in this format: Tue, 26th Aug
23-
const today = new Date().toLocaleDateString("en-GB", {
24-
weekday: "short",
25-
day: "numeric",
26-
month: "short",
27-
});
2822
const {
23+
today,
2924
accordionValue,
3025
setAccordionValue,
3126
taskFetchState,

apps/desktop-v2/components/icons.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export const clockCyanPath = "/icons/clock-cyan.svg";
6060
export const ClockCyanIcon = (props: ImageProps) => (
6161
<Image
6262
src={clockCyanPath}
63-
alt="Play green icon"
63+
alt="Clock icon"
6464
width={13}
6565
height={13}
6666
className="ml-[2px]"

apps/desktop-v2/components/supernova-task.tsx

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,30 +57,32 @@ export const SupernovaTaskComponent = (props: {
5757
}}
5858
/>
5959
</div>
60-
<div className="grow shrink basis-0 flex-col justify-start items-start gap-2.5 inline-flex">
60+
<div className="grow shrink basis-0 flex flex-col justify-start items-start gap-2.5">
6161
<div className="self-stretch justify-start items-center inline-flex">
62-
<div className="grow shrink basis-0 text-black text-base font-medium leading-[14px]">
62+
<p className="grow shrink basis-0 text-black text-base font-medium leading-[14px]">
6363
{props.task.title}
64-
</div>
65-
<div className="self-stretch justify-start items-center inline-flex gap-1">
66-
{props.task.startTime && (
67-
<StartTimeWidget startTime={props.task.startTime} />
68-
)}
69-
<DurationWidget
70-
expectedDurationSeconds={props.task.expectedDurationSeconds}
71-
/>
72-
</div>
64+
</p>
7365
</div>
7466
{props.task.description && (
7567
<div className="w-full justify-start items-center gap-0.5 inline-flex">
7668
<div className="w-3 h-3 relative">
7769
<ArrowRightIcon />
7870
</div>
79-
<div className="grow shrink basis-0 text-slate-400 text-[10px] font-medium leading-[10px]">
71+
<p className="grow shrink basis-0 text-slate-400 text-[10px] font-medium leading-[10px]">
8072
{props.task.description}
81-
</div>
73+
</p>
8274
</div>
8375
)}
76+
<div className="self-stretch justify-start items-center inline-flex gap-1">
77+
{props.task.startTime && (
78+
<StartTimeWidget startTime={props.task.startTime} />
79+
)}
80+
{props.task.expectedDurationSeconds && (
81+
<DurationWidget
82+
expectedDurationSeconds={props.task.expectedDurationSeconds}
83+
/>
84+
)}
85+
</div>
8486
</div>
8587
</div>
8688
);
@@ -114,10 +116,28 @@ export const DurationWidget = (props: { expectedDurationSeconds?: number }) => {
114116

115117
export const StartTimeWidget = (props: { startTime: Date }) => {
116118
// get the start time date
117-
const isToday = moment(props.startTime).isSame(moment(), "day");
119+
console.log(props.startTime);
120+
const dateDiffFromToday = moment(props.startTime).diff(moment(), "days");
121+
const isOverdue = dateDiffFromToday < 0;
122+
const isToday = dateDiffFromToday === 0;
123+
const lastDayOfWeek = moment().endOf("isoWeek");
124+
const lastDayOfNextWeek = moment().add(1, "week").endOf("isoWeek");
125+
const isThisWeek = moment(props.startTime).isBefore(lastDayOfWeek);
126+
const isNextWeek =
127+
moment(props.startTime).isAfter(lastDayOfWeek) &&
128+
moment(props.startTime).isBefore(lastDayOfNextWeek);
129+
const isTmrw = dateDiffFromToday === 1;
118130
const dateSection = isToday
119131
? ""
120-
: moment(props.startTime).format("dddd DD MMM");
132+
: isOverdue
133+
? moment(props.startTime).fromNow()
134+
: isTmrw
135+
? "Tomorrow"
136+
: isThisWeek
137+
? moment(props.startTime).format("dddd")
138+
: isNextWeek
139+
? "Next " + moment(props.startTime).format("dddd")
140+
: moment(props.startTime).format("MMM D");
121141

122142
return (
123143
<div className="px-[5px] rounded-[5px] justify-center items-center gap-1 inline-flex">
@@ -127,7 +147,11 @@ export const StartTimeWidget = (props: { startTime: Date }) => {
127147
height={12}
128148
alt="Cyan clock"
129149
/>
130-
<p className="text-center text-xs font-normal text-cyan-600">
150+
<p
151+
className={`text-center text-xs font-normal ${
152+
isOverdue ? "text-red-600" : "text-cyan-600"
153+
}`}
154+
>
131155
{dateSection} {moment(props.startTime).format("h:mma")}
132156
</p>
133157
</div>

apps/desktop-v2/components/task-builder-dialog.tsx

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,18 @@ export const TaskBuilderDialog = (props: {
9595
}
9696
// extract the start at time if any
9797
const extractedStartAt = extractStartAt(newTitle);
98-
let startTime: Date | undefined = undefined;
98+
let startTime: Date | undefined = props.editingTask.startTime;
9999
if (extractedStartAt !== null) {
100-
startTime = extractedStartAt.value;
100+
// set only the interdate part
101+
startTime?.setHours(extractedStartAt.value.getHours());
102+
startTime?.setMinutes(extractedStartAt.value.getMinutes());
101103
newTitle =
102104
newTitle.slice(0, extractedStartAt.match.index) +
103105
newTitle.slice(
104106
extractedStartAt.match.index + extractedStartAt.match[0].length
105107
);
106108
}
109+
107110
// extract the date if any
108111
const extractedDate = extractDate(newTitle);
109112
let date: Date | undefined = undefined;
@@ -118,6 +121,8 @@ export const TaskBuilderDialog = (props: {
118121
// modify the actual start time with the date
119122
if (date !== undefined && startTime !== undefined) {
120123
startTime.setDate(date.getDate());
124+
startTime.setMonth(date.getMonth());
125+
startTime.setFullYear(date.getFullYear());
121126
}
122127

123128
// update the task edit
@@ -149,7 +154,20 @@ export const TaskBuilderDialog = (props: {
149154
if (e.key === "Enter") {
150155
e.preventDefault(); // prevent newlines into the task builder
151156
e.stopPropagation(); // so that it doesn't bubble up to the page
152-
// submit instead
157+
// before submitting remove the date part from the original build text because
158+
// we don't want it to be parsed the next time the person opens this task
159+
// in the task builder, else would be confusing
160+
const extractedDate = extractDate(taskEdit.originalBuildText);
161+
let originalBuildText = taskEdit.originalBuildText;
162+
if (extractedDate !== null) {
163+
originalBuildText =
164+
originalBuildText.slice(0, extractedDate.match.index) +
165+
originalBuildText.slice(
166+
extractedDate.match.index + extractedDate.match[0].length
167+
);
168+
}
169+
taskEdit.originalBuildText = originalBuildText;
170+
// submit the edit/create
153171
handleSubmit();
154172
}
155173
if (e.key === "Escape") {
@@ -246,7 +264,7 @@ export const TaskBuilderDialog = (props: {
246264
</Slate>
247265
<div className="flex items-center justify-between">
248266
<div className="flex items-center gap-2 flex-wrap">
249-
{taskEdit.expectedDurationSeconds !== undefined && (
267+
{taskEdit.expectedDurationSeconds && (
250268
<DurationWidget
251269
expectedDurationSeconds={
252270
taskEdit.expectedDurationSeconds

apps/desktop-v2/hooks/useSupernovaTasksUI.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ import { reorderTaskList } from "@/utils/supernova-task";
1313

1414
export default function useSupernovaTasksUI() {
1515
const router = useRouter();
16+
// get today's date in this format: Tue, 26th Aug
17+
const today = new Date().toLocaleDateString("en-GB", {
18+
weekday: "short",
19+
day: "numeric",
20+
month: "short",
21+
});
22+
1623
const [chosenTaskIndex, setChosenTaskIndex] = useAtom(chosenTaskIndexGlobal);
1724
const [tasks, setTasks] = useState<ISupernovaTask[]>([]);
1825
const [taskFetchState, setTaskFetchState] = useState<{
@@ -426,5 +433,6 @@ export default function useSupernovaTasksUI() {
426433
doneAccordionOpened,
427434
undoneTasks,
428435
doneTasks,
436+
today,
429437
};
430438
}

apps/desktop-v2/services/local-db.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ export namespace LocalDB {
4444
};
4545

4646
export const insertTask = async (db: Database, task: ISupernovaTask) => {
47-
console.log(task);
48-
4947
await db.execute(
5048
`
5149
INSERT INTO supernova_tasks (id, originalBuildText, title, description, expectedDurationSeconds, isComplete, startTime)

apps/desktop-v2/utils/supernova-task.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,18 +116,18 @@ export function extractDate(
116116
if (match === null) {
117117
return null;
118118
}
119-
const date = new Date();
119+
let date = new Date();
120120
switch (match[0]) {
121121
case "tomorrow":
122122
case "tmr":
123123
case "tom":
124-
date.setDate(date.getDate() + 1);
124+
date = moment(date).add(1, "day").toDate();
125125
break;
126126
case "today":
127127
date.setDate(date.getDate());
128128
break;
129129
case "next week":
130-
date.setDate(date.getDate() + 7);
130+
date = moment(date).add(1, "week").toDate();
131131
break;
132132
default:
133133
const days = parseInt(match[1]);

0 commit comments

Comments
 (0)