diff --git a/client/assets/checkmark.svg b/client/assets/checkmark.svg new file mode 100644 index 0000000..6860b73 --- /dev/null +++ b/client/assets/checkmark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/client/assets/reject.svg b/client/assets/reject.svg new file mode 100644 index 0000000..e83910c --- /dev/null +++ b/client/assets/reject.svg @@ -0,0 +1,4 @@ + + + + diff --git a/client/components/BackButton.tsx b/client/components/BackButton.tsx new file mode 100644 index 0000000..a72374b --- /dev/null +++ b/client/components/BackButton.tsx @@ -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(); + + return ( + + ); +} diff --git a/client/package.json b/client/package.json index e224d3f..8e8113b 100644 --- a/client/package.json +++ b/client/package.json @@ -21,7 +21,6 @@ "@react-navigation/native": "^6.1.9", "@react-navigation/native-stack": "^6.9.17", "@tanstack/react-query": "^5.18.1", - "@types/react": "^18.2.55", "axios": "^1.6.4", "clsx": "^2.1.0", "expo": "^50.0.11", @@ -43,6 +42,7 @@ "devDependencies": { "@babel/core": "^7.20.0", "@trivago/prettier-plugin-sort-imports": "^4.3.0", + "@types/react": "^18.2.55", "@types/react-native": "^0.73.0", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "6.18.0", diff --git a/client/screens/SingleTask.tsx b/client/screens/SingleTask.tsx new file mode 100644 index 0000000..e12103a --- /dev/null +++ b/client/screens/SingleTask.tsx @@ -0,0 +1,111 @@ +import React, { useEffect, 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 { getTask, useGetTaskLabel } from '../services/task'; +import { Task } from '../types/task'; +import { Category, categoryToTypeMap, TypeOfTask } from '../types/type'; + +export default function SingleTaskScreen() { + const [taskId] = useState('1'); + const [open, setOpen] = useState(false); + const [taskType, setTaskType] = useState(TypeOfTask.ACTIVITIES); + const label = useGetTaskLabel(taskId); + const [title, setTitle] = useState(null); + const [createdDate, setCreatedDate] = useState(null); + const [notes, setNotes] = useState(''); + + function formatTimestampToTime(timestamp: string): string { + const date = new Date(timestamp); + const hours = date.getHours(); + const minutes = date.getMinutes(); + const ampm = hours >= 12 ? 'PM' : 'AM'; + const formattedHours = hours % 12 === 0 ? 12 : hours % 12; + const formattedMinutes = minutes < 10 ? `0${minutes}` : minutes; + return `${formattedHours}:${formattedMinutes} ${ampm}`; + } + + useEffect(() => { + const fetchTask = async () => { + try { + const task: Task = await getTask(taskId); + setTitle(task.task_title); + setCreatedDate(formatTimestampToTime(task.created_date)); + setNotes(task.notes || ''); + } catch (error) { + console.error('Failed to retrieve Task in Screen.', error); + } + }; + + fetchTask(); + }, [taskId]); // Execute fetchTask when taskId changes + + // Gets category based on Task Type + const getCategoryFromTaskType = (taskType: TypeOfTask): Category => { + 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 + }; + + return ( + + + + + + + + + + {title || 'Doctor’s Appointment'} {'\n'} @ {createdDate} + + {label || ''} + + {getCategoryFromTaskType(taskType) || 'Category Task'} | {taskType} + + + + + + + {notes} + + Additional Notes + + + + + {/* Once backend endpoints for assigning tasks are implemented, then can connect these buttons */} + + + + + ); +} diff --git a/client/services/task.ts b/client/services/task.ts new file mode 100644 index 0000000..885fd10 --- /dev/null +++ b/client/services/task.ts @@ -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 => { + const { data } = await axios.get(`${api_url}/tasks/${taskID}/labels`); + return data.label_name ?? ''; +}; + +export const getTask = async (taskID: string): Promise => { + 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 => { + try { + const task = await getTask(tid); + return task.task_type; + } catch (error) { + console.error('Error fetching task type:', error); + throw error; + } +}; diff --git a/client/types/task.ts b/client/types/task.ts new file mode 100644 index 0000000..dee08ae --- /dev/null +++ b/client/types/task.ts @@ -0,0 +1,18 @@ +import { TypeOfTask } from './type'; + +export interface Task { + task_title: string; + 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?: string; +} diff --git a/client/types/taskInfo.ts b/client/types/taskInfo.ts new file mode 100644 index 0000000..18fd475 --- /dev/null +++ b/client/types/taskInfo.ts @@ -0,0 +1,4 @@ +export interface TaskInfo { + title: string; + // Add other properties if needed +} diff --git a/client/types/taskLabel.ts b/client/types/taskLabel.ts new file mode 100644 index 0000000..3a3e99c --- /dev/null +++ b/client/types/taskLabel.ts @@ -0,0 +1,5 @@ +export interface TaskLabel { + task_id: number; + group_id: number; + label_name: string; +}