mirror of
				https://gitlab.com/ceda_ei/sonzai.git
				synced 2025-11-04 09:00:05 +01:00 
			
		
		
		
	Complete AddEntry. Add dep date-fns. Change format in HomeScreen.
This commit is contained in:
		@@ -10,7 +10,7 @@ import AddEntry from "./timetable/AddEntry";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const Stack = createStackNavigator();
 | 
					const Stack = createStackNavigator();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function Timetable({ timetable, subjects }) {
 | 
					export default function Timetable({ addTimetableEntry, timetable, subjects }) {
 | 
				
			||||||
	const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
 | 
						const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
 | 
				
			||||||
	return (
 | 
						return (
 | 
				
			||||||
		<Portal.Host><Stack.Navigator headerMode="none">
 | 
							<Portal.Host><Stack.Navigator headerMode="none">
 | 
				
			||||||
@@ -32,6 +32,7 @@ export default function Timetable({ timetable, subjects }) {
 | 
				
			|||||||
							subjects={subjects}
 | 
												subjects={subjects}
 | 
				
			||||||
							day={idx}
 | 
												day={idx}
 | 
				
			||||||
							days={days}
 | 
												days={days}
 | 
				
			||||||
 | 
												addTimetableEntry={addTimetableEntry}
 | 
				
			||||||
						/>
 | 
											/>
 | 
				
			||||||
					)}
 | 
										)}
 | 
				
			||||||
				</Stack.Screen>
 | 
									</Stack.Screen>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,18 +1,192 @@
 | 
				
			|||||||
import React from "react";
 | 
					import React, { useState } from "react";
 | 
				
			||||||
import PropTypes from "prop-types";
 | 
					import PropTypes from "prop-types";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
	IconButton,
 | 
						IconButton,
 | 
				
			||||||
 | 
						Card,
 | 
				
			||||||
 | 
						FAB,
 | 
				
			||||||
 | 
						List,
 | 
				
			||||||
 | 
						Menu,
 | 
				
			||||||
 | 
						Portal,
 | 
				
			||||||
 | 
						Snackbar,
 | 
				
			||||||
 | 
						TextInput,
 | 
				
			||||||
} from "react-native-paper";
 | 
					} from "react-native-paper";
 | 
				
			||||||
 | 
					import {StyleSheet} from "react-native";
 | 
				
			||||||
 | 
					import DateTimePicker from "@react-native-community/datetimepicker";
 | 
				
			||||||
 | 
					import { format } from "date-fns";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function AddEntry({navigation}) {
 | 
					function AddEntry({addTimetableEntry, days, day, subjects, navigation }) {
 | 
				
			||||||
 | 
						const [ subject, setSubject ] = useState({ id: null, name: null });
 | 
				
			||||||
 | 
						const [ showSubjectMenu, setShowSubjectMenu ] = useState(false);
 | 
				
			||||||
 | 
						const [ showTimePicker, setShowTimePicker ] = useState(false);
 | 
				
			||||||
 | 
						// Set to true if date time picker should set start or not
 | 
				
			||||||
 | 
						const [ mode, setMode ] = useState("start");
 | 
				
			||||||
 | 
						const [ start, setStart ] = useState(null);
 | 
				
			||||||
 | 
						const [ end, setEnd ] = useState(null);
 | 
				
			||||||
 | 
						const [ count, setCount ] = useState(0);
 | 
				
			||||||
 | 
						const [ snackbar, setSnackbar ] = useState({ visible: false, message: "" });
 | 
				
			||||||
 | 
						function parseCount(text) {
 | 
				
			||||||
 | 
							const num = parseInt(text);
 | 
				
			||||||
 | 
							if (isNaN(num))
 | 
				
			||||||
 | 
								setCount(0);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								setCount(num);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function onChange(_, selectedDate) {
 | 
				
			||||||
 | 
							setShowTimePicker(false);
 | 
				
			||||||
 | 
							if (selectedDate) {
 | 
				
			||||||
 | 
								switch (mode) {
 | 
				
			||||||
 | 
								case "start":
 | 
				
			||||||
 | 
									setStart(selectedDate);
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								case "end":
 | 
				
			||||||
 | 
									setEnd(selectedDate);
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function submit() {
 | 
				
			||||||
 | 
							if (subject.id === null) {
 | 
				
			||||||
 | 
								setSnackbar({ visible: true, message: "Missing subject." });
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							} else if (start === null) {
 | 
				
			||||||
 | 
								setSnackbar({ visible: true, message: "Missing start time." });
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							} else if (end === null) {
 | 
				
			||||||
 | 
								setSnackbar({ visible: true, message: "Missing end time." });
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							} else if (count === 0) {
 | 
				
			||||||
 | 
								setSnackbar({ visible: true, message: "Missing count." });
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							addTimetableEntry(day, {
 | 
				
			||||||
 | 
								sub_id: subject.id,
 | 
				
			||||||
 | 
								count,
 | 
				
			||||||
 | 
								start,
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
							navigation.pop();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const defTime = (mode == "start" ? start : end) || (new Date);
 | 
				
			||||||
	return (<>
 | 
						return (<>
 | 
				
			||||||
		<IconButton icon="arrow-left" onPress={() => navigation.pop()}/>
 | 
							<IconButton icon="arrow-left" onPress={() => navigation.pop()}/>
 | 
				
			||||||
 | 
							<Card style={style.card}>
 | 
				
			||||||
 | 
								<Card.Title title={`Add Class on ${days[day]}`} />
 | 
				
			||||||
 | 
								<Card.Content>
 | 
				
			||||||
 | 
									<List.Section>
 | 
				
			||||||
 | 
										<Menu
 | 
				
			||||||
 | 
											visible={showSubjectMenu}
 | 
				
			||||||
 | 
											onDismiss={() => setShowSubjectMenu(false)}
 | 
				
			||||||
 | 
											anchor={
 | 
				
			||||||
 | 
												<List.Item
 | 
				
			||||||
 | 
													title="Subject"
 | 
				
			||||||
 | 
													description={subject.name}
 | 
				
			||||||
 | 
													onPress={() => setShowSubjectMenu(true)}
 | 
				
			||||||
 | 
													right={props => <List.Icon {...props} icon="chevron-down" />}
 | 
				
			||||||
 | 
												/>
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										>
 | 
				
			||||||
 | 
											{subjects.map(subject => (
 | 
				
			||||||
 | 
												<Menu.Item
 | 
				
			||||||
 | 
													title={subject.name}
 | 
				
			||||||
 | 
													description={subject.id}
 | 
				
			||||||
 | 
													onPress={() => {
 | 
				
			||||||
 | 
														setSubject(subject);
 | 
				
			||||||
 | 
														setShowSubjectMenu(false);
 | 
				
			||||||
 | 
													}}
 | 
				
			||||||
 | 
													key={subject.id}
 | 
				
			||||||
 | 
												/>
 | 
				
			||||||
 | 
											))}
 | 
				
			||||||
 | 
										</Menu>
 | 
				
			||||||
 | 
										<List.Item
 | 
				
			||||||
 | 
											title="Start"
 | 
				
			||||||
 | 
											description={start && format(start, "HH:mm")}
 | 
				
			||||||
 | 
											onPress={() => {
 | 
				
			||||||
 | 
												setShowTimePicker(true);
 | 
				
			||||||
 | 
												setMode("start");
 | 
				
			||||||
 | 
											}}
 | 
				
			||||||
 | 
										/>
 | 
				
			||||||
 | 
										<List.Item
 | 
				
			||||||
 | 
											title="End"
 | 
				
			||||||
 | 
											description={end && format(end, "HH:mm")}
 | 
				
			||||||
 | 
											onPress={() => {
 | 
				
			||||||
 | 
												setShowTimePicker(true);
 | 
				
			||||||
 | 
												setMode("end");
 | 
				
			||||||
 | 
											}}
 | 
				
			||||||
 | 
										/>
 | 
				
			||||||
 | 
										<TextInput
 | 
				
			||||||
 | 
											keyboardType="numeric"
 | 
				
			||||||
 | 
											label="Count"
 | 
				
			||||||
 | 
											placeholder="How Many Classes does this count for?"
 | 
				
			||||||
 | 
											mode="outlined"
 | 
				
			||||||
 | 
											value={count === 0 ? "" : count.toString()}
 | 
				
			||||||
 | 
											onChangeText={parseCount}
 | 
				
			||||||
 | 
										/>
 | 
				
			||||||
 | 
									</List.Section>
 | 
				
			||||||
 | 
								</Card.Content>
 | 
				
			||||||
 | 
							</Card>
 | 
				
			||||||
 | 
							<Portal>
 | 
				
			||||||
 | 
								<FAB
 | 
				
			||||||
 | 
									visible={!snackbar.visible}
 | 
				
			||||||
 | 
									large
 | 
				
			||||||
 | 
									icon="check"
 | 
				
			||||||
 | 
									onPress={submit}
 | 
				
			||||||
 | 
									style={{
 | 
				
			||||||
 | 
										position: "absolute",
 | 
				
			||||||
 | 
										margin: 16,
 | 
				
			||||||
 | 
										right: 0,
 | 
				
			||||||
 | 
										bottom: 0,
 | 
				
			||||||
 | 
									}}
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
							</Portal>
 | 
				
			||||||
 | 
							{showTimePicker && (
 | 
				
			||||||
 | 
								<DateTimePicker
 | 
				
			||||||
 | 
									testID="dateTimePicker"
 | 
				
			||||||
 | 
									timeZoneOffsetInMinutes={0}
 | 
				
			||||||
 | 
									value={defTime}
 | 
				
			||||||
 | 
									mode="time"
 | 
				
			||||||
 | 
									is24Hour={true}
 | 
				
			||||||
 | 
									display="default"
 | 
				
			||||||
 | 
									onChange={onChange}
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
							)}
 | 
				
			||||||
 | 
							<Snackbar
 | 
				
			||||||
 | 
								visible={snackbar.visible}
 | 
				
			||||||
 | 
								onDismiss={() => setSnackbar({ ...snackbar, visible: false })}
 | 
				
			||||||
 | 
								action={{
 | 
				
			||||||
 | 
									label: "Dismiss",
 | 
				
			||||||
 | 
									onPress: () => setSnackbar({ ...snackbar, visible: false }),
 | 
				
			||||||
 | 
								}}
 | 
				
			||||||
 | 
							>
 | 
				
			||||||
 | 
								{snackbar.message}
 | 
				
			||||||
 | 
							</Snackbar>
 | 
				
			||||||
	</>);
 | 
						</>);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AddEntry.propTypes = {
 | 
					AddEntry.propTypes = {
 | 
				
			||||||
 | 
						addTimetableEntry: PropTypes.func,
 | 
				
			||||||
	subjects: PropTypes.array,
 | 
						subjects: PropTypes.array,
 | 
				
			||||||
	navigation: PropTypes.object,
 | 
						navigation: PropTypes.object,
 | 
				
			||||||
 | 
						days: PropTypes.array,
 | 
				
			||||||
 | 
						day: PropTypes.number,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const style = StyleSheet.create({
 | 
				
			||||||
 | 
						card: {
 | 
				
			||||||
 | 
							marginTop: 12,
 | 
				
			||||||
 | 
							marginLeft: 10,
 | 
				
			||||||
 | 
							marginRight: 10,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						text: {
 | 
				
			||||||
 | 
							marginTop: 12,
 | 
				
			||||||
 | 
							textAlign: "center",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						class: {
 | 
				
			||||||
 | 
							flexDirection: "row",
 | 
				
			||||||
 | 
							justifyContent: "space-between"
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default AddEntry;
 | 
					export default AddEntry;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,6 +13,7 @@ import {
 | 
				
			|||||||
	StyleSheet,
 | 
						StyleSheet,
 | 
				
			||||||
	ScrollView
 | 
						ScrollView
 | 
				
			||||||
} from "react-native";
 | 
					} from "react-native";
 | 
				
			||||||
 | 
					import { format } from "date-fns";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function HomeScreen({ theme, timetable, subjects, navigation, days }) {
 | 
					function HomeScreen({ theme, timetable, subjects, navigation, days }) {
 | 
				
			||||||
	return (<ScrollView>
 | 
						return (<ScrollView>
 | 
				
			||||||
@@ -31,8 +32,8 @@ function HomeScreen({ theme, timetable, subjects, navigation, days }) {
 | 
				
			|||||||
					{day.map((cls, idx) => {
 | 
										{day.map((cls, idx) => {
 | 
				
			||||||
						const subject = subjects.find(i => i.id === cls.sub_id);
 | 
											const subject = subjects.find(i => i.id === cls.sub_id);
 | 
				
			||||||
						return (<View key={idx} style={style.class}>
 | 
											return (<View key={idx} style={style.class}>
 | 
				
			||||||
 | 
												<Text>{format(cls.start, "HH:mm")} to {format(cls.end, "HH:mm")}</Text>
 | 
				
			||||||
							<Text>{subject.name}</Text>
 | 
												<Text>{subject.name}</Text>
 | 
				
			||||||
							<Text>{cls.start} to {cls.end}</Text>
 | 
					 | 
				
			||||||
							<Text>{cls.count}</Text>
 | 
												<Text>{cls.count}</Text>
 | 
				
			||||||
						</View>);
 | 
											</View>);
 | 
				
			||||||
					})}
 | 
										})}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,10 +11,12 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@react-native-community/async-storage": "^1.8.1",
 | 
					    "@react-native-community/async-storage": "^1.8.1",
 | 
				
			||||||
 | 
					    "@react-native-community/datetimepicker": "^2.3.0",
 | 
				
			||||||
    "@react-native-community/masked-view": "^0.1.7",
 | 
					    "@react-native-community/masked-view": "^0.1.7",
 | 
				
			||||||
    "@react-navigation/native": "^5.1.0",
 | 
					    "@react-navigation/native": "^5.1.0",
 | 
				
			||||||
    "@react-navigation/stack": "^5.2.1",
 | 
					    "@react-navigation/stack": "^5.2.1",
 | 
				
			||||||
    "buffer": "^5.5.0",
 | 
					    "buffer": "^5.5.0",
 | 
				
			||||||
 | 
					    "date-fns": "^2.11.0",
 | 
				
			||||||
    "react": "16.9.0",
 | 
					    "react": "16.9.0",
 | 
				
			||||||
    "react-native": "0.61.5",
 | 
					    "react-native": "0.61.5",
 | 
				
			||||||
    "react-native-gesture-handler": "^1.6.0",
 | 
					    "react-native-gesture-handler": "^1.6.0",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								yarn.lock
									
									
									
									
									
								
							@@ -966,6 +966,13 @@
 | 
				
			|||||||
    wcwidth "^1.0.1"
 | 
					    wcwidth "^1.0.1"
 | 
				
			||||||
    ws "^1.1.0"
 | 
					    ws "^1.1.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"@react-native-community/datetimepicker@^2.3.0":
 | 
				
			||||||
 | 
					  version "2.3.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-2.3.0.tgz#fd3e430ef608a92af77f841f2a4593d8f03693c4"
 | 
				
			||||||
 | 
					  integrity sha512-kEmhnvkVm0/WJxle2Oze1Wu5pSO65jeP6vdVJzglgQDI3X9bHUlId0JTKZPpDAB9nFUM8cp5X5RSR0KW0SbFsA==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    invariant "^2.2.4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@react-native-community/eslint-config@^0.0.5":
 | 
					"@react-native-community/eslint-config@^0.0.5":
 | 
				
			||||||
  version "0.0.5"
 | 
					  version "0.0.5"
 | 
				
			||||||
  resolved "https://registry.npmjs.org/@react-native-community/eslint-config/-/eslint-config-0.0.5.tgz#584f6493258202a57efc22e7be66966e43832795"
 | 
					  resolved "https://registry.npmjs.org/@react-native-community/eslint-config/-/eslint-config-0.0.5.tgz#584f6493258202a57efc22e7be66966e43832795"
 | 
				
			||||||
@@ -2082,6 +2089,11 @@ data-urls@^1.0.0:
 | 
				
			|||||||
    whatwg-mimetype "^2.2.0"
 | 
					    whatwg-mimetype "^2.2.0"
 | 
				
			||||||
    whatwg-url "^7.0.0"
 | 
					    whatwg-url "^7.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					date-fns@^2.11.0:
 | 
				
			||||||
 | 
					  version "2.11.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.11.0.tgz#ec2b44977465b9dcb370021d5e6c019b19f36d06"
 | 
				
			||||||
 | 
					  integrity sha512-8P1cDi8ebZyDxUyUprBXwidoEtiQAawYPGvpfb+Dg0G6JrQ+VozwOmm91xYC0vAv1+0VmLehEPb+isg4BGUFfA==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dayjs@^1.8.15:
 | 
					dayjs@^1.8.15:
 | 
				
			||||||
  version "1.8.21"
 | 
					  version "1.8.21"
 | 
				
			||||||
  resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.8.21.tgz#98299185b72b9b679f31c7ed987b63923c961552"
 | 
					  resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.8.21.tgz#98299185b72b9b679f31c7ed987b63923c961552"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user