Skip to content

Commit 97e5778

Browse files
authored
Merge pull request #177 from team-ppointer/fix/native-QA-173
Fix/native qa 173
2 parents 2bc18ac + 08a6b64 commit 97e5778

4 files changed

Lines changed: 62 additions & 23 deletions

File tree

apps/native/src/features/student/menu/screens/info/MyInfoScreen.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,9 @@ const MyInfoScreen = () => {
189189
isInitialized.current = false;
190190
hasLocalChanges.current = false;
191191
setLocalData({});
192+
navigation.goBack();
192193
},
194+
193195
onError: (error) => {
194196
showToast('error', error.message || '정보 저장에 실패했습니다.');
195197
},

apps/native/src/features/student/menu/screens/info/edit/EditPhoneNumberScreen.tsx

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
import { useNavigation } from '@react-navigation/native';
1313
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
1414
import { Container } from '@components/common';
15-
import { ChevronLeft, ChevronDown, CircleCheck } from 'lucide-react-native';
15+
import { ChevronLeft, ChevronDown, CircleCheck, CircleAlert } from 'lucide-react-native';
1616
import { useGetMe, usePutMe, postPhoneSend, postPhoneResend, postPhoneVerify } from '@apis';
1717
import { MenuStackParamList } from '@navigation/student/MenuNavigator';
1818
import { SafeAreaView } from 'react-native-safe-area-context';
@@ -29,8 +29,9 @@ const EditPhoneNumberScreen = () => {
2929
const [phoneNumber, setPhoneNumber] = useState(data?.phoneNumber || '');
3030
const [carrier, setCarrier] = useState<CarrierValue | null>(null);
3131
const [verificationCode, setVerificationCode] = useState('');
32+
const [verifyFeedbackMessage, setVerifyFeedbackMessage] = useState<string | null>(null);
3233
const [isCodeSent, setIsCodeSent] = useState(false);
33-
const [carrierModalVisible, setCarrierModalVisible] = useState(false);
34+
// const [carrierModalVisible, setCarrierModalVisible] = useState(false);
3435
const [timer, setTimer] = useState(120); // 2분 = 120초
3536

3637
useEffect(() => {
@@ -43,6 +44,14 @@ const EditPhoneNumberScreen = () => {
4344
}, [isCodeSent, timer]);
4445

4546
const handleSendCode = async () => {
47+
if (phoneNumber.length >= 2 && !phoneNumber.startsWith('01')) {
48+
showToast('error', '01로 시작하는 숫자를 입력해 주세요.');
49+
return;
50+
}
51+
if (phoneNumber.length !== 11) {
52+
showToast('error', '휴대폰 번호는 11자를 입력해 주세요.');
53+
return;
54+
}
4655
try {
4756
const response = await postPhoneSend(phoneNumber);
4857
if (response.data?.success) {
@@ -74,22 +83,22 @@ const EditPhoneNumberScreen = () => {
7483
}
7584
};
7685

77-
const handleVerify = async () => {
78-
if (!verificationCode || verificationCode.length !== 6) {
79-
showToast('error', '인증번호 6자리를 입력해주세요.');
80-
return;
86+
const handleVerifyCodeChange = (text: string) => {
87+
if (/^[0-9]*$/.test(text) && text.length <= 6) {
88+
setVerificationCode(text);
8189
}
90+
};
8291

92+
const handleVerify = async () => {
8393
try {
8494
const response = await postPhoneVerify(phoneNumber, verificationCode);
8595
if (response.data?.success) {
86-
const verifyMessage = response.data.message || '인증이 완료되었습니다.';
8796
// 인증 성공 시 휴대폰 번호 업데이트
8897
putMeMutate(
8998
{ phoneNumber },
9099
{
91100
onSuccess: () => {
92-
showToast('success', verifyMessage);
101+
showToast('success', '휴대폰 번호 변경이 완료되었습니다.');
93102
navigation.goBack();
94103
},
95104
onError: () => {
@@ -98,11 +107,11 @@ const EditPhoneNumberScreen = () => {
98107
}
99108
);
100109
} else {
101-
showToast('error', response.data?.message || '인증에 실패했습니다.');
110+
setVerifyFeedbackMessage(response.data?.message || '인증번호를 다시 확인해주세요.');
102111
}
103112
} catch (error) {
104113
console.error('Failed to verify verification code:', error);
105-
showToast('error', '인증에 실패했습니다.');
114+
showToast('error', (error as Error).message || '인증에 실패했습니다.');
106115
}
107116
};
108117

@@ -117,6 +126,18 @@ const EditPhoneNumberScreen = () => {
117126
return `${minutes}:${secs.toString().padStart(2, '0')}`;
118127
};
119128

129+
const isValidPhone = /^01\d{9}$/.test(phoneNumber);
130+
131+
const getPhoneFeedbackMessage = (): string | null => {
132+
if (phoneNumber.length >= 2 && !phoneNumber.startsWith('01')) {
133+
return '01로 시작하는 숫자를 입력해 주세요.';
134+
}
135+
if (phoneNumber.length > 0 && phoneNumber.length !== 11) {
136+
return '휴대폰 번호는 11자를 입력해 주세요.';
137+
}
138+
return null;
139+
};
140+
120141
const handlePhoneNumberChange = (text: string) => {
121142
const phoneRegex = /^[0-9]*$/;
122143
if (phoneRegex.test(text) && text.length <= 11) {
@@ -159,19 +180,29 @@ const EditPhoneNumberScreen = () => {
159180
/>
160181
{isCodeSent && (
161182
<Pressable
183+
disabled={timer > 0}
162184
className='bg-primary-500 items-center justify-center rounded-[8px]'
163-
style={{ width: 100, height: 48 }}
185+
style={{ width: 100, height: 48, opacity: timer > 0 ? 0.5 : 1 }}
164186
onPress={handleResendCode}>
165187
<Text className='text-16m text-white'>재전송</Text>
166188
</Pressable>
167189
)}
168190
</View>
169-
{isCodeSent && (
170-
<View className='flex-row items-center gap-2'>
171-
<CircleCheck color={colors['blue-500']} size={14} />
172-
<Text className='text-12r text-blue-500'>문자로 인증번호를 전송했어요</Text>
173-
</View>
174-
)}
191+
<View className='flex-row items-center gap-2'>
192+
{isCodeSent ? (
193+
<>
194+
<CircleCheck color={colors['blue-500']} size={14} />
195+
<Text className='text-12r text-blue-500'>문자로 인증번호를 전송했어요</Text>
196+
</>
197+
) : (
198+
<>
199+
{getPhoneFeedbackMessage() && (
200+
<CircleAlert size={14} color={colors['red-500']} />
201+
)}
202+
<Text className='text-12r text-red-500'>{getPhoneFeedbackMessage()}</Text>
203+
</>
204+
)}
205+
</View>
175206
</View>
176207
{/* <View className='gap-[10px]'>
177208
<View className='gap-[6px]'>
@@ -197,7 +228,7 @@ const EditPhoneNumberScreen = () => {
197228
<View className='w-full' style={{ position: 'relative' }}>
198229
<TextInput
199230
value={verificationCode}
200-
onChangeText={setVerificationCode}
231+
onChangeText={handleVerifyCodeChange}
201232
placeholder='인증번호 6자리'
202233
keyboardType='number-pad'
203234
maxLength={6}
@@ -215,6 +246,12 @@ const EditPhoneNumberScreen = () => {
215246
<Text className='text-14m text-primary-500'>{formatTime(timer)}</Text>
216247
</View>
217248
</View>
249+
{verifyFeedbackMessage && (
250+
<View className='flex-row items-center gap-2'>
251+
<CircleAlert size={14} color={colors['red-500']} />
252+
<Text className='text-12r text-red-500'>{verifyFeedbackMessage}</Text>
253+
</View>
254+
)}
218255
</View>
219256
)}
220257
</View>
@@ -224,8 +261,8 @@ const EditPhoneNumberScreen = () => {
224261
{!isCodeSent || timer == 0 ? (
225262
<Pressable
226263
onPress={handleSendCode}
227-
disabled={phoneNumber.length !== 11}
228-
className={`bg-primary-500 items-center rounded-[8px] px-[12px] py-[10px] ${phoneNumber.length !== 11 ? 'opacity-50' : ''}`}>
264+
disabled={!isValidPhone}
265+
className={`bg-primary-500 items-center rounded-[8px] px-[12px] py-[10px] ${!isValidPhone ? 'opacity-50' : ''}`}>
229266
<Text className='text-16m text-white'>인증번호 받기</Text>
230267
</Pressable>
231268
) : (

apps/native/src/features/student/scrap/components/Header/ScrapHeader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const ScrapHeader = ({
4848
const isActionEnabled = reducerState.selectedItems.length > 0;
4949

5050
return (
51-
<View className={`bg-${!reducerState.isSelecting ? 'background' : 'gray-200'}`}>
51+
<View className={`bg-${!reducerState.isSelecting ? 'gray-100' : 'gray-200'}`}>
5252
{!reducerState.isSelecting && (
5353
<Container className='flex-row items-center justify-between bg-gray-100 py-[14px]'>
5454
{navigateback && navigateback.canGoBack() && (

apps/native/src/features/student/scrap/screens/ScrapDetailScreen.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,9 @@ const ScrapDetailScreen = () => {
261261
// Derived state - Pointings with labels
262262
const pointingsWithLabels = useMemo(() => {
263263
if (!scrapDetail?.pointings) return [];
264-
return scrapDetail.pointings.map((pointing, idx) => ({
264+
return scrapDetail.pointings.map((pointing) => ({
265265
...pointing,
266-
label: toAlphabetSequence(idx),
266+
label: toAlphabetSequence(pointing.no - 1),
267267
}));
268268
}, [scrapDetail?.pointings]);
269269

0 commit comments

Comments
 (0)