Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/single task display screen #44

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
7b3e223
feat(SingleTask.tsx): Hardcoded screen
narayansharma-21 Feb 24, 2024
b0c3391
feat(SingleTask.tsx): Added route functionality
narayansharma-21 Feb 26, 2024
ae2cd86
feat(SingleTask.tsx): Implemented entirety of v4 of lofi with additio…
narayansharma-21 Feb 27, 2024
7a432a8
fix(task.ts): Refactored service routes to use tanStack in the Single…
narayansharma-21 Mar 1, 2024
e49287f
fix(Attempted-to-fix-the-query): SingleTask.tsx
narayansharma-21 Mar 16, 2024
d70d203
fix(SingleTask.tsx): Fixed undefined error on xcode
narayansharma-21 Mar 16, 2024
0760bc7
Merge branch 'main' into feature/single-task-display-screen
narayansharma-21 Mar 16, 2024
8a2cfa5
fix(SingleTask.tsx): Bug fix
narayansharma-21 Mar 16, 2024
7139ac2
feat: add title to task db table
MattCMcCoy Mar 18, 2024
d329142
fix: cycle import in app nav
MattCMcCoy Mar 18, 2024
17bc80a
Merge branch 'bugfix/cycleimport' into feature/addtitletotaskmodel
MattCMcCoy Mar 18, 2024
0039498
fix(SingleTask.tsx): Initial fix to title issue
narayansharma-21 Mar 18, 2024
7cfd5f7
Merge remote-tracking branch 'origin/feature/addtitletotaskmodel' int…
narayansharma-21 Mar 18, 2024
3f3389c
fix(SingleTask.tsx): Utilized new backend route to dynamically show t…
narayansharma-21 Mar 18, 2024
8f16fba
fix(AppStackBottomTabNavigator): removed single task display from nav…
narayansharma-21 Mar 18, 2024
3c14bba
Merge branch 'main' into feature/single-task-display-screen
narayansharma-21 Mar 18, 2024
2325fa5
style(Task.tsx): Updated svgs and got rid of TaskInfo type
narayansharma-21 Mar 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions client/assets/checkmark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions client/assets/reject.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions client/components/BackButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';

import { useNavigation } from '@react-navigation/native';
import { Button } from 'react-native-paper';

import { AppStackNavigation } from '../navigation/AppNavigation';

// TODO style
export function BackButton() {
const navigation = useNavigation<AppStackNavigation>();

return (
<Button
className="bg-carewallet-gray"
onPress={() => navigation.goBack()}
mode="contained"
style={{ borderRadius: 8, marginTop: 16 }}
contentStyle={{ height: 48 }}
>
Back
</Button>
);
}
10 changes: 10 additions & 0 deletions client/navigation/AppStackBottomTabNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Home from '../assets/home.svg';
import GroupScreen from '../screens/Groups';
import MedicationList from '../screens/MedicationList';
import SingleTaskScreen from '../screens/SingleTask';

const AppStackBottomTab = createBottomTabNavigator();

Expand All @@ -30,6 +31,15 @@ export function AppStackBottomTabNavigator() {
}}
component={GroupScreen}
/>
<AppStackBottomTab.Screen
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prolly shouldnt be apart of bottom nav

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah for sure, just put it there so it'd be easy for me to access when testing on expo and since I didn't have access to the other task screens. I can just pull it out from here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you remove from bottom nav?

name="Task"
options={{
headerShown: true,
tabBarIcon: () => <Home color="gray" />,
tabBarLabel: () => <Text>Task</Text>
}}
component={SingleTaskScreen}
/>
</AppStackBottomTab.Navigator>
);
}
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"nativewind": "^2.0.11",
"react": "18.2.0",
"react-native": "0.73.4",
"react-native-dropdown-picker": "^5.4.6",
"react-native-paper": "^5.12.3",
"react-native-safe-area-context": "4.8.2",
"react-native-screens": "~3.29.0",
Expand Down
118 changes: 118 additions & 0 deletions client/screens/SingleTask.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import React, { useState } from 'react';
import { Text, TextInput, View } from 'react-native';

