Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 73 additions & 73 deletions src/screens/auth/KakaoOnboardingScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ const KakaoOnboardingScreen = ({navigation}: any) => {
const heightNum = Number(formData.height);
if (heightNum < 100 || heightNum > 250) {
newErrors.height = '키는 100cm 이상 250cm 이하여야 합니다';
}
}
}

if (!formData.weight.trim()) {
Expand All @@ -121,7 +121,7 @@ const KakaoOnboardingScreen = ({navigation}: any) => {
const weightGoalNum = Number(formData.weightGoal);
if (weightGoalNum < 30 || weightGoalNum > 200) {
newErrors.weightGoal = '목표 체중은 30kg 이상 200kg 이하여야 합니다';
}
}
}

if (!formData.healthGoal) {
Expand Down Expand Up @@ -163,7 +163,7 @@ const KakaoOnboardingScreen = ({navigation}: any) => {
};

const response = await authAPI.submitOnboarding(onboardingData);

setLoading(false);

// 200 응답 (온보딩 완료) → Alert 없이 바로 홈으로 이동
Expand Down Expand Up @@ -196,7 +196,7 @@ const KakaoOnboardingScreen = ({navigation}: any) => {
};

return (
<KeyboardAvoidingView
<KeyboardAvoidingView
style={styles.container}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
<ScrollView contentContainerStyle={styles.scrollContent}>
Expand Down Expand Up @@ -410,66 +410,66 @@ const KakaoOnboardingScreen = ({navigation}: any) => {
<View style={{width: 50}} />
</View>
<View style={styles.genderOptionContainer}>
<TouchableOpacity
style={[
<TouchableOpacity
style={[
styles.genderOption,
formData.gender === 'M' && styles.genderOptionSelected,
]}
]}
onPress={() => {
handleChange('gender', 'M');
setGenderModalVisible(false);
}}>
<Text
style={[
<Text
style={[
styles.genderOptionText,
formData.gender === 'M' && styles.genderOptionTextSelected,
]}>
남성
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[
]}>
남성
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[
styles.genderOption,
formData.gender === 'F' && styles.genderOptionSelected,
]}
]}
onPress={() => {
handleChange('gender', 'F');
setGenderModalVisible(false);
}}>
<Text
style={[
<Text
style={[
styles.genderOptionText,
formData.gender === 'F' && styles.genderOptionTextSelected,
]}>
여성
</Text>
</TouchableOpacity>
</View>
]}>
여성
</Text>
</TouchableOpacity>
</View>
</TouchableOpacity>
</TouchableOpacity>
</Modal>

{/* 키, 체중 */}
<View style={styles.inputRow}>
<View style={[styles.inputGroup, styles.inputHalf]}>
<TextInput
style={styles.input}
<TextInput
style={styles.input}
placeholder="키 (cm)"
value={formData.height}
value={formData.height}
onChangeText={text => handleChange('height', text)}
keyboardType="number-pad"
placeholderTextColor="rgba(255, 255, 255, 0.7)"
/>
{errors.height && (
<Text style={styles.errorMessage}>{errors.height}</Text>
)}
</View>
</View>

<View style={[styles.inputGroup, styles.inputHalf]}>
<TextInput
style={styles.input}
<TextInput
style={styles.input}
placeholder="체중 (kg)"
value={formData.weight}
value={formData.weight}
onChangeText={text => handleChange('weight', text)}
keyboardType="number-pad"
placeholderTextColor="rgba(255, 255, 255, 0.7)"
Expand Down Expand Up @@ -501,8 +501,8 @@ const KakaoOnboardingScreen = ({navigation}: any) => {
activeOpacity={0.8}
style={styles.birthDateButtonContainer}
onPress={() => setHealthGoalModalVisible(true)}>
<TextInput
style={styles.input}
<TextInput
style={styles.input}
value={
formData.healthGoal
? healthGoalOptions.find(opt => opt.value === formData.healthGoal)?.label || ''
Expand Down Expand Up @@ -543,26 +543,26 @@ const KakaoOnboardingScreen = ({navigation}: any) => {
<View style={styles.modalOptionContainer}>
<View style={styles.optionGrid}>
{healthGoalOptions.map((option) => (
<TouchableOpacity
<TouchableOpacity
key={option.value}
style={[
styles.optionButton,
style={[
styles.optionButton,
formData.healthGoal === option.value && styles.optionButtonSelected,
]}
]}
onPress={() => {
handleChange('healthGoal', option.value);
setHealthGoalModalVisible(false);
}}>
<Text
style={[
<Text
style={[
styles.optionButtonText,
formData.healthGoal === option.value && styles.optionButtonTextSelected,
]}>
]}>
{option.label}
</Text>
</TouchableOpacity>
))}
</View>
</Text>
</TouchableOpacity>
))}
</View>
</View>
</TouchableOpacity>
</TouchableOpacity>
Expand Down Expand Up @@ -616,26 +616,26 @@ const KakaoOnboardingScreen = ({navigation}: any) => {
<View style={styles.modalOptionContainer}>
<View style={styles.optionGrid}>
{workoutDaysOptions.map((option) => (
<TouchableOpacity
<TouchableOpacity
key={option.value}
style={[
styles.optionButton,
style={[
styles.optionButton,
formData.workoutDaysPerWeek === option.value && styles.optionButtonSelected,
]}
]}
onPress={() => {
handleChange('workoutDaysPerWeek', option.value);
setWorkoutDaysModalVisible(false);
}}>
<Text
style={[
<Text
style={[
styles.optionButtonText,
formData.workoutDaysPerWeek === option.value && styles.optionButtonTextSelected,
]}>
]}>
{option.label}
</Text>
</TouchableOpacity>
))}
</View>
</Text>
</TouchableOpacity>
))}
</View>
</View>
</TouchableOpacity>
</TouchableOpacity>
Expand Down Expand Up @@ -686,27 +686,27 @@ const KakaoOnboardingScreen = ({navigation}: any) => {
<View style={styles.modalOptionContainer}>
<View style={styles.optionGrid}>
{experienceLevelOptions.map((option) => (
<TouchableOpacity
<TouchableOpacity
key={option.value}
style={[
styles.optionButton,
style={[
styles.optionButton,
formData.experienceLevel === option.value && styles.optionButtonSelected,
]}
]}
onPress={() => {
handleChange('experienceLevel', option.value);
setExperienceLevelModalVisible(false);
}}>
<Text
style={[
<Text
style={[
styles.optionButtonText,
formData.experienceLevel === option.value && styles.optionButtonTextSelected,
]}>
]}>
{option.label}
</Text>
</TouchableOpacity>
))}
</View>
</View>
</Text>
</TouchableOpacity>
))}
</View>
</View>
</TouchableOpacity>
</TouchableOpacity>
</Modal>
Expand All @@ -722,20 +722,20 @@ const KakaoOnboardingScreen = ({navigation}: any) => {
multiline
/>
</View>
</View>
</View>

<TouchableOpacity
<TouchableOpacity
style={[styles.submitBtn, loading && styles.submitBtnDisabled]}
onPress={handleSubmit}
disabled={loading}>
onPress={handleSubmit}
disabled={loading}>
{loading ? (
<ActivityIndicator color="#000000" />
) : (
<Text style={styles.submitBtnText}>완료</Text>
)}
</TouchableOpacity>
</ScrollView>
</KeyboardAvoidingView>
</TouchableOpacity>
</ScrollView>
</KeyboardAvoidingView>
);
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드 리뷰

  1. 오류 메시지 처리: if 문에서 높이나 목표 체중이 조건에 부합하지 않을 때 newErrors 객체에 오류 메시지를 적절히 추가하는 부분은 잘 되어 있습니다. 하지만, 이러한 오류 메시지를 사용자에게 어떻게 보여줄 것인지에 대한 구현이 코드에서 보이지 않습니다. 예를 들어, newErrors가 세팅되었다면, 해당 오류를 사용자에게 알릴 수 있는 UI 요소가 필요합니다.

  2. 코드 정리: +- 기호가 포함된 라인 수정은 여러 줄에 걸쳐 많습니다. 이러한 수정은 리뷰를 어렵게 할 수 있으므로, 가능한 한 관련된 변경 사항을 함께 묶어 적용하는 것이 좋습니다. 예를 들어, UI의 형식을 변경하는 부분은 하나의 커밋으로 묶고, 로직의 변화는 또 다른 커밋으로 분리하여 명확성을 높일 수 있습니다.

  3. API 호출 후 처리: authAPI.submitOnboarding(onboardingData); 호출 후 응답을 기다리면서 로딩 상태를 유지하는 것은 적절하지만, 이 API 통신에서 발생할 수 있는 오류를 처리하는 과정이 보이지 않습니다. try-catch 문을 사용하여 오류를 처리하고, 사용자에게 유효한 오류 메시지를 보여주는 것이 바람직합니다.

  4. 키보드 회피 처리: KeyboardAvoidingViewbehavior 속성에 대한 설정이 잘 되어 있지만, 이 속성이 항상 올바른 값을 가지는지 테스트해야 합니다. 특히, iOS와 Android에서의 동작 차이를 확인해야 합니다.

  5. Accessibility: UI 구성 요소에 대한 접근성(Accessible) 관련 설정도 고려할 필요가 있습니다. 예를 들어, TouchableOpacity 요소에 accessibilityLabel 속성을 추가하여 보조기술 사용자에게 더 나은 경험을 제공할 수 있습니다.

  6. 리팩토링 가능성: 코드가 반복되는 부분이 몇 군데 있습니다. 예를 들어, 성별, 건강 목표, 운동 일수를 선택하는 UI의 각 요소들은 매우 유사해 보입니다. 이를 기반으로 하나의 일반화된 컴포넌트를 만들 수 있습니다. 이로 인해 코드의 유지보수성이 높아지고 중복 코드가 줄어들 것입니다.

  7. JavaScript 스타일: style 속성에 대한 책정이 일관되지 않습니다. style={} 또는 style={[ ]}와 같은 문법의 일관성을 유지하는 것이 좋습니다.

