Skip to content

Commit

Permalink
Merge branch 'andrew_testing' of github.com:andrew-bierman/PackRat in…
Browse files Browse the repository at this point in the history
…to fix-map
  • Loading branch information
taronaleksanian committed Sep 10, 2024
2 parents dce9fdd + b74f67e commit dbb7cb1
Show file tree
Hide file tree
Showing 36 changed files with 1,886 additions and 338 deletions.
42 changes: 23 additions & 19 deletions packages/app/components/card/PackCardHeader/PackCardHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@ import useTheme from 'app/hooks/useTheme';
import { CustomCardHeader } from '../CustomCardHeader';
import { AntDesign, MaterialIcons } from '@expo/vector-icons';
import { useAuthUser } from 'app/modules/auth';
import {
RStack,
RIconButton,
EditableText,
DropdownComponent,
} from '@packrat/ui';
import { CascadedDropdownComponent } from '@packrat/ui/src/CascadedDropdown';
import { EditableText } from '@packrat/ui/src/EditableText';
import RStack from '@packrat/ui/src/RStack';
import RIconButton from '@packrat/ui/src/RIconButton';
import { useFetchSinglePack, useDeletePack } from 'app/modules/pack';
import { usePackTitleInput } from './usePackTitleInput';
import { usePackActions } from './usePackActions';
import { useRouter } from 'app/hooks/router';
import { Platform, View } from 'react-native';
import useResponsive from 'app/hooks/useResponsive';
import { EditPackModal } from 'app/modules/pack/components/EditPackModal';

interface PackCardHeaderProps {
data: any;
Expand All @@ -31,24 +29,20 @@ export const PackCardHeader = ({ data, title }: PackCardHeaderProps) => {
const { handleDeletePack } = useDeletePack(data.id);
const {
handleActionsOpenChange,
handleEdit,
handleSaveTitle,
isEditMode,
isOpen,
setIsOpen,
} = usePackTitleInput(data);
isEditModalOpen,
setIsEditModalOpen,
isTitleEditMode,
} = usePackActions({ data, refetch });

const { isDark } = useTheme();
const router = useRouter();

const optionValues: optionValues[] = [
{ label: 'Edit', value: 'Edit' },
{ label: 'Save', value: 'Save' },
{ label: 'Delete', value: 'Delete' },
];

const { xxs, xs, xxl } = useResponsive();

return (
<>
<CustomCardHeader
Expand Down Expand Up @@ -86,7 +80,7 @@ export const PackCardHeader = ({ data, title }: PackCardHeaderProps) => {
<EditableText
isLoading={isLoading}
defaultValue={title}
isFocused={isEditMode}
isFocused={isTitleEditMode}
onSave={handleSaveTitle}
/>
</RStack>
Expand All @@ -99,15 +93,17 @@ export const PackCardHeader = ({ data, title }: PackCardHeaderProps) => {
maxWidth: 100,
}}
>
<DropdownComponent
<CascadedDropdownComponent
value={null}
data={optionValues}
onValueChange={(value) => handleActionsOpenChange(value)}
placeholder={
<RIconButton
backgroundColor="transparent"
icon={<MaterialIcons name="more-horiz" size={20} />}
style={{ paddingTop: 20 }}
style={{
height: 20,
}}
/>
}
native={true}
Expand All @@ -116,6 +112,14 @@ export const PackCardHeader = ({ data, title }: PackCardHeaderProps) => {
)
}
/>
<EditPackModal
currentPack={data}
isOpen={isEditModalOpen}
onClose={() => {
setIsEditModalOpen(false);
}}
refetch={refetch}
/>
</>
);
};
42 changes: 42 additions & 0 deletions packages/app/components/card/PackCardHeader/usePackActions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useEditPack, useDeletePack } from 'app/modules/pack';
import { useState } from 'react';

export const usePackActions = ({ data, refetch }) => {
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
const [isTitleEditMode, setIsTitleEditMode] = useState(false);
const { editPack } = useEditPack();
const { handleDeletePack } = useDeletePack(data.id);

const handleActionsOpenChange = (state) => {
switch (state) {
case 'Edit':
setIsEditModalOpen(true);
break;
case 'Delete':
handleDeletePack();
break;
}
};

const handleSaveTitle = (title) => {
const packDetails = {
id: data.id,
name: title,
is_public: data.is_public,
};
editPack(packDetails, {
onSuccess: () => {
refetch?.();
},
});
setIsTitleEditMode(false);
};

return {
handleActionsOpenChange,
isTitleEditMode,
isEditModalOpen,
setIsEditModalOpen,
handleSaveTitle,
};
};
61 changes: 0 additions & 61 deletions packages/app/components/card/PackCardHeader/usePackTitleInput.ts

This file was deleted.

49 changes: 40 additions & 9 deletions packages/app/config/trpcAxiosClient.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import axios, { AxiosResponse } from 'axios';
import axios, { AxiosError, AxiosResponse } from 'axios';
import { toast } from 'app/utils/ToastUtils';
import { logoutAuthUser } from 'app/utils/userUtils';
import { getErrorMessageFromError } from 'app/utils/apiUtils';
import { Storage } from 'app/utils/storage';
import { vanillaTrpcClient } from 'app/trpc';
import { TRPCErrorResponse } from '@trpc/server/rpc';
import { TRPCClientError } from '@trpc/client';

