Skip to content

Commit

Permalink
Merge pull request #113 from ineshbose/feature/112-add_journal_entry
Browse files Browse the repository at this point in the history
Journal entry action
  • Loading branch information
ineshbose committed Feb 3, 2022
2 parents 171c8dc + a2f88ee commit 934c84c
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/app/api/journals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const getJournals = async () => {
}
};

export const createJournal = async (props: CreateData<Journal, 'item'>) => {
export const createJournal = async (props: CreateData<Journal, 'meal'>) => {
try {
const response = await axiosInstance.post<Journal>(API_PATH, {
entry_time: new Date().toISOString(),
Expand Down
6 changes: 5 additions & 1 deletion src/app/contexts/AppContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import {
import { getObject } from '../api/store';
import { createUser, getUser } from '../api/user';
import { ChildComponents } from '../types';
import { AuthToken, TrackItems, User } from '../types/api';
import { AuthToken, Journals, TrackItems, User } from '../types/api';
import { RootTabParamList, RouteNames } from '../types/navigation';

type AppContextType = {
authToken?: AuthToken;
user?: User;
items?: TrackItems;
journals?: Journals;
loading: boolean;
headerAction?: RouteNames<RootTabParamList>;
helpers: { [name: string]: Function };
Expand All @@ -28,6 +29,7 @@ const AppContext = React.createContext<AppContextType>({
export const ContextProvider = ({ children }: ChildComponents) => {
const [authToken, setAuthToken] = React.useState<AuthToken>();
const [items, setItems] = React.useState<TrackItems>([]);
const [journals, setJournals] = React.useState<Journals>([]);
const [user, setUser] = React.useState<User>();
const [headerAction, setHeaderAction] =
React.useState<RouteNames<RootTabParamList>>();
Expand Down Expand Up @@ -93,6 +95,7 @@ export const ContextProvider = ({ children }: ChildComponents) => {
authToken,
user,
items,
journals,
headerAction,
loading,
helpers: {
Expand All @@ -101,6 +104,7 @@ export const ContextProvider = ({ children }: ChildComponents) => {
signOut,
setUser,
setItems,
setJournals,
setHeaderAction,
},
}}
Expand Down
6 changes: 6 additions & 0 deletions src/app/navigation/ActionNavigator.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import * as React from 'react';
import AddItem from '../screens/Action/AddItem';
import AddJournal from '../screens/Action/AddJournal';
import { RootActionParamList } from '../types/navigation';

const Action = createNativeStackNavigator<RootActionParamList>();
Expand All @@ -13,6 +14,11 @@ export default function ActionNavigator() {
component={AddItem}
options={{ headerShown: false }}
/>
<Action.Screen
name="Journal"
component={AddJournal}
options={{ headerShown: false }}
/>
</Action.Navigator>
);
}
5 changes: 5 additions & 0 deletions src/app/navigation/BottomTabNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,11 @@ export default function BottomTabNavigator({
name: 'Item',
text: 'Food Item',
},
{
icon: 'note-add',
name: 'Journal',
text: 'Journal Entry',
},
]}
floatingIcon="add"
onPressAction={(name) =>
Expand Down
1 change: 1 addition & 0 deletions src/app/navigation/LinkingConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const linking: LinkingOptions<RootStackParamList> = {
path: 'add',
screens: {
Item: 'item',
Journal: 'journal',
},
},
},
Expand Down
134 changes: 134 additions & 0 deletions src/app/screens/Action/AddJournal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import * as React from 'react';
import { Button, Input, Layout, TopNavigation } from '@ui-kitten/components';
import { SafeAreaView, StyleSheet, View } from 'react-native';
import { NavProps, RootActionParamList } from '../../types/navigation';
import { FAB } from '../../components/FAB';
import { FormError } from '../../types/api';
import HomePage from '../HomePage';
import { createJournal } from '../../api/journals';
import { useAppContext } from '../../contexts/AppContext';

const yesterdayDate = new Date();
yesterdayDate.setDate(yesterdayDate.getDate() + 1);
const YESTERDAY = yesterdayDate.toISOString().slice(0, 10);

const todayDate = new Date();
const TODAY = todayDate.toISOString().slice(0, 10);

const tomorrowDate = new Date();
tomorrowDate.setDate(tomorrowDate.getDate() + 1);
const TOMORROW = tomorrowDate.toISOString().slice(0, 10);

const INTERVAL_TIMES = {
LAST_NIGHT: new Date(`${YESTERDAY}T22:00:00`),
MORNING: new Date(`${TODAY}T05:00:00`),
AFTERNOON: new Date(`${TODAY}T12:00:00`),
EVENING: new Date(`${TODAY}T17:00:00`),
NIGHT: new Date(`${TODAY}T22:00:00`),
NEXT_MORNING: new Date(`${TOMORROW}T05:00:00`),
};

export default function AddJournal({
navigation,
}: NavProps<RootActionParamList, 'Journal'>) {
const {
journals = [],
helpers: { setJournals },
} = useAppContext();
const [meal, setMeal] = React.useState<string>('');
const [time, setTime] = React.useState<Date>(todayDate);
const [content, setContent] = React.useState<string>('');
const [error, setError] = React.useState<FormError | any>();

const goBack = () => navigation.goBack();

const recommendedMeal = () => {
var mealName = '';

if (
(time >= INTERVAL_TIMES.LAST_NIGHT && time < INTERVAL_TIMES.MORNING) ||
(time >= INTERVAL_TIMES.NIGHT && INTERVAL_TIMES.NEXT_MORNING)
) {
mealName = 'Midnight Snack';
} else if (time >= INTERVAL_TIMES.MORNING && INTERVAL_TIMES.AFTERNOON) {
mealName = 'Breakfast';
} else if (time >= INTERVAL_TIMES.AFTERNOON && INTERVAL_TIMES.EVENING) {
mealName = 'Lunch';
} else if (time >= INTERVAL_TIMES.EVENING && INTERVAL_TIMES.NIGHT) {
mealName = 'Dinner';
}

return mealName;
};

const logEntry = async () => {
const newJournal = await createJournal({
meal,
entry_time: time.toISOString(),
content,
});
setJournals([...journals, newJournal]);
goBack();
};

const renderCancelAccessory = (props: {} | undefined) => (
<Button appearance="ghost" status="basic" {...props} onPress={goBack}>
Cancel
</Button>
);

return (
<SafeAreaView style={{ flex: 1 }}>
<Layout style={styles.container}>
<TopNavigation
alignment="start"
title="Journal Entry"
accessoryRight={renderCancelAccessory}
/>
<View
style={{
flexDirection: 'row',
margin: 10,
}}
>
<Input
placeholder={recommendedMeal() || 'meal'}
onChangeText={setMeal}
caption={error?.meal}
status={error?.meal ? 'danger' : 'basic'}
size="large"
/>
<Input
placeholder="time"
value={`${time.toDateString()} ${time.toLocaleTimeString()}`}
onChangeText={(t) => setTime(new Date(t))}
style={{ marginHorizontal: 5 }}
size="large"
disabled
/>
</View>
<Input
multiline
placeholder="journal entry..."
onChangeText={setContent}
textStyle={{ minHeight: 100 }}
style={{ margin: 10 }}
/>
</Layout>
<HomePage />
<FAB
floatingIcon="check"
color="green"
onPressMain={() =>
meal ? logEntry() : setError({ meal: 'This field is required.' })
}
/>
</SafeAreaView>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
},
});
8 changes: 4 additions & 4 deletions src/app/screens/JournalPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ const TODAY = new Date();

export default function JournalPage() {
const {
journals,
headerAction,
helpers: { setHeaderAction },
helpers: { setJournals, setHeaderAction },
} = useAppContext();
const isAction = headerAction === 'Journal';
const [fetched, setFetched] = React.useState<boolean>(false);
const [journals, setJournals] = React.useState<Journals>([]);
const [selectedJournal, setSelectedJournal] = React.useState<Journal>();
const [date, setDate] = React.useState<Date>(TODAY);

Expand All @@ -49,7 +49,7 @@ export default function JournalPage() {

const removeJournal = async () => {
if (selectedJournal) {
const newJournals = journals.filter(
const newJournals = journals?.filter(
(journal) => journal.id !== selectedJournal.id
);

Expand Down Expand Up @@ -171,7 +171,7 @@ export default function JournalPage() {
</View>
<Text style={{ marginTop: 40 }}>{selectedJournal.content}</Text>
</ScrollView>
) : journals.length > 0 ? (
) : journals && journals.length > 0 ? (
<List data={journals} renderItem={renderItem} />
) : (
<Layout style={styles.noResourceContainer}>
Expand Down
1 change: 1 addition & 0 deletions src/app/types/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export type RootAuthParamList = {

export type RootActionParamList = {
Item: undefined;
Journal: undefined;
};

export type RootTabScreenProps<Screen extends RouteNames<RootTabParamList>> =
Expand Down

0 comments on commit 934c84c

Please sign in to comment.