Skip to content

Commit 99926f8

Browse files
committed
refactor(web): modularize RecurrenceSection children
1 parent 84a7620 commit 99926f8

File tree

8 files changed

+99
-75
lines changed

8 files changed

+99
-75
lines changed

packages/web/src/views/Forms/EventForm/DateControlsSection/RecurrenceSection/RecurrenceSection.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {
2929
FREQUENCY_OPTIONS,
3030
FrequencyValues,
3131
WEEKDAYS,
32-
} from "./util/recurrence.constants";
32+
} from "./constants/recurrence.constants";
3333

3434
export interface RecurrenceSectionProps {
3535
bgColor: string;

packages/web/src/views/Forms/EventForm/DateControlsSection/RecurrenceSection/SomedayRecurrenceSection/SomedayRecurrenceSection.tsx

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
1-
import React, { Dispatch, SetStateAction, useEffect } from "react";
2-
import { Frequency } from "rrule";
1+
import React, { Dispatch, SetStateAction } from "react";
32
import { Schema_Event } from "@core/types/event.types";
43
import { StyledRepeatRow } from "@web/views/Forms/EventForm/DateControlsSection/RecurrenceSection/styled";
5-
import { FrequencyValues } from "@web/views/Forms/EventForm/DateControlsSection/RecurrenceSection/util/recurrence.util";
64
import { useRecurrence } from "../useRecurrence/useRecurrence";
75
import { SomedayRecurrenceSelect } from "./SomedayRecurrenceSelect/SomedayRecurrenceSelect";
8-
9-
export type SomedayFrequencyOption = {
10-
label: string;
11-
value: FrequencyValues;
12-
};
6+
import { SomedayFrequencyOption } from "./SomedayRecurrenceSelect/SomedayRecurrenceSelect";
137

148
export interface SomedayRecurrenceSectionProps {
159
bgColor: string;
@@ -23,15 +17,7 @@ export const SomedayRecurrenceSection = ({
2317
setEvent,
2418
}: SomedayRecurrenceSectionProps) => {
2519
const recurrenceHook = useRecurrence(event, { setEvent });
26-
const { freq, setFreq, toggleRecurrence } = recurrenceHook;
27-
const { hasRecurrence } = recurrenceHook;
28-
29-
// Set default frequency to Weekly for someday events if it's Daily
30-
useEffect(() => {
31-
if (hasRecurrence && freq === Frequency.DAILY) {
32-
setFreq(Frequency.WEEKLY);
33-
}
34-
}, [hasRecurrence, freq, setFreq]);
20+
const { freq, hasRecurrence, setFreq, toggleRecurrence } = recurrenceHook;
3521

3622
const handleSelect = (option: SomedayFrequencyOption | null) => {
3723
if (!option) {

packages/web/src/views/Forms/EventForm/DateControlsSection/RecurrenceSection/SomedayRecurrenceSection/SomedayRecurrenceSelect/SomedayRecurrenceSelect.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,14 @@ import { useTheme } from "styled-components";
1111
import { brighten, darken } from "@core/util/color.utils";
1212
import { theme } from "@web/common/styles/theme";
1313
import { RepeatIcon } from "@web/components/Icons/Repeat";
14-
import { FrequencyValues } from "../../util/recurrence.constants";
15-
import { SomedayFrequencyOption } from "../SomedayRecurrenceSection";
14+
import { FrequencyValues } from "../../constants/recurrence.constants";
1615
import { SelectContent } from "./styled";
1716

17+
export type SomedayFrequencyOption = {
18+
label: string;
19+
value: FrequencyValues;
20+
};
21+
1822
const SOMEDAY_FREQUENCY_OPTIONS: SomedayFrequencyOption[] = [
1923
{ label: "Week", value: Frequency.WEEKLY },
2024
{ label: "Month", value: Frequency.MONTHLY },
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Frequency } from "rrule";
2+
import {
3+
FREQUENCY_MAP,
4+
FREQUENCY_OPTIONS,
5+
WEEKDAYS,
6+
} from "./recurrence.constants";
7+
8+
describe("RecurrenceSection utils", () => {
9+
it("FREQUENCY_MAP returns correct labels", () => {
10+
expect(FREQUENCY_MAP[Frequency.DAILY]).toBe("Day");
11+
expect(FREQUENCY_MAP[Frequency.WEEKLY]).toBe("Week");
12+
expect(FREQUENCY_MAP[Frequency.MONTHLY]).toBe("Month");
13+
expect(FREQUENCY_MAP[Frequency.YEARLY]).toBe("Year");
14+
});
15+
16+
it("FREQUENCY_OPTIONS returns correct options", () => {
17+
const opts = FREQUENCY_OPTIONS("s");
18+
expect(opts).toEqual(
19+
expect.arrayContaining([
20+
{ label: "Years", value: Frequency.YEARLY },
21+
{ label: "Months", value: Frequency.MONTHLY },
22+
{ label: "Weeks", value: Frequency.WEEKLY },
23+
{ label: "Days", value: Frequency.DAILY },
24+
]),
25+
);
26+
});
27+
28+
it("WEEKDAYS contains all days", () => {
29+
expect(WEEKDAYS).toEqual([
30+
"sunday",
31+
"monday",
32+
"tuesday",
33+
"wednesday",
34+
"thursday",
35+
"friday",
36+
"saturday",
37+
]);
38+
expect(WEEKDAYS).toHaveLength(7);
39+
});
40+
});

packages/web/src/views/Forms/EventForm/DateControlsSection/RecurrenceSection/util/recurrence.constants.ts renamed to packages/web/src/views/Forms/EventForm/DateControlsSection/RecurrenceSection/constants/recurrence.constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export const WEEKDAYS: Array<keyof typeof WEEKDAY_RRULE_MAP> = [
2727
"friday",
2828
"saturday",
2929
];
30+
3031
export const WEEKDAY_RRULE_MAP = {
3132
monday: RRule.MO,
3233
tuesday: RRule.TU,

packages/web/src/views/Forms/EventForm/DateControlsSection/RecurrenceSection/useRecurrence/useRecurrence.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ import {
1717
FrequencyValues,
1818
WEEKDAYS,
1919
WEEKDAY_RRULE_MAP,
20-
toWeekDays,
21-
} from "../util/recurrence.util";
20+
} from "../constants/recurrence.constants";
21+
import { toWeekDays } from "../util/recurrence.util";
2222

2323
const WEEKDAY_LABELS_MAP: Record<keyof typeof WEEKDAY_RRULE_MAP, string> = {
2424
sunday: RRule.SU.toString(),
@@ -56,6 +56,7 @@ const WEEKDAY_MAP: Record<
5656
}),
5757
{},
5858
);
59+
5960
export const useRecurrence = (
6061
event: Pick<Schema_Event, "startDate" | "endDate" | "recurrence">,
6162
{ setEvent }: { setEvent: Dispatch<SetStateAction<Schema_Event | null>> },
Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,48 @@
1-
import { Frequency } from "rrule";
2-
import {
3-
FREQUENCY_MAP,
4-
FREQUENCY_OPTIONS,
5-
WEEKDAYS,
6-
} from "./recurrence.constants";
1+
import { RRule } from "rrule";
2+
import { WEEKDAYS } from "../constants/recurrence.constants";
3+
import { toWeekDays } from "./recurrence.util";
74

8-
describe("RecurrenceSection utils", () => {
9-
it("FREQUENCY_MAP returns correct labels", () => {
10-
expect(FREQUENCY_MAP[Frequency.DAILY]).toBe("Day");
11-
expect(FREQUENCY_MAP[Frequency.WEEKLY]).toBe("Week");
12-
expect(FREQUENCY_MAP[Frequency.MONTHLY]).toBe("Month");
13-
expect(FREQUENCY_MAP[Frequency.YEARLY]).toBe("Year");
14-
});
5+
describe("recurrence.util", () => {
6+
describe("toWeekDays", () => {
7+
it("should convert all weekdays to their corresponding RRule values", () => {
8+
const result = toWeekDays(WEEKDAYS);
9+
const expected = [
10+
RRule.SU, // sunday
11+
RRule.MO, // monday
12+
RRule.TU, // tuesday
13+
RRule.WE, // wednesday
14+
RRule.TH, // thursday
15+
RRule.FR, // friday
16+
RRule.SA, // saturday
17+
];
18+
expect(result).toEqual(expected);
19+
});
1520

16-
it("FREQUENCY_OPTIONS returns correct options", () => {
17-
const opts = FREQUENCY_OPTIONS("s");
18-
expect(opts).toEqual(
19-
expect.arrayContaining([
20-
{ label: "Years", value: Frequency.YEARLY },
21-
{ label: "Months", value: Frequency.MONTHLY },
22-
{ label: "Weeks", value: Frequency.WEEKLY },
23-
{ label: "Days", value: Frequency.DAILY },
24-
]),
25-
);
26-
});
21+
it("should convert a single weekday", () => {
22+
const result = toWeekDays(["monday"]);
23+
expect(result).toEqual([RRule.MO]);
24+
});
25+
26+
it("should convert multiple weekdays", () => {
27+
const result = toWeekDays(["monday", "wednesday", "friday"]);
28+
expect(result).toEqual([RRule.MO, RRule.WE, RRule.FR]);
29+
});
30+
31+
it("should handle empty array", () => {
32+
const result = toWeekDays([]);
33+
expect(result).toEqual([]);
34+
});
35+
36+
it("should preserve order of input weekdays", () => {
37+
const input = ["friday", "monday", "sunday", "thursday"];
38+
const result = toWeekDays(input as (typeof WEEKDAYS)[0][]);
39+
const expected = [RRule.FR, RRule.MO, RRule.SU, RRule.TH];
40+
expect(result).toEqual(expected);
41+
});
2742

28-
it("WEEKDAYS contains all days", () => {
29-
expect(WEEKDAYS).toEqual([
30-
"sunday",
31-
"monday",
32-
"tuesday",
33-
"wednesday",
34-
"thursday",
35-
"friday",
36-
"saturday",
37-
]);
38-
expect(WEEKDAYS).toHaveLength(7);
43+
it("should handle duplicate weekdays", () => {
44+
const result = toWeekDays(["monday", "monday", "tuesday"]);
45+
expect(result).toEqual([RRule.MO, RRule.MO, RRule.TU]);
46+
});
3947
});
4048
});

packages/web/src/views/Forms/EventForm/DateControlsSection/RecurrenceSection/util/recurrence.util.ts

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,7 @@
11
import { Weekday } from "rrule";
2-
import { Dayjs } from "@core/util/date/dayjs";
3-
import { WEEKDAYS, WEEKDAY_RRULE_MAP } from "./recurrence.constants";
2+
import { WEEKDAYS, WEEKDAY_RRULE_MAP } from "../constants/recurrence.constants";
43

5-
export const getDefaultWeekDay = (startDate: Dayjs): (typeof WEEKDAYS)[0] => {
6-
const dayOfWeek = startDate.format("dddd").toLowerCase();
7-
const day = WEEKDAYS.find((day) => dayOfWeek === day);
8-
9-
if (!day) {
10-
console.error(
11-
"No default week day found. Something went wrong. Please investigate",
12-
);
13-
14-
return "sunday";
15-
}
16-
17-
return day;
18-
};
19-
20-
export function toWeekDay(weekDay: (typeof WEEKDAYS)[0]): Weekday {
4+
function toWeekDay(weekDay: (typeof WEEKDAYS)[0]): Weekday {
215
return WEEKDAY_RRULE_MAP[weekDay];
226
}
237

0 commit comments

Comments
 (0)