const REQUESTS_TO_SKIP_SUCCESS_MESSAGE = [
'getMe',
Expand Down Expand Up @@ -34,21 +38,48 @@ const responseInterceptor = (response: AxiosResponse) => {
return response;
};

const responseErrorInterceptor = (response: AxiosResponse) => {
if (response?.response?.data?.error?.data?.httpStatus === 401) {
logoutAuthUser();
const responseErrorInterceptor = async (
error: AxiosError<TRPCErrorResponse>,
) => {
const data = error?.response?.data;
const isUnauthorized = (item) => item?.error?.data?.httpStatus === 401;
// check auth error in both single or multiple objects response
const hasUnauthorizedError = Array.isArray(data)
? data.some(isUnauthorized)
: isUnauthorized(data);

if (data && hasUnauthorizedError) {
const refreshToken = await Storage.getItem('refreshToken');

if (!refreshToken) return; // user is logged out if refreshToken isn't present

// maybe token expired? try refreshing.
try {
const tokens = await vanillaTrpcClient.refreshToken.query(refreshToken);
await Storage.setItem('token', tokens.accessToken);
await Storage.setItem('refreshToken', tokens.refreshToken);

// rety request
error.config.headers.Authorization = 'Bearer ' + tokens.accessToken;
return await axios.request(error.config);
} catch (error) {
// refreshToken has also expired. Logout user.
if (error instanceof TRPCClientError && error.data.code == 'UNAUTHORIZED')
logoutAuthUser();
return error;
}
}

if (
response.config.method === 'get' ||
error.config.method === 'get' ||
REQUESTS_TO_SKIP_ERROR_MESSAGE.some((url) =>
response.config.url?.includes?.(url),
error.config.url?.includes?.(url),
)
) {
return response;
return error;
}

const responseMessage = getErrorMessageFromError(response);
const responseMessage = getErrorMessageFromError(error);

if (responseMessage) {
toast({
Expand All @@ -58,7 +89,7 @@ const responseErrorInterceptor = (response: AxiosResponse) => {
});
}

return response;
return error;
};

axiosInstance.interceptors.response.use(
Expand Down
4 changes: 2 additions & 2 deletions packages/app/modules/auth/hooks/useLogin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ export const useLogin = (): UseLoginReturn => {
const handleLogin: UseLoginReturn['handleLogin'] = (data) => {
const { email, password } = data;
signIn({ email, password })
.then((user) => {
sessionSignIn(user);
.then((tokens) => {
sessionSignIn(tokens);
})
.catch(() => {});
};
Expand Down
12 changes: 10 additions & 2 deletions packages/app/modules/auth/hooks/useLogout.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import { Storage } from 'app/utils/storage';
import { useUserSetter } from './useUserSetter';
import { queryTrpc } from 'app/trpc';

export const useLogout = () => {
const setUser = useUserSetter();
const utils = queryTrpc.useUtils();

const logout = () => {
const logout = async () => {
setUser(null);
Storage.removeItem('token');
try {
await utils.logout.fetch(await Storage.getItem('refreshToken'));
} catch {
// pass
}
await Storage.removeItem('token');
await Storage.removeItem('refreshToken');
};

return logout;
Expand Down
14 changes: 6 additions & 8 deletions packages/app/modules/auth/hooks/useSessionSignIn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@ export const useSessionSignIn = () => {
const setUser = useUserSetter();
const router = useRouter();

const sessionSignIn = useCallback((user) => {
if (user?.token) {
(async () => {
setUser(user);
await Storage.setItem('token', user.token);
router.push('/');
})();
}
const sessionSignIn = useCallback((tokens) => {
(async () => {
await Storage.setItem('token', tokens.accessToken);
await Storage.setItem('refreshToken', tokens.refreshToken);
router.push('/');
})();
}, []);

return sessionSignIn;
Expand Down
38 changes: 22 additions & 16 deletions packages/app/modules/auth/screens/LoginScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import useTheme from '../../../hooks/useTheme';
import { useGoogleAuth, useLogin } from 'app/modules/auth';
import { SignInScreen } from '@packrat/ui/src/Bento/forms/layouts';
import { View } from 'react-native';
import { ScrollView } from 'react-native';

const demoUser = {
email: '[email protected]',
Expand Down Expand Up @@ -35,25 +36,30 @@ export function LoginScreen() {
<View
style={{
width: '100%',
alignItems: 'center',
height: '100%',
backgroundColor: currentTheme.colors.background,
}}
>
<View
style={{
paddingTop: 32,
paddingBottom: 32,
width: '90%',
maxWidth: 400,
}}
>
<SignInScreen
promptAsync={promptAsync}
signIn={signIn}
signInStatus={signInStatus}
isGoogleSignInReady={isGoogleSignInReady}
/>
</View>
<ScrollView>
<View
style={{
paddingTop: 32,
paddingBottom: 32,
justifyContent: 'center',
alignSelf: 'center',
alignItems: 'center',
width: '90%',
maxWidth: 400,
}}
>
<SignInScreen
promptAsync={promptAsync}
signIn={signIn}
signInStatus={signInStatus}
isGoogleSignInReady={isGoogleSignInReady}
/>
</View>
</ScrollView>
</View>
);
}
Loading

0 comments on commit dbb7cb1

Please sign in to comment.