Files
klatab/screens/Dashboard.tsx
2024-09-15 14:36:20 +02:00

180 lines
5.7 KiB
TypeScript

import React, { useEffect, useState, useContext } from 'react';
import { ScrollView, StyleSheet, View } from 'react-native';
import { RefreshControl } from 'react-native-web-refresh-control';
import ScheduleBuilder from '../common/ScheduleBuilder';
import { InterfaceContext } from '../Interface';
import { SettingsContext } from '../SettingsProvider';
import ErrorBoundary from 'react-native-error-boundary';
import { useColors } from '../common/colors';
import ErrorDisplay from '../common/ErrorDisplay';
import { ThemeText } from '../common/ThemeTypes';
import { addDays, format } from 'date-fns';
let errorObject;
const Dashboard = () => {
const colors = useColors();
const [scheduleData, setScheduleData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
const { fetchTimes, fetchScheduleByDate, refreshInterface, userInformation, fetchTests, fetchAppointments } = useContext(InterfaceContext);
const { settings } = useContext(SettingsContext);
const [tests, setTests] = useState([]);
const [appointments, setAppointments] = useState([]);
const fetchData = async () => {
try {
setLoading(true);
if (!userInformation) {
refreshInterface();
throw new Error("UserInformation is Null");
}
const hours = await fetchTimes();
const date = adjustedDate();
let type = userInformation.usertype === 'pupil' ? 'class' : 'teacher';
let value = userInformation.usertype === 'pupil' ? userInformation.classid : userInformation.id;
const day = await fetchScheduleByDate(type, value, userInformation.group, date);
const testList = await fetchTests(type, value, new Date());
const appointmentList = await fetchAppointments(new Date());
if (!hours || !day || !testList || !appointmentList || !userInformation) throw new Error("Data returned is Null");
setScheduleData({ hours: hours, days: [day], type: type });
setTests(testList);
setAppointments(appointmentList);
setError(false);
} catch (error) {
console.error(error);
errorObject = error;
setError(true);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchData();
}, [settings, userInformation]);
const refresh = () => {
fetchData();
};
const styles = StyleSheet.create({
container: {
display: 'flex',
flexWrap: 'wrap',
flexDirection: 'row',
justifyContent: 'space-between',
},
sideContainer: {
padding: 5,
alignItems: 'center',
flexDirection: 'column',
},
sideSectionContainer: {
borderColor: '#ccc',
borderWidth: 1,
marginBottom: 10,
alignItems: 'center',
justifyContent: 'center',
width: 130,
textAlign: 'center',
},
boxHeader: {
fontWeight: 'bold',
fontSize: 18,
marginBottom: 10,
},
box: {
backgroundColor: colors.backSecondary,
padding: 5,
margin: 5,
width: 110,
maxHeight: 100,
alignItems: 'center',
justifyContent: 'center',
},
noItemsText: {
color: colors.text,
textAlign: 'center',
marginBottom: 10,
},
});
const renderContent = () => {
if (loading && !scheduleData) {
return;
}
if (error) {
return (
<ErrorDisplay message={errorObject?.message} onRefresh={refresh} />
);
}
return (
<ErrorBoundary>
<View style={styles.container}>
<ScheduleBuilder hours={scheduleData.hours} days={scheduleData.days} type={scheduleData.type} />
<View style={styles.sideContainer}>
<View style={styles.sideSectionContainer}>
<ThemeText style={styles.boxHeader}>Prüfungen</ThemeText>
{tests.length > 0 ? (
tests.slice(0, 5).map((test, index) => (
<View key={index} style={styles.box}>
<ThemeText numberOfLines={1}>{format(test.date, 'dd.MM.yyyy')}</ThemeText>
<ThemeText numberOfLines={1}>{`${test.subject} ${test.type}`}</ThemeText>
</View>
))
) : (
<ThemeText style={styles.noItemsText}>Keine Prüfungen vorhanden</ThemeText>
)}
</View>
<View style={styles.sideSectionContainer}>
<ThemeText style={styles.boxHeader}>Termine</ThemeText>
{appointments.length > 0 ? (
appointments.slice(0, 5).map((appointment, index) => (
<View key={index} style={styles.box}>
<ThemeText numberOfLines={2}>{appointment.description}</ThemeText>
</View>
))
) : (
<ThemeText style={styles.noItemsText}>Keine Termine vorhanden</ThemeText>
)}
</View>
</View>
</View>
</ErrorBoundary>
);
};
return (
<ScrollView
// @ts-expect-error - Für Web, TS kennt userSelect nicht
style={{ flex: 1, backgroundColor: colors.backPrimary, userSelect: 'none' }}
refreshControl={<RefreshControl refreshing={loading} onRefresh={refresh} colors={[colors.primary]} />}>
{renderContent()}
</ScrollView>
);
};
export default Dashboard;
function adjustedDate() {
let date = new Date();
// Check if the current time is past 17:30
if (date.getHours() > 17 || (date.getHours() === 17 && date.getMinutes() > 30)) {
date = addDays(date, 1);
}
// Check if the new day is Saturday (6) or Sunday (0)
let day = date.getDay();
if (day === 6) {
date = addDays(date, 2); // Move to Monday
} else if (day === 0) {
date = addDays(date, 1); // Move to Monday
}
return new Date(format(date, 'yyyy-MM-dd'));
}