Skip to content

Commit

Permalink
Merge pull request #163 from Dindb-dong/feat/144/MyPage
Browse files Browse the repository at this point in the history
#116: UserRole settings
  • Loading branch information
kimheonningg authored Nov 16, 2024
2 parents f705068 + 2ee9f1c commit bbcb8c0
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 53 deletions.
45 changes: 27 additions & 18 deletions App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useContext } from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
import { NavigationContainer, DefaultTheme } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
Expand All @@ -18,7 +18,7 @@ import OrderManagementIcon from './src/assets/navbar/OrderManagement.svg';
import SignIn from './src/components/Auth/SignIn';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { BottomBarProvider, useBottomBar } from './contexts/BottomBarContext';
import { LoginProvider, UserProvider } from './src/common/Context';
import { LoginContext, LoginProvider, UserProvider } from './src/common/Context';
import Reformer from './src/components/Auth/Reformer/Reformer';
import SplashScreen from './src/common/SplashScreen';

Expand All @@ -27,7 +27,6 @@ import { getUserRole } from './src/common/storage';
export type StackProps = {
Main: undefined;
Signin: undefined;
ReformProfile: undefined;
};

const AppStack = createNativeStackNavigator<StackProps>(); // 최상위 스택. SignInStack에는 바텀바 안 뜸.
Expand All @@ -52,19 +51,18 @@ function App(): React.JSX.Element {
<BottomBarProvider>
<GestureHandlerRootView style={{ flex: 1 }}>
<LoginProvider>
<UserProvider>
<NavigationContainer theme={GlobalTheme}>
{!isSplashFinished ? (
<SplashScreen onFinish={finishSplash} />
) : (
<NavigationContainer theme={GlobalTheme}>
{!isSplashFinished ? (
<SplashScreen onFinish={finishSplash} />
) : (
<UserProvider>
<AppStack.Navigator screenOptions={{ headerShown: false }}>
<AppStack.Screen name="Main" component={MainTabNavigator} />
<AppStack.Screen name="Signin" component={SignIn} />
<AppStack.Screen name="ReformProfile" component={Reformer} />
</AppStack.Navigator>
)}
</NavigationContainer>
</UserProvider>
</UserProvider>
)}
</NavigationContainer>
</LoginProvider>
</GestureHandlerRootView>
</BottomBarProvider>
Expand Down Expand Up @@ -152,23 +150,34 @@ const Tab = createBottomTabNavigator<TabProps>();

// 하단 탭 네비게이터 정의
const MainTabNavigator = () => {
const [userInfo, setUserInfo] = useState<string>();

const [userInfo, setUserInfo] = useState<string>('customer');
const { isLogin } = useContext(LoginContext);
useEffect(() => {
const getUserRoleInfo = async () => {
const userRole = await getUserRole();
setUserInfo(userRole ? userRole : '');
if (isLogin) {
const userRole = await getUserRole();
console.log('유저롤을 설정합니다:', userRole);
setUserInfo(userRole || 'customer');
} else {
setUserInfo('customer'); // 로그인하지 않은 경우 기본값
}
};

getUserRoleInfo();
}, []);
}, [isLogin]); // isLogin 변경 시 동작

// userInfo가 null인 상태에서는 로딩 UI를 표시
if (userInfo === null) {
return null; // 혹은 로딩 스피너를 렌더링
}

