Migrate to typescript 💥

This commit is contained in:
nikolark committed 2024-07-07 12:39:27 +02:00
1 parent 61337935cf
commit bb75b70021
36 files changed
+392 -131

No files matched your search

@@ -13,8 +13,9 @@ import {
} from 'react-native';
import { Button } from 'react-native-ui-lib';
import theme from 'src/theme';
import logo from '../../../assets/DNS-logo-svart.png';
import theme from '../../theme';
const CHATEAU_NEUF_ADDRESS = 'Det Norske Studentersamfund, Slemdalsveien 15, 0369 Oslo';
@@ -14,7 +14,8 @@ import {
} from 'react-native';
import RenderHtml from 'react-native-render-html';
import theme from '../../theme';
import theme from 'src/theme';
import type { EventDetailProps } from 'src/types/navigation';
moment.locale('nb');
@@ -157,7 +158,7 @@ const EventDetail = ({
route: {
params: { event },
},
}) => {
}: EventDetailProps) => {
const { width } = useWindowDimensions();
return (
<ScrollView>
@@ -5,12 +5,13 @@ import { StyleSheet, View, Platform, SectionList, TouchableOpacity } from 'react
import { Button } from 'react-native-ui-lib';
import 'moment/locale/nb';
import theme from 'src/theme';
import useEventList from './useEventList';
import theme from '../../theme';
moment.locale('nb');
const _formatTime = (time) => {
const formatTime = (time: string) => {
return moment(time).format('llll');
};
@@ -36,7 +37,7 @@ const EventList = () => {
<Text style={styles.listItemTitle} numberOfLines={1}>
{item.title.decoded}
</Text>
<Text style={styles.listItemTime}>{_formatTime(item.start_time)}</Text>
<Text style={styles.listItemTime}>{formatTime(item.start_time)}</Text>
</View>
<View style={styles.arrow}>
<ArrowForwardIcon size={4} color={theme.colors.neufBlack} marginTop={3} />
@@ -80,7 +81,7 @@ const EventList = () => {
refreshing={refreshing}
onRefresh={handleRefresh}
onEndReached={handleLoadMore}
onEndReachedThreshould={10}
onEndReachedThreshold={10}
initialNumToRender={10}
ListFooterComponent={Footer}
style={[styles.card, styles.list]}
@@ -1,9 +1,10 @@
import { useNavigation } from '@react-navigation/native';
import moment from 'moment';
import { useEffect, useState } from 'react';
import 'moment/locale/nb';
import { fetchWithTimeout } from '../../utils';
import 'moment/locale/nb';
import type { EventType } from 'src/types/data';
import { fetchWithTimeout } from 'src/utils';
moment.locale('nb');
@@ -81,8 +82,8 @@ const useEventList = () => {
}, []);
return {
showEvent: (event) => {
navigate('EventDetail', { event });
showEvent: (event: EventType) => {
navigate('EventStack', { screen: 'EventDetail', params: { event } });
},
handleRefresh,
handleLoadMore,
@@ -3,13 +3,14 @@ import React from 'react';
import { ActivityIndicator, Linking, StyleSheet, View, Text } from 'react-native';
import { Button } from 'react-native-ui-lib';
import FormErrors from 'src/components/FormErrors';
import FormInput from 'src/components/FormInput';
import theme from 'src/theme';
import useLogin from './useLogin';
import FormErrors from '../../components/FormErrors';
import FormInput from '../../components/FormInput';
import theme from '../../theme';
const Login = () => {
const { isLoggingIn, errors, control, setFocus, onSubmit } = useLogin();
const { isLoggingIn, errors, setFocus, onSubmit } = useLogin();
return (
<ScrollView>
@@ -19,8 +20,6 @@ const Login = () => {
name="email"
label="E-post / Brukernavn"
keyboardType="email-address"
control={control}
errors={errors}
autoFocus
autoCapitalize="none"
autoCorrect={false}
@@ -30,8 +29,6 @@ const Login = () => {
name="password"
label="Passord"
secureTextEntry
control={control}
errors={errors}
autoCapitalize="none"
autoCorrect={false}
onSubmitEditing={onSubmit}
@@ -1,25 +1,29 @@
import { useNavigation } from '@react-navigation/native';
import { useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { useDispatch, useSelector } from 'react-redux';
import { requestLogin } from '../../api';
import { requestLogin } from 'src/api';
import { useAppDispatch, useAppSelector } from 'src/hooks';
interface LoginFormValues {
email: string;
password: string;
}
const useLogin = () => {
const navigation = useNavigation();
const dispatch = useDispatch();
const dispatch = useAppDispatch();
const isAuthenticated = useSelector((store) => store.isAuthenticated);
const isLoggingIn = useSelector((store) => store.isLoggingIn);
const loginError = useSelector((store) => store.loginError);
const isAuthenticated = useAppSelector((store) => store.isAuthenticated);
const isLoggingIn = useAppSelector((store) => store.isLoggingIn);
const loginError = useAppSelector((store) => store.loginError);
const {
control,
handleSubmit,
formState: { errors },
setFocus,
} = useForm();
} = useForm<LoginFormValues>();
const onSubmit = handleSubmit(({ email, password }) => {
dispatch(requestLogin(email, password));
@@ -32,7 +36,7 @@ const useLogin = () => {
}
}, [isAuthenticated, navigation]);
return { onSubmit, isLoggingIn, control, setFocus, errors: { ...errors, ...loginError } };
return { onSubmit, isLoggingIn, setFocus, errors: { ...errors, ...loginError } };
};
export default useLogin;
@@ -1,10 +1,11 @@
import React from 'react';
import { View, StyleSheet, ActivityIndicator } from 'react-native';
import theme from 'src/theme';
import MembershipInfo from './MembershipInfo';
import Proof from './Proof';
import useMembership from './useMembership';
import theme from '../../theme';
const Membership = () => {
const { isFetchingUserData, onRegisterPress, onLoginPress, onLogoutPress, user, isAuthenticated, fetchUser } =
@@ -2,7 +2,7 @@ import React from 'react';
import { ScrollView, Text, View, StyleSheet } from 'react-native';
import { Button } from 'react-native-ui-lib';
import theme from '../../theme';
import theme from 'src/theme';
const MembershipInfo = ({ onRegister, onLogin }) => (
<ScrollView>
@@ -13,9 +13,10 @@ import {
import Confetti from 'react-native-confetti';
import { Button, Incubator } from 'react-native-ui-lib';
import theme from 'src/theme';
import useProof from './useProof';
import logo from '../../../assets/DNS-logo-svart.png';
import theme from '../../theme';
const { Toast } = Incubator;
@@ -1,28 +1,27 @@
import { useNavigation } from '@react-navigation/native';
import { useEffect, useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { logout } from '../../actions';
import { requestUserData } from '../../api';
import { usePrevious } from '../../hooks';
import { logout } from 'src/actions';
import { requestUserData } from 'src/api';
import { useAppDispatch, useAppSelector, usePrevious } from 'src/hooks';
const useMembership = () => {
const navigation = useNavigation();
const dispatch = useDispatch();
const isAuthenticated = useSelector((store) => store.isAuthenticated);
const isFetchingUserData = useSelector((store) => store.isFetchingUserData);
const lastOrder = useSelector((store) => store.lastOrder);
const user = useSelector((store) => store.user);
const userToken = useSelector((store) => store.userToken);
const dispatch = useAppDispatch();
const isAuthenticated = useAppSelector((store) => store.isAuthenticated);
const isFetchingUserData = useAppSelector((store) => store.isFetchingUserData);
const lastOrder = useAppSelector((store) => store.lastOrder);
const user = useAppSelector((store) => store.user);
const userToken = useAppSelector((store) => store.userToken);
const prevUserToken = usePrevious(userToken);
const prevLastOrder = usePrevious(lastOrder);
const onLogoutPress = () => {
dispatch(logout());
navigation.navigate('Membership');
navigation.navigate('UserStack', { screen: 'Membership' });
};
const onRegisterPress = () => navigation.navigate('UserRegister');
const onLoginPress = () => navigation.navigate('Login');
const onRegisterPress = () => navigation.navigate('UserStack', { screen: 'UserRegister' });
const onLoginPress = () => navigation.navigate('UserStack', { screen: 'Login' });
const fetchUser = useCallback(() => {
dispatch(requestUserData(userToken));
}, [dispatch, userToken]);
@@ -4,7 +4,8 @@ import Constants from 'expo-constants';
import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { requestStripePaymentSheet } from '../../api';
import { requestStripePaymentSheet } from 'src/api';
import { RootState } from 'src/reduxStore';
const PROOF_QUERY = gql`
{
@@ -24,8 +25,8 @@ function getPrice(membershipTypes) {
}
const useProof = ({ user, fetchUser }) => {
const userToken = useSelector((state) => state.userToken);
const chargeError = useSelector((state) => state.chargeError);
const userToken = useSelector((state: RootState) => state.userToken);
const chargeError = useSelector((state: RootState) => state.chargeError);
const { data, loading } = useQuery(PROOF_QUERY);
const { initPaymentSheet, presentPaymentSheet } = useStripe();
const [paymentLoading, setPaymentLoading] = useState(false);
@@ -3,16 +3,16 @@ import React from 'react';
import { ActivityIndicator, StyleSheet, View, Text, ScrollView } from 'react-native';
import { Button, Incubator } from 'react-native-ui-lib';
import FormErrors from 'src/components/FormErrors';
import FormInput from 'src/components/FormInput';
import theme from 'src/theme';
import useUserRegister from './useUserRegister';
import FormErrors from '../../components/FormErrors';
import FormInput from '../../components/FormInput';
import theme from '../../theme';
const { Toast } = Incubator;
const UserRegister = () => {
const { isRegisteringUser, onSubmit, control, isValid, errors, registerError, setFocus, toast, setToast } =
useUserRegister();
const { isRegisteringUser, onSubmit, isValid, errors, registerError, setFocus, toast, setToast } = useUserRegister();
const isDisabled = isRegisteringUser || !isValid;
// TODO: validate on type
// TODO: highlight errorfields
@@ -21,26 +21,11 @@ const UserRegister = () => {
<>
<View style={styles.card}>
<ScrollView>
<FormInput
name="firstName"
label="Fornavn"
control={control}
errors={errors}
autoFocus={true}
onSubmitEditing={() => setFocus('lastName')}
/>
<FormInput
name="lastName"
label="Etternavn"
control={control}
errors={errors}
onSubmitEditing={() => setFocus('email')}
/>
<FormInput name="firstName" label="Fornavn" autoFocus onSubmitEditing={() => setFocus('lastName')} />
<FormInput name="lastName" label="Etternavn" onSubmitEditing={() => setFocus('email')} />
<FormInput
name="email"
label="E-post"
control={control}
errors={errors}
keyboardType="email-address"
autoCapitalize="none"
autoCorrect={false}
@@ -53,17 +38,13 @@ const UserRegister = () => {
<FormInput
name="phoneNumber"
label="Mobilnummer"
control={control}
errors={errors}
keyboardType="phone-pad"
onSubmitEditing={() => setFocus('password')}
/>
<FormInput
name="password"
label="Passord"
control={control}
errors={errors}
secureTextEntry={true}
secureTextEntry
autoCapitalize="none"
autoCorrect={false}
returnKeyType="send"
@@ -1,28 +1,34 @@
import { useNavigation } from '@react-navigation/native';
import { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { useSelector, useDispatch } from 'react-redux';
import { requestRegisterUser } from '../../api';
import { usePrevious } from '../../hooks';
import { requestRegisterUser } from 'src/api';
import { useAppDispatch, useAppSelector, usePrevious } from 'src/hooks';
export interface UserRegisterFormValues {
firstName: string;
lastName: string;
email: string;
phoneNumber: string;
password: string;
}
const useUserRegister = () => {
const dispatch = useDispatch();
const dispatch = useAppDispatch();
const navigation = useNavigation();
const isAuthenticated = useSelector((store) => store.isAuthenticated);
const isRegisteringUser = useSelector((store) => store.isRegisteringUser);
const registerError = useSelector((store) => store.registerError) || {};
const isAuthenticated = useAppSelector((store) => store.isAuthenticated);
const isRegisteringUser = useAppSelector((store) => store.isRegisteringUser);
const registerError = useAppSelector((store) => store.registerError) || {};
const [toast, setToast] = useState(null);
const isAuthenticatedPrev = usePrevious(isAuthenticated);
const {
control,
handleSubmit,
formState: { errors, isValid },
setFocus,
setError,
} = useForm();
} = useForm<UserRegisterFormValues>();
const onSubmit = handleSubmit((values) => {
if (!isValid) {
setToast({
@@ -38,7 +44,7 @@ const useUserRegister = () => {
// Display error messages from API on form fields
Object.keys(registerError).forEach((key) => {
setError(key, { type: 'manual', message: registerError[key] });
setError(key as keyof UserRegisterFormValues, { type: 'manual', message: registerError[key] });
});
});
@@ -48,6 +54,6 @@ const useUserRegister = () => {
}
}, [isAuthenticatedPrev, isAuthenticated, navigation]);
return { isRegisteringUser, onSubmit, control, isValid, registerError, errors, setFocus, toast, setToast };
return { isRegisteringUser, onSubmit, isValid, registerError, errors, setFocus, toast, setToast };
};
export default useUserRegister;