Skip to content

Commit

Permalink
Squashing View Event Commits Event Page #32
Browse files Browse the repository at this point in the history
  • Loading branch information
rhit-villencr committed Dec 20, 2024
1 parent c76de12 commit 4edc865
Show file tree
Hide file tree
Showing 36 changed files with 602 additions and 120 deletions.
10 changes: 8 additions & 2 deletions app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ import AddCalendarEvents from './addCalendarEvents';
import AddHealthEvents from './addHealthEvents';
import AddMeals from './addMeals';
import AddFinanceEvents from './addFinanceEvents';
import ViewEvents from './viewEvents';
import ViewFinanceEvents from './viewFinanceEvents';
import { NavigationContainer } from '@react-navigation/native';
import ViewHealthEvents from './viewHealthEvents';
import ViewCalendarEvents from './viewCalendarEvents';
import ViewMealEvents from './viewMealEvents';


const Stack = createStackNavigator<RootStackParamList>();
Expand Down Expand Up @@ -63,7 +66,10 @@ export default function Layout() {
<Stack.Screen name="addCalendarEvents" component={AddCalendarEvents} />
<Stack.Screen name="addHealthEvents" component={AddHealthEvents} />
<Stack.Screen name="addMeals" component={AddMeals} />
<Stack.Screen name="viewEvents" component={ViewEvents} />
<Stack.Screen name="viewFinanceEvents" component={ViewFinanceEvents} />
<Stack.Screen name="viewHealthEvents" component={ViewHealthEvents} />
<Stack.Screen name="viewCalendarEvents" component={ViewCalendarEvents} />
<Stack.Screen name="viewMealEvents" component={ViewMealEvents} />
</Stack.Navigator>
</NavigationContainer>
);
Expand Down
1 change: 0 additions & 1 deletion app/addHealthEvents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export default function AddHealthEvents() {
{ name: 'event_date', label: 'Date', type: 'date' },
{ name: 'event_time', label: 'Time', type: 'time' },
{ name: 'repeat_timeline', label: 'Repeating', type: 'dropdown', options: repeatingData },
{ name: 'description', label: 'Description', type: 'textarea' },
];

