Skip to content

Commit

Permalink
refactor: add supabase db types (#106)
Browse files Browse the repository at this point in the history
* refactor: add supabase db types

* Remove console.log call
  • Loading branch information
domhhv authored Oct 20, 2024
1 parent e0efe84 commit 87b1845
Show file tree
Hide file tree
Showing 45 changed files with 1,183 additions and 717 deletions.
3 changes: 0 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
# These are received when running `yarn db:start` or `yarn db:status`
# and are only required for running the local Supabase instance.
# Habitrack UI is still runnable without these values.
SUPABASE_URL=https://<your-supabase-url>.supabase.co
SUPABASE_ANON_KEY=<your-supabase-anon_key>
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="./public/favicon.ico" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
Expand Down Expand Up @@ -47,7 +47,7 @@
<div id="root">
<div class="loader-container">
<img
src="./public/android-chrome-192x192.png"
src="/android-chrome-192x192.png"
alt="Habilify logo"
width="16"
height="16"
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"db:restart": "yarn db:stop && yarn db:start",
"db:diff": "supabase db diff",
"db:migration:up": "supabase migration up",
"db:migration:new": "supabase migration new"
"db:migration:new": "supabase migration new",
"db:gen-types": "supabase gen types --lang=typescript --local > supabase/database.types.ts"
},
"lint-staged": {
"**/*.{ts,tsx}": [
Expand All @@ -72,7 +73,8 @@
"react-router-dom": "^6.22.0",
"react-stately": "^3.32.2",
"sort-by": "^1.2.0",
"tailwind-merge": "^2.5.2"
"tailwind-merge": "^2.5.2",
"type-fest": "^4.26.1"
},
"devDependencies": {
"@babel/core": "^7.23.7",
Expand Down
1 change: 0 additions & 1 deletion src/components/calendar/CalendarCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ const CalendarCell = ({
>
<OccurrenceChip
occurrences={habitOccurrences!}
habitId={+habitId}
onDelete={handleOccurrenceDelete}
/>
</motion.div>
Expand Down
13 changes: 1 addition & 12 deletions src/components/calendar/DayHabitModalDialog.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useHabits, useOccurrences, useTraits } from '@context';
import { useHabits, useOccurrences } from '@context';
import { useUser } from '@supabase/auth-helpers-react';
import { fireEvent, render, waitFor } from '@testing-library/react';
import { makeTestHabit } from '@tests';
Expand All @@ -10,7 +10,6 @@ import DayHabitModalDialog from './DayHabitModalDialog';
jest.mock('@context', () => ({
useOccurrences: jest.fn(),
useHabits: jest.fn(),
useTraits: jest.fn(),
useSnackbar: jest.fn().mockReturnValue({ showSnackbar: jest.fn() }),
}));

Expand Down Expand Up @@ -40,7 +39,6 @@ describe(DayHabitModalDialog.name, () => {
(useHabits as jest.Mock).mockReturnValue({ habits: [] });
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useTraits as jest.Mock).mockReturnValue({ traitsMap: {} });
(useOccurrences as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
Expand All @@ -53,7 +51,6 @@ describe(DayHabitModalDialog.name, () => {
(useHabits as jest.Mock).mockReturnValue({ habits: [] });
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useTraits as jest.Mock).mockReturnValue({ traitsMap: {} });
(useOccurrences as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
Expand All @@ -68,7 +65,6 @@ describe(DayHabitModalDialog.name, () => {
(useHabits as jest.Mock).mockReturnValue({ habits: [] });
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useTraits as jest.Mock).mockReturnValue({ traitsMap: {} });
(useOccurrences as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
Expand All @@ -83,7 +79,6 @@ describe(DayHabitModalDialog.name, () => {
(useHabits as jest.Mock).mockReturnValue({ habits: [] });
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useTraits as jest.Mock).mockReturnValue({ traitsMap: {} });
(useOccurrences as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
Expand All @@ -98,7 +93,6 @@ describe(DayHabitModalDialog.name, () => {
(useHabits as jest.Mock).mockReturnValue({ habits: [] });
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useTraits as jest.Mock).mockReturnValue({ traitsMap: {} });
(useOccurrences as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
Expand All @@ -113,7 +107,6 @@ describe(DayHabitModalDialog.name, () => {
});
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useTraits as jest.Mock).mockReturnValue({ traitsMap: {} });
(useOccurrences as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
Expand All @@ -128,7 +121,6 @@ describe(DayHabitModalDialog.name, () => {
});
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useTraits as jest.Mock).mockReturnValue({ traitsMap: {} });
(useOccurrences as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
Expand All @@ -150,7 +142,6 @@ describe(DayHabitModalDialog.name, () => {
});
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useTraits as jest.Mock).mockReturnValue({ traitsMap: {} });
(useOccurrences as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
Expand All @@ -166,7 +157,6 @@ describe(DayHabitModalDialog.name, () => {
});
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue('2021-01-01');
(useTraits as jest.Mock).mockReturnValue({ traitsMap: {} });
(useOccurrences as jest.Mock).mockReturnValue({
addOccurrence: jest.fn(),
addingOccurrence: false,
Expand All @@ -189,7 +179,6 @@ describe(DayHabitModalDialog.name, () => {
});
(useUser as jest.Mock).mockReturnValue({ id: '1' });
(format as jest.Mock).mockReturnValue(date.toISOString().split('T')[0]);
(useTraits as jest.Mock).mockReturnValue({ traitsMap: {} });
const mockAddOccurrence = jest.fn();
(useOccurrences as jest.Mock).mockReturnValue({
addOccurrence: mockAddOccurrence,
Expand Down
11 changes: 6 additions & 5 deletions src/components/calendar/DayHabitModalDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useOccurrences, useHabits, useTraits, useSnackbar } from '@context';
import { useOccurrences, useHabits, useSnackbar } from '@context';
import {
Button,
Modal,
Expand Down Expand Up @@ -29,7 +29,6 @@ const DayHabitModalDialog = ({
const user = useUser();
const { addOccurrence, addingOccurrence } = useOccurrences();
const [selectedHabitIds, setSelectedHabitIds] = React.useState<string[]>([]);
const { traitsMap } = useTraits();

if (!date || !open) {
return null;
Expand Down Expand Up @@ -100,9 +99,11 @@ const DayHabitModalDialog = ({
textValue={habit.name}
>
<span>{habit.name}</span>
<span className="font-regular ml-2 text-neutral-400">
{traitsMap[habit.traitId]?.name}
</span>
{habit.trait && (
<span className="font-regular ml-2 text-neutral-400">
{habit.trait.name}
</span>
)}
</SelectItem>
))}
</Select>
Expand Down
65 changes: 7 additions & 58 deletions src/components/calendar/OccurrenceChip.test.tsx
Original file line number Diff line number Diff line change
@@ -1,74 +1,43 @@
import { useHabits, useOccurrences } from '@context';
import { useOccurrences } from '@context';
import { useScreenSize } from '@hooks';
import { render, waitFor } from '@testing-library/react';
import { makeTestOccurrence } from '@tests';
import { getHabitIconUrl } from '@utils';
import React from 'react';

import OccurrenceChip, { type OccurrenceChipProps } from './OccurrenceChip';

jest.mock('@hooks', () => ({
useHabitTraitChipColor: jest.fn(),
useScreenSize: jest.fn(),
useHabitIconUrl: jest.fn(),
}));

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

describe(OccurrenceChip.name, () => {
const mockOnDelete = jest.fn();
const props: OccurrenceChipProps = {
occurrences: [
{
id: 1,
createdAt: '2021-01-01T00:00:00Z',
updatedAt: '2021-01-02T00:00:00Z',
timestamp: 1612137600000,
day: '2021-02-01',
time: null,
habitId: 2,
userId: '3',
},
],
habitId: 2,
occurrences: [makeTestOccurrence()],
onDelete: mockOnDelete,
};

it('should render img with habit icon', async () => {
(useHabits as jest.Mock).mockReturnValue({
habitsMap: {
2: {
id: 2,
name: 'Test Habit Name',
iconPath: 'path/to/test/icon',
traitId: 1,
},
},
});
(useOccurrences as jest.Mock).mockReturnValue({
occurrenceIdBeingDeleted: null,
});
const { getByAltText } = render(<OccurrenceChip {...props} />);
const img = getByAltText('Test Habit Name icon');
expect(img).toBeInTheDocument();
await waitFor(() => {
expect(img).toHaveAttribute('src', getHabitIconUrl('path/to/test/icon'));
expect(img).toHaveAttribute(
'src',
getHabitIconUrl('https://i.ibb.co/vvgw7bx/habitrack-logo.png')
);
});
});

it('should call onDelete when delete button is clicked', () => {
(useHabits as jest.Mock).mockReturnValue({
habitsMap: {
2: {
id: 2,
name: 'Test Habit Name',
iconPath: 'path/to/test/icon',
traitId: 1,
},
},
});
(useOccurrences as jest.Mock).mockReturnValue({
occurrenceIdBeingDeleted: null,
});
Expand All @@ -79,16 +48,6 @@ describe(OccurrenceChip.name, () => {
});

it('should render CircularProgress when occurrence is being deleted', () => {
(useHabits as jest.Mock).mockReturnValue({
habitsMap: {
2: {
id: 2,
name: 'Test Habit Name',
iconPath: 'path/to/test/icon',
traitId: 1,
},
},
});
(useOccurrences as jest.Mock).mockReturnValue({
occurrenceIdBeingDeleted: 1,
});
Expand All @@ -100,16 +59,6 @@ describe(OccurrenceChip.name, () => {
});

it('should not render delete button on small screens', () => {
(useHabits as jest.Mock).mockReturnValue({
habitsMap: {
2: {
id: 2,
name: 'Test Habit Name',
iconPath: 'path/to/test/icon',
traitId: 1,
},
},
});
(useOccurrences as jest.Mock).mockReturnValue({
occurrenceIdBeingDeleted: null,
});
Expand Down
26 changes: 10 additions & 16 deletions src/components/calendar/OccurrenceChip.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useHabits, useOccurrences } from '@context';
import { useHabitTraitChipColor, useScreenSize } from '@hooks';
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';
Expand All @@ -8,7 +8,6 @@ import React from 'react';

export type OccurrenceChipProps = {
occurrences: Occurrence[];
habitId: number;
onDelete: (
occurrenceId: number,
clickEvent: React.MouseEvent<HTMLButtonElement>
Expand All @@ -18,29 +17,24 @@ export type OccurrenceChipProps = {

const OccurrenceChip = ({
occurrences,
habitId,
onDelete,
colorOverride,
}: OccurrenceChipProps) => {
const { habitsMap } = useHabits();
const { occurrenceIdBeingDeleted } = useOccurrences();
const occurrenceHabit = habitsMap[habitId] || {};
const traitChipColor = useHabitTraitChipColor(occurrenceHabit.traitId);
const [{ id, habit }] = occurrences;
const { name: habitName, iconPath, trait } = habit || {};
const { color: traitColor } = trait || {};
const screenSize = useScreenSize();
const iconUrl = getHabitIconUrl(occurrenceHabit.iconPath);
const iconUrl = getHabitIconUrl(iconPath);

const isBeingDeleted = occurrenceIdBeingDeleted === occurrences[0].id;
const isBeingDeleted = occurrenceIdBeingDeleted === id;

const chipStyle = {
backgroundColor: colorOverride || traitChipColor,
backgroundColor: colorOverride || traitColor,
};

const startContent = (
<img
src={iconUrl}
alt={`${occurrenceHabit.name} icon`}
className="h-4 w-4 rounded"
/>
<img src={iconUrl} alt={`${habitName} icon`} className="h-4 w-4 rounded" />
);

const getEndContent = () => {
Expand Down Expand Up @@ -99,7 +93,7 @@ const OccurrenceChip = ({
};

return (
<Tooltip isDisabled={!occurrenceHabit.name} content={occurrenceHabit.name}>
<Tooltip isDisabled={!habitName} content={habitName}>
{renderChip()}
</Tooltip>
);
Expand Down
17 changes: 8 additions & 9 deletions src/components/habit/add-habit/AddHabitDialogButton.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { useHabits, useSnackbar } from '@context';
import { StorageBuckets, uploadFile } from '@services';
import { useUser } from '@supabase/auth-helpers-react';
import { act, fireEvent, render, waitFor } from '@testing-library/react';
import React from 'react';

import AddHabitDialogButton from './AddHabitDialogButton';

jest.mock('@context', () => ({
useHabits: jest.fn().mockReturnValue({ updateHabit: jest.fn() }),
useSnackbar: jest.fn().mockReturnValue({ showSnackbar: jest.fn() }),
useTraits: jest.fn().mockReturnValue({
traitsMap: { 1: { slug: 'trait-slug', name: 'Trait' } },
allTraits: [{ id: 1, slug: 'trait-slug', name: 'Trait' }],
}),
}));
Expand All @@ -19,14 +26,6 @@ jest.mock('@supabase/auth-helpers-react', () => ({
useSession: jest.fn(),
}));

import { useHabits, useSnackbar } from '@context';
import { StorageBuckets, uploadFile } from '@services';
import { useUser } from '@supabase/auth-helpers-react';
import { act, fireEvent, render, waitFor } from '@testing-library/react';
import React from 'react';

import AddHabitDialogButton from './AddHabitDialogButton';

describe(AddHabitDialogButton.name, () => {
it.skip('should handle data enter and dialog close', () => {
(useHabits as jest.Mock).mockReturnValue({
Expand Down
Loading

0 comments on commit 87b1845

Please sign in to comment.