import DropDownPicker from 'react-native-dropdown-picker';

import CheckMark from '../assets/checkmark.svg';
import Reject from '../assets/reject.svg';
import { BackButton } from '../components/BackButton';
import { useGetTaskLabel } from '../services/task';
import { TaskInfo } from '../types/taskInfo';
import { Category, categoryToTypeMap, TypeOfTask } from '../types/type';

export default function SingleTaskScreen() {
const [taskId] = useState<string>('1');

const [open, setOpen] = useState(false);

const [taskType, setTaskType] = useState<TypeOfTask | undefined>(
TypeOfTask.MEDICATION_MANAGEMENT
);

const label = useGetTaskLabel(taskId);

// Would extract real information in future and not display default, placeholder info
const [taskInfo] = useState({
created_date: '8:00AM',
task_id: 1,
task_info: { title: 'Doctors Appointment' },
notes:
'Description here. Description here. Description here. Description here. Description here. Description here. Description here. Description here. Description here. Description here. Description here.'
});

// Gets category based on Task Type
const getCategoryFromTaskType = (
taskType: TypeOfTask | undefined
): Category => {
console.log(taskType);
if (!taskType) {
return Category.ALL; // Return a default category if taskType is undefined
}
// Iterate over each category in the categoryToTypeMap object
for (const category in categoryToTypeMap) {
// Check if the taskType exists in the current category's array of task types
if (categoryToTypeMap[category as Category].includes(taskType)) {
return category as Category; // Return the category if found
}
}
return Category.ALL; // Return a default category if no match is found
};

// Gets title from the task_info object
const getTitleFromTaskInfo = (taskInfo: TaskInfo): string => {
try {
if ('title' in taskInfo) {
return taskInfo.title;
} else {
return '';
}
} catch (error) {
console.error('Error parsing task info to extract title:', error);
return '';
}
};

return (
<View className="flex flex-col items-start p-4">
<View className="flex-row items-center">
<BackButton />
</View>
<View className="absolute right-0 top-4 m-4">
<DropDownPicker
// Very light placeholder for the real dropdown picker. Once backend routes are added
// to update a task status, then this can be dynamically rendered
open={open}
value="value"
items={[
{ label: 'INCOMPLETE', value: 'incomplete' },
{ label: 'COMPLETE', value: 'Complete' },
{ label: 'PARTIAL', value: 'Partial' }
]}
setOpen={setOpen}
setValue={setTaskType}
placeholder="To-do"
containerStyle={{ height: 40, marginBottom: 8, width: 100 }}
/>
</View>
<View className="mt-4">
<Text className="text-base ">{label || 'Label Here'}</Text>
</View>
<View className="mt-4">
<Text className="text-base ">
{getCategoryFromTaskType(taskType) || 'Category Task'} | {taskType}
</Text>
</View>
<View className="mt-4">
<Text className="text-black font-inter text-2xl font-bold">
{getTitleFromTaskInfo(taskInfo.task_info) || 'Doctor’s Appointment'}{' '}
{'\n'} @ {taskInfo.created_date}
</Text>
</View>
<View className="mt-2">
<Text className="text-black font-inter mb-4 text-base font-normal">
{taskInfo.notes}
</Text>
<Text className="text-black font-inter text-xl font-bold">
Additional Notes{' '}
</Text>
<TextInput className="border-black mb-2 h-32 w-80 rounded-lg border-2" />
</View>

<View className="ml-auto flex-1 flex-row space-x-4">
{/* Once backend endpoints for assignining tasks are implemented, then can connect these buttons */}
<CheckMark />
<Reject />
</View>
</View>
);
}
37 changes: 37 additions & 0 deletions client/services/task.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';

import { Task } from '../types/task';
import { TypeOfTask } from '../types/type';
import { api_url } from './api-links';

export const getTaskLabel = async (
taskID: string | undefined
): Promise<string> => {
const { data } = await axios.get(`${api_url}/tasks/${taskID}/labels`);
return data.label_name;
};