const handleSave = async (saveData: any) => {
Expand Down
2 changes: 1 addition & 1 deletion app/addMeals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default function AddMeals() {
useEffect(() => {
fetchIngredients();
}, []);

cLog("AddMeals: Ingredients:", ingredients);
return (
<GenericAddPageForm
title="New Meal"
Expand Down
23 changes: 18 additions & 5 deletions app/constants.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// export const IPAddr = "http://34.204.83.156:8080" // For AWS
export const IPAddr = "http://137.112.196.177:8080" // For local testing on laptop
export const IPAddr = "http://137.112.197.27:8080" // For local testing on laptop
export const logging = true;

export const repeatingData = [
Expand Down Expand Up @@ -27,14 +27,27 @@ export const formatTime = (time) => {
export const getPageName = (page) => {
switch(page){
case 'finance':
return 'Finance';
return 'viewFinanceEvents';
case 'healthTracker':
return 'Health';
return 'viewHealthEvents';
case 'mealTracker':
return 'Meal';
return 'viewMealEvents';
case 'calendarEvents':
return 'Calendar';
return 'viewCalendarEvents';
default:
return 'Home';
}
};

export const getPageFromEventType = (eventType) => {
switch(eventType){
case 'health':
return 'healthTracker';
case 'meal':
return 'mealTracker';
case 'calendar':
return 'calendarEvents';
default:
return eventType;
}
}
7 changes: 5 additions & 2 deletions app/mainPageTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { RootStackParamList, Task } from '../components/Types';
import { useNavigation } from '@react-navigation/native';
import { StackNavigationProp } from '@react-navigation/stack';
import { cLog } from './log';
import { getPageFromEventType, getPageName } from './constants';
// import { cLog } from './log';

interface FormProps {
Expand All @@ -32,9 +33,11 @@ const GenericMainPageForm: React.FC<FormProps> = ({ title, header, nextPage, thi
const handleViewPress = (item: Task) => {
// cLog(item);
const route = { ...item, thisPage };
if(thisPage === 'index')
if(route.thisPage === 'index'){
route.thisPage = getPageFromEventType(route.event.event_type) as keyof RootStackParamList;
}
cLog("Route:",route);
navigation.navigate('viewEvents', { event: route });
navigation.navigate(getPageName(route.thisPage) as any, { event: route });
}

const renderTask = ({ item }: { item: Task }) => (
Expand Down
54 changes: 54 additions & 0 deletions app/viewCalendarEvents.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';
import axios from 'axios';
import { IPAddr, repeatingData } from './constants';
import { cLog } from './log'
import GenericViewPageForm from './viewEventPage';
import { RouteProp, useRoute } from '@react-navigation/native';
import { RootStackParamList } from '@/components/Types';

type ViewEventsRouteProp = RouteProp<RootStackParamList, 'viewCalendarEvents'>;

export default function ViewCalendarEvents() {
const route = useRoute<ViewEventsRouteProp>();
const { event } = route.params;
cLog("Passed event:", event);
const fields = [
{ name: 'title', label: 'Title', type: 'text' },
{ name: 'event_date', label: 'Date', type: 'date' },
{ name: 'event_time', label: 'Time', type: 'time' },
{ name: 'description', label: 'Description', type: 'textarea' },
{ name: 'repeat_timeline', label: 'Repeating', type: 'dropdown', options: repeatingData },
];
const handleSave = async (saveData: any) => {
try {
cLog("Save Data:", saveData);
const hit = IPAddr + '/update_calendar_event';
cLog('Updating event with:' + hit);
const response = await axios.put(hit, saveData);
cLog('Event updated successfully:' + response.data);
} catch (error) {
console.error('Error updating event:', error);
}
};

let eventDate = event.event.event_date;
if (event.event.event_date != event.event.event_time) {
const dateTimeString = `${event.event.event_date}T${event.event.event_time}`;
eventDate = new Date(dateTimeString);
}

if (eventDate) event.event['event_date'] = eventDate;
if (eventDate) event.event['event_time'] = eventDate;
if (event.event['repeat_timeline']) event.event['repeat_timeline'] = parseInt(event.event['repeat_timeline'], 10);
if (event.event['repeat_timeline'] !== undefined) event.event['repeating'] = event.event['repeat_timeline'] !== 0;

return (
<GenericViewPageForm
title="Calendar Event"
initialData={event.event}
fields={fields}
mainPage='calendarEvents'
onSave={handleSave}
/>
);
}
175 changes: 175 additions & 0 deletions app/viewEventPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import React, { useState } from 'react';
import { View, TextInput, Text, TouchableOpacity, ScrollView } from 'react-native';
import DateTimePicker from '@react-native-community/datetimepicker';
import { Dropdown } from 'react-native-element-dropdown';
import { styles } from './styles';
import { RootStackParamList } from '@/components/Types';
import { StackNavigationProp } from '@react-navigation/stack';
import { useNavigation } from '@react-navigation/native';
import MultiSelect from 'react-native-multiple-select';

interface FormProps {
title: string;
initialData: any;
fields: Array<{ name: string; label: string; type: string; options?: any }>;
mainPage: keyof RootStackParamList;
onSave: (data: any) => void;
}

const GenericViewPageForm: React.FC<FormProps> = ({ title, initialData, fields, mainPage, onSave }) => {
const [formData, setFormData] = useState(initialData);
const [showDatePicker, setShowDatePicker] = useState(false);
const [showTimePicker, setShowTimePicker] = useState(false);
const [currentField, setCurrentField] = useState<string | null>(null); // Tracks which field is being edited

type TrackerNavigationProp = StackNavigationProp<RootStackParamList, keyof RootStackParamList>;
const navigation = useNavigation<TrackerNavigationProp>();

const handleChange = (name: string, value: any) => {
setFormData({ ...formData, [name]: value });
};

const handleDateChange = (name: string, selectedDate: any) => {
if (selectedDate) {
handleChange(name, selectedDate);
setShowDatePicker(false);
}
};

const handleTimeChange = (name: string, event: any, selectedTime: any) => {
if (event.type === 'dismissed') {
setShowTimePicker(false);
} else if (selectedTime) {
handleChange(name, selectedTime);
}
};

const handleSave = () => {
const formattedData = {
...formData,
event_date: formData.event_date?.toISOString().split('T')[0],
event_time: formData.event_time?.toTimeString().split(' ')[0],
};
onSave(formattedData);
navigation.navigate(mainPage as any);
};

const showPicker = (type: 'date' | 'time', fieldName: string) => {
setCurrentField(fieldName);
if (type === 'date') {
setShowDatePicker(true);
} else {
setShowTimePicker(true);
}
};

const handleIngredientChange = (selectedItems: string[]) => {
handleChange('ingredients', selectedItems);
};
return (
<ScrollView contentContainerStyle={styles.addContainer}>
<Text style={styles.sectionHeader}>{title}</Text>
<View>
{fields.map((field, index) => (
<View key={index} style={styles.inputContainer}>
<View style={field.type === 'textarea' ? styles.inLineDescription : styles.inLine}>
<Text style={styles.inputText}>{field.label}</Text>
{field.type === 'text' && (
<TextInput
style={[styles.input, { height: 50 }]}
value={formData[field.name]}
onChangeText={(text) => handleChange(field.name, text)}
placeholder={field.label}
/>
)}
{field.type === 'date' && (
<View style={styles.dateTimeInLine}>
<TouchableOpacity onPress={() => showPicker('date', field.name)}>
<Text style={{ textAlign: 'left' }}>{formData[field.name] ? formData[field.name].toDateString() : 'Select Date'}</Text>
</TouchableOpacity>
{showDatePicker && (
<DateTimePicker
value={currentField ? formData[currentField] || new Date() : new Date()}
mode="date"
display="default"
onChange={(event, selectedDate) => handleDateChange(currentField!, selectedDate)}
/>
)}
</View>
)}
{field.type === 'multi-select' && (
<MultiSelect
items={initialData.allIngredients} // Ensure ingredients is an array
uniqueKey="value"
selectedItems={formData[field.name] || initialData.ingredients} // Default to an empty array
onSelectedItemsChange={(selectedItems) => handleIngredientChange(selectedItems)}
selectText="Select Ingredients"
searchInputPlaceholderText="Search Ingredients..."
displayKey="label"
styleDropdownMenuSubsection={styles.dropdown}
/>
)}
{field.type === 'time' && (
<View style={styles.dateTimeInLine}>
<TouchableOpacity onPress={() => showPicker('time', field.name)}>
<Text style={{ textAlign: 'left' }}>{formData[field.name] ? formData[field.name].toLocaleTimeString() : 'Select Time'}</Text>
</TouchableOpacity>
{showTimePicker && (
<DateTimePicker
minuteInterval={15}
value={currentField ? formData[currentField] || new Date() : new Date()}
mode="time"
display="default"
onChange={(event, selectedTime) => handleTimeChange(currentField!, event, selectedTime)}
/>
)}
</View>
)}
{field.type === 'dropdown' && (
<Dropdown
style={[styles.dropdown, { height: 50, width: '80%' }]}
data={field.options}
maxHeight={300}
labelField="label"
valueField="value"
value={formData[field.name]}
onChange={(item) => handleChange(field.name, item.value)}
placeholder="Select"
/>
)}

{field.type === 'textarea' && (
<TextInput
style={styles.bigInput}
value={formData[field.name]}
onChangeText={(text) => handleChange(field.name, text)}
multiline
placeholder={field.label}
/>
)}
{field.type === 'number' && (
<TextInput
style={[styles.input, { height: 50 }]}
value={formData[field.name]}
onChangeText={(text) => handleChange(field.name, text)}
placeholder={field.label}
keyboardType="numeric"
/>
)}
</View>
</View>
))}
</View>
<View style={styles.saveCancelContainer}>
<TouchableOpacity style={styles.saveButton} onPress={handleSave}>
<Text style={styles.saveText}>Save</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.cancelButton} onPress={() => navigation.navigate(mainPage as any)}>
<Text style={styles.cancelText}>Cancel</Text>
</TouchableOpacity>
</View>
</ScrollView>
);
};

export default GenericViewPageForm;
Loading

0 comments on commit 4edc865

Please sign in to comment.