결론적으로, 기능적인 부분에는 큰 문제가 없어 보이지만 오류 처리 및 사용자 경험에 대한 개선이 필요해 보입니다.

Expand Down
8 changes: 4 additions & 4 deletions src/screens/auth/LoginScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ const LoginScreen = ({navigation}: any) => {
if (shouldOnboard || isNewUser) {
navigation.replace('KakaoOnboarding');
} else {
navigation.replace('Main');
navigation.replace('Main');
}
} catch (error: any) {
console.error('❌ [카카오 로그인] 토큰 저장 실패:', error);
Expand Down Expand Up @@ -268,7 +268,7 @@ const LoginScreen = ({navigation}: any) => {
if (shouldOnboard || isNewUser) {
navigation.replace('KakaoOnboarding');
} else {
navigation.replace('Main');
navigation.replace('Main');
}
} catch (error: any) {
console.error('카카오 로그인 처리 실패:', error);
Expand Down Expand Up @@ -394,7 +394,7 @@ const LoginScreen = ({navigation}: any) => {
try {
// openAuthSessionAsync는 앱 내부 브라우저를 엽니다
result = await WebBrowser.openAuthSessionAsync(
loginUrl,
loginUrl,
deepLinkScheme
);
} catch (browserError: any) {
Expand Down Expand Up @@ -463,7 +463,7 @@ const LoginScreen = ({navigation}: any) => {
if (shouldOnboard || isNewUser) {
navigation.replace('KakaoOnboarding');
} else {
navigation.replace('Main');
navigation.replace('Main');
}
} catch (error: any) {
console.error('❌ [카카오 로그인] 토큰 저장 실패:', error);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리뷰 코멘트:

  1. 코드 형식:

    • 변경된 줄에서 중요한 코드 블록이 포함되어 있지만, 들여쓰기가 일관되지 않습니다. 코드 가독성 문제로 이어질 수 있으므로, 각 navigation.replace 호출은 동일한 수준으로 들여쓰기를 맞추는 것이 좋습니다.
  2. 에러 핸들링:

    • catch 블록에서 error를 콘솔에 로깅하고 있습니다. 추가적인 사용자 피드백 또는 에러 로그를 위한 개선이 필요합니다. 예를 들어, 사용자가 에러 발생 시 알림을 받거나 앱에서 적절한 에러 처리를 통해 더 나은 사용자 경험을 제공할 수 있습니다.
  3. 중복 코드:

    • navigation.replace('Main') 호출이 여러 곳에서 중복되어 사용되고 있습니다. 이는 유지보수성을 떨어뜨릴 수 있습니다. 이 부분은 함수로 분리하여 중복을 줄여줄 수 있습니다.
  4. 타입 안전성:

    • catch (error: any)에서 any 대신 구체적인 오류 타입을 지정하면, 코드의 안전성과 가독성을 높일 수 있습니다. 타입스크립트의 장점을 살리는 방향으로 수정하는 것이 좋습니다.

이러한 사항을 고려해보면, 현재 제출된 코드 패치에는 문제가 있어 보입니다. 코드 패치가 개선될 필요가 있으므로, 즉각적으로 머지하기는 어렵습니다.

Expand Down
Loading