Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] 신고하기 UI #90

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions lib/constants/paths.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,7 @@ abstract class Paths {
static const String myMentorIntroduce = '/my_mentor_introduce';
static const String timeSetting = '/time_setting';
static const String timeChecking = '/time_checking';

static const String report = '/report';
static const String reportDetail = '/report_detail';
}
41 changes: 41 additions & 0 deletions lib/features/home/profile/profile_detail_screen.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import 'package:cogo/common/widgets/atoms/texts/styles.dart';
import 'package:cogo/common/widgets/components/basic_button.dart';
import 'package:cogo/constants/colors.dart';
import 'package:cogo/constants/paths.dart';
import 'package:cogo/features/home/profile/profile_detail_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';

class ProfileDetailScreen extends StatelessWidget {
Expand All @@ -28,6 +30,23 @@ class ProfileDetailScreen extends StatelessWidget {
icon: SvgPicture.asset('assets/icons/button/chevron_left.svg'),
onPressed: () => Navigator.of(context).pop(),
),
actions: [
IconButton(
onPressed: () {
showModalBottomSheet(
context: context,
backgroundColor: CogoColor.white50,
shape: const RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(16)),
),
builder: (BuildContext context) {
return _buildBottomSheetContent(context);
},
);
},
icon: const Icon(Icons.more_vert))
],
title: Consumer<ProfileDetailViewModel>(
builder: (context, viewModel, child) {
if (viewModel.isLoading) {
Expand Down Expand Up @@ -175,4 +194,26 @@ class ProfileDetailScreen extends StatelessWidget {
),
);
}

Widget _buildBottomSheetContent(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
leading: const Icon(Icons.flag),
title: const Text(
'신고하기',
style: CogoTextStyle.body16,
),
onTap: () {
context.push(Paths.report);
// 설정 메뉴 선택
},
),
],
),
);
}
}
89 changes: 89 additions & 0 deletions lib/features/home/report/report_detail_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import 'package:cogo/common/widgets/atoms/texts/styles.dart';
import 'package:cogo/common/widgets/components/basic_button.dart';
import 'package:cogo/common/widgets/components/basic_textfield.dart';
import 'package:cogo/common/widgets/components/secondary_button.dart';
import 'package:cogo/constants/colors.dart';
import 'package:cogo/features/home/report/report_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:provider/provider.dart';

class ReportDetailScreen extends StatelessWidget {
const ReportDetailScreen({super.key});

@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => ReportViewModel(),
child: Scaffold(
backgroundColor: CogoColor.white50,
resizeToAvoidBottomInset: true,
appBar: AppBar(
backgroundColor: CogoColor.white50,
title: const Text(
"신고하기",
style: CogoTextStyle.body20,
),
centerTitle: true,
leading: IconButton(
icon: SvgPicture.asset('assets/icons/button/chevron_left.svg'),
onPressed: () => Navigator.of(context).pop(),
),
),
body: SingleChildScrollView(
child: SafeArea(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Consumer<ReportViewModel>(
builder: (context, viewModel, child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"신고 세부 내용",
style: CogoTextStyle.body16,
),
const SizedBox(height: 10),
BasicTextField(
controller: viewModel.reportController,
hintText: '신고하실 내용을 자세히 작성해주세요',
currentCount: viewModel.reportCharCount,
maxCount: 200,
size: BasicTextFieldSize.LARGE,
maxLines: 1,
),
const SizedBox(height: 10),
const Text('유의사항', style: CogoTextStyle.bodySB14),
const SizedBox(height: 10),
const Text(
'신고 후 신고 내역에 따라 해당 유저에게 안내가 이루어질 예정입니다.\n각 항목 별 세부 사항은 다음과 같습니다.\n\n'
'멘토링의 목적이 아닌것\n- 종교단체\n - 사업목적 (보험, 광고, etc)\n- 기타 멘토링으로 의도되지 않는 모든 행위\n\n'
'멘토링 과정에서 비매너 행위 발생\n- 잘못된 정보 제공\n- 상대방에 부적절한 언행\n- 기타 양자간 분쟁 가능성이 있는 비매너 행위',
style: CogoTextStyle.body9,
),
const SizedBox(height: 80),
Copy link
Contributor

@sunnny619 sunnny619 Jan 9, 2025

Choose a reason for hiding this comment

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

아래 바텀 버튼을 내리기 위해서 사이즈 박스로 임의로 빈공간을 주신 것 같은데 이러면 폰 마다 사이즈가 달라서 완벽하게 버튼이 아래로 위치하도록 만들기 어렵지 않나요???

Padding을 사용해서 (padding: const EdgeInsets.only(bottom: 20.0)이렇게!!) 하면 폰 화면 아래서부터 20 떨어진 곳에 위치하도록 만들 수 있어요!

Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SecondaryButton(
text: '취소',
onPressed: () => Navigator.of(context).pop(),
),
const SizedBox(width: 16), // 버튼들 사이에 16만큼 간격을 추가
BasicButton(
text: '신고',
isClickable: true,
onPressed: viewModel.postReport,
)
],
)
],
);
}),
),
),
),
),
);
}
}
89 changes: 89 additions & 0 deletions lib/features/home/report/report_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import 'package:cogo/common/widgets/atoms/texts/styles.dart';
import 'package:cogo/constants/colors.dart';
import 'package:cogo/constants/paths.dart';
import 'package:cogo/features/home/report/report_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';

