Skip to content

Commit

Permalink
Feature/task creation screen (#60)
Browse files Browse the repository at this point in the history
* feat: pass task type param to task creation screen

* feat: outline json doc, update enum

* fix: so Matt can see

* feat: parse JSON and fix format to maintain order

* feat(AddressComponent.tsx): added address component to be reused throughout taskCreation.tsx

* feat: frontend components for task creation

* style: formatting

* style: format fix

* style(TaskCreation): moved the component down and fixed radioButton component

* feat(TaskCreation): added functionality to store information/input from user

* feat: radio buttons grey when not selected

* fix: add an add task button to home page

---------

Co-authored-by: narayansharma-21 <[email protected]>
Co-authored-by: Matt McCoy <[email protected]>
  • Loading branch information
3 people authored Mar 25, 2024
1 parent e1a3312 commit 7f3ff78
Show file tree
Hide file tree
Showing 20 changed files with 391 additions and 67 deletions.
4 changes: 4 additions & 0 deletions client/assets/arrow-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 0 additions & 4 deletions client/assets/back-arrow.svg

This file was deleted.

3 changes: 3 additions & 0 deletions client/assets/radio-button-circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import { useNavigation } from '@react-navigation/native';
import { IconButton } from 'react-native-paper';

import BackArrow from '../../assets/back-arrow.svg';
import ArrowLeft from '../../assets/arrow-left.svg';
import { AppStackNavigation } from '../../navigation/types';

export function BackButton() {
Expand All @@ -13,7 +13,7 @@ export function BackButton() {
<IconButton
className="align-center m-2 flex h-[50px] w-[52px] justify-center rounded-xl bg-carewallet-gray"
mode="contained"
icon={({ color }) => <BackArrow fill={color} />}
icon={({ color }) => <ArrowLeft fill={color} />}
onPress={() => navigation.goBack()}
/>
);
Expand Down
File renamed without changes.
55 changes: 55 additions & 0 deletions client/components/task_creation/AddressComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from 'react';
import { Text, TextInput, View } from 'react-native';

export function AddressComponent() {
return (
<View>
<View className="m-4 mb-0">
<Text className="mb-2">Street Address</Text>
<TextInput
className="border-gray-300 w-full rounded-md border px-4 py-2"
placeholder={'Fill in blank'}
autoComplete="street-address"
/>
</View>

<View className="m-4 mb-0 flex flex-row">
<View className="w-[49%]">
<Text className="mb-2">City</Text>
<TextInput
className="border-gray-300 w-full rounded-md border px-4 py-2"
placeholder={'Fill in blank'}
/>
</View>
<View className="ml-2 w-[49%]">
<Text className="mb-2">State</Text>
<TextInput
className="border-gray-300 w-full rounded-md border px-4 py-2"
placeholder={'Fill in blank'}
/>
</View>
</View>

<View className="m-4 mb-0 flex flex-row">
<View className="w-[49%]">
<Text className="mb-2">Zip Code</Text>
<TextInput
className="border-gray-300 w-full rounded-md border px-4 py-2"
placeholder={'Fill in blank'}
autoComplete="postal-code"
keyboardType="numeric"
/>
</View>
<View className="ml-2 w-[49%]">
<Text className="mb-2">Phone Number</Text>
<TextInput
className="border-gray-300 w-full rounded-md border px-4 py-2"
placeholder={'Fill in blank'}
autoComplete="tel"
keyboardType="phone-pad"
/>
</View>
</View>
</View>
);
}
42 changes: 42 additions & 0 deletions client/components/task_creation/RadioGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { useState } from 'react';
import { Text, TouchableOpacity, View } from 'react-native';

import ButtonCircle from '../../assets/radio-button-circle.svg';

interface RadioGroupProps {
title: string;
options: string[];
onChange?: (value: string) => void;
}

export function RadioGroup({ title, options, onChange }: RadioGroupProps) {
const [selectedOption, setSelectedOption] = useState('');

const handleOptionSelect = (option: string) => {
setSelectedOption(option);
console.log('Selected option:', option);
if (onChange) {
onChange(option);
}
};

return (
<View className="m-4 mb-0">
<Text className="mb-2">{title}</Text>
<View className="flex flex-row justify-between">
{options.map((option, index) => (
<TouchableOpacity
key={index}
className={`flex h-12 flex-row items-center space-x-2 rounded-md border px-4 py-2 ${option === selectedOption ? 'bg-carewallet-gray' : ''}`}
onPress={() => {
handleOptionSelect(option);
}}
>
<ButtonCircle />
<Text>{option}</Text>
</TouchableOpacity>
))}
</View>
</View>
);
}
30 changes: 30 additions & 0 deletions client/components/task_creation/TextInputLine.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { useState } from 'react';
import { Text, TextInput, View } from 'react-native';

interface TextInputLineProps {
title: string;
onChange?: (value: string) => void;
}

export function TextInputLine({ title, onChange }: TextInputLineProps) {
const [inputValue, setInputValue] = useState('');

const handleInputChange = (value: string) => {
setInputValue(value);
if (onChange) {
onChange(value);
}
};

return (
<View className="m-4 mb-0">
<Text className="mb-2">{title}</Text>
<TextInput
className="border-gray-300 w-full rounded-md border px-4 py-2"
placeholder={'Fill in blank'}
onChangeText={handleInputChange}
value={inputValue}
/>
</View>
);
}
36 changes: 36 additions & 0 deletions client/components/task_creation/TextInputParagraph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React, { useState } from 'react';
import { Text, TextInput, View } from 'react-native';

interface TextInputParagraphProps {
title: string;
onChange?: (value: string) => void;
}

export function TextInputParagraph({
title,
onChange
}: TextInputParagraphProps) {
const [inputValue, setInputValue] = useState('');

const handleInputChange = (value: string) => {
setInputValue(value);
if (onChange) {
onChange(value);
}
};

return (
<View className="m-4 mb-0">
<Text className="mb-2">{title}</Text>
<TextInput
style={{ height: 100 }}
className="border-gray-300 w-full rounded-md border px-4 py-2"
placeholder={'Fill in blank'}
multiline={true}
numberOfLines={4}
onChangeText={handleInputChange}
value={inputValue}
/>
</View>
);
}
6 changes: 6 additions & 0 deletions client/navigation/AppNavigation.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';

import LoginPage from '../screens/LoginPage';
import { TaskCreation } from '../screens/TaskCreation';
import { TaskType } from '../screens/TaskType';
import { AppStackBottomTabNavigator } from './AppStackBottomTabNavigator';
import { AppStack } from './types';
Expand All @@ -23,6 +24,11 @@ export function AppNavigation() {
options={{ headerShown: false }}
component={TaskType}
/>
<AppStack.Screen
name="TaskCreation"
options={{ headerShown: false }}
component={TaskCreation}
/>
</AppStack.Navigator>
);
}
1 change: 1 addition & 0 deletions client/navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type AppStackParamList = {
TaskDisplay: { id: number };
TaskList: undefined;
CalendarTopNav: undefined;
TaskCreation: { taskType: string };
};

export type AppStackNavigation = NavigationProp<AppStackParamList>;
Expand Down
4 changes: 2 additions & 2 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
"axios": "^1.6.4",
"clsx": "^2.1.0",
"date-fns": "^3.3.1",
"moment": "^2.30.1",
"expo": "~50.0.14",
"expo-device": "~5.9.3",
"expo-document-picker": "~11.10.1",
Expand All @@ -34,9 +33,10 @@
"expo-status-bar": "~1.11.1",
"firebase": "^10.7.2",
"lodash": "^4.17.21",
"moment": "^2.30.1",
"nativewind": "^2.0.11",
"react": "18.2.0",
"react-native": "0.73.6",
"react-native": "0.73.4",
"react-native-calendars": "^1.1304.1",
"react-native-dropdown-picker": "^5.4.6",
"react-native-gesture-handler": "~2.14.0",
Expand Down
9 changes: 7 additions & 2 deletions client/screens/MedicationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,22 @@ import {
View
} from 'react-native';

import { useNavigation } from '@react-navigation/core';
import { clsx } from 'clsx';
import { Divider } from 'react-native-paper';

import { ClickableCard } from '../components/ClickableCard';
import { DocPickerButton } from '../components/DocPickerButton';
import { PopupModal } from '../components/PopupModal';
import { useCareWalletContext } from '../contexts/CareWalletContext';
import { AppStackNavigation } from '../navigation/types';
import { useAuth } from '../services/auth';
import { useMedication } from '../services/medication';
import { Medication } from '../types/medication';

export default function MedicationList() {
const [selectedMed, setSelectedMed] = useState<Medication>();
const navigator = useNavigation<AppStackNavigation>();

const [newMedState, setNewMedState] = useState({ id: '', name: '' });

Expand Down Expand Up @@ -95,11 +98,13 @@ export default function MedicationList() {
<View className="flex flex-row items-center">
<DocPickerButton />
<Pressable
onPress={() => setNewMedVisible(true)}
className="mb-2 ml-2 mt-2 self-center rounded-md border border-carewallet-gray pl-1 pr-1"
onPress={() => {
navigator.navigate('TaskType');
}}
>
<Text className="self-center text-lg text-carewallet-black">
Add New Medication
Add New Task
</Text>
</Pressable>
</View>
Expand Down
2 changes: 1 addition & 1 deletion client/screens/SingleTask.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import DropDownPicker from 'react-native-dropdown-picker';

import CheckMark from '../assets/checkmark.svg';
import Reject from '../assets/reject.svg';
import { BackButton } from '../components/task-type/BackButton';
import { BackButton } from '../components/nav_buttons/BackButton';
import { useTaskById } from '../services/task';
import { TaskTypeDescriptions, TypeToCategoryMap } from '../types/type';

Expand Down
92 changes: 92 additions & 0 deletions client/screens/TaskCreation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import React, { useState } from 'react';
import { Text, View } from 'react-native';

import { RouteProp, useRoute } from '@react-navigation/native';
import {
GestureHandlerRootView,
ScrollView
} from 'react-native-gesture-handler';

import { BackButton } from '../components/nav_buttons/BackButton';
import { AddressComponent } from '../components/task_creation/AddressComponent.tsx';
import { RadioGroup } from '../components/task_creation/RadioGroup.tsx';
import { TextInputLine } from '../components/task_creation/TextInputLine.tsx';
import { TextInputParagraph } from '../components/task_creation/TextInputParagraph.tsx';
import { TaskCreationJson } from '../types/task-creation-json.ts';

type ParamList = {
mt: {
taskType: string;
};
};

export function TaskCreation() {
const route = useRoute<RouteProp<ParamList, 'mt'>>();
const { taskType } = route.params;

const header = TaskCreationJson.types.find((t) =>
taskType.includes(t.Header)
)?.Header;

const body = TaskCreationJson.types.find((t) =>
taskType.includes(t.Header)
)?.Body;

const compList: { key: string; value: string }[] = [];

body?.forEach((item) => {
Object.entries(item).forEach(([key, value]) => {
compList.push({ key, value });
});
});

const [values, setValues] = useState<{ [key: string]: string }>({});

const handleChange = (key: string, value: string) => {
setValues((prevValues) => ({
...prevValues,
[key]: value
}));
console.log('Current values:', values);
};

return (
<GestureHandlerRootView>
<ScrollView className="mt-10">
<View className="flex w-full flex-row items-center justify-center">
<View className="mr-[95px]">
<BackButton />
</View>
<Text className="mr-auto self-center text-center text-carewallet-gray">
Step 1 of 2
</Text>
</View>
<Text className="text-center text-2xl font-bold">{header}</Text>
{compList.map((item, index) => (
<View key={index}>
{item.key === 'Address' && <AddressComponent />}
{item.value === 'TextInputLine' && (
<TextInputLine
title={item.key}
onChange={(value) => handleChange(item.key, value)}
/>
)}
{item.value === 'TextInputParagraph' && (
<TextInputParagraph
title={item.key}
onChange={(value) => handleChange(item.key, value)}
/>
)}
{item.value.startsWith('RadioGroup') && (
<RadioGroup
title={item.key}
options={item.value.substring(12).split(', ')}
onChange={(value) => handleChange(item.key, value)}
/>
)}
</View>
))}
</ScrollView>
</GestureHandlerRootView>
);
}
2 changes: 1 addition & 1 deletion client/screens/TaskList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import DropDownPicker from 'react-native-dropdown-picker';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { Button } from 'react-native-paper';

import { CloseButton } from '../components/task-type/CloseButton';
import { CloseButton } from '../components/nav_buttons/CloseButton';
import { TaskInfoComponent } from '../components/TaskInfoCard';
import { useCareWalletContext } from '../contexts/CareWalletContext';
import { AppStackNavigation } from '../navigation/types';
Expand Down
Loading

0 comments on commit 7f3ff78

Please sign in to comment.