return (
<Tab.Navigator
tabBar={props => <CustomTab {...props} />}
initialRouteName="UPCY"
screenOptions={{ headerShown: false }}>
<Tab.Screen name="UPCY" component={HomeScreen} />
{userInfo === 'reformer' && (
{isLogin && userInfo === 'reformer' && (
<Tab.Screen name="주문관리" component={OrderManagement} />
)}
<Tab.Screen name="MY" component={MyPageScreen} />
Expand Down
43 changes: 25 additions & 18 deletions src/common/Context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@ export const UserContext = createContext<{
}>({
user: null,
role: '',
setUser: () => {},
setRole: () => {},
setUser: () => { },
setRole: () => { },
});

export const UserProvider = ({ children }: { children: ReactNode }) => {
function sanitizeUserData(data: any) {
// null 오류 안 나도록 기본값 설정
return {
email: data.email || '',
phone: data.phone || '',
Expand All @@ -42,13 +41,19 @@ export const UserProvider = ({ children }: { children: ReactNode }) => {
}

const [user, setUser] = useState<UserType | null>(null);
const [role, setRole] = useState<string>(''); // 빈 문자열로 초기화
const [role, setRole] = useState<string>('');
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
const { isLogin } = useContext(LoginContext); // 로그인 상태 가져오기
const request = Request();

useEffect(() => {
const fetchUserData = async () => {
if (!isLogin) {
setUser(null); // 로그인하지 않은 상태라면 유저 데이터를 초기화
return;
}

const accessToken = await getAccessToken();
try {
if (accessToken) {
Expand All @@ -57,34 +62,33 @@ export const UserProvider = ({ children }: { children: ReactNode }) => {
};
const response = await request.get(`/api/user`, {}, headers);
if (response && response.status === 200) {
console.log('유저 데이터를 저장합니다.');
const sanitizedUserData = sanitizeUserData(response.data);
setUser(sanitizedUserData); // 전역 상태에 유저 데이터를 저장
setUser(sanitizedUserData);
setRole(sanitizedUserData.role);
setUserRole(sanitizedUserData.role);
console.log('Saving credentials:', sanitizedUserData);
} else if (response && response.status === 404) {
console.log('유저 정보가 없습니다. 로그아웃 상태로 유지합니다.');
setUser(null);
} else if (response && response.status === 401) {
console.log('Unauthorized access. Please log in again.');
} else {
setError('유저 정보를 불러오는 중 문제가 발생했습니다.');
setError('Error fetching user data.');
}
} else {
console.log(
'access token 정보가 없습니다. 로그아웃 상태로 유지합니다.',
);
console.log('No access token found. User remains logged out.');
setUser(null);
}
} catch (err) {
console.error(err);
setError('유저 정보를 가져오는 중 에러가 발생했습니다.');
Alert.alert('Error', '유저 정보를 가져오는 중 오류가 발생했습니다.');
setError('Error occurred while fetching user data.');
} finally {
setLoading(false); // 로딩 상태 종료
setLoading(false);
}
};

fetchUserData(); // Provider가 마운트될 때 유저 데이터 가져옴
}, []);
fetchUserData();
}, [isLogin]); // 로그인 상태가 변경될 때만 유저 데이터를 다시 가져옴

return (
<UserContext.Provider value={{ user, role, setUser, setRole }}>
{children}
Expand All @@ -96,15 +100,18 @@ export const useUser = () => useContext(UserContext);

export const LoginContext = createContext({
isLogin: false,
setLogin: (value: boolean) => {},
setLogin: (value: boolean) => { },
});

export const LoginProvider = ({ children }: { children: ReactNode }) => {
const [isLogin, setIsLogin] = useState<boolean>(false);
const { setUser, setRole } = useUser();
const { setUser, role, setRole } = useUser();

const logout = () => {
setRole('customer');
console.log(role);
console.log('Context의 로그아웃 실행');

setIsLogin(false);
};

Expand Down
11 changes: 10 additions & 1 deletion src/common/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,16 @@ export async function getUserRole() {
}

export function setUserRole(role) {
setSecureValue(userRole, role);
const username = userRole; // key 이름
const password = role; // 저장할 market_uuid 값

Keychain.setInternetCredentials(userRole, username, password)
.then(() => {
console.log("Market UUID saved successfully");
})
.catch(error => {
console.error("Failed to save Market UUID:", error);
});
}

const marketUUIDKeyName = 'marketUUID';
Expand Down
14 changes: 14 additions & 0 deletions src/components/Auth/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,28 @@ export async function processLoginResponse( // 통상 로그인시 호출 함수
setLogin: (value: boolean) => void,
setUser: (user: UserType) => void // setUser 전달
) {
const request = Request();
// const navigation = useNavigation<StackNavigationProp<MyPageProps>>();
if (response?.status === 200) {
const accessToken = await response.data.access;
const refreshToken = await response.data.refresh;
const headers = {
Authorization: `Bearer ${accessToken}`
}
setAccessToken(accessToken);
setRefreshToken(refreshToken);
console.log({ accessToken }, ',', { refreshToken });
setLogin(true);
try { // 유저 롤 설정 // 근데 이걸 꼭 여기서 할 필요가 있나? 혹시 모르니 만들어두긴 함
const response = await request.get(`/api/user`, {}, headers)
if (response?.status === 200) {
const user_role = response.data.role;
setUserRole(user_role);
}
} catch (err) {
console.log(err);
console.log('유저롤 설정 오류');
}
navigate(); // 인자로 전달받은 네비게이팅 수행
console.log('로그인 성공');

Expand Down
16 changes: 12 additions & 4 deletions src/components/Auth/Reformer/ReformFormCareer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { err } from 'react-native-svg';
import { useNavigation } from '@react-navigation/native';
import { StackNavigationProp } from '@react-navigation/stack';
import { SignInParams } from '../SignIn';
import { getAccessToken, getMarketUUID, setMarketUUID } from '../../../common/storage';
import { getAccessToken, getMarketUUID, getUserRole, setMarketUUID } from '../../../common/storage';
import { PhotoType } from '../../../hooks/useImagePicker';

const SelectView = styled.View`
Expand Down Expand Up @@ -809,7 +809,6 @@ export default function ReformCareer({ fix, form, setForm }: ReformProps) {
setForm(prev => {
return { ...prev, introduce: response.data.introduce }
})
console.log('패치된 데이터:', form);
}
} catch (err) {
console.error(err);
Expand Down Expand Up @@ -958,15 +957,24 @@ export default function ReformCareer({ fix, form, setForm }: ReformProps) {
onPress={!fix ? handleSubmit : handleFix}
style={{ width: '90%', alignSelf: 'center', marginBottom: 10 }}
/>
{fix &&
{fix && <View>
<BottomButton
value="check"
pressed={false}
onPress={() => {
console.log(form);
}}
style={{ width: '90%', alignSelf: 'center', marginBottom: 10 }}
/>}
/>
<BottomButton
value="role"
pressed={false}
onPress={() => {

}}
style={{ width: '90%', alignSelf: 'center', marginBottom: 10 }}
/>
</View>}
</View>
{careerIndex >= 0 && (
<CareerModal
Expand Down
6 changes: 5 additions & 1 deletion src/components/Auth/Reformer/ReformerMyPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import DetailScreenHeader from '../../../components/Home/components/DetailScreen
import { PhotoType } from '../../../hooks/useImagePicker.ts';
import Request from '../../../common/requests.js';
import { MypageStackProps } from '../../../pages/MyPage.tsx';
import { getAccessToken, getRefreshToken, removeAccessToken, removeRefreshToken } from '../../../common/storage.js';
import { getAccessToken, getRefreshToken, getUserRole, removeAccessToken, removeRefreshToken, setUserRole } from '../../../common/storage.js';
import { CommonActions, useFocusEffect } from '@react-navigation/native';
import { Title20B } from '../../../styles/GlobalText.tsx';
import DeleteModal from '../DeleteModal.tsx';
Expand Down Expand Up @@ -212,6 +212,7 @@ export const ReformerMyPageScreen = ({ navigation, route }: MypageStackProps) =>
};

const Logout = async () => {
const role = getUserRole();
const accessToken = await getAccessToken();
const refreshToken = await getRefreshToken();
const params = {
Expand All @@ -227,6 +228,9 @@ export const ReformerMyPageScreen = ({ navigation, route }: MypageStackProps) =>
removeAccessToken();
removeRefreshToken();
setLogin(false);
setUserRole('customer');
console.log('유저롤:', role);

navigation.dispatch(
CommonActions.navigate({
name: "Main",
Expand Down
2 changes: 2 additions & 0 deletions src/components/Auth/Upcyer/UpcyerMyPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
removeAccessToken,
removeNickname,
removeRefreshToken,
setUserRole,
} from '../../../common/storage';
import { useCallback, useContext, useEffect, useRef, useState } from 'react';
import { LoginContext } from '../../../common/Context';
Expand Down Expand Up @@ -225,6 +226,7 @@ export const UpcyerMyPageMainScreen = ({ navigation, route }: MypageStackProps)
removeAccessToken();
removeRefreshToken();
setLogin(false);
setUserRole('customer');
console.log('AccessToken: ', { accessToken }, '| RefreshToken: ', { refreshToken });
navigation.dispatch(
CommonActions.navigate({
Expand Down
2 changes: 1 addition & 1 deletion src/components/Home/Market/ServicePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const ServicePage: React.FC<ServicePageProps> = ({
return (
<Tabs.ScrollView
ref={scrollViewRef}
style={{ marginBottom: service || product ? 60 : -2000 }}
// style={{ marginBottom: service || product ? 60 : -2000 }}
bounces={false}
overScrollMode="never">
<View style={styles.container}>
Expand Down
23 changes: 16 additions & 7 deletions src/pages/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { stylesList } from '../components/Home/HomeMain';
import SearchPage from './SearchPage';
import { ServiceDetailOption } from '../components/Home/Market/Service';
import ReportPage from './ReportPage';
import { getUserRole } from '../common/storage';

export type HomeStackParams = {
Home: { searchTerm?: string };
Expand Down Expand Up @@ -202,6 +203,11 @@ const HomeMainScreen = ({
const [selectedStylesList, setSelectedStylesList] =
useState<string[]>(stylesList);

const checkRole = async () => {
const role = await getUserRole();
console.log('유저롤:', role);
}

return (
<Fragment>
<SafeAreaView style={{ flex: 0, backgroundColor: PURPLE }} />
Expand All @@ -212,20 +218,23 @@ const HomeMainScreen = ({
<BottomSheetModalProvider>
<View>
<HomeTabView
onSearch={() => {}}
onSearch={() => { }}
selectedTab={selectedTab}
onTabChange={handleTabChange}
setSelectedFilterOption={setSelectedFilterOption}
setSelectedStylesList={setSelectedStylesList}
/>
</View>
{selectedTab === 'Goods' && (
<Service
selectedStylesList={selectedStylesList}
selectedFilterOption={selectedFilterOption}
searchTerm={searchTerm}
navigation={navigation}
/>
<View>
<Button onPress={checkRole}></Button>
<Service
selectedStylesList={selectedStylesList}
selectedFilterOption={selectedFilterOption}
searchTerm={searchTerm}
navigation={navigation}
/>
</View>
)}
{selectedTab === 'Market' && <ReformerMarket />}
{selectedTab === 'temp' && (
Expand Down
Loading

0 comments on commit bbcb8c0

Please sign in to comment.