class ReportScreen extends StatelessWidget {
const ReportScreen({super.key});

@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => ReportViewModel(),
child: Scaffold(
backgroundColor: CogoColor.white50,
resizeToAvoidBottomInset: true,
appBar: AppBar(
backgroundColor: CogoColor.white50,
title: const Text(
"신고하기",
style: CogoTextStyle.body20,
),
centerTitle: true,
leading: IconButton(
icon: SvgPicture.asset('assets/icons/button/chevron_left.svg'),
onPressed: () => Navigator.of(context).pop(),
),
),
body: SingleChildScrollView(
child: SafeArea(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Consumer<ReportViewModel>(
builder: (context, viewModel, child) {
return Column(
children: [
ListTile(
title: const Text(
'멘토링의 목적을 가지고 멘토가 만난것 같지 않아요',
style: CogoTextStyle.body16,
),
trailing: const Icon(Icons.chevron_right),
onTap: () {
context.push(Paths.reportDetail);
},
),
const Divider(height: 1, color: CogoColor.systemGray02),
ListTile(
title: const Text(
'멘토링 중에 분쟁 발생했어요',
style: CogoTextStyle.body16,
),
trailing: const Icon(Icons.chevron_right),
onTap: () {
context.push(Paths.reportDetail);
},
),
const Divider(height: 1, color: CogoColor.systemGray02),
ListTile(
title: const Text(
'멘토의 소속이나, 인적사항이 거짓인것 같아요',
style: CogoTextStyle.body16,
),
trailing: const Icon(Icons.chevron_right),
onTap: () {
context.push(Paths.reportDetail);
},
),
const Divider(height: 1, color: CogoColor.systemGray02),
ListTile(
title: const Text('기타 부적절한 행위가 있었어요',
style: CogoTextStyle.body16),
trailing: const Icon(Icons.chevron_right),
onTap: () {
context.push(Paths.reportDetail);
}),
],
);
}),
),
),
),
),
);
}
}
17 changes: 17 additions & 0 deletions lib/features/home/report/report_view_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'package:flutter/cupertino.dart';

class ReportViewModel extends ChangeNotifier {
final TextEditingController reportController = TextEditingController();

int get reportCharCount => reportController.text.length;

ReportViewModel() {
reportController.addListener(() {
notifyListeners();
});
}

bool postReport() {
return true;
}
}
16 changes: 16 additions & 0 deletions lib/route/routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import 'package:cogo/features/home/mentor_detail/views/mentor_introduction_scree
import 'package:cogo/features/home/mentor_detail/views/mentor_question1_screen.dart';
import 'package:cogo/features/home/mentor_detail/views/mentor_question2_screen.dart';
import 'package:cogo/features/home/profile/profile_detail_screen.dart';
import 'package:cogo/features/home/report/report_detail_screen.dart';
import 'package:cogo/features/home/report/report_screen.dart';
import 'package:cogo/features/home/search/search_screen.dart';
import 'package:cogo/features/mypage/mentor_introduce/my_mentor_introduce_screen.dart';
import 'package:cogo/features/mypage/mentor_time_checking/mentor_time_checking_screen.dart';
Expand Down Expand Up @@ -242,6 +244,20 @@ final AppRouter = GoRouter(
child: const MentorTimeCheckingScreen(),
),
),
GoRoute(
path: Paths.report,
pageBuilder: (context, state) => MaterialPage(
key: state.pageKey,
child: const ReportScreen(),
),
),
GoRoute(
path: Paths.reportDetail,
pageBuilder: (context, state) => MaterialPage(
key: state.pageKey,
child: const ReportDetailScreen(),
),
),
StatefulShellRoute.indexedStack(
builder: (context, state, navigationShell) {
return ScaffoldWithNestedNavigation(
Expand Down