Skip to content

Commit

Permalink
feat(occurrences): migrate context to zustand store (#116)
Browse files Browse the repository at this point in the history
  • Loading branch information
domhhv authored Oct 24, 2024
1 parent e7f94e9 commit 25f7886
Show file tree
Hide file tree
Showing 27 changed files with 442 additions and 518 deletions.
23 changes: 9 additions & 14 deletions src/components/App.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
import { generateCalendarRange } from '@helpers';
import { getWeeksInMonth } from '@internationalized/date';
import { act, render } from '@testing-library/react';
import React from 'react';
import { useCalendar } from 'react-aria';
import { useCalendarState } from 'react-stately';

import App from './App';

jest.mock('react-aria', () => ({
useLocale: jest.fn(),
useCalendar: jest.fn(),
Expand Down Expand Up @@ -30,20 +39,6 @@ jest.mock('react-aria', () => ({
I18nProvider: jest.fn().mockImplementation(({ children }) => children),
}));

jest.mock('@context', () => ({
HabitsProvider: jest.fn().mockImplementation(({ children }) => children),
OccurrencesProvider: jest.fn().mockImplementation(({ children }) => children),
}));

import { generateCalendarRange } from '@helpers';
import { getWeeksInMonth } from '@internationalized/date';
import { act, render } from '@testing-library/react';
import React from 'react';
import { useCalendar } from 'react-aria';
import { useCalendarState } from 'react-stately';

import App from './App';

Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
Expand Down
7 changes: 1 addition & 6 deletions src/components/Providers.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { OccurrencesProvider } from '@context';
import { supabaseClient } from '@helpers';
import { NextUIProvider } from '@nextui-org/react';
import { SessionContextProvider } from '@supabase/auth-helpers-react';
Expand All @@ -13,11 +12,7 @@ type ProviderProps = {
const LowerProviders = ({ children }: ProviderProps) => {
const navigate = useNavigate();

return (
<NextUIProvider navigate={navigate}>
<OccurrencesProvider>{children}</OccurrencesProvider>
</NextUIProvider>
);
return <NextUIProvider navigate={navigate}>{children}</NextUIProvider>;
};

const PotentialSupabaseProvider = ({ children }: { children: ReactNode }) => {
Expand Down
4 changes: 2 additions & 2 deletions src/components/calendar/Calendar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useOccurrences } from '@context';
import { generateCalendarRange } from '@helpers';
import { useDocumentTitle } from '@hooks';
import { CalendarDate, GregorianCalendar } from '@internationalized/date';
import { useOccurrencesStore } from '@stores';
import { capitalizeFirstLetter } from '@utils';
import React from 'react';
import { type AriaButtonProps, useCalendar, useLocale } from 'react-aria';
Expand All @@ -20,7 +20,7 @@ const createCalendar = (identifier: string) => {
};

const Calendar = () => {
const { onRangeChange } = useOccurrences();
const { onRangeChange } = useOccurrencesStore();
const { locale } = useLocale();
const state = useCalendarState({
locale,
Expand Down
4 changes: 2 additions & 2 deletions src/components/calendar/CalendarCell.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useOccurrences } from '@context';
import { useScreenSize } from '@hooks';
import { CalendarBlank } from '@phosphor-icons/react';
import { useOccurrencesStore } from '@stores';
import { useUser } from '@supabase/auth-helpers-react';
import clsx from 'clsx';
import { format } from 'date-fns';
Expand Down Expand Up @@ -31,7 +31,7 @@ const CalendarCell = ({
const cellRef = React.useRef<HTMLDivElement>(null);
const user = useUser();
const { removeOccurrence, fetchingOccurrences, occurrencesByDate } =
useOccurrences();
useOccurrencesStore();
const today = new Date();
const isToday =
today.getDate() === dateNumber &&
Expand Down
39 changes: 11 additions & 28 deletions src/components/calendar/CalendarHeader.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { OccurrencesProvider } from '@context';
import { render } from '@testing-library/react';
import React from 'react';

Expand All @@ -24,54 +23,38 @@ describe(CalendarHeader.name, () => {
};

it.skip('should render month and year', () => {
const { getByText } = render(
<OccurrencesProvider>
<CalendarHeader {...props} />
</OccurrencesProvider>
);
const { getByText } = render(<CalendarHeader {...props} />);
expect(getByText('January 2022')).toBeInTheDocument();
});

it.skip('should disable previous button', () => {
const { getByRole } = render(
<OccurrencesProvider>
<CalendarHeader
{...props}
prevButtonProps={{ ...props.prevButtonProps, disabled: true }}
/>
</OccurrencesProvider>
<CalendarHeader
{...props}
prevButtonProps={{ ...props.prevButtonProps, disabled: true }}
/>
);
expect(getByRole('navigate-back')).toBeDisabled();
});

it.skip('should disable next button', () => {
const { getByRole } = render(
<OccurrencesProvider>
<CalendarHeader
{...props}
nextButtonProps={{ ...props.nextButtonProps, disabled: true }}
/>
</OccurrencesProvider>
<CalendarHeader
{...props}
nextButtonProps={{ ...props.nextButtonProps, disabled: true }}
/>
);
expect(getByRole('navigate-forward')).toBeDisabled();
});

it.skip('should call onNavigateBack', () => {
const { getByRole } = render(
<OccurrencesProvider>
<CalendarHeader {...props} />
</OccurrencesProvider>
);
const { getByRole } = render(<CalendarHeader {...props} />);
getByRole('navigate-back').click();
expect(props.onNavigateBack).toHaveBeenCalled();
});

it.skip('should call onNavigateForward', () => {
const { getByRole } = render(
<OccurrencesProvider>
<CalendarHeader {...props} />
</OccurrencesProvider>
);
const { getByRole } = render(<CalendarHeader {...props} />);
getByRole('navigate-forward').click();
expect(props.onNavigateForward).toHaveBeenCalled();
});
Expand Down
5 changes: 2 additions & 3 deletions src/components/calendar/CalendarHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { useOccurrences } from '@context';
import { useScreenSize } from '@hooks';
import { Select, SelectItem, Button } from '@nextui-org/react';
import { ArrowFatLeft, ArrowFatRight } from '@phosphor-icons/react';
import { useTraitsStore, useHabitsStore } from '@stores';
import { useTraitsStore, useHabitsStore, useOccurrencesStore } from '@stores';
import { useUser } from '@supabase/auth-helpers-react';
import React from 'react';

Expand Down Expand Up @@ -53,7 +52,7 @@ const CalendarHeader = ({
}: CalendarHeaderProps) => {
const { habits } = useHabitsStore();
const { traits } = useTraitsStore();
const { filteredBy, filterBy } = useOccurrences();
const { filteredBy, filterBy } = useOccurrencesStore();
const user = useUser();
const screenSize = useScreenSize();

Expand Down
29 changes: 12 additions & 17 deletions src/components/calendar/DayHabitModalDialog.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useOccurrences } from '@context';
import { useHabitsStore } from '@stores';
import { useHabitsStore, useOccurrencesStore } from '@stores';
import { useUser } from '@supabase/auth-helpers-react';
import { fireEvent, render, waitFor } from '@testing-library/react';
import { makeTestHabit } from '@tests';
Expand All @@ -8,13 +7,9 @@ import React from 'react';

import DayHabitModalDialog from './DayHabitModalDialog';

jest.mock('@context', () => ({
useOccurrences: jest.fn(),
useSnackbar: jest.fn().mockReturnValue({ showSnackbar: jest.fn() }),
}));

jest.mock('@stores', () => ({
useHabitsStore: jest.fn(),
useOccurrencesStore: jest.fn(),
}));

jest.mock('@supabase/auth-helpers-react', () => ({
Expand Down Expand Up @@ -43,7 +38,7 @@ describe(DayHabitModalDialog.name, () => {
(useHabitsStore as unknown as jest.Mock).mockReturnValue({ habits: [] });
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useOccurrences as jest.Mock).mockReturnValue({
(useOccurrencesStore as unknown as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
});
Expand All @@ -55,7 +50,7 @@ describe(DayHabitModalDialog.name, () => {
(useHabitsStore as unknown as jest.Mock).mockReturnValue({ habits: [] });
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useOccurrences as jest.Mock).mockReturnValue({
(useOccurrencesStore as unknown as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
});
Expand All @@ -69,7 +64,7 @@ describe(DayHabitModalDialog.name, () => {
(useHabitsStore as unknown as jest.Mock).mockReturnValue({ habits: [] });
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useOccurrences as jest.Mock).mockReturnValue({
(useOccurrencesStore as unknown as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
});
Expand All @@ -83,7 +78,7 @@ describe(DayHabitModalDialog.name, () => {
(useHabitsStore as unknown as jest.Mock).mockReturnValue({ habits: [] });
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useOccurrences as jest.Mock).mockReturnValue({
(useOccurrencesStore as unknown as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
});
Expand All @@ -97,7 +92,7 @@ describe(DayHabitModalDialog.name, () => {
(useHabitsStore as unknown as jest.Mock).mockReturnValue({ habits: [] });
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useOccurrences as jest.Mock).mockReturnValue({
(useOccurrencesStore as unknown as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
});
Expand All @@ -111,7 +106,7 @@ describe(DayHabitModalDialog.name, () => {
});
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useOccurrences as jest.Mock).mockReturnValue({
(useOccurrencesStore as unknown as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
});
Expand All @@ -125,7 +120,7 @@ describe(DayHabitModalDialog.name, () => {
});
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useOccurrences as jest.Mock).mockReturnValue({
(useOccurrencesStore as unknown as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
});
Expand All @@ -146,7 +141,7 @@ describe(DayHabitModalDialog.name, () => {
});
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useOccurrences as jest.Mock).mockReturnValue({
(useOccurrencesStore as unknown as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
});
Expand All @@ -161,7 +156,7 @@ describe(DayHabitModalDialog.name, () => {
});
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useOccurrences as jest.Mock).mockReturnValue({
(useOccurrencesStore as unknown as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
});
Expand All @@ -184,7 +179,7 @@ describe(DayHabitModalDialog.name, () => {
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue(date.toISOString().split('T')[0]);
const mockAddOccurrence = jest.fn();
(useOccurrences as jest.Mock).mockReturnValue({
(useOccurrencesStore as unknown as jest.Mock).mockReturnValue({
addOccurrence: mockAddOccurrence,
addingOccurrence: false,
});
Expand Down
5 changes: 2 additions & 3 deletions src/components/calendar/DayHabitModalDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useOccurrences } from '@context';
import {
Button,
Modal,
Expand All @@ -9,7 +8,7 @@ import {
Select,
SelectItem,
} from '@nextui-org/react';
import { useHabitsStore } from '@stores';
import { useHabitsStore, useOccurrencesStore } from '@stores';
import { useUser } from '@supabase/auth-helpers-react';
import { format } from 'date-fns';
import React, { type MouseEventHandler } from 'react';
Expand All @@ -27,7 +26,7 @@ const DayHabitModalDialog = ({
}: DayHabitModalDialogProps) => {
const { habits } = useHabitsStore();
const user = useUser();
const { addOccurrence, addingOccurrence } = useOccurrences();
const { addOccurrence, addingOccurrence } = useOccurrencesStore();
const [selectedHabitIds, setSelectedHabitIds] = React.useState<string[]>([]);

if (!date || !open) {
Expand Down
14 changes: 7 additions & 7 deletions src/components/calendar/OccurrenceChip.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useOccurrences } from '@context';
import { useScreenSize } from '@hooks';
import { useOccurrencesStore } from '@stores';
import { render, waitFor } from '@testing-library/react';
import { makeTestOccurrence } from '@tests';
import { getHabitIconUrl } from '@utils';
Expand All @@ -11,8 +11,8 @@ jest.mock('@hooks', () => ({
useScreenSize: jest.fn(),
}));

jest.mock('@context', () => ({
useOccurrences: jest.fn(),
jest.mock('@stores', () => ({
useOccurrencesStore: jest.fn(),
}));

describe(OccurrenceChip.name, () => {
Expand All @@ -23,7 +23,7 @@ describe(OccurrenceChip.name, () => {
};

it('should render img with habit icon', async () => {
(useOccurrences as jest.Mock).mockReturnValue({
(useOccurrencesStore as unknown as jest.Mock).mockReturnValue({
occurrenceIdBeingDeleted: null,
});
const { getByAltText } = render(<OccurrenceChip {...props} />);
Expand All @@ -38,7 +38,7 @@ describe(OccurrenceChip.name, () => {
});

it('should call onDelete when delete button is clicked', () => {
(useOccurrences as jest.Mock).mockReturnValue({
(useOccurrencesStore as unknown as jest.Mock).mockReturnValue({
occurrenceIdBeingDeleted: null,
});
const { getByRole } = render(<OccurrenceChip {...props} />);
Expand All @@ -48,7 +48,7 @@ describe(OccurrenceChip.name, () => {
});

it('should render CircularProgress when occurrence is being deleted', () => {
(useOccurrences as jest.Mock).mockReturnValue({
(useOccurrencesStore as unknown as jest.Mock).mockReturnValue({
occurrenceIdBeingDeleted: 1,
});
const { getByRole, queryByRole } = render(<OccurrenceChip {...props} />);
Expand All @@ -59,7 +59,7 @@ describe(OccurrenceChip.name, () => {
});

it('should not render delete button on small screens', () => {
(useOccurrences as jest.Mock).mockReturnValue({
(useOccurrencesStore as unknown as jest.Mock).mockReturnValue({
occurrenceIdBeingDeleted: null,
});
(useScreenSize as jest.Mock).mockReturnValue(1024);
Expand Down
4 changes: 2 additions & 2 deletions src/components/calendar/OccurrenceChip.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useOccurrences } from '@context';
import { useScreenSize } from '@hooks';
import type { Occurrence } from '@models';
import { Spinner, Chip, Button, Tooltip, Badge } from '@nextui-org/react';
import { X } from '@phosphor-icons/react';
import { useOccurrencesStore } from '@stores';
import { getHabitIconUrl } from '@utils';
import React from 'react';

Expand All @@ -20,7 +20,7 @@ const OccurrenceChip = ({
onDelete,
colorOverride,
}: OccurrenceChipProps) => {
const { occurrenceIdBeingDeleted } = useOccurrences();
const { occurrenceIdBeingDeleted } = useOccurrencesStore();
const [{ id, habit }] = occurrences;
const { name: habitName, iconPath, trait } = habit || {};
const { color: traitColor } = trait || {};
Expand Down
4 changes: 0 additions & 4 deletions src/components/habit/add-habit/AddHabitDialogButton.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ import React from 'react';

import AddHabitDialogButton from './AddHabitDialogButton';

jest.mock('@context', () => ({
useSnackbar: jest.fn().mockReturnValue({ showSnackbar: jest.fn() }),
}));

jest.mock('@stores', () => ({
useSnackbarsStore: jest.fn(),
useHabitsStore: jest.fn(),
Expand Down
Loading

0 comments on commit 25f7886

Please sign in to comment.