Skip to content

Commit

Permalink
feat: add tasks due for tomorrow
Browse files Browse the repository at this point in the history
  • Loading branch information
paolojulian committed Sep 15, 2024
1 parent 57f2d86 commit ba38481
Show file tree
Hide file tree
Showing 15 changed files with 171 additions and 65 deletions.
10 changes: 2 additions & 8 deletions app/(tabs)/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import { RouteNames } from '@/app/_layout';
import { getDefaultTypeFromTabIndex } from '@/components/add/utils';
import BottomBar from '@/components/navigation/BottomBar/BottomBar';
import { TabName } from '@/utils/constants';
import { router, Tabs } from 'expo-router';
import React, { ComponentProps } from 'react';

export enum TabName {
Home = 'index',
Journal = 'journal',
Expense = 'expenses',
Todo = 'todos',
}

/** Don't modify the arrangement of this array since it is used to get the current route from the navigation */
const tabs = [TabName.Home, TabName.Expense, TabName.Todo, TabName.Journal];

Expand All @@ -35,7 +29,7 @@ const TabBar: ComponentProps<typeof Tabs>['tabBar'] = props => {
const handleAddPress = () => {
const defaultType = getDefaultTypeFromTabIndex(navigation.getState().index);
router.push({
pathname: RouteNames.Add,
pathname: RouteNames.Add as never,
params: {
defaultType: defaultType,
},
Expand Down
2 changes: 1 addition & 1 deletion components/add/AddExpenseForm/AddExpenseForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { TabName } from '@/app/(tabs)/_layout';
import {
ADD_EXPENSE_FORM_TEST_IDS,
ADD_EXPENSE_VALIDATION_SCHEMA,
Expand All @@ -16,6 +15,7 @@ import ThemedView from '@/components/common/ThemedView';
import { useGetOrCreateCategory } from '@/hooks/services/category/useGetOrCreateCategory';
import { useCreateExpense } from '@/hooks/services/expense/useCreateExpenses';
import { GlobalSnackbar } from '@/managers/SnackbarManager';
import { TabName } from '@/utils/constants';
import { convertDateToEpoch } from '@/utils/date/date.utils';
import { selectionAsync } from 'expo-haptics';
import { useNavigation } from 'expo-router';
Expand Down
2 changes: 1 addition & 1 deletion components/add/AddTaskForm/AddTaskForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { TabName } from '@/app/(tabs)/_layout';
import {
ADD_TASK_VALIDATION_SCHEMA,
convertTaskFormToTask,
Expand All @@ -14,6 +13,7 @@ import Snackbar from '@/components/common/Snackbar';
import ThemedView from '@/components/common/ThemedView';
import { useCreateTask } from '@/hooks/services/task/useCreateTask';
import { GlobalSnackbar } from '@/managers/SnackbarManager';
import { TabName } from '@/utils/constants';
import { useNavigation } from 'expo-router';
import { Formik } from 'formik';
import { Fragment, useRef, useState } from 'react';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import Button from '@/components/common/Button';
import { useGetOrCreateCategory } from '@/hooks/services/category/useGetOrCreateCategory';
import { GlobalSnackbar } from '@/managers/SnackbarManager';
import { useNavigation } from 'expo-router';
import { TabName } from '@/app/(tabs)/_layout';
import { TabName } from '@/utils/constants';

type EditExpenseFormProps = {
id: Expense['id'];
Expand Down
4 changes: 2 additions & 2 deletions components/home/HomeJournalOverview.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { TabName } from '@/app/(tabs)/_layout';
import { colors } from '@/constants/Colors';
import { useJournal } from '@/hooks/services/journal/useJournal';
import { router } from 'expo-router';
Expand All @@ -8,6 +7,7 @@ import AppCard from '../common/AppCard';
import JournalIcon from '../common/icons/JournalIcon';
import Stack from '../common/Stack';
import ThemedText from '../common/ThemedText';
import { TabName } from '@/utils/constants';

const today = new Date();
function HomeJournalOverview() {
Expand All @@ -16,7 +16,7 @@ function HomeJournalOverview() {
const hasJournalToday: boolean = !!data?.id;

const handlePress = () => {
router.push(TabName.Journal);
router.push(TabName.Journal as never);
};

return (
Expand Down
4 changes: 2 additions & 2 deletions components/home/HomeTaskOverview.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { TabName } from '@/app/(tabs)/_layout';
import { colors } from '@/constants/Colors';
import useTaskOverview from '@/hooks/services/task/useTaskOverview';
import { router } from 'expo-router';
Expand All @@ -7,12 +6,13 @@ import { TouchableOpacity, View } from 'react-native';
import AppCard from '../common/AppCard';
import Stack from '../common/Stack';
import ThemedText from '../common/ThemedText';
import { TabName } from '@/utils/constants';

function HomeTaskOverview() {
const { data } = useTaskOverview();

const handlePress = () => {
router.push(TabName.Todo);
router.push(TabName.Todo as never);
};

return (
Expand Down
2 changes: 1 addition & 1 deletion components/home/RecentTransactions/RecentTransactions.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { TabName } from '@/app/(tabs)/_layout';
import Container from '@/components/common/Container';
import LinkText from '@/components/common/LinkText';
import Row from '@/components/common/Row';
Expand All @@ -9,6 +8,7 @@ import useExpenses from '@/hooks/services/expense/useExpenses';
import { useFocusEffect, useNavigation } from 'expo-router';
import React, { Fragment } from 'react';
import EmptyRecentTransactions from './EmptyRecentTransactions';
import { TabName } from '@/utils/constants';

function RecentTransactions() {
const navigation = useNavigation();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import { TextInput } from 'react-native';
import { NOTE_PLACEHOLDER } from '@/components/add/AddTaskForm/AddTaskForm.utils';
import { useUpdateTask } from '@/hooks/services/task/useUpdateTask';
import { useNavigation } from 'expo-router';
import { TabName } from '@/app/(tabs)/_layout';
import { GlobalSnackbar } from '@/managers/SnackbarManager';
import { TabName } from '@/utils/constants';

type EditTaskFormProps = {
id: Task['id'];
Expand Down
2 changes: 1 addition & 1 deletion components/tasks/TaskList/TaskItem/TaskItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default function TaskItem({ onRemove, onRevert, task }: TaskItemProps) {
}}
>
<Checkbox
style={{ borderRadius: 6 }}
style={{ borderRadius: 6, pointerEvents: 'none' }}
value={isChecked}
onValueChange={setChecked}
color={isChecked ? colors.v2.grayLight : colors.v2.grayLight}
Expand Down
4 changes: 3 additions & 1 deletion database/migrations/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Migration } from '@/database/migrations/migration.types';
import dayjs from 'dayjs';

const todayUnix = dayjs().startOf('day').add(8, 'hours').unix();
const tomorrowUnix = dayjs().startOf('day').add(1, 'day').add(8, 'hours').unix();

export const taskMigrations = [
{
Expand Down Expand Up @@ -35,7 +36,8 @@ export const taskMigrations = [
('Create a task', '', 1, 0, 0, 0, ${todayUnix}, null, null, null, null, null),
('Create a journal', '', 1, 0, 0, 0, ${todayUnix}, null, null, null, null, null),
('Create an expense', '', 1, 0, 0, 0, ${todayUnix}, null, null, null, null, null),
('Set a monthly budget', '', 1, 0, 0, 0, ${todayUnix}, null, null, null, null, null)
('Set a monthly budget', '', 1, 0, 0, 0, ${todayUnix}, null, null, null, null, null),
('Tomorrow', '', 1, 0, 0, 0, ${tomorrowUnix}, null, null, null, null, null)
;
`,
},
Expand Down
7 changes: 5 additions & 2 deletions hooks/services/task/useTasksTomorrow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { Task, TaskQueryKeys } from './task.types';
import { useSQLiteContext } from 'expo-sqlite';
import dayjs from 'dayjs';

type SupportedTaskFields = Pick<Task, 'id' | 'reminder_date' | 'title'>;
type SupportedTaskFields = Pick<Task, 'id' | 'reminder_date' | 'title'> & {
reminder_date: number;
};

export const useTasksTomorrow = () => {
const db = useSQLiteContext();
Expand All @@ -27,7 +29,8 @@ export const useTasksTomorrow = () => {
function buildQuery() {
return `
SELECT id, reminder_date, title FROM task
WHERE reminder_date BETWEEN $startOfDayEpoch AND $endOfDayEpoch
WHERE reminder_date IS NOT NULL
AND reminder_date BETWEEN $startOfDayEpoch AND $endOfDayEpoch
AND is_completed = 0
`;
}
81 changes: 55 additions & 26 deletions hooks/useNotification/useNotification.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import { getStoredNotificationId, storeNotificationId } from '@/utils/storage/notifications';
import { Alert } from 'react-native';
import { useTasksToday } from '../services/task/useTasksToday';
import { cancelNotification, scheduleNotificationsForToday } from './useNotification.utils';
import {
cancelNotification,
scheduleNotificationsForToday,
scheduleNotificationsForTomorrow,
} from './useNotification.utils';
import { useTasksTomorrow } from '../services/task/useTasksTomorrow';

const TODAY_NOTIFICATION_KEY = 'today';
const NOTIFICATION_KEY = {
TODAY: 'today',
TOMORROW: 'tomorrow',
};
const isProduction: boolean = process.env.NODE_ENV === 'production';

export const useNotification = () => {
const { refetch: refetchTasksForToday } = useTasksToday();
// const { data: tasksTomorrow, isLoading: isLoadingTasksTomorrow } = useTasksTomorrow();
const { refetch: refetchTasksForTomorrow } = useTasksTomorrow();

const scheduleNotificationsForTasksToday = async (): Promise<void> => {
const { data: tasksToday } = await refetchTasksForToday();
Expand All @@ -17,8 +25,9 @@ export const useNotification = () => {
return;
}

const [storedNotificationId, getStoredNotificationIdError] =
await getStoredNotificationId(TODAY_NOTIFICATION_KEY);
const [storedNotificationId, getStoredNotificationIdError] = await getStoredNotificationId(
NOTIFICATION_KEY.TODAY,
);
if (getStoredNotificationIdError !== null) {
Alert.alert('Error', getStoredNotificationIdError.message);
return;
Expand All @@ -40,27 +49,47 @@ export const useNotification = () => {
return;
}

await storeNotificationId(TODAY_NOTIFICATION_KEY, notificationId);
if (notificationId === null) {
// No notifications was made
return;
}

await storeNotificationId(NOTIFICATION_KEY.TODAY, notificationId);
};

const scheduleNotificationsForTasksTomorrow = async (): Promise<void> => {
const { data: tasksTomorrow } = await refetchTasksForTomorrow();

if (tasksTomorrow === undefined || tasksTomorrow.length === 0) {
return;
}

const [storedNotificationId, getStoredNotificationIdError] = await getStoredNotificationId(
NOTIFICATION_KEY.TOMORROW,
);
if (getStoredNotificationIdError !== null) {
Alert.alert('Error', getStoredNotificationIdError.message);
return;
}

if (!isProduction && storedNotificationId !== null) {
await cancelNotification(storedNotificationId);
}

if (isProduction && storedNotificationId !== null) {
// There is no need to schedule a notifiation because
// there is already a scheduled notification for today
return;
}

const [notificationId, error] = await scheduleNotificationsForTomorrow(tasksTomorrow);
if (error !== null) {
Alert.alert('Error', error.message);
return;
}

await storeNotificationId(NOTIFICATION_KEY.TOMORROW, notificationId);
};

// const scheduleNotificationsForTasksTomorrow = async () => {};

// const cancelNotificationForTask = async (taskId: Task['id']): Promise<void> => {
// const [notificationId, error] = await getStoredNotificationId(taskId);
// if (error !== null) {
// Alert.alert('Error', error.message);
// return;
// }
//
// if (notificationId === null) {
// return;
// }
//
// const [_, notificationError] = await cancelNotification(notificationId);
// if (notificationError !== null) {
// Alert.alert('Error', notificationError.message);
// }
// };

return { scheduleNotificationsForTasksToday };
return { scheduleNotificationsForTasksToday, scheduleNotificationsForTasksTomorrow };
};
Loading

0 comments on commit ba38481

Please sign in to comment.