Skip to content

Commit 8186306

Browse files
committed
비밀번호 분실 대처
비밀번호 분실 대처
1 parent 428852c commit 8186306

File tree

7 files changed

+572
-314
lines changed

7 files changed

+572
-314
lines changed

lib/features/home/screen.dart

+6-3
Original file line numberDiff line numberDiff line change
@@ -479,12 +479,15 @@ class _MainPageState extends State<MainPage>
479479
ItineraryEditor(
480480
itineraryCubit:
481481
itineraryCubit),
482-
// CustomBottomSheetMap(),
483482
),
484483
);
485484
ServerWrapper
486-
.getScheduleDetailWithClear(
487-
itineraryCubit);
485+
.getScheduleDetailWithClear(
486+
itineraryCubit)
487+
.then((bool value) {
488+
if (!value) return;
489+
refreshRoute(itineraryCubit.state);
490+
});
488491
},
489492
onEditPressed: () {
490493
Navigator.push(

lib/features/itinerary/screen.dart

+363-306
Large diffs are not rendered by default.

lib/features/login/screen.dart

+140-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
77
import 'package:flutter_svg/flutter_svg.dart';
88
import 'package:tradule/common/app_bar_blur.dart';
99
import 'package:tradule/common/login_text_form_field.dart';
10+
import 'package:tradule/common/my_text_style.dart';
1011
import 'package:tradule/common/section.dart';
1112
import 'package:tradule/server_wrapper/server_wrapper.dart';
1213
import 'package:tradule/common/color.dart';
@@ -254,7 +255,145 @@ class _LoginScreenState extends State<LoginScreen> {
254255
const SizedBox(height: 10),
255256
TextButton(
256257
onPressed: () {
257-
print('비밀번호 찾기 버튼 클릭');
258+
// print('비밀번호 찾기 버튼 클릭');
259+
// 이메일 입력 다이얼로그 표시
260+
showDialog(
261+
context: context,
262+
builder: (_) {
263+
var emailController =
264+
TextEditingController();
265+
return AlertDialog(
266+
title: const Text('비밀번호 찾기'),
267+
content: Column(
268+
mainAxisSize: MainAxisSize.min,
269+
children: [
270+
const Text(
271+
'가입 시 사용한 이메일을 입력하세요.',
272+
style: TextStyle(
273+
fontSize: 12.0,
274+
fontFamily: 'NotoSansKR',
275+
fontVariations: [
276+
FontVariation('wght', 200.0),
277+
],
278+
),
279+
),
280+
const SizedBox(height: 10),
281+
TextFormField(
282+
controller: emailController,
283+
decoration: InputDecoration(
284+
hintText: 'Email',
285+
hintStyle: TextStyle(
286+
color: cGray,
287+
fontFamily: 'NotoSansKR',
288+
fontVariations: const [
289+
FontVariation('wght', 200.0),
290+
],
291+
),
292+
filled: true,
293+
fillColor:
294+
const Color(0xFFF8F8F8),
295+
border: OutlineInputBorder(
296+
borderRadius:
297+
BorderRadius.circular(30.0),
298+
borderSide: BorderSide.none,
299+
),
300+
contentPadding:
301+
const EdgeInsets.symmetric(
302+
vertical: 17.0,
303+
horizontal: 25.0,
304+
),
305+
),
306+
),
307+
const SizedBox(height: 10),
308+
ElevatedButton(
309+
onPressed: () async {
310+
Navigator.pop(context);
311+
var result = await ServerWrapper
312+
.sendPasswordResetEmail(
313+
emailController.text);
314+
print(result.message);
315+
if (!context.mounted) return;
316+
if (!result.success) {
317+
print('비밀번호 찾기 실패');
318+
showDialog(
319+
context: context,
320+
builder: (context) {
321+
return AlertDialog(
322+
title:
323+
const Text('비밀번호 찾기'),
324+
content: Column(
325+
mainAxisSize:
326+
MainAxisSize.min,
327+
children: [
328+
Text(
329+
result.message!,
330+
style: myTextStyle(
331+
fontSize: 12.0,
332+
),
333+
),
334+
const SizedBox(
335+
height: 10),
336+
ElevatedButton(
337+
onPressed: () {
338+
Navigator.pop(
339+
context);
340+
},
341+
child: const Text(
342+
'확인'),
343+
),
344+
],
345+
),
346+
);
347+
},
348+
);
349+
return;
350+
}
351+
showDialog(
352+
context: context,
353+
builder: (context) {
354+
return AlertDialog(
355+
title:
356+
const Text('비밀번호 찾기'),
357+
content: Column(
358+
mainAxisSize:
359+
MainAxisSize.min,
360+
children: [
361+
const Text(
362+
'입력하신 이메일로 비밀번호 재설정 링크를 보냈습니다.',
363+
style: TextStyle(
364+
fontSize: 12.0,
365+
fontFamily:
366+
'NotoSansKR',
367+
fontVariations: [
368+
FontVariation(
369+
'wght',
370+
200.0),
371+
],
372+
),
373+
),
374+
const SizedBox(
375+
height: 10),
376+
ElevatedButton(
377+
onPressed: () {
378+
Navigator.pop(
379+
context);
380+
},
381+
child:
382+
const Text('확인'),
383+
),
384+
],
385+
),
386+
);
387+
},
388+
);
389+
},
390+
child: const Text('전송'),
391+
),
392+
],
393+
),
394+
);
395+
},
396+
);
258397
},
259398
child: Text(
260399
'forgot your password?',

lib/server_wrapper/data/daily_itinerary_data.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -181,15 +181,15 @@ class DailyItineraryCubit extends Cubit<DailyItineraryData> {
181181
void resetMovement(int index, {MovementData? movementData}) {
182182
if (index < 0 || index >= state.movementList.length) return;
183183
var newMovements = List<MovementCubit>.from(state.movementList);
184-
newMovements[index] = MovementCubit(movementData ?? MovementData.initial());
184+
newMovements[index].update(movementData ?? MovementData.initial());
185185
emit(state.copyWith(movementList: newMovements));
186186
}
187187

188188
void processingMovement(int index, {bool processing = true}) {
189189
if (index < 0 || index >= state.movementList.length) return;
190190
var newMovements = List<MovementCubit>.from(state.movementList);
191-
newMovements[index] = MovementCubit(
192-
newMovements[index].state.copyWith(processing: processing));
191+
newMovements[index]
192+
.update(newMovements[index].state.copyWith(processing: processing));
193193
emit(state.copyWith(movementList: newMovements));
194194
}
195195
}

lib/server_wrapper/server_wrapper.dart

+27-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ class SignUpResult {
3030
SignUpResult(this.success, {this.message});
3131
}
3232

33+
class SendPasswordResetEmailResult {
34+
bool success;
35+
String? message;
36+
SendPasswordResetEmailResult(this.success, {this.message});
37+
}
38+
3339
class ServerWrapper {
3440
static FirebaseFirestore firestore = FirebaseFirestore.instanceFor(
3541
app: Firebase.app(), databaseId: 'tradule-db');
@@ -988,7 +994,27 @@ class ServerWrapper {
988994
return true;
989995
}
990996

991-
// ------------------------- 파이어 베이스 -------------------------
997+
static Future<SendPasswordResetEmailResult> sendPasswordResetEmail(
998+
String email) async {
999+
try {
1000+
await FirebaseAuth.instance.sendPasswordResetEmail(email: email);
1001+
return SendPasswordResetEmailResult(true);
1002+
} on FirebaseAuthException catch (e) {
1003+
if (e.code == 'invalid-email') {
1004+
return SendPasswordResetEmailResult(false, message: '가입되지 않은 이메일입니다.');
1005+
} else if (e.code == 'user-not-found') {
1006+
return SendPasswordResetEmailResult(false, message: '가입되지 않은 이메일입니다.');
1007+
} else {
1008+
return SendPasswordResetEmailResult(false, message: '알 수 없는 오류: $e');
1009+
}
1010+
} catch (e) {
1011+
print(e);
1012+
return SendPasswordResetEmailResult(false,
1013+
message: '비밀번호 재설정 이메일 전송에 실패하였습니다.');
1014+
}
1015+
}
1016+
1017+
// ------------------------- 파이어 스토어 -------------------------
9921018
static Future<void> markAccountAsDeleted(String email) async {
9931019
await firestore.collection('users').doc(email).set({
9941020
'isDeleted': true, // 탈퇴 계정으로 설정

pubspec.lock

+32
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,38 @@ packages:
10291029
url: "https://pub.dev"
10301030
source: hosted
10311031
version: "2.1.8"
1032+
pointer_interceptor:
1033+
dependency: "direct main"
1034+
description:
1035+
name: pointer_interceptor
1036+
sha256: "57210410680379aea8b1b7ed6ae0c3ad349bfd56fe845b8ea934a53344b9d523"
1037+
url: "https://pub.dev"
1038+
source: hosted
1039+
version: "0.10.1+2"
1040+
pointer_interceptor_ios:
1041+
dependency: transitive
1042+
description:
1043+
name: pointer_interceptor_ios
1044+
sha256: a6906772b3205b42c44614fcea28f818b1e5fdad73a4ca742a7bd49818d9c917
1045+
url: "https://pub.dev"
1046+
source: hosted
1047+
version: "0.10.1"
1048+
pointer_interceptor_platform_interface:
1049+
dependency: transitive
1050+
description:
1051+
name: pointer_interceptor_platform_interface
1052+
sha256: "0597b0560e14354baeb23f8375cd612e8bd4841bf8306ecb71fcd0bb78552506"
1053+
url: "https://pub.dev"
1054+
source: hosted
1055+
version: "0.10.0+1"
1056+
pointer_interceptor_web:
1057+
dependency: transitive
1058+
description:
1059+
name: pointer_interceptor_web
1060+
sha256: "7a7087782110f8c1827170660b09f8aa893e0e9a61431dbbe2ac3fc482e8c044"
1061+
url: "https://pub.dev"
1062+
source: hosted
1063+
version: "0.10.2+1"
10321064
pointycastle:
10331065
dependency: transitive
10341066
description:

pubspec.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ dependencies:
5858
tsp_route_finder: ^0.0.3
5959
wheel_picker: ^0.1.1
6060
scroll_datetime_picker: ^0.1.2
61+
pointer_interceptor: ^0.10.1+2
6162
# flutter_time_picker_spinner: ^2.0.0
6263
# fluttertoast: ^8.2.8
6364
# avs_svg_provider: ^1.0.1

0 commit comments

Comments
 (0)