export const getTask = async (taskID: string): Promise<Task> => {
const { data } = await axios.get(`${api_url}/tasks/${taskID}`);
return data;
};

export const useGetTaskLabel = (taskId: string | undefined): string => {
const { data: label } = useQuery({
queryKey: ['taskId', taskId],
queryFn: () => getTaskLabel(taskId)
});
return label ?? ''; // Empty string if no label found
};

// Helper Function to get Task Type by ID using getTaskId
export const getTaskType = async (tid: string): Promise<TypeOfTask> => {
try {
const task = await getTask(tid);
return task.task_type;
} catch (error) {
console.error('Error fetching task type:', error);
throw error;
}
};
17 changes: 17 additions & 0 deletions client/types/task.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { TypeOfTask } from './type';

export interface Task {
task_id: number;
group_id: number;
created_by: string;
created_date: string;
start_date?: string | null;
end_date?: string | null;
notes?: string | null;
repeating: boolean;
repeating_interval?: string | null;
repeating_end_date?: string | null;
task_status: string;
task_type: TypeOfTask;
task_info?: JSON | null;
}
4 changes: 4 additions & 0 deletions client/types/taskInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface TaskInfo {
title: string;
// Add other properties if needed
}
5 changes: 5 additions & 0 deletions client/types/taskLabel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface TaskLabel {
task_id: number;
group_id: number;
label_name: string;
}
52 changes: 52 additions & 0 deletions client/types/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
export enum TypeOfTask {
MEDICATION_MANAGEMENT = 'Medication Management',
PHYSICIAN_APPT = 'Physician Appointment',
PRESCRIPTION_MGMT = 'Prescription Management',
LABS_OUTPATIENT_SERVICES = 'Labs & Outpatient Services',
REHAB_HOME_THERAPIES = 'Rehab/Home Therapies',
TRANSITIONAL_CARE_COORD = 'Transitional Care Coordination',
FAMILY_CONVERSATIONS = 'Family Conversations',
TRANSPORTATION = 'Transportation',
RESPITE_CAREGIVER_SUPPORT = 'Respite and Caregiver Support',
HOME_SAFETY = 'Home Safety',
HEALTH_INSURANCE = 'Health Insurance',
MANAGING_EXPENSES_BILL_PAYMENTS = 'Managing Expenses & Bill Payments',
LEGAL = 'Legal',
FINANCIAL = 'Financial',
OTHER = 'Other'
}

export enum Category {
ALL = '',
HEALTH = 'Health & Medication',
PERSONAL = 'Personal',
HOME = 'Home & Lifestyle',
FINANCIAL = 'Financial & Legal'
}

export const categoryToTypeMap: Record<Category, TypeOfTask[]> = {
[Category.ALL]: [],
[Category.HEALTH]: [
TypeOfTask.MEDICATION_MANAGEMENT,
TypeOfTask.PHYSICIAN_APPT,
TypeOfTask.PRESCRIPTION_MGMT,
TypeOfTask.LABS_OUTPATIENT_SERVICES,
TypeOfTask.REHAB_HOME_THERAPIES,
TypeOfTask.TRANSITIONAL_CARE_COORD,
TypeOfTask.HEALTH_INSURANCE
],
[Category.PERSONAL]: [
TypeOfTask.FAMILY_CONVERSATIONS,
TypeOfTask.RESPITE_CAREGIVER_SUPPORT
],
[Category.HOME]: [
TypeOfTask.TRANSPORTATION,
TypeOfTask.REHAB_HOME_THERAPIES,
TypeOfTask.TRANSITIONAL_CARE_COORD,
TypeOfTask.HOME_SAFETY
],
[Category.FINANCIAL]: [
TypeOfTask.FINANCIAL,
TypeOfTask.MANAGING_EXPENSES_BILL_PAYMENTS
]
};
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra package.json not needed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:ahhhhhhhhh: forgot about that

"dependencies": {
"@tanstack/react-query": "^5.24.1",
"react-native-dropdown-picker": "^5.4.6"
}
}