-
Notifications
You must be signed in to change notification settings - Fork 0
20260202 #477 user 신고 페이지 추가 #485
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
Merged
The head ref may contain hidden characters: "20260202_#477_user_\uC2E0\uACE0_\uD398\uC774\uC9C0_\uCD94\uAC00"
Merged
Changes from 2 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
802480c
user 신고 페이지 추가 : feat : 회원 Member 신고 기능 추가 API는 아직 미완성 https://github…
Cassiiopeia 01cf510
user 신고 페이지 추가 : refactor : API 아직 미완성, UI만 구현 공통로직 제거 https://github…
Cassiiopeia 59f0103
Merge branch 'main' into 20260202_#477_user_신고_페이지_추가
Cassiiopeia 782713c
user 신고 페이지 추가 : refactor : 빌드실패 추가 https://github.com/TEAM-ROMROM/Ro…
Cassiiopeia File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| /// 회원 신고 사유 enum (프론트 ↔︎ 백엔드 매핑) | ||
| /// | ||
| /// id : 백엔드 코드 (MemberReportReason.code) | ||
| /// label : 클라이언트 표시용 한글 이름 | ||
| /// serverName : 백엔드 enum 이름 | ||
| /// | ||
| /// 백엔드 enum 참고 (가정): | ||
| /// BAD_MANNERS(1), FRAUD(2), MISREPRESENTATION(3), NO_SHOW(4), ETC(5) | ||
| /// | ||
| /// 사용 예시 | ||
| /// MemberReportReason.values.forEach((reason) => print(reason.label)); | ||
| /// final codes = selectedReasons.map((e) => e.id).toSet(); // API 전송용 | ||
| enum MemberReportReason { | ||
| badManners(id: 1, label: '비매너/욕설/혐오/성적 발언', serverName: 'BAD_MANNERS'), | ||
| fraud(id: 2, label: '사기 의심/거래 금지 물품', serverName: 'FRAUD'), | ||
| misrepresentation(id: 3, label: '물건 상태 불일치(허위 매물)', serverName: 'MISREPRESENTATION'), | ||
| noShow(id: 4, label: '노쇼(약속 불이행)', serverName: 'NO_SHOW'), | ||
| etc(id: 5, label: '기타(직접 입력)', serverName: 'ETC'); | ||
|
|
||
| final int id; | ||
| final String label; | ||
| final String serverName; | ||
|
|
||
| const MemberReportReason({required this.id, required this.label, required this.serverName}); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,187 @@ | ||
| import 'package:flutter/material.dart'; | ||
| import 'package:flutter_screenutil/flutter_screenutil.dart'; | ||
|
|
||
| import 'package:romrom_fe/models/app_colors.dart'; | ||
| import 'package:romrom_fe/models/app_theme.dart'; | ||
| import 'package:romrom_fe/widgets/common/completion_button.dart'; | ||
| import 'package:romrom_fe/enums/member_report_reason.dart'; | ||
| import 'package:romrom_fe/services/apis/report_api.dart'; | ||
| import 'package:romrom_fe/utils/error_utils.dart'; | ||
| import 'package:romrom_fe/widgets/common/common_modal.dart'; | ||
| import 'package:romrom_fe/widgets/common_app_bar.dart'; | ||
|
|
||
| /// 회원 신고하기 페이지 | ||
| class MemberReportScreen extends StatefulWidget { | ||
| final String memberId; // 신고 대상 회원 ID | ||
|
|
||
| const MemberReportScreen({super.key, required this.memberId}); | ||
|
|
||
| @override | ||
| State<MemberReportScreen> createState() => _MemberReportScreenState(); | ||
| } | ||
|
|
||
| class _MemberReportScreenState extends State<MemberReportScreen> { | ||
| // 선택된 신고 사유 집합 | ||
| final Set<MemberReportReason> _selectedReasons = {}; | ||
| late final TextEditingController _extraCommentController; | ||
|
|
||
| @override | ||
| void initState() { | ||
| super.initState(); | ||
| _extraCommentController = TextEditingController(); | ||
| _extraCommentController.addListener(() { | ||
| setState(() {}); // 글자 수 반영용 | ||
| }); | ||
| } | ||
|
|
||
| @override | ||
| void dispose() { | ||
| _extraCommentController.dispose(); | ||
| super.dispose(); | ||
| } | ||
|
|
||
| @override | ||
| Widget build(BuildContext context) { | ||
| return Scaffold( | ||
| backgroundColor: AppColors.primaryBlack, | ||
| appBar: CommonAppBar( | ||
| title: '신고하기', | ||
| onBackPressed: () { | ||
| Navigator.of(context).pop(); | ||
| }, | ||
| showBottomBorder: true, | ||
| ), | ||
| body: Stack( | ||
| children: [ | ||
| Padding( | ||
| padding: EdgeInsets.symmetric(horizontal: 24.w), | ||
| child: Column( | ||
| crossAxisAlignment: CrossAxisAlignment.start, | ||
| children: [ | ||
| SizedBox(height: 40.h), | ||
| Text('신고 사유', style: CustomTextStyles.h2.copyWith(fontWeight: FontWeight.w600)), | ||
| SizedBox(height: 24.h), | ||
| // 신고 사유 리스트 | ||
| ...MemberReportReason.values.map((reason) => _buildReasonRow(reason)), | ||
| if (_selectedReasons.contains(MemberReportReason.etc)) ...[ | ||
| Container( | ||
| width: 345.w, | ||
| height: 140.h, | ||
| padding: EdgeInsets.all(16.w), | ||
| decoration: BoxDecoration( | ||
| color: AppColors.secondaryBlack1, | ||
| borderRadius: BorderRadius.circular(8.r), | ||
| border: Border.all(color: AppColors.textColorWhite.withValues(alpha: 0.3), width: 1.5.w), | ||
| ), | ||
| child: TextField( | ||
| controller: _extraCommentController, | ||
| maxLines: null, | ||
| maxLength: 300, | ||
| style: CustomTextStyles.p2, | ||
| cursorColor: AppColors.textColorWhite, | ||
| decoration: InputDecoration( | ||
| isCollapsed: true, | ||
| border: InputBorder.none, | ||
| counterText: '', // 기본 counter 숨김 | ||
| hintText: '신고 사유를 상세하게 적어주세요', | ||
| hintStyle: CustomTextStyles.p2.copyWith(color: AppColors.textColorWhite.withValues(alpha: 0.4)), | ||
| ), | ||
| ), | ||
| ), | ||
| SizedBox(height: 8.h), | ||
| Align( | ||
| alignment: Alignment.centerRight, | ||
| child: Text( | ||
| '${_extraCommentController.text.length}/300', | ||
| style: CustomTextStyles.p3.copyWith( | ||
| fontWeight: FontWeight.w600, | ||
| color: AppColors.textColorWhite.withValues(alpha: 0.5), | ||
| ), | ||
| ), | ||
| ), | ||
| ], | ||
| ], | ||
| ), | ||
| ), | ||
|
|
||
| // 하단 고정 신고하기 버튼 (bottom 기준 97.h) | ||
| Positioned( | ||
| left: 24.w, | ||
| right: 24.w, | ||
| bottom: 97.h, | ||
| child: CompletionButton( | ||
| isEnabled: _selectedReasons.isNotEmpty, | ||
| buttonText: '신고 하기', | ||
| enabledOnPressed: () async { | ||
| try { | ||
| final api = ReportApi(); | ||
| await api.reportMember( | ||
| memberId: widget.memberId, | ||
| memberReportReasons: _selectedReasons.map((e) => e.id).toSet(), | ||
| extraComment: _extraCommentController.text.trim(), | ||
| ); | ||
| } catch (e) { | ||
| debugPrint('회원 신고 요청 중 오류: $e'); | ||
| // 에러 코드 파싱 | ||
| final messageForUser = ErrorUtils.getErrorMessage(e); | ||
|
|
||
| await CommonModal.error( | ||
| context: context, | ||
| message: messageForUser, | ||
| onConfirm: () => Navigator.of(context).pop(), | ||
| ); | ||
| return; | ||
| } | ||
|
|
||
| if (!mounted) return; | ||
|
|
||
| Navigator.of(context).pop(true); // 성공 결과 반환 | ||
| }, | ||
| ), | ||
| ), | ||
| ], | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| /// 신고 사유 선택/해제 토글 | ||
| void _toggleReason(MemberReportReason reason) { | ||
| setState(() { | ||
| if (_selectedReasons.contains(reason)) { | ||
| _selectedReasons.remove(reason); | ||
| } else { | ||
| _selectedReasons.add(reason); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| /// 신고 사유 행 | ||
| Widget _buildReasonRow(MemberReportReason reason) { | ||
| return Padding( | ||
| padding: EdgeInsets.only(bottom: 24.h), | ||
| child: GestureDetector( | ||
| behavior: HitTestBehavior.opaque, | ||
| onTap: () => _toggleReason(reason), | ||
| child: Row( | ||
| crossAxisAlignment: CrossAxisAlignment.center, | ||
| children: [ | ||
| SizedBox( | ||
| width: 20.w, | ||
| height: 20.w, | ||
| child: Checkbox( | ||
| value: _selectedReasons.contains(reason), | ||
| onChanged: (_) => _toggleReason(reason), | ||
| activeColor: AppColors.primaryYellow, | ||
| checkColor: AppColors.primaryBlack, | ||
| shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4.r)), | ||
| side: BorderSide(color: AppColors.primaryYellow, width: 1.w), | ||
| ), | ||
| ), | ||
| SizedBox(width: 12.w), | ||
| Expanded(child: Text(reason.label, style: CustomTextStyles.h3)), | ||
| ], | ||
| ), | ||
| ), | ||
| ); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.