Files
klatab/Interface.tsx
2024-09-16 08:13:19 +02:00

191 lines
6.8 KiB
TypeScript

import React, { createContext, useContext, useState, useEffect } from 'react';
import axios from 'axios';
import { SettingsContext } from './SettingsProvider';
import { format } from 'date-fns';
import Settings from './screens/Settings';
import { ThemeButton, ThemeText } from './common/ThemeTypes';
import { StyleSheet, Text, View } from 'react-native';
import { useColors } from './common/colors';
import {decode as atob, encode as btoa} from 'base-64'
let errorObject;
export const InterfaceContext = createContext<any>(null);
const Interface = ({ children }) => {
const colors = useColors();
const { settings } = useContext(SettingsContext);
const [userInformation, setUserInformation] = useState(null);
const [baseData, setBaseData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
const fetchData = async () => {
try {
if (!settings.url) throw new InterfaceError("Invalid URL")
const userinformation = await fetchUserInformation(settings.username);
const basedata = await fetchBaseData();
setUserInformation(userinformation)
setBaseData(basedata)
if (!userinformation || !basedata) throw new InterfaceError("Data returned is Null");
setError(false)
} catch (error) {
console.error(error);
errorObject = error;
setError(true)
} finally {
setLoading(false)
}
}
useEffect(() => {
fetchData();
}, [settings]);
const refresh = () => {
fetchData();
};
const axiosInstance = axios.create({
baseURL: settings.url,
});
axiosInstance.interceptors.request.use(
(config) => {
if (!settings.url) {
throw new InterfaceError("Invalid URL")
}
if (settings.requireAuth) {
const { username, password } = settings;
const token = btoa(`${username}:${password}`);
config.headers.Authorization = `Basic ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
const fetchBaseData = async () => {
return await requestGet('basedata/');
};
const fetchUserInformation = async (username) => {
const userinformation = await requestGet(`userinformation/?username=${username}`, false);
if (!userinformation) {
return await requestGet(`demoinformation/`);
}
return userinformation;
};
const fetchTimes = async () => {
return await requestGet('hours/');
};
const fetchScheduleByWeek = async (type, value, group, week, year) => {
const groupparam = type === 'class' && group ? `&group=${group}` : '';
return await requestGet(`schedule/week/?type=${type}&value=${value}${groupparam}&week=${week}&year=${year}`);
};
const fetchScheduleByDate = async (type, value, group, date) => {
const groupparam = type === 'class' ? `&group=${group}` : '';
return await requestGet(`schedule/date/?type=${type}&value=${value}${groupparam}&date=${format(date, 'yyyy-MM-dd')}`);
};
const fetchAppointments = async (date) => {
return await requestGet(`appointments/?date=${format(date, 'yyyy-MM-dd')}`);
};
const fetchTests = async (type, value, date) => {
return await requestGet(`tests/?type=${type}&value=${value}&date=${format(date, 'yyyy-MM-dd')}`);
};
const fetchDayTypes = async (from, until) => {
return await requestGet(`daytypes/?from=${format(from, 'yyyy-MM-dd')}&until=${format(until, 'yyyy-MM-dd')}`);
};
const fetchFreeRooms = async (date, from, until) => {
return await requestGet(`freerooms/?date=${format(date, 'yyyy-MM-dd')}&from=${from}&until=${until}`);
};
const requestGet = async (url, handleError = true) => {
try {
const response = await axiosInstance.get(url);
if (response.status === 200 && response.data.success === true) {
return response.data.data;
} else {
throw new InterfaceError(response.data.message);
}
} catch (error) {
if (!handleError) {
return null
}else if (error.response) {
if (error.response.data.message){
throw new InterfaceError(error.response.status + ": " + error.response.data.message);
}else if (error.response.status === 404) {
throw new InterfaceError('404: URL wurde auf dem Server nicht gefunden');
} else if (error.response.status === 500) {
throw new InterfaceError('500: Ein unbekannter Fehler ist auf dem Webservice aufgetreten');
} else if (error.response.status === 502) {
throw new InterfaceError('502: Webservice ist unerreichbar');
}
throw new Error(`${error.response.status}: Ein fehler ist auf dem Server aufgetreten`);
} else if (error.request) {
throw new InterfaceError('Netzwerkfehler');
} else {
throw new InterfaceError(error.message || 'Ein unbekannter fehler ist aufgetreten');
}
}
};
const styles = StyleSheet.create({
container: {
paddingTop: 30,
flex: 1,
backgroundColor: colors.backSecondary,
},
titleBox: {
paddingHorizontal: 20,
paddingVertical: 10,
},
title: {
fontSize: 20,
fontWeight: 'bold',
},
button: {
marginTop: 5,
}
})
const renderContent = () => {
if (error) return (
<View style={styles.container}>
<View style={styles.titleBox}>
<ThemeText style={styles.title}>Fehler beim laden der Daten</ThemeText>
<ThemeText>{errorObject?.message}</ThemeText>
<ThemeButton style={styles.button} onPress={refresh}><Text>Neu Versuchen</Text></ThemeButton>
</View>
<Settings />
</View>
)
if (!loading) return (children)
//return (children)
}
return (
<InterfaceContext.Provider value={{ userInformation, baseData, refreshInterface: refresh, fetchBaseData, fetchTimes, fetchScheduleByWeek, fetchScheduleByDate, fetchAppointments, fetchTests, fetchDayTypes, fetchFreeRooms }}>
{renderContent()}
</InterfaceContext.Provider>
);
};
export default Interface;
export class InterfaceError extends Error {
constructor(message) {
super(message);
this.name = "InterfaceError";
}
}