From 5972f1506ffcfa7bb0cbd47e44f867a74bcfbdb5 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 12 Mar 2026 01:20:44 +0900 Subject: [PATCH 001/134] =?UTF-8?q?feat:=20user=20model=20=EC=83=88?= =?UTF-8?q?=EB=A1=9C=20=EB=A7=8C=EB=93=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/shared/models/user.dart | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 lib/shared/models/user.dart diff --git a/lib/shared/models/user.dart b/lib/shared/models/user.dart new file mode 100644 index 0000000..ca93ced --- /dev/null +++ b/lib/shared/models/user.dart @@ -0,0 +1,28 @@ +// 최초 작성자: 강선욱 +// 사용자 정보를 저장하는 모델 클래스 + +class User { + final String id; + final String? profileUrl; + final String nickname; + + const User({required this.id, this.profileUrl, required this.nickname}); + + // API 데이터와 모델 클래스 데이터 매핑 + factory User.fromJson(Map json) { + return User( + id: json['id'] as String, + profileUrl: json['profile_url'] as String?, + nickname: json['nickname'] as String, + ); + } + + // 특정 필드만 변경하여 새 User 객체를 반환하는 메서드 + User copyWith({String? id, String? profileUrl, String? nickname}) { + return User( + id: id ?? this.id, + profileUrl: profileUrl ?? this.profileUrl, + nickname: nickname ?? this.nickname, + ); + } +} From e0e65aac76c52cd708a904721679b3b2441793ca Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 12 Mar 2026 14:37:50 +0900 Subject: [PATCH 002/134] =?UTF-8?q?feat:=20challenge=20base=20model=20?= =?UTF-8?q?=EC=83=88=EB=A1=9C=20=EB=A7=8C=EB=93=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/model/challenge_model.dart | 593 ------------------ lib/features/challenge/model/image_model.dart | 17 - .../challenge/models/challenge_base.dart | 27 + 3 files changed, 27 insertions(+), 610 deletions(-) delete mode 100644 lib/features/challenge/model/challenge_model.dart delete mode 100644 lib/features/challenge/model/image_model.dart create mode 100644 lib/features/challenge/models/challenge_base.dart diff --git a/lib/features/challenge/model/challenge_model.dart b/lib/features/challenge/model/challenge_model.dart deleted file mode 100644 index 1bf9885..0000000 --- a/lib/features/challenge/model/challenge_model.dart +++ /dev/null @@ -1,593 +0,0 @@ -// 최초 작성자: 강선욱 -// 챌린지 관련 데이터 관리 모델 -import 'package:intl/intl.dart'; -import 'package:flutter/foundation.dart'; -import 'package:haenaem/features/user/model/user_model.dart'; -import 'package:haenaem/features/challenge/model/image_model.dart'; - -// 챌린지의 상태(완료, 실패 위기, 일반)를 정의하는 열거형 -enum ChallengeStatus { - completed, // 초록색 카드 - urgent, // 빨간색 카드 - normal, // 회색 카드 -} - -// 메인화면에서 관리하는 챌린지 모델 -class ChallengeMainModel { - final int notificationNumber; - final List> myChallenges; - - ChallengeMainModel({ - required this.notificationNumber, - required this.myChallenges, - }); - - factory ChallengeMainModel.fromJson(Map json) { - return ChallengeMainModel( - notificationNumber: json['notificationNumber'] ?? 0, - myChallenges: List>.from(json['myChallenges'] ?? []), - ); - } - - /// 특정 인덱스의 챌린지 상태를 가져오는 함수 - ChallengeStatus getStatus(int index) { - final challenge = myChallenges[index]; - if (challenge['doIt'] == true) return ChallengeStatus.completed; - if (challenge['warning'] == true) return ChallengeStatus.urgent; - return ChallengeStatus.normal; - } - - /// 특정 인덱스의 참여 인원 정보를 반환하는 함수 - String getParticipantInfo(int index) { - final challenge = myChallenges[index]; - return "${challenge['todaySuccessCount']}/${challenge['participantNumber']}명"; - } -} - -// class ChallengeModel { -// final int challengeId; // 챌린지 id -// final String title; // 챌린지 제목 -// final String content; // 챌린지 소개 -// final int maxParticipantNumber; // 최대 인원수 -// final int participantNumber; // 참여 인원수 -// final int duringDate; // 시작 경과일 -// final bool isDoneToday; // API의 'doIt' 매핑 -// final bool isUrgent; // API의 'warning' 매핑 - -// ChallengeModel({ -// required this.challengeId, -// required this.title, -// required this.content, -// required this.maxParticipantNumber, -// required this.participantNumber, -// required this.duringDate, -// required this.isDoneToday, -// required this.isUrgent, -// }); - -// // API(Map) 데이터를 모델 객체로 변환하는 생성자 -// factory ChallengeModel.fromJson(Map json) { -// return ChallengeModel( -// challengeId: json['challengeId'] ?? 0, -// title: json['title'] ?? '', -// content: json['content'] ?? '', -// maxParticipantNumber: json['maxParticipantNumber'] ?? 0, -// participantNumber: json['participantNumber'] ?? 0, -// duringDate: json['duringDate'] ?? 0, -// isDoneToday: json['doIt'] ?? false, -// isUrgent: json['warning'] ?? false, -// ); -// } - -// // 함수의 용도: 모델의 데이터를 기반으로 UI에 표시할 상태값을 계산함 -// ChallengeStatus getStatus() { -// if (isDoneToday) { -// return ChallengeStatus.completed; // 완료 상태 (초록색) -// } else if (isUrgent) { -// return ChallengeStatus.urgent; // 긴급 상태 (빨간색) -// } -// return ChallengeStatus.normal; // 일반 상태 (회색) -// } -// } - -// 챌린지 상세정보에서 사용하는 챌린지 모델 -class ChallengeDetailModel { - final String title; - final String startDate; - final String endDate; - final int requiredWeeklyCount; // 인증 빈도수 - final bool photoRequired; - final List tags; - final String description; - final HostModel host; - final int participantCount; - final List todaySuccessUsers; - - ChallengeDetailModel({ - required this.title, - required this.startDate, - required this.endDate, - required this.requiredWeeklyCount, - required this.photoRequired, - required this.tags, - required this.description, - required this.host, - required this.participantCount, - required this.todaySuccessUsers, - }); - - factory ChallengeDetailModel.fromJson(Map json) { - return ChallengeDetailModel( - title: json['title'] ?? '', - startDate: json['startDate'] ?? '', - endDate: json['endDate'] ?? '', - requiredWeeklyCount: json['requiredWeeklyCount'] ?? 0, - photoRequired: json['photoRequired'] ?? false, - tags: (json['tags'] as List? ?? []).map((t) { - if (t is String) { - return ChallengeTagModel(id: 0, tag: t, tagCategory: 'ETC'); - } else if (t is Map) { - return ChallengeTagModel.fromJson(t); - } else { - return ChallengeTagModel(id: 0, tag: '', tagCategory: 'ETC'); - } - }).toList(), - description: json['description'] ?? '', - host: HostModel.fromJson(json['host'] ?? {}), - participantCount: json['participantCount'] ?? 0, - todaySuccessUsers: - (json['todaySuccessUsers'] as List?) - ?.map((e) => ParticipantModel.fromJson(e)) - .toList() ?? - [], - ); - } -} - -// 챌린지 생성 데이터 관리 클래스 -class ChallengeCreateResponse { - final int id; - final String challengeLink; - final List friends; - - ChallengeCreateResponse({ - required this.id, - required this.challengeLink, - required this.friends, - }); - - factory ChallengeCreateResponse.fromJson(Map json) { - final String link = json['challengeLink'] ?? ''; - int finalId = 0; - - // 💡 서버가 'id'를 주면 그걸 쓰고, 없거나 null이면 링크에서 숫자를 추출합니다. - if (json['id'] != null && json['id'] != 0) { - finalId = json['id']; - } else if (link.isNotEmpty) { - // 링크 예시: http://localhost:3000/challenges/14 - try { - finalId = int.parse(Uri.parse(link).pathSegments.last); - print( - '🎯 링크에서 ID 추출 성공: $finalId', - ); // TODO: 링크에서 id 추출하지 않고 백엔드한테 받아야 함. - } catch (e) { - // Uri 파싱이 안 될 경우를 대비한 split 백업 로직 - finalId = int.tryParse(link.split('/').last) ?? 0; - } - } - - return ChallengeCreateResponse( - id: finalId, - challengeLink: link, - friends: (json['friends'] as List? ?? []) - .map((f) => FriendModel.fromJson(f)) - .toList(), - ); - } -} - -// 챌린지 내 현황 탭 데이터 관리 클래스 -class ChallengeCalendarModel { - final int totalSuccessDays; - final int currentStreakDays; - final bool challengeOwner; - - ChallengeCalendarModel({ - required this.totalSuccessDays, - required this.currentStreakDays, - required this.challengeOwner, - }); - - factory ChallengeCalendarModel.fromJson(Map json) { - return ChallengeCalendarModel( - totalSuccessDays: json['totalSuccessDays'] ?? 0, - currentStreakDays: json['currentStreakDays'] ?? 0, - challengeOwner: json['challengeOwner'] ?? false, - ); - } -} - -// 챌린지 내 현황 달력 그리드 모델 -class ChallengeCalendarPhoto { - final int postId; - final String postDate; - final String? imageUrl; - - ChallengeCalendarPhoto({ - required this.postId, - required this.postDate, - this.imageUrl, - }); - - factory ChallengeCalendarPhoto.fromJson(Map json) { - return ChallengeCalendarPhoto( - postId: json['postId'] ?? 0, - postDate: json['postDate'] ?? '', - imageUrl: json['imageUrl'], - ); - } -} - -// 댓글 데이터 관리 -class ChallengeComment { - final int commentId; - final String userNickname; - final String? userPicture; - final String contents; - final DateTime? createdAt; - final DateTime? updatedAt; - final bool mine; - - ChallengeComment({ - required this.commentId, - required this.userNickname, - this.userPicture, - required this.contents, - required this.createdAt, - required this.updatedAt, - required this.mine, - }); - - factory ChallengeComment.fromJson(Map json) { - return ChallengeComment( - commentId: json['commentId'] ?? 0, - userNickname: json['userNickname'] ?? '익명', - userPicture: json['userPicture'], - contents: json['contents'] ?? '', - updatedAt: json['updatedAt'] != null - ? DateTime.parse(json['updatedAt']) - .toLocal() // 로컬 시간대 변환 추가 - : null, - createdAt: json['createdAt'] != null - ? DateTime.parse(json['createdAt']).toLocal() - : null, - mine: json['mine'] ?? false, - ); - } - - // 업데이트 시 상태 유지를 위한 copyWith - ChallengeComment copyWith({ - int? commentId, - String? userNickname, - String? userPicture, - String? contents, - DateTime? createdAt, - DateTime? updatedAt, - bool? mine, - }) { - return ChallengeComment( - commentId: commentId ?? this.commentId, - userNickname: userNickname ?? this.userNickname, - userPicture: userPicture ?? this.userPicture, - contents: contents ?? this.contents, - createdAt: createdAt ?? this.createdAt, - updatedAt: updatedAt ?? this.updatedAt, - mine: mine ?? this.mine, - ); - } -} - -// 개별 인증글 모델 -class CertificationPostModel { - final int postId; - final String postDate; - final int challengeId; - final String challengeTitle; - final int totalSuccessDays; - final String content; - final String? userNickname; - final String? userImageUrl; - final List images; - final DateTime? createdAt; - final DateTime? updatedAt; - final int likeNumber; - final int commentNumber; - final bool liked; - final bool author; - final List comments; - - String? get imageUrl => images.isNotEmpty ? images.first.imageUrl : null; - String? get userName => userNickname; - int get likeCount => likeNumber; - bool get hasImage => images.isNotEmpty; - - CertificationPostModel({ - required this.postId, - required this.postDate, - required this.challengeId, - required this.challengeTitle, - required this.totalSuccessDays, - required this.content, - required this.images, - this.userNickname, - this.userImageUrl, - this.createdAt, - this.updatedAt, - this.likeNumber = 0, - this.commentNumber = 0, - this.liked = false, - this.author = false, - this.comments = const [], - }); - - // 피드 탭에서 좋아요 수 업데이트를 위해 필요한 copyWith 메서드 - CertificationPostModel copyWith({ - int? postId, - String? postDate, - String? challengeTitle, - int? totalSuccessDays, - String? content, - String? userNickname, - String? userImageUrl, - List? images, - DateTime? createdAt, - DateTime? updatedAt, - int? likeNumber, - int? commentNumber, - bool? liked, - bool? author, - List? comments, - }) { - return CertificationPostModel( - postId: postId ?? this.postId, - challengeId: challengeId ?? challengeId, - postDate: postDate ?? this.postDate, - challengeTitle: challengeTitle ?? this.challengeTitle, - totalSuccessDays: totalSuccessDays ?? this.totalSuccessDays, - content: content ?? this.content, - userNickname: userNickname ?? this.userNickname, - userImageUrl: userImageUrl ?? this.userImageUrl, - images: images ?? this.images, - createdAt: createdAt ?? this.createdAt, - updatedAt: updatedAt ?? this.updatedAt, - likeNumber: likeNumber ?? this.likeNumber, - commentNumber: commentNumber ?? this.commentNumber, - liked: liked ?? this.liked, - author: author ?? this.author, - comments: comments ?? this.comments, - ); - } - - factory CertificationPostModel.fromJson(Map json) { - // 1. 상세 조회용 'images' 리스트 처리 (객체 형태) - List extractedImages = []; - - String dateStr = json['postDate'] ?? ""; - if (dateStr.isEmpty && json['createdAt'] != null) { - dateStr = json['createdAt'].toString().split('T').first; - } - - // 1. 신규 규격 (객체 리스트: images) 처리 - if (json['images'] != null && json['images'] is List) { - extractedImages = (json['images'] as List) - .map((item) => PostImage.fromJson(item)) - .toList(); - } - // 2. 구 규격 대응 (문자열 리스트 혹은 단일 URL일 경우 ID 0으로 생성) - else if (json['imageUrl'] != null) { - extractedImages.add(PostImage(imageId: 0, imageUrl: json['imageUrl'])); - } else if (json['articleImageUrl'] != null && - json['articleImageUrl'] is List) { - extractedImages = (json['articleImageUrl'] as List) - .map((url) => PostImage(imageId: 0, imageUrl: url.toString())) - .toList(); - } - - return CertificationPostModel( - postId: json['postId'] ?? 0, - postDate: json['postDate'] ?? dateStr, - challengeId: json['challengeId'] ?? 0, - challengeTitle: json['challengeTitle'] ?? '제목 없음', - totalSuccessDays: json['totalSuccessDays'] ?? 0, - content: json['content'] ?? '', - images: extractedImages, // 💡 사진이 없으면 빈 리스트 [] 가 됩니다. - userNickname: json['userNickname'] ?? '익명', - userImageUrl: json['userImageUrl'], - updatedAt: json['updatedAt'] != null - ? DateTime.parse(json['updatedAt'].toString()).toLocal() - : null, - createdAt: json['createdAt'] != null - ? DateTime.parse(json['createdAt'].toString()).toLocal() - : null, - likeNumber: json['likeNumber'] ?? 0, - commentNumber: json['commentNumber'] ?? 0, - liked: json['liked'] ?? false, - author: json['author'] ?? false, - comments: (json['comments'] as List? ?? []) - .map((c) => ChallengeComment.fromJson(c)) - .toList(), - ); - } -} - -// 마이페이지 탭 구분을 위한 전용 이름 -enum MyPageTab { inProgress, success, fail } - -// 내 페이지 - 나의 챌린지 - 진행중인 챌린지 -class ChallengeInProgressModel { - final int challengeId; - final String title; - final int requiredWeeklyCount; // 필수는 유지하되 - final int todaySuccessCount; - final int participantNumber; - final int duringDate; - final String endDate; - final double achievementRate; - final String status; - - ChallengeInProgressModel({ - required this.challengeId, - required this.title, - required this.requiredWeeklyCount, - required this.todaySuccessCount, - required this.participantNumber, - required this.duringDate, - required this.endDate, - required this.achievementRate, - required this.status, - }); - - factory ChallengeInProgressModel.fromJson(Map json) { - double rate = (json['achievementRate'] ?? 0).toDouble(); - - // 💡 방어 로직: 0%일 때 직접 계산하는 로직에서도 null 체크 강화 - final int today = json['todaySuccessCount'] ?? 0; - final int weekly = json['requiredWeeklyCount'] ?? 0; - - if (rate == 0 && weekly > 0) { - rate = today / weekly; - } else if (rate > 1.0) { - rate = rate / 100.0; - } - - return ChallengeInProgressModel( - challengeId: json['challengeId'] ?? 0, - title: json['title'] ?? '', - requiredWeeklyCount: json['requiredWeeklyCount'] ?? 0, - todaySuccessCount: json['todaySuccessCount'] ?? 0, - participantNumber: json['participantNumber'] ?? 0, - duringDate: json['duringDate'] ?? 0, - endDate: json['endDate'] ?? '', - achievementRate: rate, - status: json['status'] ?? 'IN_PROGRESS', - ); - } - - // 기존 UI 위젯 수정을 최소화하기 위한 Getter - String get dateInfo => "완료일까지 D-${_calculateDDay()}"; - String get countInfo => "$todaySuccessCount/$participantNumber명"; - double get progress => achievementRate; - - int _calculateDDay() { - try { - final end = DateTime.parse(endDate); - final dDay = end.difference(DateTime.now()).inDays; - return dDay < 0 ? 0 : dDay; - } catch (_) { - return 0; - } - } -} - -// 챌린지 검색 -// TODO: 챌린지 아이디 부분 수정 -class SearchChallengeModel { - final int challengeId; - final String title; - final int participantNumber; - final int requiredWeeklyCount; - final bool photoRequired; - final List tags; - - SearchChallengeModel({ - required this.challengeId, - required this.title, - required this.participantNumber, - required this.requiredWeeklyCount, - required this.photoRequired, - required this.tags, - }); - - factory SearchChallengeModel.fromJson(Map json) { - return SearchChallengeModel( - challengeId: json['id'] ?? 0, - title: json['title'] ?? '', - participantNumber: json['participantNumber'] ?? 0, - requiredWeeklyCount: json['requiredWeeklyCount'] ?? 0, - photoRequired: json['photoRequired'] ?? true, - tags: (json['tags'] as List? ?? []) - .map((t) => ChallengeTagModel.fromJson(t)) - .toList(), - ); - } -} - -// 태그 모델 -class ChallengeTagModel { - final int id; - final String tag; - final String tagCategory; - - int get tagId => id; - - ChallengeTagModel({ - required this.id, - required this.tag, - required this.tagCategory, - }); - - factory ChallengeTagModel.fromJson(Map json) { - return ChallengeTagModel( - id: json['tagId'] ?? 0, - tag: json['tag'] ?? '', - tagCategory: json['tagCategory'] ?? 'AGE', - ); - } -} - -// 챌린지 초대 탭 응답 모델 (GET /api/challenges/{challengeId}/invite) -class ChallengeInviteResponse { - final String challengeLink; // 초대 링크 - final List friends; // 친구 목록 (초대 상태 포함) - - ChallengeInviteResponse({required this.challengeLink, required this.friends}); - - factory ChallengeInviteResponse.fromJson(Map json) { - return ChallengeInviteResponse( - // 초대 링크 매핑 - challengeLink: json['inviteLink'] ?? '', - - friends: ((json['responseList'] ?? []) as List) - .map((e) => ChallengeInviteFriend.fromJson(e)) - .toList(), - ); - } -} - -class ChallengeInviteFriend { - final int userId; - final String nickname; - final String? profileImageUrl; - final bool isInvited; // 이미 초대되었는지 여부 - - ChallengeInviteFriend({ - required this.userId, - required this.nickname, - this.profileImageUrl, - required this.isInvited, - }); - - factory ChallengeInviteFriend.fromJson(Map json) { - return ChallengeInviteFriend( - // API 명세: a. 유저id - userId: json['userId'] ?? 0, - // API 명세: b. 유저 닉네임 - nickname: json['nickname'] ?? '', - // API 명세: b. 유저 프로필 이미지 url - profileImageUrl: json['profileImageUrl'], - // API 명세: c. 이미 해당 챌린지에 초대되었는지에 대한 여부 - // 초대 상태 체크 ('INVITED' 문자열이거나 true일 경우) - isInvited: json['inviteStatus'] == 'INVITED', - ); - } -} diff --git a/lib/features/challenge/model/image_model.dart b/lib/features/challenge/model/image_model.dart deleted file mode 100644 index 780dd22..0000000 --- a/lib/features/challenge/model/image_model.dart +++ /dev/null @@ -1,17 +0,0 @@ -// 리팩토링: 강선욱 -// 이미지 관련 정보 관리 클래스 - -// 인증글 사진 정보를 관리하는 클래스 -class PostImage { - final int imageId; - final String imageUrl; - - PostImage({required this.imageId, required this.imageUrl}); - - factory PostImage.fromJson(Map json) { - return PostImage( - imageId: json['imageId'] ?? 0, - imageUrl: json['imageUrl'] ?? '', - ); - } -} diff --git a/lib/features/challenge/models/challenge_base.dart b/lib/features/challenge/models/challenge_base.dart new file mode 100644 index 0000000..7d4bd8f --- /dev/null +++ b/lib/features/challenge/models/challenge_base.dart @@ -0,0 +1,27 @@ +class ChallengeBase { + final String id; + final String title; + final bool isLeader; + + const ChallengeBase({ + required this.id, + required this.title, + required this.isLeader, + }); + + factory ChallengeBase.fromJson(Map json) { + return ChallengeBase( + id: json['id'] as String, + title: json['title'] as String, + isLeader: json['is_leader'] as bool, + ); + } + + ChallengeBase copyWith({String? id, String? title, bool? isLeader}) { + return ChallengeBase( + id: id ?? this.id, + title: title ?? this.title, + isLeader: isLeader ?? this.isLeader, + ); + } +} From 0e75575c424b3649985db654f7f2ce0b43f0d47d Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 12 Mar 2026 14:39:22 +0900 Subject: [PATCH 003/134] =?UTF-8?q?feat:=20home=20challenge=20card=20model?= =?UTF-8?q?=20=EC=83=88=EB=A1=9C=20=EB=A7=8C=EB=93=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/models/home_challenge_card.dart | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 lib/features/challenge/models/home_challenge_card.dart diff --git a/lib/features/challenge/models/home_challenge_card.dart b/lib/features/challenge/models/home_challenge_card.dart new file mode 100644 index 0000000..e69de29 From 58343a5f9bc384dd0927fb77ea750fef68ac6f23 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 12 Mar 2026 14:40:38 +0900 Subject: [PATCH 004/134] =?UTF-8?q?refactor:=20model=20=ED=8F=B4=EB=8D=94?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20models=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/models/challenge_model.dart | 593 ++++++++++++++++++ .../challenge/models/image_model.dart | 17 + 2 files changed, 610 insertions(+) create mode 100644 lib/features/challenge/models/challenge_model.dart create mode 100644 lib/features/challenge/models/image_model.dart diff --git a/lib/features/challenge/models/challenge_model.dart b/lib/features/challenge/models/challenge_model.dart new file mode 100644 index 0000000..1bf9885 --- /dev/null +++ b/lib/features/challenge/models/challenge_model.dart @@ -0,0 +1,593 @@ +// 최초 작성자: 강선욱 +// 챌린지 관련 데이터 관리 모델 +import 'package:intl/intl.dart'; +import 'package:flutter/foundation.dart'; +import 'package:haenaem/features/user/model/user_model.dart'; +import 'package:haenaem/features/challenge/model/image_model.dart'; + +// 챌린지의 상태(완료, 실패 위기, 일반)를 정의하는 열거형 +enum ChallengeStatus { + completed, // 초록색 카드 + urgent, // 빨간색 카드 + normal, // 회색 카드 +} + +// 메인화면에서 관리하는 챌린지 모델 +class ChallengeMainModel { + final int notificationNumber; + final List> myChallenges; + + ChallengeMainModel({ + required this.notificationNumber, + required this.myChallenges, + }); + + factory ChallengeMainModel.fromJson(Map json) { + return ChallengeMainModel( + notificationNumber: json['notificationNumber'] ?? 0, + myChallenges: List>.from(json['myChallenges'] ?? []), + ); + } + + /// 특정 인덱스의 챌린지 상태를 가져오는 함수 + ChallengeStatus getStatus(int index) { + final challenge = myChallenges[index]; + if (challenge['doIt'] == true) return ChallengeStatus.completed; + if (challenge['warning'] == true) return ChallengeStatus.urgent; + return ChallengeStatus.normal; + } + + /// 특정 인덱스의 참여 인원 정보를 반환하는 함수 + String getParticipantInfo(int index) { + final challenge = myChallenges[index]; + return "${challenge['todaySuccessCount']}/${challenge['participantNumber']}명"; + } +} + +// class ChallengeModel { +// final int challengeId; // 챌린지 id +// final String title; // 챌린지 제목 +// final String content; // 챌린지 소개 +// final int maxParticipantNumber; // 최대 인원수 +// final int participantNumber; // 참여 인원수 +// final int duringDate; // 시작 경과일 +// final bool isDoneToday; // API의 'doIt' 매핑 +// final bool isUrgent; // API의 'warning' 매핑 + +// ChallengeModel({ +// required this.challengeId, +// required this.title, +// required this.content, +// required this.maxParticipantNumber, +// required this.participantNumber, +// required this.duringDate, +// required this.isDoneToday, +// required this.isUrgent, +// }); + +// // API(Map) 데이터를 모델 객체로 변환하는 생성자 +// factory ChallengeModel.fromJson(Map json) { +// return ChallengeModel( +// challengeId: json['challengeId'] ?? 0, +// title: json['title'] ?? '', +// content: json['content'] ?? '', +// maxParticipantNumber: json['maxParticipantNumber'] ?? 0, +// participantNumber: json['participantNumber'] ?? 0, +// duringDate: json['duringDate'] ?? 0, +// isDoneToday: json['doIt'] ?? false, +// isUrgent: json['warning'] ?? false, +// ); +// } + +// // 함수의 용도: 모델의 데이터를 기반으로 UI에 표시할 상태값을 계산함 +// ChallengeStatus getStatus() { +// if (isDoneToday) { +// return ChallengeStatus.completed; // 완료 상태 (초록색) +// } else if (isUrgent) { +// return ChallengeStatus.urgent; // 긴급 상태 (빨간색) +// } +// return ChallengeStatus.normal; // 일반 상태 (회색) +// } +// } + +// 챌린지 상세정보에서 사용하는 챌린지 모델 +class ChallengeDetailModel { + final String title; + final String startDate; + final String endDate; + final int requiredWeeklyCount; // 인증 빈도수 + final bool photoRequired; + final List tags; + final String description; + final HostModel host; + final int participantCount; + final List todaySuccessUsers; + + ChallengeDetailModel({ + required this.title, + required this.startDate, + required this.endDate, + required this.requiredWeeklyCount, + required this.photoRequired, + required this.tags, + required this.description, + required this.host, + required this.participantCount, + required this.todaySuccessUsers, + }); + + factory ChallengeDetailModel.fromJson(Map json) { + return ChallengeDetailModel( + title: json['title'] ?? '', + startDate: json['startDate'] ?? '', + endDate: json['endDate'] ?? '', + requiredWeeklyCount: json['requiredWeeklyCount'] ?? 0, + photoRequired: json['photoRequired'] ?? false, + tags: (json['tags'] as List? ?? []).map((t) { + if (t is String) { + return ChallengeTagModel(id: 0, tag: t, tagCategory: 'ETC'); + } else if (t is Map) { + return ChallengeTagModel.fromJson(t); + } else { + return ChallengeTagModel(id: 0, tag: '', tagCategory: 'ETC'); + } + }).toList(), + description: json['description'] ?? '', + host: HostModel.fromJson(json['host'] ?? {}), + participantCount: json['participantCount'] ?? 0, + todaySuccessUsers: + (json['todaySuccessUsers'] as List?) + ?.map((e) => ParticipantModel.fromJson(e)) + .toList() ?? + [], + ); + } +} + +// 챌린지 생성 데이터 관리 클래스 +class ChallengeCreateResponse { + final int id; + final String challengeLink; + final List friends; + + ChallengeCreateResponse({ + required this.id, + required this.challengeLink, + required this.friends, + }); + + factory ChallengeCreateResponse.fromJson(Map json) { + final String link = json['challengeLink'] ?? ''; + int finalId = 0; + + // 💡 서버가 'id'를 주면 그걸 쓰고, 없거나 null이면 링크에서 숫자를 추출합니다. + if (json['id'] != null && json['id'] != 0) { + finalId = json['id']; + } else if (link.isNotEmpty) { + // 링크 예시: http://localhost:3000/challenges/14 + try { + finalId = int.parse(Uri.parse(link).pathSegments.last); + print( + '🎯 링크에서 ID 추출 성공: $finalId', + ); // TODO: 링크에서 id 추출하지 않고 백엔드한테 받아야 함. + } catch (e) { + // Uri 파싱이 안 될 경우를 대비한 split 백업 로직 + finalId = int.tryParse(link.split('/').last) ?? 0; + } + } + + return ChallengeCreateResponse( + id: finalId, + challengeLink: link, + friends: (json['friends'] as List? ?? []) + .map((f) => FriendModel.fromJson(f)) + .toList(), + ); + } +} + +// 챌린지 내 현황 탭 데이터 관리 클래스 +class ChallengeCalendarModel { + final int totalSuccessDays; + final int currentStreakDays; + final bool challengeOwner; + + ChallengeCalendarModel({ + required this.totalSuccessDays, + required this.currentStreakDays, + required this.challengeOwner, + }); + + factory ChallengeCalendarModel.fromJson(Map json) { + return ChallengeCalendarModel( + totalSuccessDays: json['totalSuccessDays'] ?? 0, + currentStreakDays: json['currentStreakDays'] ?? 0, + challengeOwner: json['challengeOwner'] ?? false, + ); + } +} + +// 챌린지 내 현황 달력 그리드 모델 +class ChallengeCalendarPhoto { + final int postId; + final String postDate; + final String? imageUrl; + + ChallengeCalendarPhoto({ + required this.postId, + required this.postDate, + this.imageUrl, + }); + + factory ChallengeCalendarPhoto.fromJson(Map json) { + return ChallengeCalendarPhoto( + postId: json['postId'] ?? 0, + postDate: json['postDate'] ?? '', + imageUrl: json['imageUrl'], + ); + } +} + +// 댓글 데이터 관리 +class ChallengeComment { + final int commentId; + final String userNickname; + final String? userPicture; + final String contents; + final DateTime? createdAt; + final DateTime? updatedAt; + final bool mine; + + ChallengeComment({ + required this.commentId, + required this.userNickname, + this.userPicture, + required this.contents, + required this.createdAt, + required this.updatedAt, + required this.mine, + }); + + factory ChallengeComment.fromJson(Map json) { + return ChallengeComment( + commentId: json['commentId'] ?? 0, + userNickname: json['userNickname'] ?? '익명', + userPicture: json['userPicture'], + contents: json['contents'] ?? '', + updatedAt: json['updatedAt'] != null + ? DateTime.parse(json['updatedAt']) + .toLocal() // 로컬 시간대 변환 추가 + : null, + createdAt: json['createdAt'] != null + ? DateTime.parse(json['createdAt']).toLocal() + : null, + mine: json['mine'] ?? false, + ); + } + + // 업데이트 시 상태 유지를 위한 copyWith + ChallengeComment copyWith({ + int? commentId, + String? userNickname, + String? userPicture, + String? contents, + DateTime? createdAt, + DateTime? updatedAt, + bool? mine, + }) { + return ChallengeComment( + commentId: commentId ?? this.commentId, + userNickname: userNickname ?? this.userNickname, + userPicture: userPicture ?? this.userPicture, + contents: contents ?? this.contents, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + mine: mine ?? this.mine, + ); + } +} + +// 개별 인증글 모델 +class CertificationPostModel { + final int postId; + final String postDate; + final int challengeId; + final String challengeTitle; + final int totalSuccessDays; + final String content; + final String? userNickname; + final String? userImageUrl; + final List images; + final DateTime? createdAt; + final DateTime? updatedAt; + final int likeNumber; + final int commentNumber; + final bool liked; + final bool author; + final List comments; + + String? get imageUrl => images.isNotEmpty ? images.first.imageUrl : null; + String? get userName => userNickname; + int get likeCount => likeNumber; + bool get hasImage => images.isNotEmpty; + + CertificationPostModel({ + required this.postId, + required this.postDate, + required this.challengeId, + required this.challengeTitle, + required this.totalSuccessDays, + required this.content, + required this.images, + this.userNickname, + this.userImageUrl, + this.createdAt, + this.updatedAt, + this.likeNumber = 0, + this.commentNumber = 0, + this.liked = false, + this.author = false, + this.comments = const [], + }); + + // 피드 탭에서 좋아요 수 업데이트를 위해 필요한 copyWith 메서드 + CertificationPostModel copyWith({ + int? postId, + String? postDate, + String? challengeTitle, + int? totalSuccessDays, + String? content, + String? userNickname, + String? userImageUrl, + List? images, + DateTime? createdAt, + DateTime? updatedAt, + int? likeNumber, + int? commentNumber, + bool? liked, + bool? author, + List? comments, + }) { + return CertificationPostModel( + postId: postId ?? this.postId, + challengeId: challengeId ?? challengeId, + postDate: postDate ?? this.postDate, + challengeTitle: challengeTitle ?? this.challengeTitle, + totalSuccessDays: totalSuccessDays ?? this.totalSuccessDays, + content: content ?? this.content, + userNickname: userNickname ?? this.userNickname, + userImageUrl: userImageUrl ?? this.userImageUrl, + images: images ?? this.images, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + likeNumber: likeNumber ?? this.likeNumber, + commentNumber: commentNumber ?? this.commentNumber, + liked: liked ?? this.liked, + author: author ?? this.author, + comments: comments ?? this.comments, + ); + } + + factory CertificationPostModel.fromJson(Map json) { + // 1. 상세 조회용 'images' 리스트 처리 (객체 형태) + List extractedImages = []; + + String dateStr = json['postDate'] ?? ""; + if (dateStr.isEmpty && json['createdAt'] != null) { + dateStr = json['createdAt'].toString().split('T').first; + } + + // 1. 신규 규격 (객체 리스트: images) 처리 + if (json['images'] != null && json['images'] is List) { + extractedImages = (json['images'] as List) + .map((item) => PostImage.fromJson(item)) + .toList(); + } + // 2. 구 규격 대응 (문자열 리스트 혹은 단일 URL일 경우 ID 0으로 생성) + else if (json['imageUrl'] != null) { + extractedImages.add(PostImage(imageId: 0, imageUrl: json['imageUrl'])); + } else if (json['articleImageUrl'] != null && + json['articleImageUrl'] is List) { + extractedImages = (json['articleImageUrl'] as List) + .map((url) => PostImage(imageId: 0, imageUrl: url.toString())) + .toList(); + } + + return CertificationPostModel( + postId: json['postId'] ?? 0, + postDate: json['postDate'] ?? dateStr, + challengeId: json['challengeId'] ?? 0, + challengeTitle: json['challengeTitle'] ?? '제목 없음', + totalSuccessDays: json['totalSuccessDays'] ?? 0, + content: json['content'] ?? '', + images: extractedImages, // 💡 사진이 없으면 빈 리스트 [] 가 됩니다. + userNickname: json['userNickname'] ?? '익명', + userImageUrl: json['userImageUrl'], + updatedAt: json['updatedAt'] != null + ? DateTime.parse(json['updatedAt'].toString()).toLocal() + : null, + createdAt: json['createdAt'] != null + ? DateTime.parse(json['createdAt'].toString()).toLocal() + : null, + likeNumber: json['likeNumber'] ?? 0, + commentNumber: json['commentNumber'] ?? 0, + liked: json['liked'] ?? false, + author: json['author'] ?? false, + comments: (json['comments'] as List? ?? []) + .map((c) => ChallengeComment.fromJson(c)) + .toList(), + ); + } +} + +// 마이페이지 탭 구분을 위한 전용 이름 +enum MyPageTab { inProgress, success, fail } + +// 내 페이지 - 나의 챌린지 - 진행중인 챌린지 +class ChallengeInProgressModel { + final int challengeId; + final String title; + final int requiredWeeklyCount; // 필수는 유지하되 + final int todaySuccessCount; + final int participantNumber; + final int duringDate; + final String endDate; + final double achievementRate; + final String status; + + ChallengeInProgressModel({ + required this.challengeId, + required this.title, + required this.requiredWeeklyCount, + required this.todaySuccessCount, + required this.participantNumber, + required this.duringDate, + required this.endDate, + required this.achievementRate, + required this.status, + }); + + factory ChallengeInProgressModel.fromJson(Map json) { + double rate = (json['achievementRate'] ?? 0).toDouble(); + + // 💡 방어 로직: 0%일 때 직접 계산하는 로직에서도 null 체크 강화 + final int today = json['todaySuccessCount'] ?? 0; + final int weekly = json['requiredWeeklyCount'] ?? 0; + + if (rate == 0 && weekly > 0) { + rate = today / weekly; + } else if (rate > 1.0) { + rate = rate / 100.0; + } + + return ChallengeInProgressModel( + challengeId: json['challengeId'] ?? 0, + title: json['title'] ?? '', + requiredWeeklyCount: json['requiredWeeklyCount'] ?? 0, + todaySuccessCount: json['todaySuccessCount'] ?? 0, + participantNumber: json['participantNumber'] ?? 0, + duringDate: json['duringDate'] ?? 0, + endDate: json['endDate'] ?? '', + achievementRate: rate, + status: json['status'] ?? 'IN_PROGRESS', + ); + } + + // 기존 UI 위젯 수정을 최소화하기 위한 Getter + String get dateInfo => "완료일까지 D-${_calculateDDay()}"; + String get countInfo => "$todaySuccessCount/$participantNumber명"; + double get progress => achievementRate; + + int _calculateDDay() { + try { + final end = DateTime.parse(endDate); + final dDay = end.difference(DateTime.now()).inDays; + return dDay < 0 ? 0 : dDay; + } catch (_) { + return 0; + } + } +} + +// 챌린지 검색 +// TODO: 챌린지 아이디 부분 수정 +class SearchChallengeModel { + final int challengeId; + final String title; + final int participantNumber; + final int requiredWeeklyCount; + final bool photoRequired; + final List tags; + + SearchChallengeModel({ + required this.challengeId, + required this.title, + required this.participantNumber, + required this.requiredWeeklyCount, + required this.photoRequired, + required this.tags, + }); + + factory SearchChallengeModel.fromJson(Map json) { + return SearchChallengeModel( + challengeId: json['id'] ?? 0, + title: json['title'] ?? '', + participantNumber: json['participantNumber'] ?? 0, + requiredWeeklyCount: json['requiredWeeklyCount'] ?? 0, + photoRequired: json['photoRequired'] ?? true, + tags: (json['tags'] as List? ?? []) + .map((t) => ChallengeTagModel.fromJson(t)) + .toList(), + ); + } +} + +// 태그 모델 +class ChallengeTagModel { + final int id; + final String tag; + final String tagCategory; + + int get tagId => id; + + ChallengeTagModel({ + required this.id, + required this.tag, + required this.tagCategory, + }); + + factory ChallengeTagModel.fromJson(Map json) { + return ChallengeTagModel( + id: json['tagId'] ?? 0, + tag: json['tag'] ?? '', + tagCategory: json['tagCategory'] ?? 'AGE', + ); + } +} + +// 챌린지 초대 탭 응답 모델 (GET /api/challenges/{challengeId}/invite) +class ChallengeInviteResponse { + final String challengeLink; // 초대 링크 + final List friends; // 친구 목록 (초대 상태 포함) + + ChallengeInviteResponse({required this.challengeLink, required this.friends}); + + factory ChallengeInviteResponse.fromJson(Map json) { + return ChallengeInviteResponse( + // 초대 링크 매핑 + challengeLink: json['inviteLink'] ?? '', + + friends: ((json['responseList'] ?? []) as List) + .map((e) => ChallengeInviteFriend.fromJson(e)) + .toList(), + ); + } +} + +class ChallengeInviteFriend { + final int userId; + final String nickname; + final String? profileImageUrl; + final bool isInvited; // 이미 초대되었는지 여부 + + ChallengeInviteFriend({ + required this.userId, + required this.nickname, + this.profileImageUrl, + required this.isInvited, + }); + + factory ChallengeInviteFriend.fromJson(Map json) { + return ChallengeInviteFriend( + // API 명세: a. 유저id + userId: json['userId'] ?? 0, + // API 명세: b. 유저 닉네임 + nickname: json['nickname'] ?? '', + // API 명세: b. 유저 프로필 이미지 url + profileImageUrl: json['profileImageUrl'], + // API 명세: c. 이미 해당 챌린지에 초대되었는지에 대한 여부 + // 초대 상태 체크 ('INVITED' 문자열이거나 true일 경우) + isInvited: json['inviteStatus'] == 'INVITED', + ); + } +} diff --git a/lib/features/challenge/models/image_model.dart b/lib/features/challenge/models/image_model.dart new file mode 100644 index 0000000..780dd22 --- /dev/null +++ b/lib/features/challenge/models/image_model.dart @@ -0,0 +1,17 @@ +// 리팩토링: 강선욱 +// 이미지 관련 정보 관리 클래스 + +// 인증글 사진 정보를 관리하는 클래스 +class PostImage { + final int imageId; + final String imageUrl; + + PostImage({required this.imageId, required this.imageUrl}); + + factory PostImage.fromJson(Map json) { + return PostImage( + imageId: json['imageId'] ?? 0, + imageUrl: json['imageUrl'] ?? '', + ); + } +} From dca08fbd8335905429b8dd013c6cfe946c0c7d67 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 12 Mar 2026 14:41:02 +0900 Subject: [PATCH 005/134] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20user?= =?UTF-8?q?=5Fmodel.dart=EC=97=90=20=EC=9D=B8=EB=8D=B1=EC=8A=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/user/model/user_model.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/features/user/model/user_model.dart b/lib/features/user/model/user_model.dart index 0a294cd..2fb31c8 100644 --- a/lib/features/user/model/user_model.dart +++ b/lib/features/user/model/user_model.dart @@ -2,6 +2,7 @@ // 사용자 객체와 관련된 정보를 관리 모델 // 마이페이지 사용자 프로필 부분 +@Deprecated('shared/models/user.dart에 정의된 model을 대신 사용') class UserProfileModel { final String nickname; final String introduction; @@ -26,6 +27,7 @@ class UserProfileModel { } // 방장 정보를 관리하는 클래스 +@Deprecated('shared/models/user.dart에 정의된 model을 대신 사용') class HostModel { final String name; final String profileImageUrl; @@ -41,6 +43,7 @@ class HostModel { } // 챌린지 참여 멤버 정보를 관리하는 클래스 +@Deprecated('shared/models/user.dart에 정의된 model을 대신 사용') class ParticipantModel { final String name; final String profileImageUrl; @@ -56,6 +59,7 @@ class ParticipantModel { } // 친구 정보를 관리하는 클래스 +@Deprecated('shared/models/user.dart에 정의된 model을 대신 사용') class FriendModel { final int id; final String email; @@ -84,6 +88,7 @@ class FriendModel { // challenge_member_provider.dart // challenge_repository.dart // challenge_members_screen.dart +@Deprecated('shared/models/user.dart에 정의된 model을 대신 사용') class ChallengeMember { final int memberId; final String nickname; From 49667906fff14adbed62c3034e2c9e71669beacb Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 12 Mar 2026 15:50:46 +0900 Subject: [PATCH 006/134] =?UTF-8?q?refactor:=20models=20=ED=8F=B4=EB=8D=94?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD=20=EC=82=AC=ED=95=AD?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/auth/signup/providers/signup_provider.dart | 2 +- .../challenge/create/screens/challenge_create_screen.dart | 2 +- .../challenge/create/widgets/challenge_tag_bottom_sheet.dart | 2 +- lib/features/challenge/data/challenge_repository.dart | 2 +- .../challenge/detail/screens/challenge_main_screen.dart | 2 +- lib/features/challenge/detail/views/calendar_view.dart | 2 +- .../challenge/detail/widgets/challenge_detail_content.dart | 2 +- .../challenge/invite/widgets/challenge_invite_content.dart | 2 +- lib/features/challenge/provider/challenge_provider.dart | 2 +- .../verification/screens/challenge_verification_screen.dart | 4 ++-- lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart | 2 +- .../challenge/widgets/challenge_create_success_dialog.dart | 2 +- lib/features/challenge/widgets/comment_popup_menu.dart | 2 +- lib/features/feed/data/feed_repository.dart | 2 +- lib/features/feed/model/feed_model.dart | 2 +- lib/features/feed/screens/challenge_search_screen.dart | 2 +- lib/features/feed/screens/post_detail_screen.dart | 2 +- lib/features/feed/widgets/feed_post_card.dart | 2 +- lib/features/home/home_screen.dart | 2 +- lib/features/user/data/user_repository.dart | 2 +- lib/features/user/provider/tag_provider.dart | 2 +- lib/features/user/screens/challenge_list_screen.dart | 2 +- lib/features/user/widgets/challenge_section.dart | 2 +- 23 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/features/auth/signup/providers/signup_provider.dart b/lib/features/auth/signup/providers/signup_provider.dart index 71942b2..4717c09 100644 --- a/lib/features/auth/signup/providers/signup_provider.dart +++ b/lib/features/auth/signup/providers/signup_provider.dart @@ -5,7 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/features/challenge/data/challenge_repository.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; import '../models/signup_state.dart'; import 'package:haenaem/features/user/data/user_repository.dart'; diff --git a/lib/features/challenge/create/screens/challenge_create_screen.dart b/lib/features/challenge/create/screens/challenge_create_screen.dart index f022e6d..70b64c7 100644 --- a/lib/features/challenge/create/screens/challenge_create_screen.dart +++ b/lib/features/challenge/create/screens/challenge_create_screen.dart @@ -5,7 +5,7 @@ import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'dart:convert'; import '../../../../shared/widgets/challenge_label.dart'; diff --git a/lib/features/challenge/create/widgets/challenge_tag_bottom_sheet.dart b/lib/features/challenge/create/widgets/challenge_tag_bottom_sheet.dart index 9c4a75d..99560d6 100644 --- a/lib/features/challenge/create/widgets/challenge_tag_bottom_sheet.dart +++ b/lib/features/challenge/create/widgets/challenge_tag_bottom_sheet.dart @@ -4,7 +4,7 @@ import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/features/challenge/create/widgets/plus_button.dart'; import 'package:haenaem/shared/widgets/custom_bottom_sheet.dart'; diff --git a/lib/features/challenge/data/challenge_repository.dart b/lib/features/challenge/data/challenge_repository.dart index a36e255..863e7d8 100644 --- a/lib/features/challenge/data/challenge_repository.dart +++ b/lib/features/challenge/data/challenge_repository.dart @@ -7,7 +7,7 @@ import 'package:flutter/material.dart'; import 'package:image/image.dart' as img; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter/foundation.dart'; import 'package:haenaem/features/auth/services/auth_service.dart'; diff --git a/lib/features/challenge/detail/screens/challenge_main_screen.dart b/lib/features/challenge/detail/screens/challenge_main_screen.dart index d084976..f0884fe 100644 --- a/lib/features/challenge/detail/screens/challenge_main_screen.dart +++ b/lib/features/challenge/detail/screens/challenge_main_screen.dart @@ -6,7 +6,7 @@ import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/features/challenge/widgets/challenge_popup_menu.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/challenge/widgets/challenge_create_success_dialog.dart'; import 'package:haenaem/shared/widgets/bottom_action_button.dart'; import 'package:haenaem/features/challenge/verification/screens/challenge_verification_screen.dart'; diff --git a/lib/features/challenge/detail/views/calendar_view.dart b/lib/features/challenge/detail/views/calendar_view.dart index c3091ca..7264945 100644 --- a/lib/features/challenge/detail/views/calendar_view.dart +++ b/lib/features/challenge/detail/views/calendar_view.dart @@ -9,7 +9,7 @@ import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:intl/intl.dart'; import 'package:haenaem/features/feed/screens/post_detail_screen.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; class CalendarView extends ConsumerStatefulWidget { final int challengeId; diff --git a/lib/features/challenge/detail/widgets/challenge_detail_content.dart b/lib/features/challenge/detail/widgets/challenge_detail_content.dart index 36e8083..806c3cf 100644 --- a/lib/features/challenge/detail/widgets/challenge_detail_content.dart +++ b/lib/features/challenge/detail/widgets/challenge_detail_content.dart @@ -3,7 +3,7 @@ import 'package:intl/intl.dart'; import 'package:flutter_svg/svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/shared/models/tag_data.dart'; import 'package:haenaem/shared/widgets/tag_badge.dart'; diff --git a/lib/features/challenge/invite/widgets/challenge_invite_content.dart b/lib/features/challenge/invite/widgets/challenge_invite_content.dart index c708a73..09cd8bc 100644 --- a/lib/features/challenge/invite/widgets/challenge_invite_content.dart +++ b/lib/features/challenge/invite/widgets/challenge_invite_content.dart @@ -8,7 +8,7 @@ import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/core/utils/korean_string_utils.dart'; import 'package:haenaem/features/challenge/data/challenge_repository.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; // import 'package:share_plus/share_plus.dart'; // [공통 위젯] 챌린지 초대 본문 (링크 공유 + 친구 검색 + 리스트) diff --git a/lib/features/challenge/provider/challenge_provider.dart b/lib/features/challenge/provider/challenge_provider.dart index e2849d7..9e162c3 100644 --- a/lib/features/challenge/provider/challenge_provider.dart +++ b/lib/features/challenge/provider/challenge_provider.dart @@ -3,7 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../data/challenge_repository.dart'; import 'package:haenaem/features/user/data/user_repository.dart'; -import '../model/challenge_model.dart'; +import '../models/challenge_model.dart'; import 'package:haenaem/features/user/model/user_model.dart'; import 'dart:io'; diff --git a/lib/features/challenge/verification/screens/challenge_verification_screen.dart b/lib/features/challenge/verification/screens/challenge_verification_screen.dart index 811e064..1f6335d 100644 --- a/lib/features/challenge/verification/screens/challenge_verification_screen.dart +++ b/lib/features/challenge/verification/screens/challenge_verification_screen.dart @@ -8,8 +8,8 @@ import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; -import 'package:haenaem/features/challenge/model/image_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/image_model.dart'; import 'package:intl/intl.dart'; import '../../../../shared/widgets/challenge_label.dart'; diff --git a/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart b/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart index 9af2a05..beb07ac 100644 --- a/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart +++ b/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart @@ -6,7 +6,7 @@ import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/features/challenge/widgets/DeleteConfirmDialog.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'edit_article_dialog.dart'; import 'package:haenaem/features/challenge/verification/screens/challenge_verification_screen.dart'; diff --git a/lib/features/challenge/widgets/challenge_create_success_dialog.dart b/lib/features/challenge/widgets/challenge_create_success_dialog.dart index 5990baf..e33de65 100644 --- a/lib/features/challenge/widgets/challenge_create_success_dialog.dart +++ b/lib/features/challenge/widgets/challenge_create_success_dialog.dart @@ -452,7 +452,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/challenge/invite/widgets/challenge_invite_content.dart'; class ChallengeCreateSuccessDialog extends StatelessWidget { diff --git a/lib/features/challenge/widgets/comment_popup_menu.dart b/lib/features/challenge/widgets/comment_popup_menu.dart index 64131b6..bcdc2da 100644 --- a/lib/features/challenge/widgets/comment_popup_menu.dart +++ b/lib/features/challenge/widgets/comment_popup_menu.dart @@ -4,7 +4,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/features/challenge/widgets/DeleteConfirmDialog.dart'; import 'edit_article_dialog.dart'; diff --git a/lib/features/feed/data/feed_repository.dart b/lib/features/feed/data/feed_repository.dart index f865aff..5552a96 100644 --- a/lib/features/feed/data/feed_repository.dart +++ b/lib/features/feed/data/feed_repository.dart @@ -1,5 +1,5 @@ import 'package:dio/dio.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; class FeedRepository { final Dio _dio; diff --git a/lib/features/feed/model/feed_model.dart b/lib/features/feed/model/feed_model.dart index 4ae85f0..6d96db7 100644 --- a/lib/features/feed/model/feed_model.dart +++ b/lib/features/feed/model/feed_model.dart @@ -1,4 +1,4 @@ -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; // 피드 상태를 관리하는 클래스 // 로딩 상태, 에러 상태 관리 diff --git a/lib/features/feed/screens/challenge_search_screen.dart b/lib/features/feed/screens/challenge_search_screen.dart index 1c37ee1..e353d0e 100644 --- a/lib/features/feed/screens/challenge_search_screen.dart +++ b/lib/features/feed/screens/challenge_search_screen.dart @@ -6,7 +6,7 @@ import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/features/feed/screens/challenge_detail_screen.dart'; // 챌린지 소개 화면 뷰 재활용 import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/user/model/user_model.dart'; class ChallengeSearchScreen extends ConsumerStatefulWidget { diff --git a/lib/features/feed/screens/post_detail_screen.dart b/lib/features/feed/screens/post_detail_screen.dart index d95be25..0984824 100644 --- a/lib/features/feed/screens/post_detail_screen.dart +++ b/lib/features/feed/screens/post_detail_screen.dart @@ -7,7 +7,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/challenge/widgets/comment_popup_menu.dart'; import 'package:haenaem/features/feed/widgets/feed_post_card.dart'; // FeedPostCard 임포트 diff --git a/lib/features/feed/widgets/feed_post_card.dart b/lib/features/feed/widgets/feed_post_card.dart index 4a31ac4..55bba0e 100644 --- a/lib/features/feed/widgets/feed_post_card.dart +++ b/lib/features/feed/widgets/feed_post_card.dart @@ -7,7 +7,7 @@ import 'package:haenaem/features/feed/screens/post_detail_screen.dart'; // 인 import 'package:intl/intl.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/challenge/widgets/ChallengeFeedPopupMenu.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; diff --git a/lib/features/home/home_screen.dart b/lib/features/home/home_screen.dart index d154597..1fedce2 100644 --- a/lib/features/home/home_screen.dart +++ b/lib/features/home/home_screen.dart @@ -5,7 +5,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/features/challenge/create/screens/challenge_create_screen.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/features/challenge/detail/screens/challenge_main_screen.dart'; import 'package:haenaem/features/notification/screens/notification_main_screen.dart'; diff --git a/lib/features/user/data/user_repository.dart b/lib/features/user/data/user_repository.dart index 92b0c38..3798ad6 100644 --- a/lib/features/user/data/user_repository.dart +++ b/lib/features/user/data/user_repository.dart @@ -5,7 +5,7 @@ import 'package:http_parser/http_parser.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:haenaem/core/network/dio_provider.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/user/model/user_model.dart'; part 'user_repository.g.dart'; diff --git a/lib/features/user/provider/tag_provider.dart b/lib/features/user/provider/tag_provider.dart index 8b0ae14..4ef2e3d 100644 --- a/lib/features/user/provider/tag_provider.dart +++ b/lib/features/user/provider/tag_provider.dart @@ -2,7 +2,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../../challenge/data/challenge_repository.dart'; -import '../../challenge/model/challenge_model.dart'; +import '../../challenge/models/challenge_model.dart'; import 'package:haenaem/features/user/model/user_model.dart'; import 'package:haenaem/features/user/data/user_repository.dart'; import 'package:flutter/foundation.dart'; diff --git a/lib/features/user/screens/challenge_list_screen.dart b/lib/features/user/screens/challenge_list_screen.dart index 78a2d8c..1c489ab 100644 --- a/lib/features/user/screens/challenge_list_screen.dart +++ b/lib/features/user/screens/challenge_list_screen.dart @@ -8,7 +8,7 @@ import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:haenaem/features/challenge/model/challenge_model.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; /// 클래스의 용도: 챌린지 목록을 진행중, 완료, 실패 탭으로 구분하여 보여주는 화면 diff --git a/lib/features/user/widgets/challenge_section.dart b/lib/features/user/widgets/challenge_section.dart index e3b6e28..bc5725d 100644 --- a/lib/features/user/widgets/challenge_section.dart +++ b/lib/features/user/widgets/challenge_section.dart @@ -4,7 +4,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/theme/app_colors.dart'; import '../../../core/theme/app_typography.dart'; -import '../../challenge/model/challenge_model.dart'; +import '../../challenge/models/challenge_model.dart'; import '../../challenge/provider/challenge_provider.dart'; import '../screens/challenge_list_screen.dart'; From 04c0b2fe34b69061ce49bdb3e5d39c5ee002a88e Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 12 Mar 2026 15:51:10 +0900 Subject: [PATCH 007/134] =?UTF-8?q?refactor:=20=EB=AA=A8=EB=8D=B8=20?= =?UTF-8?q?=EC=84=A4=EB=AA=85=20=20=EC=A3=BC=EC=84=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/models/challenge_base.dart | 4 +- .../challenge/models/home_challenge_card.dart | 67 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/lib/features/challenge/models/challenge_base.dart b/lib/features/challenge/models/challenge_base.dart index 7d4bd8f..da9d2f7 100644 --- a/lib/features/challenge/models/challenge_base.dart +++ b/lib/features/challenge/models/challenge_base.dart @@ -1,7 +1,9 @@ +// 최초 작성자: 강선욱 +// 챌린지 기본 정보를 정의한 모델 class ChallengeBase { final String id; final String title; - final bool isLeader; + final bool isLeader; // 현재 로그인 중인 유저가 해당 챌린지의 방장인지 여부 const ChallengeBase({ required this.id, diff --git a/lib/features/challenge/models/home_challenge_card.dart b/lib/features/challenge/models/home_challenge_card.dart index e69de29..a52d008 100644 --- a/lib/features/challenge/models/home_challenge_card.dart +++ b/lib/features/challenge/models/home_challenge_card.dart @@ -0,0 +1,67 @@ +import 'challenge_base.dart'; + +// 최초 작성자: 강선욱 +// 홈 화면 챌린지 카드 모델 +// ChallengeBase에 정의된 필드(id, title, isLeader)를 토대로 홈 화면에서 필요한 데이터로 구성 +class HomeChallengeCard { + final ChallengeBase challengeBase; // id, title, isLeader + final int streakCount; // 최근 인증 연속 일수 + final int participantCount; // 참여 인원 수 + final int successParticipantCount; // 인증 완료 인원 수 + final bool warning; // 챌린지 실패 여부 + final bool isDone; // 오늘 인증 완료 여부 + final DateTime endDate; // 챌린지 종료 날짜 + final int weeklyFrequency; // 주간 최소 인증 빈도 + final bool isStreak; // 연속 인증 중인지 여부 + + const HomeChallengeCard({ + required this.challengeBase, + required this.streakCount, + required this.participantCount, + required this.successParticipantCount, + required this.warning, + required this.isDone, + required this.endDate, + required this.weeklyFrequency, + required this.isStreak, + }); + + factory HomeChallengeCard.fromJson(Map json) { + return HomeChallengeCard( + challengeBase: ChallengeBase.fromJson(json), + streakCount: json['streak_count'] as int, + participantCount: json['participant_count'] as int, + successParticipantCount: json['success_participant_count'] as int, + warning: json['warning'] as bool, + isDone: json['is_done'] as bool, + endDate: DateTime.parse(json['end_date'] as String), + weeklyFrequency: json['weekly_frequency'] as int, + isStreak: json['is_streak'] as bool, + ); + } + + HomeChallengeCard copyWith({ + ChallengeBase? challengeBase, + int? streakCount, + int? participantCount, + int? successParticipantCount, + bool? warning, + bool? isDone, + DateTime? endDate, + int? weeklyFrequency, + bool? isStreak, + }) { + return HomeChallengeCard( + challengeBase: challengeBase ?? this.challengeBase, + streakCount: streakCount ?? this.streakCount, + participantCount: participantCount ?? this.participantCount, + successParticipantCount: + successParticipantCount ?? this.successParticipantCount, + warning: warning ?? this.warning, + isDone: isDone ?? this.isDone, + endDate: endDate ?? this.endDate, + weeklyFrequency: weeklyFrequency ?? this.weeklyFrequency, + isStreak: isStreak ?? this.isStreak, + ); + } +} From 31dc741b3d111f62d1793c4712f1f9b887b34165 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 12 Mar 2026 16:01:08 +0900 Subject: [PATCH 008/134] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20Challe?= =?UTF-8?q?ngeMainModel=EC=97=90=20=EC=9D=B8=EB=8D=B1=EC=8A=A4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/models/challenge_model.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/features/challenge/models/challenge_model.dart b/lib/features/challenge/models/challenge_model.dart index 1bf9885..96f993f 100644 --- a/lib/features/challenge/models/challenge_model.dart +++ b/lib/features/challenge/models/challenge_model.dart @@ -3,7 +3,7 @@ import 'package:intl/intl.dart'; import 'package:flutter/foundation.dart'; import 'package:haenaem/features/user/model/user_model.dart'; -import 'package:haenaem/features/challenge/model/image_model.dart'; +import 'package:haenaem/features/challenge/models/image_model.dart'; // 챌린지의 상태(완료, 실패 위기, 일반)를 정의하는 열거형 enum ChallengeStatus { @@ -13,6 +13,9 @@ enum ChallengeStatus { } // 메인화면에서 관리하는 챌린지 모델 +@Deprecated( + 'challenge/models/home_challenge_card.dart에 정의된 모델 대신 사용 / notificationNumber 변수는 따로 관리', +) class ChallengeMainModel { final int notificationNumber; final List> myChallenges; From 3db7cf8af60c8705e92ee215e28b8f537c84d351 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 12 Mar 2026 17:14:03 +0900 Subject: [PATCH 009/134] =?UTF-8?q?feat:=20rankCard=20model=20=EC=83=88?= =?UTF-8?q?=EB=A1=9C=20=EB=A7=8C=EB=93=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/models/rank_card.dart | 41 ++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 lib/features/challenge/models/rank_card.dart diff --git a/lib/features/challenge/models/rank_card.dart b/lib/features/challenge/models/rank_card.dart new file mode 100644 index 0000000..a01c821 --- /dev/null +++ b/lib/features/challenge/models/rank_card.dart @@ -0,0 +1,41 @@ +import 'package:haenaem/shared/models/user.dart'; + +// 최초 작성자: 강선욱 +// 랭킹 카드 모델 클래스 +// User에 정의된 필드(id, profileUrl, nickname)를 토대로 랭킹 화면에서 필요한 데이터로 구성 +class RankCard { + final User user; // id, profileUrl, nickname + final int rank; // 사용자 순위 + final int totalSuccessCount; // 총 인증 완료 횟수 + final int streakCount; // 최근 인증 연속 횟수 + + const RankCard({ + required this.user, + required this.rank, + required this.totalSuccessCount, + required this.streakCount, + }); + + factory RankCard.fromJson(Map json) { + return RankCard( + user: User.fromJson(json), + rank: json['rank'] as int, + totalSuccessCount: json['total_success_count'] as int, + streakCount: json['streak_count'] as int, + ); + } + + RankCard copyWith({ + User? user, + int? rank, + int? totalSuccessCount, + int? streakCount, + }) { + return RankCard( + user: user ?? this.user, + rank: rank ?? this.rank, + totalSuccessCount: totalSuccessCount ?? this.totalSuccessCount, + streakCount: streakCount ?? this.streakCount, + ); + } +} From 5bb09e5c4196f093ec83acaf25e8b4dd30e7a3e5 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 12 Mar 2026 17:14:26 +0900 Subject: [PATCH 010/134] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20rankin?= =?UTF-8?q?g=20model=EC=97=90=20=EC=9D=B8=EB=8D=B1=EC=8A=A4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/detail/model/ranking_model.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/features/challenge/detail/model/ranking_model.dart b/lib/features/challenge/detail/model/ranking_model.dart index eb98c93..dec0b85 100644 --- a/lib/features/challenge/detail/model/ranking_model.dart +++ b/lib/features/challenge/detail/model/ranking_model.dart @@ -1,3 +1,4 @@ +@Deprecated('challenge/models/rank_card.dart에 정의된 모델을 대신 사용') class RankingResponse { final List topRankings; final RankingUser myRanking; @@ -14,6 +15,7 @@ class RankingResponse { } } +@Deprecated('challenge/models/rank_card.dart에 정의된 모델을 대신 사용') class RankingUser { final int userId; final String nickname; From 89bd16a3cdddbd674163a3d6c77af4e3d27b2026 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 12 Mar 2026 21:30:41 +0900 Subject: [PATCH 011/134] =?UTF-8?q?feat:=20post=20model=20=EB=A7=8C?= =?UTF-8?q?=EB=93=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/feed/model/post.dart | 61 +++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 lib/features/feed/model/post.dart diff --git a/lib/features/feed/model/post.dart b/lib/features/feed/model/post.dart new file mode 100644 index 0000000..c196a2c --- /dev/null +++ b/lib/features/feed/model/post.dart @@ -0,0 +1,61 @@ +import 'package:haenaem/shared/models/user.dart'; + +// 최초 작성자: 강선욱 +// 인증글 모델 클래스 +// User에 정의된 필드(id, profileUrl, nickname)를 작성자 정보로 재사용 +class Post { + final String title; // 인증글 제목 + final String content; // 인증글 내용 + final String? pictureUrl; // 인증글 사진 주소 + final int likeCount; // 좋아요 수 + final bool isLiked; // 현재 로그인 유저의 좋아요 여부 + final int commentCount; // 댓글 수 + final DateTime date; // 작성 날짜 + final User writer; // 작성자 정보 (id, profileUrl, nickname) + + const Post({ + required this.title, + required this.content, + this.pictureUrl, + required this.likeCount, + required this.isLiked, + required this.commentCount, + required this.date, + required this.writer, + }); + + factory Post.fromJson(Map json) { + return Post( + title: json['title'] as String, + content: json['content'] as String, + pictureUrl: json['picture_url'] as String?, + likeCount: json['like_count'] as int, + isLiked: json['is_liked'] as bool, + commentCount: json['comment_count'] as int, + date: DateTime.parse(json['date'] as String), + writer: User.fromJson(json['writer'] as Map), + ); + } + + Post copyWith({ + String? title, + String? content, + String? pictureUrl, + int? likeCount, + bool? isLiked, + int? commentCount, + DateTime? date, + User? writer, + }) { + return Post( + title: title ?? this.title, + content: content ?? this.content, + pictureUrl: pictureUrl ?? this.pictureUrl, + likeCount: likeCount ?? this.likeCount, + isLiked: isLiked ?? this.isLiked, + commentCount: commentCount ?? this.commentCount, + date: date ?? this.date, + writer: writer ?? this.writer, + ); + } +} From e9c6745ac452dfb1caa98e27830a33fdfacad292 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 12 Mar 2026 21:33:55 +0900 Subject: [PATCH 012/134] =?UTF-8?q?feat:=20post=20model=EC=97=90=20?= =?UTF-8?q?=EC=9D=B8=EC=A6=9D=EA=B8=80=20id=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/feed/model/post.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/features/feed/model/post.dart b/lib/features/feed/model/post.dart index c196a2c..e6c4055 100644 --- a/lib/features/feed/model/post.dart +++ b/lib/features/feed/model/post.dart @@ -4,6 +4,7 @@ import 'package:haenaem/shared/models/user.dart'; // 인증글 모델 클래스 // User에 정의된 필드(id, profileUrl, nickname)를 작성자 정보로 재사용 class Post { + final String id; // 인증글 id final String title; // 인증글 제목 final String content; // 인증글 내용 final String? pictureUrl; // 인증글 사진 주소 @@ -14,6 +15,7 @@ class Post { final User writer; // 작성자 정보 (id, profileUrl, nickname) const Post({ + required this.id, required this.title, required this.content, this.pictureUrl, @@ -26,6 +28,7 @@ class Post { factory Post.fromJson(Map json) { return Post( + id: json['id'] as String, title: json['title'] as String, content: json['content'] as String, pictureUrl: json['picture_url'] as String?, @@ -38,6 +41,7 @@ class Post { } Post copyWith({ + String? id, String? title, String? content, String? pictureUrl, @@ -48,6 +52,7 @@ class Post { User? writer, }) { return Post( + id: id ?? this.id, title: title ?? this.title, content: content ?? this.content, pictureUrl: pictureUrl ?? this.pictureUrl, From 95b5d510b33a3779335e466c5c806e64776f52a3 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 12 Mar 2026 21:37:40 +0900 Subject: [PATCH 013/134] =?UTF-8?q?feat:=20comment=20model=20=EB=A7=8C?= =?UTF-8?q?=EB=93=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/feed/model/comment.dart | 46 ++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 lib/features/feed/model/comment.dart diff --git a/lib/features/feed/model/comment.dart b/lib/features/feed/model/comment.dart new file mode 100644 index 0000000..7d1eaf1 --- /dev/null +++ b/lib/features/feed/model/comment.dart @@ -0,0 +1,46 @@ +import 'package:haenaem/shared/models/user.dart'; + +// 최초 작성자: 강선욱 +// 댓글 모델 클래스 +// User에 정의된 필드(id, profileUrl, nickname)를 작성자 정보로 재사용 +class Comment { + final String id; // 댓글 id + final String content; // 댓글 내용 + final DateTime date; // 초기 댓글 작성 날짜 + final bool isEdited; // 댓글 수정 여부 + final User writer; // 작성자 정보 (id, profileUrl, nickname) + + const Comment({ + required this.id, + required this.content, + required this.date, + required this.isEdited, + required this.writer, + }); + + factory Comment.fromJson(Map json) { + return Comment( + id: json['id'] as String, + content: json['content'] as String, + date: DateTime.parse(json['date'] as String), + isEdited: json['is_edited'] as bool, + writer: User.fromJson(json['writer'] as Map), + ); + } + + Comment copyWith({ + String? id, + String? content, + DateTime? date, + bool? isEdited, + User? writer, + }) { + return Comment( + id: id ?? this.id, + content: content ?? this.content, + date: date ?? this.date, + isEdited: isEdited ?? this.isEdited, + writer: writer ?? this.writer, + ); + } +} From 9cdf6539fdb83e52284153f660b3d2bbfc11878c Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 12 Mar 2026 21:44:54 +0900 Subject: [PATCH 014/134] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20challe?= =?UTF-8?q?nge=5Fmodel.dart=20=ED=8C=8C=EC=9D=BC=EC=97=90=20=EC=9D=B8?= =?UTF-8?q?=EB=8D=B1=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/models/challenge_model.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/features/challenge/models/challenge_model.dart b/lib/features/challenge/models/challenge_model.dart index 96f993f..e0a2d9d 100644 --- a/lib/features/challenge/models/challenge_model.dart +++ b/lib/features/challenge/models/challenge_model.dart @@ -232,6 +232,7 @@ class ChallengeCalendarPhoto { } // 댓글 데이터 관리 +@Deprecated('feed/models/comment.dart 내부에 정의된 Comment 모델 대신 사용') class ChallengeComment { final int commentId; final String userNickname; @@ -291,6 +292,7 @@ class ChallengeComment { } // 개별 인증글 모델 +@Deprecated('feed/models/post.dart 내부에 정의된 Post 모델을 대신 사용') class CertificationPostModel { final int postId; final String postDate; From bf5352ebf5e9616b9c92b7222f68e967ffafef18 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 12 Mar 2026 21:45:59 +0900 Subject: [PATCH 015/134] =?UTF-8?q?refactor:=20feed/model=20->=20feed/mode?= =?UTF-8?q?ls=20=EB=A1=9C=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/feed/{model => models}/comment.dart | 0 lib/features/feed/{model => models}/feed_model.dart | 0 lib/features/feed/{model => models}/post.dart | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename lib/features/feed/{model => models}/comment.dart (100%) rename lib/features/feed/{model => models}/feed_model.dart (100%) rename lib/features/feed/{model => models}/post.dart (100%) diff --git a/lib/features/feed/model/comment.dart b/lib/features/feed/models/comment.dart similarity index 100% rename from lib/features/feed/model/comment.dart rename to lib/features/feed/models/comment.dart diff --git a/lib/features/feed/model/feed_model.dart b/lib/features/feed/models/feed_model.dart similarity index 100% rename from lib/features/feed/model/feed_model.dart rename to lib/features/feed/models/feed_model.dart diff --git a/lib/features/feed/model/post.dart b/lib/features/feed/models/post.dart similarity index 100% rename from lib/features/feed/model/post.dart rename to lib/features/feed/models/post.dart From 9fcc11e5f462969ba5a706a1eba06a65a8aa4a41 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Fri, 13 Mar 2026 00:51:00 +0900 Subject: [PATCH 016/134] =?UTF-8?q?feat:=20=EC=86=8C=EC=85=9C=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20user=20search=20card=20model=20=EB=A7=8C=EB=93=A4?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../social/model/user_search_card.dart | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 lib/features/social/model/user_search_card.dart diff --git a/lib/features/social/model/user_search_card.dart b/lib/features/social/model/user_search_card.dart new file mode 100644 index 0000000..fc7140c --- /dev/null +++ b/lib/features/social/model/user_search_card.dart @@ -0,0 +1,30 @@ +import 'package:haenaem/shared/models/user.dart'; + +// 최초 작성자: 강선욱 +// 친구 상태 관리 +enum FriendState { + friend, // 친구 + pending, // 대기중 + stranger, // 비친구 +} + +// 최초 작성자: 강선욱 +// 소셜 화면 사용자 검색 카드 모델 +// User에 정의된 필드(id, profileUrl, nickname)를 재사용 +class UserSearchCard { + final User user; // 사용자 정보 (id, profileUrl, nickname) + final FriendState state; // 현재 로그인 유저와의 상태 + + const UserSearchCard({required this.user, required this.state}); + + factory UserSearchCard.fromJson(Map json) { + return UserSearchCard( + user: User.fromJson(json['user'] as Map), + state: FriendState.values.byName(json['state'] as String), + ); + } + + UserSearchCard copyWith({User? user, FriendState? state}) { + return UserSearchCard(user: user ?? this.user, state: state ?? this.state); + } +} From 0c9d46dde3b5793d1695786dab5fe9c308c05b1b Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Fri, 13 Mar 2026 00:57:21 +0900 Subject: [PATCH 017/134] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20social?= =?UTF-8?q?=5Fmodel.dart=20=ED=8C=8C=EC=9D=BC=EC=97=90=20=EC=9D=B8?= =?UTF-8?q?=EB=8D=B1=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/social/models/social_model.dart | 114 +++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 lib/features/social/models/social_model.dart diff --git a/lib/features/social/models/social_model.dart b/lib/features/social/models/social_model.dart new file mode 100644 index 0000000..c63760b --- /dev/null +++ b/lib/features/social/models/social_model.dart @@ -0,0 +1,114 @@ +/// 최초 작성자: 정승빈 +library; + +import 'package:flutter/material.dart'; + +/// 클래스의 용도: 친구 정보를 관리하는 데이터 모델 +@Deprecated('shared/models/user.dart에 User 모델 대신 사용') +class Friend { + final int id; + final String nickname; + final String? profileImageUrl; + final String title; // UI 연동용 (API에 없을 시 기본값 처리) + + /// 함수의 용도: Friend 클래스의 생성자 + /// 매개 변수: String nickname, String title, String? profileImage + Friend({ + required this.id, + required this.nickname, + this.profileImageUrl, + this.title = '해냄 메이트', + }); + + factory Friend.fromJson(Map json) { + return Friend( + id: json['id'], + nickname: json['nickname'], + profileImageUrl: json['profileImageUrl'], + ); + } +} + +/// 클래스의 용도: 검색 결과 유저 정보 및 요청 상태를 저장하는 모델 +@Deprecated('social/models/user_search_card.dart에 UserSearchCard 모델 대신 사용') +class SearchResultUser { + final int? userId; // 검색 시 사용 + final int? requestId; // 요청 취소 시 사용 + final String nickname; + final String? profileImageUrl; + final String? createdAt; + bool isRequested; + bool isFriend; + + /// 함수의 용도: SearchResultUser 클래스의 생성자 + /// 매개 변수: nickname, title, profileImage, isRequested, requestTime + SearchResultUser({ + this.userId, + this.requestId, + required this.nickname, + this.profileImageUrl, + this.createdAt, + this.isRequested = false, + this.isFriend = false, + }); + + factory SearchResultUser.fromSearchJson(Map json) { + // 🔥 [디버깅용 로그] 서버가 주는 실제 상태값 확인하기 + // 나중에 해결되면 이 줄은 지우셔도 됩니다. + debugPrint( + "닉네임: ${json['nickname']} / 서버상태값: ${json['relationshipStatus']}", + ); + + return SearchResultUser( + userId: json['userId'], + nickname: json['nickname'], + profileImageUrl: json['profileImageUrl'], + // 1. 이미 친구인 경우 [추가] + isFriend: json['relationshipStatus'] == 'FRIEND', + // 2. 내가 이미 신청을 보낸 경우 + isRequested: json['relationshipStatus'] == 'PENDING_SENT', + requestId: json['requestId'], // 취소를 위해 ID도 저장 + ); + } + + factory SearchResultUser.fromSentJson(Map json) { + return SearchResultUser( + requestId: json['requestId'], + nickname: json['nickname'], + profileImageUrl: json['profileImageUrl'], + createdAt: json['createdAt'], + isRequested: true, + ); + } +} + +/// 클래스의 용도: 받은 친구 요청의 상세 정보를 관리하는 데이터 모델 +class ReceivedRequest { + final int requestId; + final int fromUserId; + final String nickname; + final String? profileImageUrl; + final String createdAt; + final String title; + + /// 함수의 용도: ReceivedRequest 클래스의 생성자 + /// 매개 변수: nickname, title, mutualFriends, time, profileImage + ReceivedRequest({ + required this.requestId, + required this.fromUserId, + required this.nickname, + this.profileImageUrl, + required this.createdAt, + this.title = '새로운 친구 요청', + }); + + factory ReceivedRequest.fromJson(Map json) { + return ReceivedRequest( + requestId: json['requestId'], + fromUserId: json['fromUserId'], + nickname: json['nickname'], + profileImageUrl: json['profileImageUrl'], + createdAt: json['createdAt'], + ); + } +} From 788266a5f1ae82afacd922c7d00d33ed898eef54 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Fri, 13 Mar 2026 00:58:20 +0900 Subject: [PATCH 018/134] =?UTF-8?q?refactor:=20social/model=20->=20social/?= =?UTF-8?q?models=20=EB=A1=9C=20=ED=8F=B4=EB=8D=94=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge_verification_screen.dart | 2 +- lib/features/feed/provider/feed_provider.dart | 2 +- lib/features/feed/views/share_feed_view.dart | 2 +- .../social/data/social_repository.dart | 2 +- lib/features/social/model/social_model.dart | 112 ------------------ .../{model => models}/user_search_card.dart | 0 .../social/screens/friend_add_screen.dart | 2 +- .../social/screens/friend_edit_screen.dart | 2 +- .../social/screens/social_screen.dart | 2 +- 9 files changed, 7 insertions(+), 119 deletions(-) delete mode 100644 lib/features/social/model/social_model.dart rename lib/features/social/{model => models}/user_search_card.dart (100%) diff --git a/lib/features/challenge/verification/screens/challenge_verification_screen.dart b/lib/features/challenge/verification/screens/challenge_verification_screen.dart index 1f6335d..b5a9404 100644 --- a/lib/features/challenge/verification/screens/challenge_verification_screen.dart +++ b/lib/features/challenge/verification/screens/challenge_verification_screen.dart @@ -25,7 +25,7 @@ import '../widgets/ai_fail_box.dart'; import 'package:haenaem/features/challenge/verification/widgets/reverification_guide_box.dart'; import '../widgets/verification_submit_button.dart'; import 'package:haenaem/features/challenge/widgets/verification_cancel_dialog.dart'; -import 'package:haenaem/features/feed/model/feed_model.dart'; +import 'package:haenaem/features/feed/models/feed_model.dart'; // 챌린지 인증하기 화면 class ChallengeVerificationScreen extends ConsumerStatefulWidget { diff --git a/lib/features/feed/provider/feed_provider.dart b/lib/features/feed/provider/feed_provider.dart index 80f6ecd..014e6be 100644 --- a/lib/features/feed/provider/feed_provider.dart +++ b/lib/features/feed/provider/feed_provider.dart @@ -1,7 +1,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:dio/dio.dart'; import 'package:haenaem/features/feed/data/feed_repository.dart'; -import 'package:haenaem/features/feed/model/feed_model.dart'; +import 'package:haenaem/features/feed/models/feed_model.dart'; import 'package:haenaem/features/auth/services/auth_service.dart'; // 1. Repository Provider 추가 (Dio 객체는 별도의 공통 Provider에서 가져오는 것이 좋습니다) diff --git a/lib/features/feed/views/share_feed_view.dart b/lib/features/feed/views/share_feed_view.dart index 0832324..baccab0 100644 --- a/lib/features/feed/views/share_feed_view.dart +++ b/lib/features/feed/views/share_feed_view.dart @@ -7,7 +7,7 @@ import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/features/feed/provider/feed_provider.dart'; import 'package:haenaem/features/feed/widgets/feed_post_card.dart'; -import 'package:haenaem/features/feed/model/feed_model.dart'; +import 'package:haenaem/features/feed/models/feed_model.dart'; class ShareFeedView extends ConsumerStatefulWidget { final ScrollController scrollController; diff --git a/lib/features/social/data/social_repository.dart b/lib/features/social/data/social_repository.dart index 9bbf312..c2a3cc7 100644 --- a/lib/features/social/data/social_repository.dart +++ b/lib/features/social/data/social_repository.dart @@ -3,7 +3,7 @@ library; import 'package:dio/dio.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import '../model/social_model.dart'; +import '../models/social_model.dart'; import '../../auth/services/auth_service.dart'; import 'package:flutter/material.dart'; diff --git a/lib/features/social/model/social_model.dart b/lib/features/social/model/social_model.dart deleted file mode 100644 index 953f796..0000000 --- a/lib/features/social/model/social_model.dart +++ /dev/null @@ -1,112 +0,0 @@ -/// 최초 작성자: 정승빈 -library; - -import 'package:flutter/material.dart'; - -/// 클래스의 용도: 친구 정보를 관리하는 데이터 모델 -class Friend { - final int id; - final String nickname; - final String? profileImageUrl; - final String title; // UI 연동용 (API에 없을 시 기본값 처리) - - /// 함수의 용도: Friend 클래스의 생성자 - /// 매개 변수: String nickname, String title, String? profileImage - Friend({ - required this.id, - required this.nickname, - this.profileImageUrl, - this.title = '해냄 메이트', - }); - - factory Friend.fromJson(Map json) { - return Friend( - id: json['id'], - nickname: json['nickname'], - profileImageUrl: json['profileImageUrl'], - ); - } -} - -/// 클래스의 용도: 검색 결과 유저 정보 및 요청 상태를 저장하는 모델 -class SearchResultUser { - final int? userId; // 검색 시 사용 - final int? requestId; // 요청 취소 시 사용 - final String nickname; - final String? profileImageUrl; - final String? createdAt; - bool isRequested; - bool isFriend; - - /// 함수의 용도: SearchResultUser 클래스의 생성자 - /// 매개 변수: nickname, title, profileImage, isRequested, requestTime - SearchResultUser({ - this.userId, - this.requestId, - required this.nickname, - this.profileImageUrl, - this.createdAt, - this.isRequested = false, - this.isFriend = false, - }); - - factory SearchResultUser.fromSearchJson(Map json) { - // 🔥 [디버깅용 로그] 서버가 주는 실제 상태값 확인하기 - // 나중에 해결되면 이 줄은 지우셔도 됩니다. - debugPrint( - "닉네임: ${json['nickname']} / 서버상태값: ${json['relationshipStatus']}", - ); - - return SearchResultUser( - userId: json['userId'], - nickname: json['nickname'], - profileImageUrl: json['profileImageUrl'], - // 1. 이미 친구인 경우 [추가] - isFriend: json['relationshipStatus'] == 'FRIEND', - // 2. 내가 이미 신청을 보낸 경우 - isRequested: json['relationshipStatus'] == 'PENDING_SENT', - requestId: json['requestId'], // 취소를 위해 ID도 저장 - ); - } - - factory SearchResultUser.fromSentJson(Map json) { - return SearchResultUser( - requestId: json['requestId'], - nickname: json['nickname'], - profileImageUrl: json['profileImageUrl'], - createdAt: json['createdAt'], - isRequested: true, - ); - } -} - -/// 클래스의 용도: 받은 친구 요청의 상세 정보를 관리하는 데이터 모델 -class ReceivedRequest { - final int requestId; - final int fromUserId; - final String nickname; - final String? profileImageUrl; - final String createdAt; - final String title; - - /// 함수의 용도: ReceivedRequest 클래스의 생성자 - /// 매개 변수: nickname, title, mutualFriends, time, profileImage - ReceivedRequest({ - required this.requestId, - required this.fromUserId, - required this.nickname, - this.profileImageUrl, - required this.createdAt, - this.title = '새로운 친구 요청', - }); - - factory ReceivedRequest.fromJson(Map json) { - return ReceivedRequest( - requestId: json['requestId'], - fromUserId: json['fromUserId'], - nickname: json['nickname'], - profileImageUrl: json['profileImageUrl'], - createdAt: json['createdAt'], - ); - } -} diff --git a/lib/features/social/model/user_search_card.dart b/lib/features/social/models/user_search_card.dart similarity index 100% rename from lib/features/social/model/user_search_card.dart rename to lib/features/social/models/user_search_card.dart diff --git a/lib/features/social/screens/friend_add_screen.dart b/lib/features/social/screens/friend_add_screen.dart index ffa6e0c..51c6e39 100644 --- a/lib/features/social/screens/friend_add_screen.dart +++ b/lib/features/social/screens/friend_add_screen.dart @@ -7,7 +7,7 @@ import 'package:intl/intl.dart'; import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; import '../data/social_repository.dart'; -import '../model/social_model.dart'; +import '../models/social_model.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:dio/dio.dart'; import '../../../core/utils/korean_string_utils.dart'; diff --git a/lib/features/social/screens/friend_edit_screen.dart b/lib/features/social/screens/friend_edit_screen.dart index c29f9a1..b8a7dad 100644 --- a/lib/features/social/screens/friend_edit_screen.dart +++ b/lib/features/social/screens/friend_edit_screen.dart @@ -6,7 +6,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; -import '../model/social_model.dart'; +import '../models/social_model.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../data/social_repository.dart'; import '../../../core/utils/korean_string_utils.dart'; diff --git a/lib/features/social/screens/social_screen.dart b/lib/features/social/screens/social_screen.dart index 33edb27..e92bfd0 100644 --- a/lib/features/social/screens/social_screen.dart +++ b/lib/features/social/screens/social_screen.dart @@ -9,7 +9,7 @@ import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; import 'friend_add_screen.dart'; import '../data/social_repository.dart'; -import '../model/social_model.dart'; +import '../models/social_model.dart'; import '../../../core/utils/korean_string_utils.dart'; class SocialScreen extends ConsumerStatefulWidget { From e8120c15cab7c618a7a2ffca9684eb7411a0ba5e Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Fri, 13 Mar 2026 01:02:54 +0900 Subject: [PATCH 019/134] =?UTF-8?q?feat:=20FriendRequestCard=20model=20?= =?UTF-8?q?=EC=83=88=EB=A1=9C=20=EB=A7=8C=EB=93=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../social/models/friend_request_card.dart | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 lib/features/social/models/friend_request_card.dart diff --git a/lib/features/social/models/friend_request_card.dart b/lib/features/social/models/friend_request_card.dart new file mode 100644 index 0000000..edc773e --- /dev/null +++ b/lib/features/social/models/friend_request_card.dart @@ -0,0 +1,36 @@ +import 'package:haenaem/shared/models/user.dart'; + +// 최초 작성자: 강선욱 +// 친구 요청 카드 모델 +// User에 정의된 필드(id, profileUrl, nickname)를 재사용 +class FriendRequestCard { + final User user; // 요청자 정보 (id, profileUrl, nickname) + final String requestId; // 친구 요청 id + final DateTime requestDate; // 친구 요청 날짜 + + const FriendRequestCard({ + required this.user, + required this.requestId, + required this.requestDate, + }); + + factory FriendRequestCard.fromJson(Map json) { + return FriendRequestCard( + user: User.fromJson(json['user'] as Map), + requestId: json['request_id'] as String, + requestDate: DateTime.parse(json['request_date'] as String), + ); + } + + FriendRequestCard copyWith({ + User? user, + String? requestId, + DateTime? requestDate, + }) { + return FriendRequestCard( + user: user ?? this.user, + requestId: requestId ?? this.requestId, + requestDate: requestDate ?? this.requestDate, + ); + } +} From 44671f5587b57808001db0c275898165de2be28b Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Fri, 13 Mar 2026 01:07:48 +0900 Subject: [PATCH 020/134] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20social?= =?UTF-8?q?=5Fmodel.dart=EC=97=90=20=EC=9D=B8=EB=8D=B1=EC=8A=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/social/models/social_model.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/features/social/models/social_model.dart b/lib/features/social/models/social_model.dart index c63760b..fe5c5cb 100644 --- a/lib/features/social/models/social_model.dart +++ b/lib/features/social/models/social_model.dart @@ -83,6 +83,9 @@ class SearchResultUser { } /// 클래스의 용도: 받은 친구 요청의 상세 정보를 관리하는 데이터 모델 +@Deprecated( + 'social/models/friend_request_card.dart에 FriendRequestCard 모델 대신 사용', +) class ReceivedRequest { final int requestId; final int fromUserId; From 41c5c48ffecbe6a59d179112493e6bc07debf375 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 14:10:09 +0900 Subject: [PATCH 021/134] =?UTF-8?q?feat:=20SearchChallengeCard=20model=20?= =?UTF-8?q?=EC=83=88=EB=A1=9C=20=EB=A7=8C=EB=93=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/shared/models/search_challenge_card.dart | 41 ++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 lib/shared/models/search_challenge_card.dart diff --git a/lib/shared/models/search_challenge_card.dart b/lib/shared/models/search_challenge_card.dart new file mode 100644 index 0000000..e53f2a7 --- /dev/null +++ b/lib/shared/models/search_challenge_card.dart @@ -0,0 +1,41 @@ +import 'package:haenaem/features/challenge/models/challenge_base.dart'; + +// 최초 작성자: 강선욱 +// 챌린지 검색 후 검색 결과로 나오는 챌린지 카드 모델 +// ChallengeBase에 정의된 필드(id, title, isLeader)를 재사용 +class SearchChallengeCard { + final ChallengeBase base; // 챌린지 기본 정보 (id, title, isLeader) + final int participantCount; // 챌린지 참여자 수 + final DateTime endDate; // 챌린지 완료일 + final List tags; // 챌린지 태그 리스트 + + const SearchChallengeCard({ + required this.base, + required this.participantCount, + required this.endDate, + required this.tags, + }); + + factory SearchChallengeCard.fromJson(Map json) { + return SearchChallengeCard( + base: ChallengeBase.fromJson(json), + participantCount: json['participant_count'] as int, + endDate: DateTime.parse(json['end_date'] as String), + tags: List.from(json['tag'] as List), + ); + } + + SearchChallengeCard copyWith({ + ChallengeBase? base, + int? participantCount, + DateTime? endDate, + List? tags, + }) { + return SearchChallengeCard( + base: base ?? this.base, + participantCount: participantCount ?? this.participantCount, + endDate: endDate ?? this.endDate, + tags: tags ?? this.tags, + ); + } +} From ebcd2d87176f8e2afc5375583c54838728c28439 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 14:18:05 +0900 Subject: [PATCH 022/134] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8=EC=97=90=20=EC=9D=B8=EB=8D=B1=EC=8A=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/models/challenge_model.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/features/challenge/models/challenge_model.dart b/lib/features/challenge/models/challenge_model.dart index e0a2d9d..6502938 100644 --- a/lib/features/challenge/models/challenge_model.dart +++ b/lib/features/challenge/models/challenge_model.dart @@ -496,6 +496,9 @@ class ChallengeInProgressModel { // 챌린지 검색 // TODO: 챌린지 아이디 부분 수정 +@Deprecated( + 'shared/models/search_challenge_card.dart에 있는 SearchChallengeCard 모델 대신 사용', +) class SearchChallengeModel { final int challengeId; final String title; From 3ed4d6b4974896e4eea0337d6197fba2052cd6ca Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 14:20:16 +0900 Subject: [PATCH 023/134] =?UTF-8?q?refactor:=20ChallengeBase=20=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=20shared/models=20=ED=8F=B4=EB=8D=94=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/models/home_challenge_card.dart | 2 +- lib/{features/challenge => shared}/models/challenge_base.dart | 0 lib/shared/models/search_challenge_card.dart | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename lib/{features/challenge => shared}/models/challenge_base.dart (100%) diff --git a/lib/features/challenge/models/home_challenge_card.dart b/lib/features/challenge/models/home_challenge_card.dart index a52d008..9cb4be0 100644 --- a/lib/features/challenge/models/home_challenge_card.dart +++ b/lib/features/challenge/models/home_challenge_card.dart @@ -1,4 +1,4 @@ -import 'challenge_base.dart'; +import '../../../shared/models/challenge_base.dart'; // 최초 작성자: 강선욱 // 홈 화면 챌린지 카드 모델 diff --git a/lib/features/challenge/models/challenge_base.dart b/lib/shared/models/challenge_base.dart similarity index 100% rename from lib/features/challenge/models/challenge_base.dart rename to lib/shared/models/challenge_base.dart diff --git a/lib/shared/models/search_challenge_card.dart b/lib/shared/models/search_challenge_card.dart index e53f2a7..7f4b5fe 100644 --- a/lib/shared/models/search_challenge_card.dart +++ b/lib/shared/models/search_challenge_card.dart @@ -1,4 +1,4 @@ -import 'package:haenaem/features/challenge/models/challenge_base.dart'; +import 'package:haenaem/shared/models/challenge_base.dart'; // 최초 작성자: 강선욱 // 챌린지 검색 후 검색 결과로 나오는 챌린지 카드 모델 From 59618c84907178aaf3d46d0773bd4dcdf727f28c Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 14:35:30 +0900 Subject: [PATCH 024/134] =?UTF-8?q?refactor:=20HomeChallengeCard=20?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8=20shared/models=20=ED=8F=B4=EB=8D=94?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/models/home_challenge_card.dart | 2 +- lib/shared/models/home_challenge_card.dart | 67 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 lib/shared/models/home_challenge_card.dart diff --git a/lib/features/challenge/models/home_challenge_card.dart b/lib/features/challenge/models/home_challenge_card.dart index 9cb4be0..a52d008 100644 --- a/lib/features/challenge/models/home_challenge_card.dart +++ b/lib/features/challenge/models/home_challenge_card.dart @@ -1,4 +1,4 @@ -import '../../../shared/models/challenge_base.dart'; +import 'challenge_base.dart'; // 최초 작성자: 강선욱 // 홈 화면 챌린지 카드 모델 diff --git a/lib/shared/models/home_challenge_card.dart b/lib/shared/models/home_challenge_card.dart new file mode 100644 index 0000000..9cb4be0 --- /dev/null +++ b/lib/shared/models/home_challenge_card.dart @@ -0,0 +1,67 @@ +import '../../../shared/models/challenge_base.dart'; + +// 최초 작성자: 강선욱 +// 홈 화면 챌린지 카드 모델 +// ChallengeBase에 정의된 필드(id, title, isLeader)를 토대로 홈 화면에서 필요한 데이터로 구성 +class HomeChallengeCard { + final ChallengeBase challengeBase; // id, title, isLeader + final int streakCount; // 최근 인증 연속 일수 + final int participantCount; // 참여 인원 수 + final int successParticipantCount; // 인증 완료 인원 수 + final bool warning; // 챌린지 실패 여부 + final bool isDone; // 오늘 인증 완료 여부 + final DateTime endDate; // 챌린지 종료 날짜 + final int weeklyFrequency; // 주간 최소 인증 빈도 + final bool isStreak; // 연속 인증 중인지 여부 + + const HomeChallengeCard({ + required this.challengeBase, + required this.streakCount, + required this.participantCount, + required this.successParticipantCount, + required this.warning, + required this.isDone, + required this.endDate, + required this.weeklyFrequency, + required this.isStreak, + }); + + factory HomeChallengeCard.fromJson(Map json) { + return HomeChallengeCard( + challengeBase: ChallengeBase.fromJson(json), + streakCount: json['streak_count'] as int, + participantCount: json['participant_count'] as int, + successParticipantCount: json['success_participant_count'] as int, + warning: json['warning'] as bool, + isDone: json['is_done'] as bool, + endDate: DateTime.parse(json['end_date'] as String), + weeklyFrequency: json['weekly_frequency'] as int, + isStreak: json['is_streak'] as bool, + ); + } + + HomeChallengeCard copyWith({ + ChallengeBase? challengeBase, + int? streakCount, + int? participantCount, + int? successParticipantCount, + bool? warning, + bool? isDone, + DateTime? endDate, + int? weeklyFrequency, + bool? isStreak, + }) { + return HomeChallengeCard( + challengeBase: challengeBase ?? this.challengeBase, + streakCount: streakCount ?? this.streakCount, + participantCount: participantCount ?? this.participantCount, + successParticipantCount: + successParticipantCount ?? this.successParticipantCount, + warning: warning ?? this.warning, + isDone: isDone ?? this.isDone, + endDate: endDate ?? this.endDate, + weeklyFrequency: weeklyFrequency ?? this.weeklyFrequency, + isStreak: isStreak ?? this.isStreak, + ); + } +} From 3bf47da7fe0c487eb75bf5430681b597e6949f0a Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 14:42:25 +0900 Subject: [PATCH 025/134] =?UTF-8?q?refactor:=20ChallengeBase=20=EC=B0=B8?= =?UTF-8?q?=EC=A1=B0=20=EC=A3=BC=EC=86=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/models/home_challenge_card.dart | 2 +- lib/shared/models/home_challenge_card.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/features/challenge/models/home_challenge_card.dart b/lib/features/challenge/models/home_challenge_card.dart index a52d008..3e5c328 100644 --- a/lib/features/challenge/models/home_challenge_card.dart +++ b/lib/features/challenge/models/home_challenge_card.dart @@ -1,4 +1,4 @@ -import 'challenge_base.dart'; +import 'package:haenaem/shared/models/challenge_base.dart'; // 최초 작성자: 강선욱 // 홈 화면 챌린지 카드 모델 diff --git a/lib/shared/models/home_challenge_card.dart b/lib/shared/models/home_challenge_card.dart index 9cb4be0..a52d008 100644 --- a/lib/shared/models/home_challenge_card.dart +++ b/lib/shared/models/home_challenge_card.dart @@ -1,4 +1,4 @@ -import '../../../shared/models/challenge_base.dart'; +import 'challenge_base.dart'; // 최초 작성자: 강선욱 // 홈 화면 챌린지 카드 모델 From 9a763d873c0ecc74883d68ff96748a197ea914c9 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 14:42:58 +0900 Subject: [PATCH 026/134] =?UTF-8?q?feat:=20=EC=83=88=EB=A1=9C=EC=9A=B4=20M?= =?UTF-8?q?yPageChallengeCard=20=EB=AA=A8=EB=8D=B8=20=EB=A7=8C=EB=93=A4?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/model/my_page_challenge_card.dart | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 lib/features/user/model/my_page_challenge_card.dart diff --git a/lib/features/user/model/my_page_challenge_card.dart b/lib/features/user/model/my_page_challenge_card.dart new file mode 100644 index 0000000..2770f6b --- /dev/null +++ b/lib/features/user/model/my_page_challenge_card.dart @@ -0,0 +1,60 @@ +import 'package:haenaem/shared/models/home_challenge_card.dart'; + +// 최초 작성자: 강선욱 +// 마이페이지 챌린지 카드 모델 +// HomeChallengeCard에 정의된 필드를 challengeInfo로 재사용 + +enum ChallengeStatus { + inProgress, // 진행중 + completed, // 완료 + failed, // 실패 +} + +class MyPageChallengeCard { + final HomeChallengeCard challengeInfo; // 챌린지 기본 정보 + final double rate; // 챌린지 달성률 + final ChallengeStatus status; // 챌린지 상태 + final DateTime? failedDate; // 챌린지 실패 날짜 + final int maxStreakCount; // 최고 연속 일수 + final bool isParticipated; // 참여중 여부 + + const MyPageChallengeCard({ + required this.challengeInfo, + required this.rate, + required this.status, + this.failedDate, + required this.maxStreakCount, + required this.isParticipated, + }); + + factory MyPageChallengeCard.fromJson(Map json) { + return MyPageChallengeCard( + challengeInfo: HomeChallengeCard.fromJson(json), + rate: (json['rate'] as num).toDouble(), + status: ChallengeStatus.values.byName(json['status'] as String), + failedDate: json['failed_date'] != null + ? DateTime.parse(json['failed_date'] as String) + : null, + maxStreakCount: json['max_streak_count'] as int, + isParticipated: json['is_participated'] as bool, + ); + } + + MyPageChallengeCard copyWith({ + HomeChallengeCard? challengeInfo, + double? rate, + ChallengeStatus? status, + DateTime? failedDate, + int? maxStreakCount, + bool? isParticipated, + }) { + return MyPageChallengeCard( + challengeInfo: challengeInfo ?? this.challengeInfo, + rate: rate ?? this.rate, + status: status ?? this.status, + failedDate: failedDate ?? this.failedDate, + maxStreakCount: maxStreakCount ?? this.maxStreakCount, + isParticipated: isParticipated ?? this.isParticipated, + ); + } +} From e416cc0527664aee87def814c219c929624e1865 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 14:45:16 +0900 Subject: [PATCH 027/134] =?UTF-8?q?feat:=20invite=20challenge=20card=20?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/invite_challenge_card.dart | 30 +++++++++++++++++++ .../{model => models}/notification_model.dart | 5 +++- .../provider/notification_provider.dart | 2 +- .../views/all_notifications_view.dart | 2 +- 4 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 lib/features/notification/models/invite_challenge_card.dart rename lib/features/notification/{model => models}/notification_model.dart (95%) diff --git a/lib/features/notification/models/invite_challenge_card.dart b/lib/features/notification/models/invite_challenge_card.dart new file mode 100644 index 0000000..2247936 --- /dev/null +++ b/lib/features/notification/models/invite_challenge_card.dart @@ -0,0 +1,30 @@ +// 최초작성자: 정승빈 +// 챌린지 초대 목록 아이템 모델 +import 'package:haenaem/shared/models/user.dart'; +import 'package:haenaem/shared/models/search_challenge_card.dart'; + +class InviteChallengecard { + final SearchChallengeCard challengeInfo; // 초대된 챌린지의 상세정보 + final User inviterUser; // 초대한 유저의 정보 (ID, 프로필 URL, 닉네임 포함) + + InviteChallengecard({required this.challengeInfo, required this.inviterUser}); + + // 서버에서 받은 JSON 데이터를 [InviteChallengecard] 객체로 변환하는 팩토리 생성자 + factory InviteChallengecard.fromJson(Map json) { + String? rawProfileUrl = json['profileUrl']; + // URL이 null이 아니고, 공백을 제거했을 때 빈 문자열("")이라면 null로 간주 + // (서버에서 잘못된 빈 값이 넘어올 경우를 대비한 방어 코드) + if (rawProfileUrl != null && rawProfileUrl.trim().isEmpty) { + rawProfileUrl = null; + } + + return InviteChallengecard( + challengeInfo: SearchChallengeCard.fromJson(json), + inviterUser: User( + id: json['inviterId'] ?? 0, + nickname: json['inviterNickname'] ?? '알 수 없음', + profileUrl: rawProfileUrl, // 빈 문자열이면 null로 처리 + ), + ); + } +} diff --git a/lib/features/notification/model/notification_model.dart b/lib/features/notification/models/notification_model.dart similarity index 95% rename from lib/features/notification/model/notification_model.dart rename to lib/features/notification/models/notification_model.dart index 1d3c5d1..3a9abfb 100644 --- a/lib/features/notification/model/notification_model.dart +++ b/lib/features/notification/models/notification_model.dart @@ -1,5 +1,5 @@ // 최초 작성자: 정승빈 -// 알림 데이터 모델 (enum으로 알림 타입 구분) +// 알림 데이터 모델 class NotificationModel { final String message; final String type; @@ -53,6 +53,9 @@ class NotificationModel { } } +@Deprecated( + 'notification/models/challenge_invite_card내에 ChallengeInviteCard 대신 사용', +) // 챌린지 초대 목록 아이템 모델 class ChallengeInviteModel { final int challengeId; diff --git a/lib/features/notification/provider/notification_provider.dart b/lib/features/notification/provider/notification_provider.dart index 197872a..e96718a 100644 --- a/lib/features/notification/provider/notification_provider.dart +++ b/lib/features/notification/provider/notification_provider.dart @@ -2,7 +2,7 @@ // 알림 목록 상태 및 탭 상태 관리 import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../data/notification_repository.dart'; -import '../model/notification_model.dart'; +import '../models/notification_model.dart'; // 홈 화면 새로고침이 필요한지 여부를 저장하는 스위치 (초기값: false) final needsHomeRefreshProvider = StateProvider((ref) => false); diff --git a/lib/features/notification/views/all_notifications_view.dart b/lib/features/notification/views/all_notifications_view.dart index fdfce5e..410624e 100644 --- a/lib/features/notification/views/all_notifications_view.dart +++ b/lib/features/notification/views/all_notifications_view.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../provider/notification_provider.dart'; -import '../model/notification_model.dart'; +import '../models/notification_model.dart'; import '../widgets/notification_date_header.dart'; import '../widgets/notification_list_tile.dart'; import '../../../core/theme/app_colors.dart'; From 5dcdbca562bb05af695b933c76e4224c8b8b8558 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 14:49:29 +0900 Subject: [PATCH 028/134] =?UTF-8?q?refactor:=20user/model=20->=20user/mode?= =?UTF-8?q?ls=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/models/challenge_model.dart | 3 + .../user/model/my_page_challenge_card.dart | 60 ---------- lib/features/user/model/user_model.dart | 110 ------------------ 3 files changed, 3 insertions(+), 170 deletions(-) delete mode 100644 lib/features/user/model/my_page_challenge_card.dart delete mode 100644 lib/features/user/model/user_model.dart diff --git a/lib/features/challenge/models/challenge_model.dart b/lib/features/challenge/models/challenge_model.dart index 6502938..74640e2 100644 --- a/lib/features/challenge/models/challenge_model.dart +++ b/lib/features/challenge/models/challenge_model.dart @@ -429,6 +429,9 @@ class CertificationPostModel { enum MyPageTab { inProgress, success, fail } // 내 페이지 - 나의 챌린지 - 진행중인 챌린지 +@Deprecated( + 'user/models/my_page_challenge_card.dart내에 MyPageChallengeCard 모델 대신 사용', +) class ChallengeInProgressModel { final int challengeId; final String title; diff --git a/lib/features/user/model/my_page_challenge_card.dart b/lib/features/user/model/my_page_challenge_card.dart deleted file mode 100644 index 2770f6b..0000000 --- a/lib/features/user/model/my_page_challenge_card.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'package:haenaem/shared/models/home_challenge_card.dart'; - -// 최초 작성자: 강선욱 -// 마이페이지 챌린지 카드 모델 -// HomeChallengeCard에 정의된 필드를 challengeInfo로 재사용 - -enum ChallengeStatus { - inProgress, // 진행중 - completed, // 완료 - failed, // 실패 -} - -class MyPageChallengeCard { - final HomeChallengeCard challengeInfo; // 챌린지 기본 정보 - final double rate; // 챌린지 달성률 - final ChallengeStatus status; // 챌린지 상태 - final DateTime? failedDate; // 챌린지 실패 날짜 - final int maxStreakCount; // 최고 연속 일수 - final bool isParticipated; // 참여중 여부 - - const MyPageChallengeCard({ - required this.challengeInfo, - required this.rate, - required this.status, - this.failedDate, - required this.maxStreakCount, - required this.isParticipated, - }); - - factory MyPageChallengeCard.fromJson(Map json) { - return MyPageChallengeCard( - challengeInfo: HomeChallengeCard.fromJson(json), - rate: (json['rate'] as num).toDouble(), - status: ChallengeStatus.values.byName(json['status'] as String), - failedDate: json['failed_date'] != null - ? DateTime.parse(json['failed_date'] as String) - : null, - maxStreakCount: json['max_streak_count'] as int, - isParticipated: json['is_participated'] as bool, - ); - } - - MyPageChallengeCard copyWith({ - HomeChallengeCard? challengeInfo, - double? rate, - ChallengeStatus? status, - DateTime? failedDate, - int? maxStreakCount, - bool? isParticipated, - }) { - return MyPageChallengeCard( - challengeInfo: challengeInfo ?? this.challengeInfo, - rate: rate ?? this.rate, - status: status ?? this.status, - failedDate: failedDate ?? this.failedDate, - maxStreakCount: maxStreakCount ?? this.maxStreakCount, - isParticipated: isParticipated ?? this.isParticipated, - ); - } -} diff --git a/lib/features/user/model/user_model.dart b/lib/features/user/model/user_model.dart deleted file mode 100644 index 2fb31c8..0000000 --- a/lib/features/user/model/user_model.dart +++ /dev/null @@ -1,110 +0,0 @@ -// 리팩토링: 강선욱 -// 사용자 객체와 관련된 정보를 관리 모델 - -// 마이페이지 사용자 프로필 부분 -@Deprecated('shared/models/user.dart에 정의된 model을 대신 사용') -class UserProfileModel { - final String nickname; - final String introduction; - final String profileImageUrl; - final List tags; - - UserProfileModel({ - required this.nickname, - required this.introduction, - required this.profileImageUrl, - required this.tags, - }); - - factory UserProfileModel.fromJson(Map json) { - return UserProfileModel( - nickname: json['nickname'] ?? '', - introduction: json['introduction'] ?? '', - profileImageUrl: json['profileImageUrl'] ?? '', - tags: List.from(json['tags'] ?? []), - ); - } -} - -// 방장 정보를 관리하는 클래스 -@Deprecated('shared/models/user.dart에 정의된 model을 대신 사용') -class HostModel { - final String name; - final String profileImageUrl; - - HostModel({required this.name, required this.profileImageUrl}); - - factory HostModel.fromJson(Map json) { - return HostModel( - name: json['name'] ?? '익명', - profileImageUrl: json['profileImageUrl'] ?? '', - ); - } -} - -// 챌린지 참여 멤버 정보를 관리하는 클래스 -@Deprecated('shared/models/user.dart에 정의된 model을 대신 사용') -class ParticipantModel { - final String name; - final String profileImageUrl; - - ParticipantModel({required this.name, required this.profileImageUrl}); - - factory ParticipantModel.fromJson(Map json) { - return ParticipantModel( - name: json['name'] ?? '', - profileImageUrl: json['profileImageUrl'] ?? '', - ); - } -} - -// 친구 정보를 관리하는 클래스 -@Deprecated('shared/models/user.dart에 정의된 model을 대신 사용') -class FriendModel { - final int id; - final String email; - final String nickname; - final String? profileImageUrl; - - FriendModel({ - required this.id, - required this.email, - required this.nickname, - this.profileImageUrl, - }); - - factory FriendModel.fromJson(Map json) { - return FriendModel( - id: json['id'] ?? 0, - email: json['email'] ?? '', - nickname: json['nickname'] ?? '', - profileImageUrl: json['profileImageUrl'], - ); - } -} - -// 챌린지 멤버 정보를 관리하는 클래스 (memberId 포함) -// 챌린지 멤버 관리 기능에 쓰임 -// challenge_member_provider.dart -// challenge_repository.dart -// challenge_members_screen.dart -@Deprecated('shared/models/user.dart에 정의된 model을 대신 사용') -class ChallengeMember { - final int memberId; - final String nickname; - final String? profileImageUrl; - - ChallengeMember({ - required this.memberId, - required this.nickname, - this.profileImageUrl, - }); - - factory ChallengeMember.fromJson(Map json) { - return ChallengeMember( - memberId: json['userId'] as int, - nickname: json['nickname'] as String, - profileImageUrl: json['profileImageUrl'] as String?, - ); - } -} From 03677ff2a4df72c7d5cfd7fd84d1b2d811ae3798 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 14:49:45 +0900 Subject: [PATCH 029/134] =?UTF-8?q?refactor:=20user/model=20->=20user/mode?= =?UTF-8?q?ls=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/models/my_page_challenge_card.dart | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 lib/features/user/models/my_page_challenge_card.dart diff --git a/lib/features/user/models/my_page_challenge_card.dart b/lib/features/user/models/my_page_challenge_card.dart new file mode 100644 index 0000000..2770f6b --- /dev/null +++ b/lib/features/user/models/my_page_challenge_card.dart @@ -0,0 +1,60 @@ +import 'package:haenaem/shared/models/home_challenge_card.dart'; + +// 최초 작성자: 강선욱 +// 마이페이지 챌린지 카드 모델 +// HomeChallengeCard에 정의된 필드를 challengeInfo로 재사용 + +enum ChallengeStatus { + inProgress, // 진행중 + completed, // 완료 + failed, // 실패 +} + +class MyPageChallengeCard { + final HomeChallengeCard challengeInfo; // 챌린지 기본 정보 + final double rate; // 챌린지 달성률 + final ChallengeStatus status; // 챌린지 상태 + final DateTime? failedDate; // 챌린지 실패 날짜 + final int maxStreakCount; // 최고 연속 일수 + final bool isParticipated; // 참여중 여부 + + const MyPageChallengeCard({ + required this.challengeInfo, + required this.rate, + required this.status, + this.failedDate, + required this.maxStreakCount, + required this.isParticipated, + }); + + factory MyPageChallengeCard.fromJson(Map json) { + return MyPageChallengeCard( + challengeInfo: HomeChallengeCard.fromJson(json), + rate: (json['rate'] as num).toDouble(), + status: ChallengeStatus.values.byName(json['status'] as String), + failedDate: json['failed_date'] != null + ? DateTime.parse(json['failed_date'] as String) + : null, + maxStreakCount: json['max_streak_count'] as int, + isParticipated: json['is_participated'] as bool, + ); + } + + MyPageChallengeCard copyWith({ + HomeChallengeCard? challengeInfo, + double? rate, + ChallengeStatus? status, + DateTime? failedDate, + int? maxStreakCount, + bool? isParticipated, + }) { + return MyPageChallengeCard( + challengeInfo: challengeInfo ?? this.challengeInfo, + rate: rate ?? this.rate, + status: status ?? this.status, + failedDate: failedDate ?? this.failedDate, + maxStreakCount: maxStreakCount ?? this.maxStreakCount, + isParticipated: isParticipated ?? this.isParticipated, + ); + } +} From cdc46b079a07efeaa71cb7f7d9e471b8ec557435 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 14:50:06 +0900 Subject: [PATCH 030/134] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8=EC=97=90=20=EC=9D=B8=EB=8D=B1=EC=8A=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/user/models/user_model.dart | 110 +++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 lib/features/user/models/user_model.dart diff --git a/lib/features/user/models/user_model.dart b/lib/features/user/models/user_model.dart new file mode 100644 index 0000000..2fb31c8 --- /dev/null +++ b/lib/features/user/models/user_model.dart @@ -0,0 +1,110 @@ +// 리팩토링: 강선욱 +// 사용자 객체와 관련된 정보를 관리 모델 + +// 마이페이지 사용자 프로필 부분 +@Deprecated('shared/models/user.dart에 정의된 model을 대신 사용') +class UserProfileModel { + final String nickname; + final String introduction; + final String profileImageUrl; + final List tags; + + UserProfileModel({ + required this.nickname, + required this.introduction, + required this.profileImageUrl, + required this.tags, + }); + + factory UserProfileModel.fromJson(Map json) { + return UserProfileModel( + nickname: json['nickname'] ?? '', + introduction: json['introduction'] ?? '', + profileImageUrl: json['profileImageUrl'] ?? '', + tags: List.from(json['tags'] ?? []), + ); + } +} + +// 방장 정보를 관리하는 클래스 +@Deprecated('shared/models/user.dart에 정의된 model을 대신 사용') +class HostModel { + final String name; + final String profileImageUrl; + + HostModel({required this.name, required this.profileImageUrl}); + + factory HostModel.fromJson(Map json) { + return HostModel( + name: json['name'] ?? '익명', + profileImageUrl: json['profileImageUrl'] ?? '', + ); + } +} + +// 챌린지 참여 멤버 정보를 관리하는 클래스 +@Deprecated('shared/models/user.dart에 정의된 model을 대신 사용') +class ParticipantModel { + final String name; + final String profileImageUrl; + + ParticipantModel({required this.name, required this.profileImageUrl}); + + factory ParticipantModel.fromJson(Map json) { + return ParticipantModel( + name: json['name'] ?? '', + profileImageUrl: json['profileImageUrl'] ?? '', + ); + } +} + +// 친구 정보를 관리하는 클래스 +@Deprecated('shared/models/user.dart에 정의된 model을 대신 사용') +class FriendModel { + final int id; + final String email; + final String nickname; + final String? profileImageUrl; + + FriendModel({ + required this.id, + required this.email, + required this.nickname, + this.profileImageUrl, + }); + + factory FriendModel.fromJson(Map json) { + return FriendModel( + id: json['id'] ?? 0, + email: json['email'] ?? '', + nickname: json['nickname'] ?? '', + profileImageUrl: json['profileImageUrl'], + ); + } +} + +// 챌린지 멤버 정보를 관리하는 클래스 (memberId 포함) +// 챌린지 멤버 관리 기능에 쓰임 +// challenge_member_provider.dart +// challenge_repository.dart +// challenge_members_screen.dart +@Deprecated('shared/models/user.dart에 정의된 model을 대신 사용') +class ChallengeMember { + final int memberId; + final String nickname; + final String? profileImageUrl; + + ChallengeMember({ + required this.memberId, + required this.nickname, + this.profileImageUrl, + }); + + factory ChallengeMember.fromJson(Map json) { + return ChallengeMember( + memberId: json['userId'] as int, + nickname: json['nickname'] as String, + profileImageUrl: json['profileImageUrl'] as String?, + ); + } +} From e47b67e175fc5d94e7e84a74cf4eec39d297b3ee Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 15:08:19 +0900 Subject: [PATCH 031/134] =?UTF-8?q?refactor:=20user/model=20->=20user/mode?= =?UTF-8?q?ls=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/auth/signup/screens/auth_gate.dart | 2 +- lib/features/challenge/data/challenge_repository.dart | 2 +- lib/features/challenge/models/challenge_model.dart | 2 +- lib/features/challenge/provider/challenge_member_provider.dart | 2 +- lib/features/challenge/provider/challenge_provider.dart | 2 +- lib/features/challenge/settings/challenge_members_screen.dart | 2 +- lib/features/challenge/widgets/delegate_dialog.dart | 2 +- lib/features/feed/screens/challenge_search_screen.dart | 2 +- lib/features/user/data/user_repository.dart | 2 +- lib/features/user/provider/tag_provider.dart | 2 +- lib/features/user/screens/profile_edit_screen.dart | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/features/auth/signup/screens/auth_gate.dart b/lib/features/auth/signup/screens/auth_gate.dart index ad72f8d..46fb919 100644 --- a/lib/features/auth/signup/screens/auth_gate.dart +++ b/lib/features/auth/signup/screens/auth_gate.dart @@ -6,7 +6,7 @@ import 'package:haenaem/features/main/screens/main_screen.dart'; import 'package:haenaem/features/auth/login/login_screen.dart'; import 'signup_main_screen.dart'; import 'package:haenaem/features/user/data/user_repository.dart'; -import 'package:haenaem/features/user/model/user_model.dart'; +import 'package:haenaem/features/user/models/user_model.dart'; import 'package:haenaem/features/notification/services/fcm_service.dart'; // 앱을 껐다 켰을 때 저장된 토큰을 확인 diff --git a/lib/features/challenge/data/challenge_repository.dart b/lib/features/challenge/data/challenge_repository.dart index 863e7d8..83a86c1 100644 --- a/lib/features/challenge/data/challenge_repository.dart +++ b/lib/features/challenge/data/challenge_repository.dart @@ -11,7 +11,7 @@ import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter/foundation.dart'; import 'package:haenaem/features/auth/services/auth_service.dart'; -import 'package:haenaem/features/user/model/user_model.dart'; +import 'package:haenaem/features/user/models/user_model.dart'; import 'package:haenaem/core/network/dio_provider.dart'; part 'challenge_repository.g.dart'; diff --git a/lib/features/challenge/models/challenge_model.dart b/lib/features/challenge/models/challenge_model.dart index 74640e2..0bda4a7 100644 --- a/lib/features/challenge/models/challenge_model.dart +++ b/lib/features/challenge/models/challenge_model.dart @@ -2,7 +2,7 @@ // 챌린지 관련 데이터 관리 모델 import 'package:intl/intl.dart'; import 'package:flutter/foundation.dart'; -import 'package:haenaem/features/user/model/user_model.dart'; +import 'package:haenaem/features/user/models/user_model.dart'; import 'package:haenaem/features/challenge/models/image_model.dart'; // 챌린지의 상태(완료, 실패 위기, 일반)를 정의하는 열거형 diff --git a/lib/features/challenge/provider/challenge_member_provider.dart b/lib/features/challenge/provider/challenge_member_provider.dart index db79c31..6ee5df6 100644 --- a/lib/features/challenge/provider/challenge_member_provider.dart +++ b/lib/features/challenge/provider/challenge_member_provider.dart @@ -3,7 +3,7 @@ library; import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../data/challenge_repository.dart'; -import '../../user/model/user_model.dart'; +import '../../user/models/user_model.dart'; part 'challenge_member_provider.g.dart'; diff --git a/lib/features/challenge/provider/challenge_provider.dart b/lib/features/challenge/provider/challenge_provider.dart index 9e162c3..3fe2b0d 100644 --- a/lib/features/challenge/provider/challenge_provider.dart +++ b/lib/features/challenge/provider/challenge_provider.dart @@ -4,7 +4,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../data/challenge_repository.dart'; import 'package:haenaem/features/user/data/user_repository.dart'; import '../models/challenge_model.dart'; -import 'package:haenaem/features/user/model/user_model.dart'; +import 'package:haenaem/features/user/models/user_model.dart'; import 'dart:io'; part 'challenge_provider.g.dart'; diff --git a/lib/features/challenge/settings/challenge_members_screen.dart b/lib/features/challenge/settings/challenge_members_screen.dart index ff0739f..ad226f3 100644 --- a/lib/features/challenge/settings/challenge_members_screen.dart +++ b/lib/features/challenge/settings/challenge_members_screen.dart @@ -9,7 +9,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:dio/dio.dart'; import 'package:haenaem/core/utils/korean_string_utils.dart'; -import 'package:haenaem/features/user/model/user_model.dart'; +import 'package:haenaem/features/user/models/user_model.dart'; import 'package:haenaem/features/challenge/provider/challenge_member_provider.dart'; import 'widgets/kick_confirm_dialog.dart'; diff --git a/lib/features/challenge/widgets/delegate_dialog.dart b/lib/features/challenge/widgets/delegate_dialog.dart index 4a00e1e..f0b04fb 100644 --- a/lib/features/challenge/widgets/delegate_dialog.dart +++ b/lib/features/challenge/widgets/delegate_dialog.dart @@ -4,7 +4,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:haenaem/features/user/model/user_model.dart'; +import 'package:haenaem/features/user/models/user_model.dart'; import '../provider/challenge_provider.dart'; import 'package:haenaem/features/challenge/provider/challenge_member_provider.dart'; import 'package:haenaem/shared/widgets/challenge_exit_base_dialog.dart'; diff --git a/lib/features/feed/screens/challenge_search_screen.dart b/lib/features/feed/screens/challenge_search_screen.dart index e353d0e..a7f89cf 100644 --- a/lib/features/feed/screens/challenge_search_screen.dart +++ b/lib/features/feed/screens/challenge_search_screen.dart @@ -7,7 +7,7 @@ import 'package:haenaem/features/feed/screens/challenge_detail_screen.dart'; // import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/features/challenge/models/challenge_model.dart'; -import 'package:haenaem/features/user/model/user_model.dart'; +import 'package:haenaem/features/user/models/user_model.dart'; class ChallengeSearchScreen extends ConsumerStatefulWidget { const ChallengeSearchScreen({super.key}); diff --git a/lib/features/user/data/user_repository.dart b/lib/features/user/data/user_repository.dart index 3798ad6..06d6edc 100644 --- a/lib/features/user/data/user_repository.dart +++ b/lib/features/user/data/user_repository.dart @@ -6,7 +6,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:haenaem/core/network/dio_provider.dart'; import 'package:haenaem/features/challenge/models/challenge_model.dart'; -import 'package:haenaem/features/user/model/user_model.dart'; +import 'package:haenaem/features/user/models/user_model.dart'; part 'user_repository.g.dart'; // 회원가입 + 내페이지 diff --git a/lib/features/user/provider/tag_provider.dart b/lib/features/user/provider/tag_provider.dart index 4ef2e3d..60b5bc7 100644 --- a/lib/features/user/provider/tag_provider.dart +++ b/lib/features/user/provider/tag_provider.dart @@ -3,7 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../../challenge/data/challenge_repository.dart'; import '../../challenge/models/challenge_model.dart'; -import 'package:haenaem/features/user/model/user_model.dart'; +import 'package:haenaem/features/user/models/user_model.dart'; import 'package:haenaem/features/user/data/user_repository.dart'; import 'package:flutter/foundation.dart'; import '../../auth/signup/models/signup_state.dart'; diff --git a/lib/features/user/screens/profile_edit_screen.dart b/lib/features/user/screens/profile_edit_screen.dart index 050d186..c3d2315 100644 --- a/lib/features/user/screens/profile_edit_screen.dart +++ b/lib/features/user/screens/profile_edit_screen.dart @@ -6,7 +6,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:image_picker/image_picker.dart'; import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; -import 'package:haenaem/features/user/model/user_model.dart'; +import 'package:haenaem/features/user/models/user_model.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/shared/models/tag_data.dart'; import 'package:haenaem/shared/widgets/app_tag_chip.dart'; From fe0e8b96d2d752289f63b8ffab6888825536bcee Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 15:18:12 +0900 Subject: [PATCH 032/134] =?UTF-8?q?feat:=20ChallengeDetail=20=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/shared/models/challenge_detail.dart | 75 +++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 lib/shared/models/challenge_detail.dart diff --git a/lib/shared/models/challenge_detail.dart b/lib/shared/models/challenge_detail.dart new file mode 100644 index 0000000..56408a5 --- /dev/null +++ b/lib/shared/models/challenge_detail.dart @@ -0,0 +1,75 @@ +import 'package:haenaem/shared/models/challenge_base.dart'; +import 'package:haenaem/shared/models/user.dart'; + +// 최초 작성자: 강선욱 +// 챌린지 상세 모델 +// ChallengeBase에 정의된 필드(id, title, isLeader)를 재사용 +// User 모델을 방장(host), 오늘 인증한 유저 리스트(todaySuccessUsers)에 재사용 +class ChallengeDetail { + final ChallengeBase challengeBase; // 챌린지 기본 정보 (id, title, isLeader) + final DateTime startDate; // 챌린지 시작 날짜 + final DateTime endDate; // 챌린지 종료 날짜 + final int weeklyFrequency; // 주간 최소 인증 빈도 + final bool photoRequired; // 사진 인증 필요 여부 + final List tags; // 챌린지 태그 리스트 + final String description; // 챌린지 설명 + final User leader; // 방장 정보 (id, profileUrl, nickname) + final int participantCount; // 참여자 수 + final List todaySuccessUsers; // 오늘 인증 완료한 유저 리스트 + + const ChallengeDetail({ + required this.challengeBase, + required this.startDate, + required this.endDate, + required this.weeklyFrequency, + required this.photoRequired, + required this.tags, + required this.description, + required this.leader, + required this.participantCount, + required this.todaySuccessUsers, + }); + + factory ChallengeDetail.fromJson(Map json) { + return ChallengeDetail( + challengeBase: ChallengeBase.fromJson(json), + startDate: DateTime.parse(json['start_date'] as String), + endDate: DateTime.parse(json['end_date'] as String), + weeklyFrequency: json['weekly_frequency'] as int, + photoRequired: json['photo_required'] as bool, + tags: List.from(json['tags'] as List), + description: json['description'] as String, + leader: User.fromJson(json['host'] as Map), + participantCount: json['participant_count'] as int, + todaySuccessUsers: (json['today_success_users'] as List) + .map((e) => User.fromJson(e as Map)) + .toList(), + ); + } + + ChallengeDetail copyWith({ + ChallengeBase? challengeBase, + DateTime? startDate, + DateTime? endDate, + int? weeklyFrequency, + bool? photoRequired, + List? tags, + String? description, + User? leader, + int? participantCount, + List? todaySuccessUsers, + }) { + return ChallengeDetail( + challengeBase: challengeBase ?? this.challengeBase, + startDate: startDate ?? this.startDate, + endDate: endDate ?? this.endDate, + weeklyFrequency: weeklyFrequency ?? this.weeklyFrequency, + photoRequired: photoRequired ?? this.photoRequired, + tags: tags ?? this.tags, + description: description ?? this.description, + leader: leader ?? this.leader, + participantCount: participantCount ?? this.participantCount, + todaySuccessUsers: todaySuccessUsers ?? this.todaySuccessUsers, + ); + } +} From b114eec2fc1870fae1e8279f303a16d2b639afbd Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 15:18:26 +0900 Subject: [PATCH 033/134] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8=EC=97=90=20=EC=9D=B8=EB=8D=B1=EC=8A=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/models/challenge_model.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/features/challenge/models/challenge_model.dart b/lib/features/challenge/models/challenge_model.dart index 0bda4a7..341edc0 100644 --- a/lib/features/challenge/models/challenge_model.dart +++ b/lib/features/challenge/models/challenge_model.dart @@ -94,6 +94,7 @@ class ChallengeMainModel { // } // 챌린지 상세정보에서 사용하는 챌린지 모델 +@Deprecated('shared/models/challenge_detail.dart에 있는 ChallengeDetail 모델 대신 사용') class ChallengeDetailModel { final String title; final String startDate; @@ -148,6 +149,7 @@ class ChallengeDetailModel { } // 챌린지 생성 데이터 관리 클래스 +@Deprecated('사용 X') class ChallengeCreateResponse { final int id; final String challengeLink; @@ -190,6 +192,7 @@ class ChallengeCreateResponse { } // 챌린지 내 현황 탭 데이터 관리 클래스 +@Deprecated('사용 X') class ChallengeCalendarModel { final int totalSuccessDays; final int currentStreakDays; @@ -211,6 +214,7 @@ class ChallengeCalendarModel { } // 챌린지 내 현황 달력 그리드 모델 +@Deprecated('feed/models/post.dart에 있는 모델 대신 사용') class ChallengeCalendarPhoto { final int postId; final String postDate; From c1ad05035164daac87861262342cab74ad8cf376 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 15:27:53 +0900 Subject: [PATCH 034/134] =?UTF-8?q?refactor:=20=EC=B1=8C=EB=A6=B0=EC=A7=80?= =?UTF-8?q?=20id=EA=B0=92=20int=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/shared/models/challenge_base.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/shared/models/challenge_base.dart b/lib/shared/models/challenge_base.dart index da9d2f7..fb1aa59 100644 --- a/lib/shared/models/challenge_base.dart +++ b/lib/shared/models/challenge_base.dart @@ -1,7 +1,7 @@ // 최초 작성자: 강선욱 // 챌린지 기본 정보를 정의한 모델 class ChallengeBase { - final String id; + final int id; final String title; final bool isLeader; // 현재 로그인 중인 유저가 해당 챌린지의 방장인지 여부 @@ -13,13 +13,13 @@ class ChallengeBase { factory ChallengeBase.fromJson(Map json) { return ChallengeBase( - id: json['id'] as String, + id: json['id'] as int, title: json['title'] as String, isLeader: json['is_leader'] as bool, ); } - ChallengeBase copyWith({String? id, String? title, bool? isLeader}) { + ChallengeBase copyWith({int? id, String? title, bool? isLeader}) { return ChallengeBase( id: id ?? this.id, title: title ?? this.title, From efeb823cab572f2fe0c38f062e9e3eea33f7cfba Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 15:50:19 +0900 Subject: [PATCH 035/134] =?UTF-8?q?refactor:=20=EC=83=88=EB=A1=9C=EC=9A=B4?= =?UTF-8?q?=20notification=20model=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notification/data/notification_repository.dart | 6 +++--- lib/features/notification/models/notification_model.dart | 2 ++ .../notification/provider/notification_provider.dart | 9 +++++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/features/notification/data/notification_repository.dart b/lib/features/notification/data/notification_repository.dart index e0a7b14..6806c9e 100644 --- a/lib/features/notification/data/notification_repository.dart +++ b/lib/features/notification/data/notification_repository.dart @@ -3,7 +3,7 @@ import 'package:dio/dio.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import '../model/notification_model.dart'; +import 'package:haenaem/features/notification/models/invite_challenge_card.dart'; // 1. SecureStorage 프로바이더 생성 final secureStorageProvider = Provider((ref) { @@ -86,12 +86,12 @@ class NotificationRepository { } // 챌린지 초대 목록 조회 - Future> getChallengeInvites() async { + Future> getChallengeInvites() async { try { final response = await dio.get('/api/challenges/invites'); // 응답이 배열(List) 형태 final List data = response.data; - return data.map((e) => ChallengeInviteModel.fromJson(e)).toList(); + return data.map((e) => InviteChallengecard.fromJson(e)).toList(); } on DioException catch (e) { print('❌ [초대 조회 에러]: ${e.response?.data}'); throw Exception('초대 목록을 불러오는데 실패했습니다.'); diff --git a/lib/features/notification/models/notification_model.dart b/lib/features/notification/models/notification_model.dart index 3a9abfb..6222f21 100644 --- a/lib/features/notification/models/notification_model.dart +++ b/lib/features/notification/models/notification_model.dart @@ -53,6 +53,7 @@ class NotificationModel { } } +/* @Deprecated( 'notification/models/challenge_invite_card내에 ChallengeInviteCard 대신 사용', ) @@ -93,3 +94,4 @@ class ChallengeInviteModel { ); } } +*/ diff --git a/lib/features/notification/provider/notification_provider.dart b/lib/features/notification/provider/notification_provider.dart index e96718a..d97b186 100644 --- a/lib/features/notification/provider/notification_provider.dart +++ b/lib/features/notification/provider/notification_provider.dart @@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../data/notification_repository.dart'; import '../models/notification_model.dart'; +import 'package:haenaem/features/notification/models/invite_challenge_card.dart'; // 홈 화면 새로고침이 필요한지 여부를 저장하는 스위치 (초기값: false) final needsHomeRefreshProvider = StateProvider((ref) => false); @@ -143,13 +144,13 @@ class NotificationNotifier extends StateNotifier { } class ChallengeInviteState { - final List invites; + final List invites; final bool isLoading; ChallengeInviteState({required this.invites, this.isLoading = false}); ChallengeInviteState copyWith({ - List? invites, + List? invites, bool? isLoading, }) { return ChallengeInviteState( @@ -191,7 +192,7 @@ class ChallengeInviteNotifier extends StateNotifier { // 성공하면 UI 목록에서 해당 카드 즉시 제거 state = state.copyWith( invites: state.invites - .where((i) => i.challengeId != challengeId) + .where((i) => i.challengeInfo.base.id != challengeId) .toList(), ); } catch (e) { @@ -207,7 +208,7 @@ class ChallengeInviteNotifier extends StateNotifier { // 성공하면 UI 목록에서 해당 카드 즉시 제거 state = state.copyWith( invites: state.invites - .where((i) => i.challengeId != challengeId) + .where((i) => i.challengeInfo.base.id != challengeId) .toList(), ); } catch (e) { From f9f541cdbd85f36ed583cd886dbd96dc6107efa4 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 14 Mar 2026 15:51:22 +0900 Subject: [PATCH 036/134] =?UTF-8?q?refactor:=20home=ED=99=94=EB=A9=B4=20Ch?= =?UTF-8?q?allengeCard=20=EC=9C=84=EC=A0=AF=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/home/enums/challenge_status.dart | 6 + .../home/{ => screens}/home_screen.dart | 2 +- .../home/widgets/home_challenge_card.dart | 166 ++++++++++++++++++ lib/features/main/screens/main_screen.dart | 2 +- .../views/challenge_invites_view.dart | 28 +-- lib/shared/models/search_challenge_card.dart | 10 +- 6 files changed, 195 insertions(+), 19 deletions(-) create mode 100644 lib/features/home/enums/challenge_status.dart rename lib/features/home/{ => screens}/home_screen.dart (99%) create mode 100644 lib/features/home/widgets/home_challenge_card.dart diff --git a/lib/features/home/enums/challenge_status.dart b/lib/features/home/enums/challenge_status.dart new file mode 100644 index 0000000..9808ccd --- /dev/null +++ b/lib/features/home/enums/challenge_status.dart @@ -0,0 +1,6 @@ +// 챌린지의 상태(완료, 실패 위기, 일반)를 정의하는 열거형 +enum ChallengeStatus { + completed, // 초록색 카드 + urgent, // 빨간색 카드 + normal, // 회색 카드 +} diff --git a/lib/features/home/home_screen.dart b/lib/features/home/screens/home_screen.dart similarity index 99% rename from lib/features/home/home_screen.dart rename to lib/features/home/screens/home_screen.dart index 1fedce2..49573ee 100644 --- a/lib/features/home/home_screen.dart +++ b/lib/features/home/screens/home_screen.dart @@ -1,4 +1,4 @@ -// // 최초 작성자 : 강선욱 +// 최초 작성자 : 강선욱 import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; // 추가 import 'package:flutter_svg/flutter_svg.dart'; diff --git a/lib/features/home/widgets/home_challenge_card.dart b/lib/features/home/widgets/home_challenge_card.dart new file mode 100644 index 0000000..8a4528a --- /dev/null +++ b/lib/features/home/widgets/home_challenge_card.dart @@ -0,0 +1,166 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; + +import 'package:haenaem/shared/models/home_challenge_card.dart'; +import '../enums/challenge_status.dart'; +import 'package:haenaem/features/challenge/detail/screens/challenge_main_screen.dart'; + +class ChallengeCard extends StatelessWidget { + final Map challenge; + final ChallengeStatus status; + + const ChallengeCard({ + super.key, + required this.challenge, + required this.status, + }); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ChallengeMainScreen( + challengeId: challenge['challengeId'] ?? 0, + challengeTitle: challenge['title'], + ), + ), + ); + }, + child: Padding( + padding: const EdgeInsets.only(left: 20, right: 20, bottom: 12), + child: Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: _getCardColor(status), + borderRadius: BorderRadius.circular(12), + ), + child: IntrinsicHeight( + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + challenge['title'] ?? '', + style: AppTypography.b1.copyWith( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + const SizedBox(height: 4), + _buildSuccessDays(), + const SizedBox(height: 4), + _buildBottomInfo(), + ], + ), + ), + _buildDivider(), + SizedBox(width: 44, child: Center(child: _buildStatusIcon())), + ], + ), + ), + ), + ), + ); + } + + Widget _buildSuccessDays() { + final during = challenge['duringDate'] ?? 0; + final isDone = challenge['doIt'] ?? false; + return Row( + children: [ + if (during >= 2 && isDone) + Padding( + padding: const EdgeInsets.only(right: 4), + child: SvgPicture.asset( + 'assets/images/icons/small_fire_icon.svg', + width: 16, + height: 16, + ), + ), + Text('$during일째', style: AppTypography.b2.copyWith(fontSize: 14)), + ], + ); + } + + Widget _buildBottomInfo() { + if (status == ChallengeStatus.urgent) { + return const Text( + '오늘 챌린지를 하지 않으면 실패해요!', + style: TextStyle(color: AppColors.notification, fontSize: 12), + ); + } + return Row( + children: [ + SvgPicture.asset( + 'assets/images/icons/mini_success_icon.svg', + width: 16, + height: 16, + ), + const SizedBox(width: 4), + Text( + '인증인원 ${challenge['todaySuccessCount']}/${challenge['participantNumber']}', + style: AppTypography.b2.copyWith(fontSize: 14), + ), + ], + ); + } + + Widget _buildDivider() { + return SizedBox( + width: 40, + child: Center( + child: CustomPaint( + size: const Size(1, double.infinity), + painter: VerticalDashPainter(), + ), + ), + ); + } + + Widget _buildStatusIcon() { + if (status == ChallengeStatus.completed) + return SvgPicture.asset('assets/images/icons/success_icon.svg'); + if (status == ChallengeStatus.urgent) + return SvgPicture.asset('assets/images/icons/warning_icon.svg'); + return const SizedBox(width: 24); + } + + Color _getCardColor(ChallengeStatus status) { + if (status == ChallengeStatus.completed) return AppColors.success; + if (status == ChallengeStatus.urgent) return AppColors.warning; + return AppColors.gray5; + } +} + +class VerticalDashPainter extends CustomPainter { + @override + void paint(Canvas canvas, Size size) { + double dashHeight = 5, dashSpace = 3, startY = 0; + // 캔버스의 중앙 X축 계산 + final double centerX = size.width / 2; + final paint = Paint() + ..color = AppColors + .gray3 // 점선 색상 농도 조절 + ..strokeWidth = 1; + + while (startY < size.height) { + // Offset의 X좌표를 centerX로 고정하여 직선도 유지 + canvas.drawLine( + Offset(centerX, startY), + Offset(centerX, startY + dashHeight), + paint, + ); + startY += dashHeight + dashSpace; + } + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/lib/features/main/screens/main_screen.dart b/lib/features/main/screens/main_screen.dart index e958544..5c4a2c9 100644 --- a/lib/features/main/screens/main_screen.dart +++ b/lib/features/main/screens/main_screen.dart @@ -1,6 +1,6 @@ // 최초 작성자 : 김채영 import 'package:flutter/material.dart'; -import 'package:haenaem/features/home/home_screen.dart'; +import 'package:haenaem/features/home/screens/home_screen.dart'; import 'package:haenaem/features/social/screens/social_screen.dart'; import '../widgets/bottom_nav_bar.dart'; import 'package:haenaem/features/user/screens/my_page_screen.dart'; diff --git a/lib/features/notification/views/challenge_invites_view.dart b/lib/features/notification/views/challenge_invites_view.dart index a93d3f3..2f8393d 100644 --- a/lib/features/notification/views/challenge_invites_view.dart +++ b/lib/features/notification/views/challenge_invites_view.dart @@ -36,17 +36,17 @@ class ChallengeInvitesView extends ConsumerWidget { final invite = state.invites[index]; return ChallengeInviteCard( - challengeId: invite.challengeId, - inviterName: invite.inviterNickname, - inviterProfileImageUrl: invite.inviterProfileImageUrl, - challengeName: invite.challengeTitle, - participantCount: invite.participantCount, - dDay: 'D-${invite.remainingDays}', - labels: invite.tags, + challengeId: invite.challengeInfo.base.id, + inviterName: invite.inviterUser.nickname, + inviterProfileImageUrl: invite.inviterUser.profileUrl, + challengeName: invite.challengeInfo.base.title, + participantCount: invite.challengeInfo.participantCount, + dDay: 'D-${invite.challengeInfo.dDay}', + labels: invite.challengeInfo.tags, // 수락 콜백 연결 onAccept: () async { try { - await notifier.acceptInvite(invite.challengeId); + await notifier.acceptInvite(invite.challengeInfo.base.id); ref.read(needsHomeRefreshProvider.notifier).state = true; // 홈 화면 새로고침 필요 플래그 켜기 @@ -58,7 +58,9 @@ class ChallengeInvitesView extends ConsumerWidget { // 다이얼로그(showDialog) 대신 스낵바를 띄웁니다. ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: Text('${invite.challengeTitle} 초대를 수락했습니다.'), + content: Text( + '${invite.challengeInfo.base.title} 초대를 수락했습니다.', + ), behavior: SnackBarBehavior.floating, // 화면 아래에 살짝 떠 있는 스타일 duration: const Duration(seconds: 3), // ✨ 꿀팁: 스낵바 우측에 '이동' 버튼 추가 @@ -70,7 +72,7 @@ class ChallengeInvitesView extends ConsumerWidget { safeNavigator.push( MaterialPageRoute( builder: (context) => ChallengeMainScreen( - challengeId: invite.challengeId, + challengeId: invite.challengeInfo.base.id, ), ), ); @@ -95,7 +97,7 @@ class ChallengeInvitesView extends ConsumerWidget { // 거절 콜백 연결 onReject: () async { try { - await notifier.rejectInvite(invite.challengeId); + await notifier.rejectInvite(invite.challengeInfo.base.id); ref.read(needsHomeRefreshProvider.notifier).state = true; // 홈 화면 새로고침 필요 플래그 켜기 @@ -103,7 +105,9 @@ class ChallengeInvitesView extends ConsumerWidget { if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: Text('${invite.challengeTitle} 초대를 거절했습니다.'), + content: Text( + '${invite.challengeInfo.base.title} 초대를 거절했습니다.', + ), behavior: SnackBarBehavior.floating, // 화면 아래에 살짝 떠 있는 스타일 duration: const Duration(seconds: 3), ), diff --git a/lib/shared/models/search_challenge_card.dart b/lib/shared/models/search_challenge_card.dart index 7f4b5fe..7b05a91 100644 --- a/lib/shared/models/search_challenge_card.dart +++ b/lib/shared/models/search_challenge_card.dart @@ -6,13 +6,13 @@ import 'package:haenaem/shared/models/challenge_base.dart'; class SearchChallengeCard { final ChallengeBase base; // 챌린지 기본 정보 (id, title, isLeader) final int participantCount; // 챌린지 참여자 수 - final DateTime endDate; // 챌린지 완료일 + final DateTime dDay; // 챌린지 종료 D-Day final List tags; // 챌린지 태그 리스트 const SearchChallengeCard({ required this.base, required this.participantCount, - required this.endDate, + required this.dDay, required this.tags, }); @@ -20,7 +20,7 @@ class SearchChallengeCard { return SearchChallengeCard( base: ChallengeBase.fromJson(json), participantCount: json['participant_count'] as int, - endDate: DateTime.parse(json['end_date'] as String), + dDay: DateTime.parse(json['end_date'] as String), tags: List.from(json['tag'] as List), ); } @@ -28,13 +28,13 @@ class SearchChallengeCard { SearchChallengeCard copyWith({ ChallengeBase? base, int? participantCount, - DateTime? endDate, + DateTime? dDay, List? tags, }) { return SearchChallengeCard( base: base ?? this.base, participantCount: participantCount ?? this.participantCount, - endDate: endDate ?? this.endDate, + dDay: dDay ?? this.dDay, tags: tags ?? this.tags, ); } From b9869fa2209224ff58ac67b8c1419578548bd397 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Sun, 15 Mar 2026 02:34:08 +0900 Subject: [PATCH 037/134] =?UTF-8?q?refactor:=20=EC=83=88=20=EC=86=8C?= =?UTF-8?q?=EC=85=9C=20=EB=AA=A8=EB=8D=B8=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F?= =?UTF-8?q?=20=EC=86=8C=EC=85=9C=20=EA=B8=B0=EB=8A=A5=20=EC=A0=84=EB=A9=B4?= =?UTF-8?q?=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/app.dart | 2 +- lib/features/main/screens/main_screen.dart | 4 +- .../social/data/social_repository.dart | 87 +- .../social/models/friend_request_card.dart | 6 +- lib/features/social/models/social_model.dart | 2 + .../social/provider/friend_list_provider.dart | 27 + .../provider/friend_list_provider.g.dart | 26 + .../provider/friend_request_provider.dart | 89 ++ .../provider/friend_request_provider.g.dart | 48 ++ .../social/provider/user_search_provider.dart | 118 +++ .../provider/user_search_provider.g.dart | 26 + .../social/screens/friend_add_screen.dart | 809 +----------------- .../social/screens/friend_edit_screen.dart | 352 +------- .../social/screens/social_main_screen.dart | 208 +++++ .../social/screens/social_screen.dart | 260 ------ .../social/views/received_request_view.dart | 80 ++ .../social/views/sent_request_view.dart | 52 ++ .../social/views/user_search_view.dart | 152 ++++ .../social/widgets/animated_toast.dart | 108 +++ .../social/widgets/delete_confirm_dialog.dart | 79 ++ .../social/widgets/friend_edit_tile.dart | 82 ++ .../social/widgets/friend_list_tile.dart | 66 ++ .../social/widgets/received_request_card.dart | 132 +++ .../social/widgets/sent_request_card.dart | 120 +++ .../social/widgets/user_search_tile.dart | 100 +++ lib/main.dart | 4 +- 26 files changed, 1662 insertions(+), 1377 deletions(-) create mode 100644 lib/features/social/provider/friend_list_provider.dart create mode 100644 lib/features/social/provider/friend_list_provider.g.dart create mode 100644 lib/features/social/provider/friend_request_provider.dart create mode 100644 lib/features/social/provider/friend_request_provider.g.dart create mode 100644 lib/features/social/provider/user_search_provider.dart create mode 100644 lib/features/social/provider/user_search_provider.g.dart create mode 100644 lib/features/social/screens/social_main_screen.dart delete mode 100644 lib/features/social/screens/social_screen.dart create mode 100644 lib/features/social/views/received_request_view.dart create mode 100644 lib/features/social/views/sent_request_view.dart create mode 100644 lib/features/social/views/user_search_view.dart create mode 100644 lib/features/social/widgets/animated_toast.dart create mode 100644 lib/features/social/widgets/delete_confirm_dialog.dart create mode 100644 lib/features/social/widgets/friend_edit_tile.dart create mode 100644 lib/features/social/widgets/friend_list_tile.dart create mode 100644 lib/features/social/widgets/received_request_card.dart create mode 100644 lib/features/social/widgets/sent_request_card.dart create mode 100644 lib/features/social/widgets/user_search_tile.dart diff --git a/lib/app.dart b/lib/app.dart index 232d0a6..af5c98e 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -1,7 +1,7 @@ // 최초 작성자: 김채영 import 'package:flutter/material.dart'; -import 'package:haenaem/features/social/screens/social_screen.dart'; +import 'package:haenaem/features/social/screens/social_main_screen.dart'; import 'features/challenge/create/screens/challenge_create_screen.dart'; import 'features/user/screens/my_page_screen.dart'; import 'features/main/screens/main_screen.dart'; diff --git a/lib/features/main/screens/main_screen.dart b/lib/features/main/screens/main_screen.dart index 5c4a2c9..75b39fc 100644 --- a/lib/features/main/screens/main_screen.dart +++ b/lib/features/main/screens/main_screen.dart @@ -1,7 +1,7 @@ // 최초 작성자 : 김채영 import 'package:flutter/material.dart'; import 'package:haenaem/features/home/screens/home_screen.dart'; -import 'package:haenaem/features/social/screens/social_screen.dart'; +import 'package:haenaem/features/social/screens/social_main_screen.dart'; import '../widgets/bottom_nav_bar.dart'; import 'package:haenaem/features/user/screens/my_page_screen.dart'; import 'package:haenaem/features/feed/screens/feed_screen.dart'; @@ -22,7 +22,7 @@ class _MainScreenState extends State { const HomeScreen(), const Center(child: Text("통계 화면")), const FeedScreen(), - const SocialScreen(), + const SocialMainScreen(), const MyPageScreen(), ]; diff --git a/lib/features/social/data/social_repository.dart b/lib/features/social/data/social_repository.dart index c2a3cc7..1d08366 100644 --- a/lib/features/social/data/social_repository.dart +++ b/lib/features/social/data/social_repository.dart @@ -3,10 +3,14 @@ library; import 'package:dio/dio.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import '../models/social_model.dart'; -import '../../auth/services/auth_service.dart'; import 'package:flutter/material.dart'; +// 새 모델들 Import +import '../../../shared/models/user.dart'; +import '../models/user_search_card.dart'; +import '../models/friend_request_card.dart'; +import '../../auth/services/auth_service.dart'; + // Dio Provider with Interceptor for adding Authorization header final dioProvider = Provider((ref) { final dio = Dio( @@ -54,22 +58,37 @@ class SocialRepository { SocialRepository(this._dio); // 1. 친구 목록 조회 (GET /api/users/friend/list) - Future> getFriendList() async { + Future> getFriendList() async { final response = await _dio.get('/api/users/friend/list'); // 응답 데이터가 null일 경우를 대비해 빈 리스트 처리를 추가합니다. - return (response.data as List?)?.map((e) => Friend.fromJson(e)).toList() ?? + return (response.data as List?)?.map((e) => User.fromJson(e)).toList() ?? []; } // 2. 유저 검색 (GET /api/users/search) - Future> searchUsers(String nickname) async { + Future> searchUsers(String nickname) async { final response = await _dio.get( '/api/users/search', queryParameters: {'nickname': nickname}, ); - return (response.data as List?) - ?.map((e) => SearchResultUser.fromSearchJson(e)) - .toList() ?? + return (response.data as List?)?.map((e) { + // 서버의 relationshipStatus를 FriendState enum으로 변환 + FriendState state = FriendState.stranger; + if (e['relationshipStatus'] == 'FRIEND') { + state = FriendState.friend; + } else if (e['relationshipStatus'] == 'PENDING_SENT') { + state = FriendState.pending; + } + + return UserSearchCard( + user: User.fromJson({ + 'id': e['userId'], + 'nickname': e['nickname'], + 'profileUrl': e['profileImageUrl'], + }), + state: state, + ); + }).toList() ?? []; } @@ -80,12 +99,23 @@ class SocialRepository { } // 4. 보낸 신청 목록 조회 (GET /api/users/friend/request/sent) - Future> getSentRequests() async { + Future> getSentRequests() async { // Swagger operationId: getSentRequests final response = await _dio.get('/api/users/friend/request/sent'); - return (response.data as List?) - ?.map((e) => SearchResultUser.fromSentJson(e)) - .toList() ?? + + return (response.data as List?)?.map((e) { + return FriendRequestCard( + user: User.fromJson({ + 'id': e['userId'] ?? 0, // 보낸 대상의 id (서버 응답 확인 필요) + 'nickname': e['nickname'], + 'profileUrl': e['profileImageUrl'], + }), + requestId: e['requestId'], + requestDate: e['createdAt'] != null + ? DateTime.parse(e['createdAt']) + : DateTime.now(), + ); + }).toList() ?? []; } @@ -96,12 +126,23 @@ class SocialRepository { } // 6. 받은 신청 목록 조회 (GET /api/users/friend/request/received) - Future> getReceivedRequests() async { + Future> getReceivedRequests() async { // Swagger operationId: getReceivedRequests final response = await _dio.get('/api/users/friend/request/received'); - return (response.data as List?) - ?.map((e) => ReceivedRequest.fromJson(e)) - .toList() ?? + + return (response.data as List?)?.map((e) { + return FriendRequestCard( + user: User.fromJson({ + 'id': e['fromUserId'], + 'nickname': e['nickname'], + 'profileUrl': e['profileImageUrl'], + }), + requestId: e['requestId'], + requestDate: e['createdAt'] != null + ? DateTime.parse(e['createdAt']) + : DateTime.now(), + ); + }).toList() ?? []; } @@ -123,17 +164,3 @@ class SocialRepository { await _dio.delete('/api/users/friend/delete/$nickname'); } } - -// 1. 친구 목록을 서버에서 가져오는 FutureProvider -// SocialScreen에서 ref.watch(friendListProvider)로 사용합니다. -final friendListProvider = FutureProvider>((ref) async { - final repo = ref.watch(socialRepositoryProvider); - return await repo.getFriendList(); // GET /api/users/friend/list 호출 -}); - -// 2. (옵션) 보낸/받은 요청 목록도 Provider로 관리하면 화면 갱신이 더 편해집니다. -final receivedRequestsProvider = FutureProvider>(( - ref, -) async { - return await ref.watch(socialRepositoryProvider).getReceivedRequests(); -}); diff --git a/lib/features/social/models/friend_request_card.dart b/lib/features/social/models/friend_request_card.dart index edc773e..773b4c7 100644 --- a/lib/features/social/models/friend_request_card.dart +++ b/lib/features/social/models/friend_request_card.dart @@ -5,7 +5,7 @@ import 'package:haenaem/shared/models/user.dart'; // User에 정의된 필드(id, profileUrl, nickname)를 재사용 class FriendRequestCard { final User user; // 요청자 정보 (id, profileUrl, nickname) - final String requestId; // 친구 요청 id + final int requestId; // 친구 요청 id final DateTime requestDate; // 친구 요청 날짜 const FriendRequestCard({ @@ -17,14 +17,14 @@ class FriendRequestCard { factory FriendRequestCard.fromJson(Map json) { return FriendRequestCard( user: User.fromJson(json['user'] as Map), - requestId: json['request_id'] as String, + requestId: json['request_id'] as int, requestDate: DateTime.parse(json['request_date'] as String), ); } FriendRequestCard copyWith({ User? user, - String? requestId, + int? requestId, DateTime? requestDate, }) { return FriendRequestCard( diff --git a/lib/features/social/models/social_model.dart b/lib/features/social/models/social_model.dart index fe5c5cb..3fd0a0c 100644 --- a/lib/features/social/models/social_model.dart +++ b/lib/features/social/models/social_model.dart @@ -1,4 +1,5 @@ /// 최초 작성자: 정승빈 +/* library; import 'package:flutter/material.dart'; @@ -115,3 +116,4 @@ class ReceivedRequest { ); } } +*/ diff --git a/lib/features/social/provider/friend_list_provider.dart b/lib/features/social/provider/friend_list_provider.dart new file mode 100644 index 0000000..881698f --- /dev/null +++ b/lib/features/social/provider/friend_list_provider.dart @@ -0,0 +1,27 @@ +// 친구 목록 상태 및 편집 로직 +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import '../data/social_repository.dart'; +import '../../../shared/models/user.dart'; + +part 'friend_list_provider.g.dart'; + +@riverpod +class FriendList extends _$FriendList { + @override + Future> build() async { + // 초기 친구 목록 불러오기 + return ref.watch(socialRepositoryProvider).getFriendList(); + } + + // 친구 삭제 로직 + Future removeFriend(String nickname) async { + try { + await ref.read(socialRepositoryProvider).deleteFriend(nickname); + // 삭제 성공 시, 서버에서 목록을 다시 불러와서 UI 갱신 + ref.invalidateSelf(); + } catch (e) { + // 에러 처리는 여기서 하거나, UI 단에서 잡을 수 있도록 던짐 + rethrow; + } + } +} diff --git a/lib/features/social/provider/friend_list_provider.g.dart b/lib/features/social/provider/friend_list_provider.g.dart new file mode 100644 index 0000000..06a3796 --- /dev/null +++ b/lib/features/social/provider/friend_list_provider.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'friend_list_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$friendListHash() => r'5753be3a1b415d7c3b8ee674c269380e252eda94'; + +/// See also [FriendList]. +@ProviderFor(FriendList) +final friendListProvider = + AutoDisposeAsyncNotifierProvider>.internal( + FriendList.new, + name: r'friendListProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$friendListHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$FriendList = AutoDisposeAsyncNotifier>; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/social/provider/friend_request_provider.dart b/lib/features/social/provider/friend_request_provider.dart new file mode 100644 index 0000000..d789125 --- /dev/null +++ b/lib/features/social/provider/friend_request_provider.dart @@ -0,0 +1,89 @@ +// 받은/보낸 요청 상태 관리 +import 'package:flutter/foundation.dart'; +import 'package:dio/dio.dart'; + +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import '../data/social_repository.dart'; +import '../models/friend_request_card.dart'; +import 'friend_list_provider.dart'; + +part 'friend_request_provider.g.dart'; + +// 받은 요청 상태 관리 +@riverpod +class ReceivedRequests extends _$ReceivedRequests { + @override + Future> build() async { + return ref.watch(socialRepositoryProvider).getReceivedRequests(); + } + + // 친구 요청 수락 로직 + Future acceptRequest(int requestId) async { + try { + await ref.read(socialRepositoryProvider).acceptRequest(requestId); + ref.invalidateSelf(); // 받은 요청 목록 새로고침 + ref.invalidate(friendListProvider); // 친구가 추가되었으니 친구 목록도 새로고침 + } catch (e) { + if (e is DioException) { + debugPrint('---------- [친구 수락 실패] ----------'); + debugPrint('대상 Request ID: $requestId'); + debugPrint('상태 코드: ${e.response?.statusCode}'); + debugPrint('에러 메시지: ${e.response?.data}'); + debugPrint('요청 경로: ${e.requestOptions.path}'); + debugPrint('------------------------------------'); + } else { + debugPrint('수락 중 알 수 없는 에러: $e'); + } + rethrow; + } + } + + // 친구 요청 거절 로직 + Future rejectRequest(int requestId) async { + try { + await ref.read(socialRepositoryProvider).rejectRequest(requestId); + ref.invalidateSelf(); + } catch (e) { + if (e is DioException) { + debugPrint('---------- [친구 거절 실패] ----------'); + debugPrint('거절할 ID: $requestId'); + debugPrint('상태 코드: ${e.response?.statusCode}'); + debugPrint('에러 메시지: ${e.response?.data}'); + debugPrint('요청 경로: ${e.requestOptions.path}'); + debugPrint('------------------------------------'); + } else { + debugPrint('거절 중 알 수 없는 에러: $e'); + } + rethrow; + } + } +} + +// 보낸 요청 상태 관리 +@riverpod +class SentRequests extends _$SentRequests { + @override + Future> build() async { + return ref.watch(socialRepositoryProvider).getSentRequests(); + } + + // 친구 요청 취소 로직 + Future cancelRequest(int requestId) async { + try { + await ref.read(socialRepositoryProvider).cancelRequest(requestId); + ref.invalidateSelf(); + } catch (e) { + if (e is DioException) { + debugPrint('---------- [친구 요청 취소 실패] ----------'); + debugPrint('취소할 Request ID: $requestId'); + debugPrint('상태 코드: ${e.response?.statusCode}'); + debugPrint('에러 메시지: ${e.response?.data}'); + debugPrint('요청 경로: ${e.requestOptions.path}'); + debugPrint('---------------------------------------'); + } else { + debugPrint('요청 취소 중 알 수 없는 에러: $e'); + } + rethrow; + } + } +} diff --git a/lib/features/social/provider/friend_request_provider.g.dart b/lib/features/social/provider/friend_request_provider.g.dart new file mode 100644 index 0000000..d000f52 --- /dev/null +++ b/lib/features/social/provider/friend_request_provider.g.dart @@ -0,0 +1,48 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'friend_request_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$receivedRequestsHash() => r'4b5c706f34051662afd50c7b5f97fd3ea4258799'; + +/// See also [ReceivedRequests]. +@ProviderFor(ReceivedRequests) +final receivedRequestsProvider = + AutoDisposeAsyncNotifierProvider< + ReceivedRequests, + List + >.internal( + ReceivedRequests.new, + name: r'receivedRequestsProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$receivedRequestsHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$ReceivedRequests = AutoDisposeAsyncNotifier>; +String _$sentRequestsHash() => r'8416bec6bc2187d5ccfeb4aacc1dc6c248b552a6'; + +/// See also [SentRequests]. +@ProviderFor(SentRequests) +final sentRequestsProvider = + AutoDisposeAsyncNotifierProvider< + SentRequests, + List + >.internal( + SentRequests.new, + name: r'sentRequestsProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$sentRequestsHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$SentRequests = AutoDisposeAsyncNotifier>; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/social/provider/user_search_provider.dart b/lib/features/social/provider/user_search_provider.dart new file mode 100644 index 0000000..cf016d3 --- /dev/null +++ b/lib/features/social/provider/user_search_provider.dart @@ -0,0 +1,118 @@ +// 유저 검색 상태 관리 +import 'package:flutter/foundation.dart'; +import 'package:dio/dio.dart'; + +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import '../data/social_repository.dart'; +import '../models/user_search_card.dart'; +import '../../../core/utils/korean_string_utils.dart'; + +part 'user_search_provider.g.dart'; + +@riverpod +class UserSearch extends _$UserSearch { + @override + FutureOr> build() { + // 초기 상태는 검색 결과가 없는 빈 리스트 + return []; + } + + // 사용자 검색 로직 (필터링 및 정렬 포함) + Future searchUsers(String query) async { + final trimmedQuery = query.trim(); + if (trimmedQuery.isEmpty) { + state = const AsyncValue.data([]); + return; + } + + // 로딩 상태 시작 + state = const AsyncValue.loading(); + + try { + // 1. 서버로부터 검색 결과 리스트를 받아옴 + // 서버 API가 초성 검색을 지원하지 않더라도, 결과 목록을 받아온 뒤 + // 클라이언트에서 2차 필터링을 수행할 수 있도록 raw 데이터를 받습니다. + final rawResults = await ref + .read(socialRepositoryProvider) + .searchUsers(""); + // TODO: [성능 최적화 필요] 현재 서버 API가 초성 검색을 지원하지 않아, + // 임시로 전체 유저 목록을 받아와 클라이언트에서 필터링하고 있습니다. + // 유저 수가 늘어나면 앱 속도가 느려질 수 있으므로, + // 추후 백엔드에 초성 검색 기능(DB 쿼리 수정 등)을 요청하여 + // 서버 사이드 필터링으로 교체해야 합니다. + + // 클라이언트 사이드 초성 및 닉네임 필터링 + final filtered = rawResults.where((card) { + final name = card.user.nickname.toLowerCase(); + final searchLower = trimmedQuery.toLowerCase(); + + // 닉네임 전체 또는 초성 문자열에 검색어가 포함되는지 체크 + return name.contains(searchLower) || + KoreanStringUtils.getChoseongString(name).contains(searchLower); + }).toList(); + + // 가나다순 정렬 + // 순서: 한글 > 영문 대문자 > 영문 소문자 > 숫자 > 특수문자 + filtered.sort( + (a, b) => KoreanStringUtils.compareKoreanFirst( + a.user.nickname, + b.user.nickname, + ), + ); + + // 결과 상태 반영 + state = AsyncValue.data(filtered); + } catch (e, stack) { + // 🐛 디버깅 로그 추가: DioException인지 확인하여 상세 에러 출력 + if (e is DioException) { + debugPrint('---------- [검색 오류 발생] ----------'); + debugPrint('상태 코드: ${e.response?.statusCode}'); + debugPrint('에러 데이터: ${e.response?.data}'); + debugPrint('에러 메시지: ${e.message}'); + debugPrint('------------------------------------'); + } else { + debugPrint('시스템 오류: $e'); + } + + // 에러 상태 반영 + state = AsyncValue.error(e, stack); + } + } + + // 친구 신청 및 결과 리스트 내 상태 즉시 갱신 + Future sendFriendRequest(UserSearchCard card) async { + // 이미 친구 신청이 진행 중인 경우 중복 요청 방지 + if (card.state == FriendState.pending) return; + + final previousState = state.value ?? []; // 현재 검색 결과 리스트 + + try { + await ref + .read(socialRepositoryProvider) + .sendFriendRequest(card.user.nickname); + + // 성공 시 해당 카드의 상태만 FriendState.pending으로 변경하여 UI 즉각 갱신 + state = AsyncValue.data([ + for (final c in previousState) + if (c.user.nickname == card.user.nickname) + c.copyWith(state: FriendState.pending) + else + c, + ]); + } catch (e) { + // 🐛 디버깅 로그 추가: 친구 신청 실패 시 상세 원인 파악 + if (e is DioException) { + debugPrint('---------- [친구 신청 실패] ----------'); + debugPrint('대상 닉네임: ${card.user.nickname}'); + debugPrint('상태 코드: ${e.response?.statusCode}'); + debugPrint('서버 응답: ${e.response?.data}'); + debugPrint('------------------------------------'); + } else { + debugPrint('친구 신청 중 알 수 없는 에러: $e'); + } + + // 에러는 UI에서 토스트를 띄우도록 rethrow + rethrow; + } + } +} diff --git a/lib/features/social/provider/user_search_provider.g.dart b/lib/features/social/provider/user_search_provider.g.dart new file mode 100644 index 0000000..d87d273 --- /dev/null +++ b/lib/features/social/provider/user_search_provider.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user_search_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$userSearchHash() => r'a57c0b98ab17c8db2554261f31e07158b0e09dce'; + +/// See also [UserSearch]. +@ProviderFor(UserSearch) +final userSearchProvider = + AutoDisposeAsyncNotifierProvider>.internal( + UserSearch.new, + name: r'userSearchProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$userSearchHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$UserSearch = AutoDisposeAsyncNotifier>; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/social/screens/friend_add_screen.dart b/lib/features/social/screens/friend_add_screen.dart index 51c6e39..1d2d81e 100644 --- a/lib/features/social/screens/friend_add_screen.dart +++ b/lib/features/social/screens/friend_add_screen.dart @@ -1,795 +1,58 @@ /// 최초 작성자: 정승빈 -library; - import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:intl/intl.dart'; import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; -import '../data/social_repository.dart'; -import '../models/social_model.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:dio/dio.dart'; -import '../../../core/utils/korean_string_utils.dart'; -// --- 메인 화면 --- +import '../views/user_search_view.dart'; +import '../views/received_request_view.dart'; +import '../views/sent_request_view.dart'; -/// 클래스의 용도: 친구 검색, 받은 요청, 보낸 요청을 관리하는 친구 추가 메인 화면 -class FriendAddScreen extends ConsumerStatefulWidget { +class FriendAddScreen extends StatelessWidget { final int initialTabIndex; - const FriendAddScreen({ - super.key, - this.initialTabIndex = 0, // 기본값은 0 (친구 신청 탭) - }); - - @override - ConsumerState createState() => FriendAddScreenState(); -} - -class FriendAddScreenState extends ConsumerState - with SingleTickerProviderStateMixin { - late TabController tabController; - final TextEditingController searchController = TextEditingController(); - - // 서버로부터 받아올 데이터 리스트 - List filteredResults = []; - List receivedRequests = []; - List sentRequests = []; - bool isSearchPerformed = false; - bool isLoading = false; - - /// 함수의 용도: 컨트롤러 및 리포지토리 데이터 상태 복구 - /// 매개 변수: 없음 - /// 반환 값: 없음 - @override - void initState() { - super.initState(); - // 탭 컨트롤러를 만들 때 initialIndex를 외부에서 받은 값으로 설정 - tabController = TabController( - length: 3, - vsync: this, - initialIndex: widget.initialTabIndex, - ); - // 화면 진입 시 받은 요청과 보낸 요청 목록을 먼저 불러옵니다. - _fetchInitialData(); - } - - /// 초기 데이터(받은/보낸 요청) 로드 - Future _fetchInitialData() async { - final repo = ref.read(socialRepositoryProvider); - try { - final received = await repo - .getReceivedRequests(); // GET /api/users/friend/request/received - final sent = await repo - .getSentRequests(); // GET /api/users/friend/request/sent - setState(() { - receivedRequests = received; - sentRequests = sent; - }); - } on DioException catch (e) { - if (!mounted) return; - - // 개발자를 위한 상세 로그 - debugPrint('---------- [초기 데이터 로드 오류] ----------'); - debugPrint('상태 코드: ${e.response?.statusCode}'); - debugPrint('에러 경로: ${e.requestOptions.path}'); - debugPrint('에러 내용: ${e.response?.data}'); - debugPrint('-----------------------------------------'); - - displayToast('데이터를 불러오는데 실패했습니다.'); - } catch (e) { - if (!mounted) return; - debugPrint('초기 데이터 로드 중 알 수 없는 에러: $e'); - displayToast('데이터 로딩 중 오류가 발생했습니다.'); - } - } + const FriendAddScreen({super.key, this.initialTabIndex = 0}); - /// 함수의 용도: 사용된 리소스 해제 - /// 매개 변수: 없음 - /// 반환 값: 없음 - @override - void dispose() { - tabController.dispose(); - searchController.dispose(); - super.dispose(); - } - - /// 닉네임 유저 검색 수행 - Future performSearch() async { - final query = searchController.text.trim(); - if (query.isEmpty) return; - - setState(() { - isLoading = true; - isSearchPerformed = true; - }); - - try { - // 1. 서버로부터 검색 결과 리스트를 받아옴 - // 서버 API가 초성 검색을 지원하지 않더라도, 결과 목록을 받아온 뒤 - // 클라이언트에서 2차 필터링을 수행할 수 있도록 raw 데이터를 받습니다. - final rawResults = await ref - .read(socialRepositoryProvider) - .searchUsers(""); - // TODO: [성능 최적화 필요] 현재 서버 API가 초성 검색을 지원하지 않아, - // 임시로 전체 유저 목록을 받아와 클라이언트에서 필터링하고 있습니다. - // 유저 수가 늘어나면 앱 속도가 느려질 수 있으므로, - // 추후 백엔드에 초성 검색 기능(DB 쿼리 수정 등)을 요청하여 - // 서버 사이드 필터링으로 교체해야 합니다. - - // 2. 클라이언트 사이드 필터링 (social_screen.dart와 동일 로직 적용) - // 서버에서 'ㅎㄴ'으로 검색 시 결과가 없더라도, 만약 서버가 전체 유저나 - // 유사 유저를 반환한다면 이 로직이 '해냄'을 찾아냅니다. - final filtered = rawResults.where((user) { - final name = user.nickname.toLowerCase(); - final searchLower = query.toLowerCase(); - - // 닉네임 포함 여부 OR 초성 포함 여부 확인 - return name.contains(searchLower) || - KoreanStringUtils.getChoseongString(name).contains(searchLower); - }).toList(); - - // 3. 정렬 (social_screen.dart와 동일 로직 적용) - // 순서: 한글 > 영문 대문자 > 영문 소문자 > 숫자 > 특수문자 - filtered.sort( - (a, b) => KoreanStringUtils.compareKoreanFirst(a.nickname, b.nickname), - ); - - if (!mounted) return; - setState(() { - filteredResults = filtered; - isLoading = false; - }); - } on DioException catch (e) { - // DioException을 직접 잡아 구체적인 원인 파악 - if (!mounted) return; - - // 디버그 콘솔에 상세 오류 출력 - debugPrint('---------- [검색 오류 발생] ----------'); - debugPrint('상태 코드: ${e.response?.statusCode}'); - debugPrint('에러 데이터: ${e.response?.data}'); - debugPrint('에러 메시지: ${e.message}'); - debugPrint('------------------------------------'); - - setState(() => isLoading = false); - - // 사용자에게는 최소한의 정보만 전달 - displayToast('검색 결과가 없거나 오류가 발생했습니다.'); - } catch (e) { - if (!mounted) return; - debugPrint('시스템 오류: $e'); - setState(() => isLoading = false); - displayToast('잠시 후 다시 시도해 주세요.'); - } - } - - /// 친구 신청 보내기 - Future sendFriendRequestAction(SearchResultUser user) async { - // 1. 이미 신청된 상태면 아무 작업도 하지 않음 (중복 방지) - if (user.isRequested) return; - - try { - // POST /api/users/friend/request/{toUserNickName} - await ref.read(socialRepositoryProvider).sendFriendRequest(user.nickname); - - // 2. 비동기 작업 후 위젯이 여전히 화면에 있는지 확인 (unmounted 에러 방지) - if (!mounted) return; - - setState(() { - user.isRequested = true; // 로컬 상태 즉시 반영 - }); - - _fetchInitialData(); // 보낸 요청 목록 갱신 - displayToast('${user.nickname} 님에게 친구 신청을 보냈습니다!'); - } on DioException catch (e) { - if (!mounted) return; - - // 🔥 [디버깅용 로그] 정확한 에러 원인 확인 - debugPrint('---------- [친구 신청 실패] ----------'); - debugPrint('대상 닉네임: ${user.nickname}'); - debugPrint('상태 코드: ${e.response?.statusCode}'); - debugPrint('서버 응답: ${e.response?.data}'); // 에러 메시지나 코드 확인 - debugPrint('------------------------------------'); - - // 사용자에게는 기존과 동일하게 안내 - displayToast('이미 신청되었거나 신청에 실패했습니다.'); - } catch (e) { - if (!mounted) return; - debugPrint('친구 신청 중 알 수 없는 에러: $e'); - displayToast('신청 중 오류가 발생했습니다.'); - } - } - - /// 신청 취소하기 - Future cancelFriendRequestAction(SearchResultUser user) async { - if (user.requestId == null) return; - try { - // PATCH /api/users/friend/request/sent/cancel/{requestId} - await ref.read(socialRepositoryProvider).cancelRequest(user.requestId!); - _fetchInitialData(); - displayToast('친구 신청을 취소했습니다.'); - } catch (e) { - displayToast('취소에 실패했습니다.'); - } - } - - /// 친구 수락하기 - Future acceptFriendRequestAction(ReceivedRequest req) async { - try { - // PATCH /api/users/friend/request/accept/{requestId} - await ref.read(socialRepositoryProvider).acceptRequest(req.requestId); - if (!mounted) return; - - // 보낸/받은 요청 목록 갱신 - _fetchInitialData(); - // 실제 친구 목록(SocialScreen용)도 새로고침하여 데이터 일치화 - ref.invalidate(friendListProvider); - - displayToast('${req.nickname} 님과 친구가 되었습니다!'); - } on DioException catch (e) { - if (!mounted) return; - - // 🔥 [수락 실패 디버그] - debugPrint('---------- [친구 수락 실패] ----------'); - debugPrint('대상 닉네임: ${req.nickname}'); - debugPrint('대상 Request ID: ${req.requestId}'); - debugPrint('상태 코드: ${e.response?.statusCode}'); - debugPrint('에러 메시지: ${e.response?.data}'); - debugPrint('요청 경로: ${e.requestOptions.path}'); - debugPrint('------------------------------------'); - - displayToast('수락 처리에 실패했습니다. (코드: ${e.response?.statusCode})'); - } catch (e) { - if (!mounted) return; - debugPrint('수락 중 알 수 없는 에러: $e'); - displayToast('수락 중 오류가 발생했습니다.'); - } - } - - /// 친구 거절하기 - Future rejectFriendRequestAction(ReceivedRequest req) async { - try { - // PATCH /api/users/friend/request/reject/{rejectId} - // 주의: requestId가 null인지 확인이 필요할 수 있습니다. - await ref.read(socialRepositoryProvider).rejectRequest(req.requestId); - - if (!mounted) return; - _fetchInitialData(); // 목록 갱신 - displayToast('요청을 거절했습니다.'); - } on DioException catch (e) { - if (!mounted) return; - - // 🔥 [거절 실패 디버그] - debugPrint('---------- [친구 거절 실패] ----------'); - debugPrint('거절할 ID: ${req.requestId}'); - debugPrint('상태 코드: ${e.response?.statusCode}'); - debugPrint('에러 메시지: ${e.response?.data}'); - debugPrint('요청 경로: ${e.requestOptions.path}'); - debugPrint('------------------------------------'); - - displayToast('거절 처리에 실패했습니다. (코드: ${e.response?.statusCode})'); - } catch (e) { - if (!mounted) return; - debugPrint('거절 중 알 수 없는 에러: $e'); - displayToast('거절 중 오류가 발생했습니다.'); - } - } - - /// 함수의 용도: 커스텀 Overlay 애니메이션 토스트 표시 - /// 매개 변수: String message (출력 문구) - /// 반환 값: 없음 - void displayToast(String message) { - final overlay = Overlay.of(context); - late OverlayEntry overlayEntry; - - overlayEntry = OverlayEntry( - builder: (context) => AnimatedToast( - message: message, - onDismissed: () { - overlayEntry.remove(); - }, - ), - ); - - overlay.insert(overlayEntry); - } - - /// 함수의 용도: 메인 빌드 메서드 - /// 매개 변수: BuildContext context (빌드 컨텍스트) - /// 반환 값: Widget (완성된 화면 위젯) @override Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Colors.white, - appBar: AppBar( + return DefaultTabController( + length: 3, + initialIndex: initialTabIndex, + child: Scaffold( backgroundColor: Colors.white, - elevation: 0, - leading: IconButton( - icon: const Icon(Icons.arrow_back, color: AppColors.black), - onPressed: () => Navigator.pop(context), - ), - centerTitle: true, - title: const Text('친구 추가', style: AppTypography.h2), - ), - body: Column( - children: [ - TabBar( - controller: tabController, - indicatorColor: AppColors.primaryAble, - labelColor: AppColors.primaryAble, - unselectedLabelColor: AppColors.gray2, - labelStyle: AppTypography.b1.copyWith(fontWeight: FontWeight.w500), - tabs: const [ - Tab(text: '친구 신청'), - Tab(text: '받은 요청'), - Tab(text: '보낸 요청'), - ], - ), - Expanded( - child: TabBarView( - controller: tabController, - children: [buildSearchTab(), buildReceivedTab(), buildSentTab()], + appBar: AppBar( + backgroundColor: Colors.white, + elevation: 0, + leading: IconButton( + icon: const Icon(Icons.arrow_back, color: AppColors.black), + onPressed: () => Navigator.pop(context), + ), + centerTitle: true, + title: const Text('친구 추가', style: AppTypography.h2), + bottom: PreferredSize( + preferredSize: const Size.fromHeight(48), + child: TabBar( + indicatorColor: AppColors.primaryAble, + labelColor: AppColors.primaryAble, + unselectedLabelColor: AppColors.gray2, + labelStyle: AppTypography.b1.copyWith( + fontWeight: FontWeight.w500, + ), + tabs: const [ + Tab(text: '친구 신청'), + Tab(text: '받은 요청'), + Tab(text: '보낸 요청'), + ], ), ), - ], - ), - ); - } - - /// 함수의 용도: 검색창과 검색 결과를 포함하는 탭 빌드 - Widget buildSearchTab() { - return Column( - children: [ - buildSearchInputSection(), - if (isSearchPerformed) ...[ - buildResultCountHeader(filteredResults.length), - Expanded(child: buildSearchResultList()), - ] else - const Expanded(child: SizedBox.expand()), - ], - ); - } - - /// 함수의 용도: 받은 요청 목록을 포함하는 탭 빌드 - Widget buildReceivedTab() { - return Container( - color: const Color(0x7FDFE1DC), - child: receivedRequests.isEmpty - ? const Center(child: Text('받은 요청이 없습니다.', style: AppTypography.b2)) - : ListView.builder( - padding: const EdgeInsets.all(16), - itemCount: receivedRequests.length, - itemBuilder: (context, index) { - final req = receivedRequests[index]; - return buildReceivedCard( - req, - onAccept: () => acceptFriendRequestAction(req), - onReject: () => rejectFriendRequestAction(req), - ); - }, - ), - ); - } - - /// 함수의 용도: 보낸 요청 목록을 포함하는 탭 빌드 - Widget buildSentTab() { - return Container( - color: const Color(0x7FDFE1DC), - child: sentRequests.isEmpty - ? const Center(child: Text('보낸 요청이 없습니다.', style: AppTypography.b2)) - : ListView.builder( - padding: const EdgeInsets.all(16), - itemCount: sentRequests.length, - itemBuilder: (context, index) => - buildSentCard(sentRequests[index]), - ), - ); - } - - /// 함수의 용도: 검색창 입력 필드 영역 생성 - Widget buildSearchInputSection() { - return Padding( - padding: const EdgeInsets.all(20), - child: Container( - height: 40, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - border: Border.all(color: AppColors.gray4), ), - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Row( + body: const TabBarView( children: [ - SvgPicture.asset( - 'assets/images/icons/search_icon.svg', - width: 18, - colorFilter: const ColorFilter.mode( - AppColors.gray3, - BlendMode.srcIn, - ), - ), - const SizedBox(width: 8), - Expanded( - child: TextField( - controller: searchController, - onSubmitted: (query) => performSearch(), - textInputAction: TextInputAction.search, - decoration: const InputDecoration( - hintText: '닉네임을 검색하세요', - hintStyle: AppTypography.b2, - border: InputBorder.none, - isDense: true, - ), - style: AppTypography.b1, - ), - ), + UserSearchView(), + ReceivedRequestView(), + SentRequestView(), ], ), ), ); } - - /// 함수의 용도: 검색 결과 수 헤더 생성 - Widget buildResultCountHeader(int count) { - return Container( - width: double.infinity, - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), - child: Text('검색 결과 $count명', style: AppTypography.b2), - ); - } - - /// 함수의 용도: 검색된 유저 리스트 생성 - Widget buildSearchResultList() { - return ListView.builder( - padding: const EdgeInsets.symmetric(horizontal: 20), - itemCount: filteredResults.length, - itemBuilder: (context, index) { - final user = filteredResults[index]; - return Padding( - padding: const EdgeInsets.symmetric(vertical: 12), - child: Row( - children: [ - buildProfileCircle(user.profileImageUrl, 44), - const SizedBox(width: 12), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - user.nickname, - style: AppTypography.h3.copyWith(fontSize: 15), - ), - Text( - "해냄 메이트", // api에 title이 없으므로 기본값 설정 - //TODO: 추후 title 필드가 추가되면 반영 - style: AppTypography.c1.copyWith(color: AppColors.gray2), - ), - ], - ), - ), - buildRequestButton(user), - ], - ), - ); - }, - ); - } - - /// 함수의 용도: 받은 요청 카드 위젯 생성 - Widget buildReceivedCard( - ReceivedRequest req, { - required VoidCallback onAccept, - required VoidCallback onReject, - }) { - return Container( - margin: const EdgeInsets.only(bottom: 12), - padding: const EdgeInsets.all(20), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - ), - child: Column( - children: [ - Row( - children: [ - buildProfileCircle(req.profileImageUrl, 48), - const SizedBox(width: 12), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(req.nickname, style: AppTypography.h3), - Text( - "함께 아는 친구 0명", - //"함께 아는 친구 ${req.mutualFriends}명", - //TODO: 추후 mutualFriends 필드가 추가되면 반영 - style: AppTypography.c1.copyWith(color: AppColors.gray2), - ), - Text( - DateFormat( - 'yyyy년 MM월 dd일', - ).format(DateTime.parse(req.createdAt)), - style: AppTypography.c2.copyWith(color: AppColors.gray3), - ), - ], - ), - ), - ], - ), - const SizedBox(height: 16), - Row( - children: [ - Expanded( - child: buildActionButton( - '거절', - const Color(0x7FDFE1DC), - AppColors.gray2, - onReject, // 전달받은 거절 액션 연결 - ), - ), - const SizedBox(width: 10), - Expanded( - child: buildActionButton( - '수락', - AppColors.primaryAble, - Colors.white, - onAccept, // 전달받은 수락 액션 연결 - ), - ), - ], - ), - ], - ), - ); - } - - /// 함수의 용도: 보낸 요청 카드 위젯 생성 - /// 매개 변수: SearchResultUser user (대상 유저) - Widget buildSentCard(SearchResultUser user) { - return Container( - margin: const EdgeInsets.only(bottom: 12), - padding: const EdgeInsets.all(20), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - ), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - buildProfileCircle(user.profileImageUrl, 48), - const SizedBox(width: 12), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(user.nickname, style: AppTypography.h3), - Text( - user.createdAt != null - ? DateFormat( - 'yyyy년 MM월 dd일', - ).format(DateTime.parse(user.createdAt!)) - : '', - style: AppTypography.c2.copyWith( - color: AppColors.gray3, - ), - ), - ], - ), - ], - ), - buildBadge('대기 중'), - ], - ), - const SizedBox(height: 16), - buildActionButton( - '요청 취소', - const Color(0x7FDFE1DC), - AppColors.gray2, - () => cancelFriendRequestAction(user), // 위에서 만든 취소 액션 연결 - ), - ], - ), - ); - } - - /// 함수의 용도: 상태 표시를 위한 배지 위젯 생성 - /// 매개 변수: String text (배지 문구) - Widget buildBadge(String text) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), - decoration: BoxDecoration( - color: const Color(0xFFE8F5E9), - borderRadius: BorderRadius.circular(8), - ), - child: Text( - text, - style: const TextStyle(color: Color(0xFF444444), fontSize: 12), - ), - ); - } - - /// 함수의 용도: 공통 버튼 위젯 생성 - /// 매개 변수: String label, Color bg, Color text, VoidCallback onTap - Widget buildActionButton( - String label, - Color bg, - Color text, - VoidCallback onTap, - ) { - return GestureDetector( - onTap: onTap, - child: Container( - width: double.infinity, - height: 48, - decoration: BoxDecoration( - color: bg, - borderRadius: BorderRadius.circular(10), - ), - alignment: Alignment.center, - child: Text( - label, - style: AppTypography.b1.copyWith( - color: text, - fontWeight: FontWeight.w500, - ), - ), - ), - ); - } - - /// 함수의 용도: 유저 프로필 이미지 원형 위젯 생성 (Asset -> Network 이미지 대응) - /// 매개 변수: String? imagePath, double size - Widget buildProfileCircle(String? imageUrl, double size) { - return Container( - width: size, - height: size, - decoration: BoxDecoration( - color: const Color(0x7FDFE1DC), - shape: BoxShape.circle, - // 서버에서 오는 이미지는 NetworkImage로 처리해야 합니다. - image: imageUrl != null && imageUrl.startsWith('http') - ? DecorationImage(image: NetworkImage(imageUrl), fit: BoxFit.cover) - : (imageUrl != null - ? DecorationImage( - image: AssetImage(imageUrl), - fit: BoxFit.cover, - ) - : null), - ), - child: imageUrl == null - ? Center( - child: SvgPicture.asset( - 'assets/images/icons/default_profile_icon.svg', - width: size, - ), - ) - : null, - ); - } - - /// 함수의 용도: 검색 결과의 친구 신청/신청됨 버튼 생성 - /// 매개 변수: SearchResultUser user (대상 유저) - Widget buildRequestButton(SearchResultUser user) { - // 1. 이미 친구인 유저는 버튼 자체를 노출하지 않음 [추가] - if (user.isFriend) { - return const SizedBox.shrink(); - } - - return GestureDetector( - // 2. 이미 신청된 상태(isRequested)면 클릭 방지 - onTap: user.isRequested ? null : () => sendFriendRequestAction(user), - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), - decoration: BoxDecoration( - color: user.isRequested ? AppColors.disable : AppColors.primaryAble, - borderRadius: BorderRadius.circular(8), - ), - child: Text( - user.isRequested ? '신청됨' : '친구 신청', - style: AppTypography.c1.copyWith( - color: user.isRequested ? AppColors.gray2 : Colors.white, - fontWeight: FontWeight.w500, - ), - ), - ), - ); - } -} - -// --- 애니메이션 컴포넌트 --- - -/// 클래스의 용도: 화면 하단에 메시지를 띄우는 애니메이션 토스트 위젯 -class AnimatedToast extends StatefulWidget { - final String message; - final VoidCallback onDismissed; - - const AnimatedToast({ - super.key, - required this.message, - required this.onDismissed, - }); - - @override - State createState() => AnimatedToastState(); -} - -class AnimatedToastState extends State - with SingleTickerProviderStateMixin { - late AnimationController controller; - late Animation slideAnimation; - late Animation opacityAnimation; - - /// 함수의 용도: 애니메이션 컨트롤러 및 애니메이션 초기화 - @override - void initState() { - super.initState(); - controller = AnimationController( - vsync: this, - duration: const Duration(milliseconds: 500), - ); - - slideAnimation = Tween( - begin: const Offset(0, 0.5), - end: Offset.zero, - ).animate(CurvedAnimation(parent: controller, curve: Curves.easeOutQuart)); - - opacityAnimation = Tween( - begin: 0.0, - end: 1.0, - ).animate(CurvedAnimation(parent: controller, curve: Curves.easeIn)); - - controller.forward().then((_) async { - await Future.delayed(const Duration(seconds: 2)); - if (mounted) { - await controller.reverse(); - widget.onDismissed(); - } - }); - } - - /// 함수의 용도: 애니메이션 컨트롤러 해제 - @override - void dispose() { - controller.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Positioned( - bottom: 60, - left: 20, - right: 20, - child: IgnorePointer( - child: Material( - color: Colors.transparent, - child: FadeTransition( - opacity: opacityAnimation, - child: SlideTransition( - position: slideAnimation, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 24, - vertical: 16, - ), - decoration: BoxDecoration( - color: const Color(0xCC1A1D1B), - borderRadius: BorderRadius.circular(8), - ), - child: Text( - widget.message, - textAlign: TextAlign.center, - style: AppTypography.b1.copyWith(color: Colors.white), - ), - ), - ), - ), - ), - ), - ); - } } diff --git a/lib/features/social/screens/friend_edit_screen.dart b/lib/features/social/screens/friend_edit_screen.dart index b8a7dad..5ed48cd 100644 --- a/lib/features/social/screens/friend_edit_screen.dart +++ b/lib/features/social/screens/friend_edit_screen.dart @@ -1,35 +1,31 @@ /// 최초 작성자: 정승빈 - -library; - import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; + import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; -import '../models/social_model.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import '../data/social_repository.dart'; import '../../../core/utils/korean_string_utils.dart'; +import '../../../shared/models/user.dart'; +import '../widgets/animated_toast.dart'; +import '../provider/friend_list_provider.dart'; +import '../widgets/delete_confirm_dialog.dart'; +import '../widgets/friend_edit_tile.dart'; -/// 클래스의 용도: 기존 친구 목록을 검색하고 삭제할 수 있는 편집 화면 class FriendEditScreen extends ConsumerStatefulWidget { - // ConsumerStatefulWidget으로 변경 - final List initialFriends; + final List initialFriends; // 초기 친구 목록을 전달받는 매개변수 const FriendEditScreen({super.key, required this.initialFriends}); @override - ConsumerState createState() => FriendEditScreenState(); + ConsumerState createState() => _FriendEditScreenState(); } -class FriendEditScreenState extends ConsumerState { +class _FriendEditScreenState extends ConsumerState { final TextEditingController searchController = TextEditingController(); - late List totalList; - List filteredList = []; + late List totalList; + List filteredList = []; - /// 함수의 용도: 초기 상태 설정 및 원본 리스트 복사 - /// 매개 변수: 없음 - /// 반환 값: 없음 @override void initState() { super.initState(); @@ -38,17 +34,21 @@ class FriendEditScreenState extends ConsumerState { _applySortAndState(); } - /// 함수의 용도: 입력 쿼리에 따라 리스트 필터링 - /// 매개 변수: String query (검색어) - /// 반환 값: 없음 + @override + void dispose() { + searchController.dispose(); + super.dispose(); + } + + // 입력 쿼리에 따라 리스트 필터링 void filterList(String query) { setState(() { String trimmedQuery = query.trim().toLowerCase(); if (trimmedQuery.isEmpty) { filteredList = List.from(totalList); } else { - filteredList = totalList.where((friend) { - String nickname = friend.nickname.toLowerCase(); + filteredList = totalList.where((user) { + String nickname = user.nickname.toLowerCase(); return nickname.contains(trimmedQuery) || KoreanStringUtils.getChoseongString( nickname, @@ -59,72 +59,47 @@ class FriendEditScreenState extends ConsumerState { }); } - /// 정렬 로직 호출 및 상태 반영 + // 정렬 로직 호출 및 상태 반영 void _applySortAndState() { filteredList.sort( (a, b) => KoreanStringUtils.compareKoreanFirst(a.nickname, b.nickname), ); } - /// 함수의 용도: 커스텀 Overlay 애니메이션 토스트 표시 - /// 매개 변수: String message (출력 문구) - /// 반환 값: 없음 - void displayToast(String message) { - final overlay = Overlay.of(context); - late OverlayEntry overlayEntry; - - overlayEntry = OverlayEntry( - builder: (context) => AnimatedToast( - message: message, - onDismissed: () { - overlayEntry.remove(); - }, - ), - ); - - overlay.insert(overlayEntry); - } - - /// 함수의 용도: 삭제 확인 다이얼로그 노출 - /// 매개 변수: Friend friend (삭제 대상 친구) - /// 반환 값: 없음 - void showDeleteDialog(Friend friend) { + // 삭제 확인 다이얼로그 표시 + void showDeleteDialog(User user) { showDialog( context: context, - // 1. 여기서 context 이름을 dialogContext로 변경하여 혼동 방지 builder: (dialogContext) => DeleteConfirmDialog( - usernickName: friend.nickname, + userNickname: user.nickname, onDelete: () async { try { + // 새로 생성한 Provider의 Notifier를 통한 삭제 로직 호출 await ref - .read(socialRepositoryProvider) - .deleteFriend(friend.nickname); + .read(friendListProvider.notifier) + .removeFriend(user.nickname); - // 2. 화면(FriendEditScreen)이 살아있는지 확인 (setState용) if (!mounted) return; setState(() { - totalList.removeWhere((f) => f.nickname == friend.nickname); + totalList.removeWhere((u) => u.nickname == user.nickname); filterList(searchController.text); }); - // 3. 다이얼로그가 아직 열려있는지 확인 후 닫기 (Navigator용) - // 'context' 대신 'dialogContext'를 사용하세요. + // 다이얼로그가 아직 열려있는지 확인 후 닫기 if (dialogContext.mounted) { Navigator.pop(dialogContext); } - displayToast('${friend.nickname} 님이 삭제되었습니다.'); + displayToast(context, '${user.nickname} 님이 삭제되었습니다.'); } catch (e) { if (!mounted) return; - - // 여기서도 dialogContext가 살아있는지 확인하면 더 안전합니다. + // 다이얼로그가 아직 열려있는지 확인 후 닫기 if (dialogContext.mounted) { Navigator.pop(dialogContext); } - - displayToast('삭제에 실패했습니다. 다시 시도해 주세요.'); - debugPrint('친구 삭제 실패: $e'); + displayToast(context, '삭제에 실패했습니다. 다시 시도해 주세요.'); + debugPrint('친구 삭제 실패: $e'); // 디버그 로그 } }, ), @@ -147,17 +122,15 @@ class FriendEditScreenState extends ConsumerState { ), body: Column( children: [ - buildSearchHeader(), - Expanded(child: buildEditListView()), + _buildSearchHeader(), + Expanded(child: _buildEditListView()), ], ), ); } - /// 함수의 용도: 검색창 영역 빌드 - /// 매개 변수: 없음 - /// 반환 값: Widget - Widget buildSearchHeader() { + // 검색창 영역 빌드 + Widget _buildSearchHeader() { return Padding( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), child: Container( @@ -198,254 +171,21 @@ class FriendEditScreenState extends ConsumerState { ); } - /// 함수의 용도: 필터링된 편집 리스트뷰 빌드 - /// 매개 변수: 없음 - /// 반환 값: Widget - Widget buildEditListView() { + // 편집 리스트 빌드 + Widget _buildEditListView() { if (filteredList.isEmpty) { return const Center(child: Text('검색 결과가 없습니다.', style: AppTypography.b2)); } return ListView.builder( padding: const EdgeInsets.symmetric(horizontal: 20), itemCount: filteredList.length, - itemBuilder: (context, index) => buildEditTile(filteredList[index]), - ); - } - - /// 함수의 용도: 개별 친구 편집 항목 타일 생성 - /// 매개 변수: Friend friend (대상 친구 데이터) - /// 반환 값: Widget - Widget buildEditTile(Friend friend) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Row( - children: [ - Container( - width: 44, - height: 44, - decoration: BoxDecoration( - color: const Color(0x7FDFE1DC), - shape: BoxShape.circle, - image: friend.profileImageUrl != null - ? DecorationImage( - image: NetworkImage(friend.profileImageUrl!), - fit: BoxFit.cover, - ) - : null, - ), - child: friend.profileImageUrl == null - ? Center( - child: SvgPicture.asset( - 'assets/images/icons/default_profile_icon.svg', - width: 24, - ), - ) - : null, - ), - const SizedBox(width: 12), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - friend.nickname, - style: AppTypography.h3.copyWith(fontSize: 15), - ), - Text( - friend.title, - style: AppTypography.c1.copyWith(color: AppColors.gray2), - ), - ], - ), - ), - IconButton( - onPressed: () => showDeleteDialog(friend), - icon: SvgPicture.asset( - 'assets/images/icons/big_trash_icon.svg', - width: 24, - colorFilter: const ColorFilter.mode( - AppColors.notification, - BlendMode.srcIn, - ), - ), - ), - ], - ), - ); - } -} - -/// 클래스의 용도: 친구 삭제 여부를 묻는 팝업 다이얼로그 -class DeleteConfirmDialog extends StatelessWidget { - final String usernickName; - final VoidCallback onDelete; - - const DeleteConfirmDialog({ - super.key, - required this.usernickName, - required this.onDelete, - }); - - @override - Widget build(BuildContext context) { - return Dialog( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), - backgroundColor: Colors.white, - child: Padding( - padding: const EdgeInsets.all(20), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Text('친구 삭제', style: AppTypography.h2), - const SizedBox(height: 12), - Text( - '$usernickName 님을 삭제하시겠습니까?', - style: AppTypography.b2.copyWith(color: AppColors.gray2), - textAlign: TextAlign.center, - ), - const SizedBox(height: 24), - Row( - children: [ - Expanded( - child: GestureDetector( - onTap: () => Navigator.pop(context), - child: Container( - height: 48, - decoration: BoxDecoration( - color: const Color(0x7FDFE1DC), - borderRadius: BorderRadius.circular(10), - ), - child: const Center( - child: Text('취소', style: AppTypography.b1), - ), - ), - ), - ), - const SizedBox(width: 10), - Expanded( - child: GestureDetector( - onTap: onDelete, - child: Container( - height: 48, - decoration: BoxDecoration( - color: const Color(0x7FDFE1DC), - borderRadius: BorderRadius.circular(10), - ), - child: Center( - child: Text( - '삭제하기', - style: AppTypography.b1.copyWith( - color: AppColors.notification, - fontWeight: FontWeight.w600, - ), - ), - ), - ), - ), - ), - ], - ), - ], - ), - ), - ); - } -} - -/// 클래스의 용도: 화면 하단에 메시지를 띄우는 애니메이션 토스트 위젯 -class AnimatedToast extends StatefulWidget { - final String message; - final VoidCallback onDismissed; - - const AnimatedToast({ - super.key, - required this.message, - required this.onDismissed, - }); - - @override - State createState() => AnimatedToastState(); -} - -class AnimatedToastState extends State - with SingleTickerProviderStateMixin { - late AnimationController animationController; - late Animation slideAnimation; - late Animation opacityAnimation; - - /// 함수의 용도: 애니메이션 초기화 및 자동 소멸 로직 - /// 매개 변수: 없음 - /// 반환 값: 없음 - @override - void initState() { - super.initState(); - animationController = AnimationController( - vsync: this, - duration: const Duration(milliseconds: 500), - ); - - slideAnimation = - Tween(begin: const Offset(0, 0.5), end: Offset.zero).animate( - CurvedAnimation( - parent: animationController, - curve: Curves.easeOutQuart, - ), + itemBuilder: (context, index) { + final user = filteredList[index]; + return FriendEditTile( + user: user, + onDeleteTap: () => showDeleteDialog(user), ); - - opacityAnimation = Tween(begin: 0.0, end: 1.0).animate( - CurvedAnimation(parent: animationController, curve: Curves.easeIn), - ); - - animationController.forward().then((_) async { - await Future.delayed(const Duration(seconds: 2)); - if (mounted) { - await animationController.reverse(); - widget.onDismissed(); - } - }); - } - - /// 함수의 용도: 애니메이션 컨트롤러 해제 - /// 매개 변수: 없음 - /// 반환 값: 없음 - @override - void dispose() { - animationController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Positioned( - bottom: 60, - left: 20, - right: 20, - child: IgnorePointer( - child: Material( - color: Colors.transparent, - child: FadeTransition( - opacity: opacityAnimation, - child: SlideTransition( - position: slideAnimation, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 24, - vertical: 16, - ), - decoration: BoxDecoration( - color: const Color(0xCC1A1D1B), - borderRadius: BorderRadius.circular(8), - ), - child: Text( - widget.message, - textAlign: TextAlign.center, - style: AppTypography.b1.copyWith(color: Colors.white), - ), - ), - ), - ), - ), - ), + }, ); } } diff --git a/lib/features/social/screens/social_main_screen.dart b/lib/features/social/screens/social_main_screen.dart new file mode 100644 index 0000000..e12bbcc --- /dev/null +++ b/lib/features/social/screens/social_main_screen.dart @@ -0,0 +1,208 @@ +/// 최초 작성자: 정승빈 +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import '../../../../core/theme/app_colors.dart'; +import '../../../../core/theme/app_typography.dart'; +import '../../../core/utils/korean_string_utils.dart'; +import '../../../shared/models/user.dart'; +import '../provider/friend_list_provider.dart'; +import '../widgets/friend_list_tile.dart'; +import 'friend_add_screen.dart'; +import 'friend_edit_screen.dart'; + +class SocialMainScreen extends ConsumerStatefulWidget { + const SocialMainScreen({super.key}); + + @override + ConsumerState createState() => _SocialMainScreenState(); +} + +class _SocialMainScreenState extends ConsumerState { + final TextEditingController searchController = TextEditingController(); + String searchQuery = ''; + + @override + void dispose() { + searchController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + // 새로운 Provider 구독 + final friendListAsync = ref.watch(friendListProvider); + + return Scaffold( + backgroundColor: Colors.white, + appBar: _buildAppBar(context), + body: Column( + children: [ + _buildSearchBar(), + // 친구 목록 섹션 + Expanded( + child: friendListAsync.when( + data: (totalFriends) { + // 1. 검색 필터링 + final filteredFriends = totalFriends.where((user) { + final name = user.nickname.toLowerCase(); + final query = searchQuery.toLowerCase(); + return name.contains(query) || + KoreanStringUtils.getChoseongString(name).contains(query); + }).toList(); + + // 2. 가나다순 정렬 + filteredFriends.sort( + (a, b) => KoreanStringUtils.compareKoreanFirst( + a.nickname, + b.nickname, + ), + ); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildListHeader(filteredFriends.length, totalFriends), + Expanded( + child: RefreshIndicator( + color: AppColors.primaryAble, + onRefresh: () async { + // 스크롤을 당기면 데이터를 강제로 다시 불러옵니다. + return await ref.refresh(friendListProvider.future); + }, + child: filteredFriends.isEmpty + ? _buildEmptyState() + : _buildFriendList(filteredFriends), + ), + ), + ], + ); + }, + loading: () => const Center(child: CircularProgressIndicator()), + error: (err, stack) => + const Center(child: Text('친구 목록을 불러오지 못했습니다.')), + ), + ), + ], + ), + ); + } + + PreferredSizeWidget _buildAppBar(BuildContext context) { + return AppBar( + backgroundColor: Colors.white, + elevation: 0, + centerTitle: true, + title: const Text('친구', style: AppTypography.h3), + actions: [ + IconButton( + icon: SvgPicture.asset('assets/images/icons/friend_add_icon.svg'), + onPressed: () async { + // await를 사용하여 FriendAddScreen이 닫힐 때까지 기다림 + await Navigator.push( + context, + MaterialPageRoute(builder: (context) => const FriendAddScreen()), + ); + + // 화면이 닫히고 돌아오면 친구 목록 Provider를 강제로 새로고침 + ref.invalidate(friendListProvider); + }, + ), + ], + ); + } + + Widget _buildSearchBar() { + return Padding( + padding: const EdgeInsets.all(20), + child: Container( + height: 40, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + border: Border.all(color: AppColors.gray4), + ), + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/icons/search_icon.svg', + width: 18, + colorFilter: const ColorFilter.mode( + AppColors.gray3, + BlendMode.srcIn, + ), + ), + const SizedBox(width: 8), + Expanded( + child: TextField( + controller: searchController, + onChanged: (value) => setState(() => searchQuery = value), + decoration: const InputDecoration( + hintText: '친구 검색', + hintStyle: AppTypography.b2, + border: InputBorder.none, + isDense: true, + ), + style: AppTypography.b1, + ), + ), + ], + ), + ), + ); + } + + Widget _buildListHeader(int count, List totalFriends) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('친구 $count', style: AppTypography.b2), + GestureDetector( + onTap: () async { + // await로 편집 화면이 닫힐 때까지 대기 + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + FriendEditScreen(initialFriends: totalFriends), + ), + ); + + // 편집 화면에서 돌아오면 친구 목록 새로고침 (삭제 반영) + ref.invalidate(friendListProvider); + }, + child: Text( + '편집', + style: AppTypography.c1.copyWith(color: AppColors.gray2), + ), + ), + ], + ), + ); + } + + // 친구가 없을 때 보여줄 빈 상태 위젯 + Widget _buildEmptyState() { + return SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + child: SizedBox( + height: MediaQuery.of(context).size.height * 0.5, + child: const Center(child: Text('친구가 없습니다.')), + ), + ); + } + + // 친구 목록을 보여주는 위젯 + Widget _buildFriendList(List filteredFriends) { + return ListView.builder( + physics: const AlwaysScrollableScrollPhysics(), // 스크롤이 가능하도록 설정 + padding: const EdgeInsets.symmetric(horizontal: 20), + itemCount: filteredFriends.length, + itemBuilder: (context, index) => + FriendListTile(user: filteredFriends[index]), + ); + } +} diff --git a/lib/features/social/screens/social_screen.dart b/lib/features/social/screens/social_screen.dart deleted file mode 100644 index e92bfd0..0000000 --- a/lib/features/social/screens/social_screen.dart +++ /dev/null @@ -1,260 +0,0 @@ -/// 최초 작성자: 정승빈 (수정: Gemini) -library; - -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; // 추가 -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:haenaem/features/social/screens/friend_edit_screen.dart'; -import '../../../../core/theme/app_colors.dart'; -import '../../../../core/theme/app_typography.dart'; -import 'friend_add_screen.dart'; -import '../data/social_repository.dart'; -import '../models/social_model.dart'; -import '../../../core/utils/korean_string_utils.dart'; - -class SocialScreen extends ConsumerStatefulWidget { - const SocialScreen({super.key}); - - @override - ConsumerState createState() => _SocialScreenState(); -} - -class _SocialScreenState extends ConsumerState { - final TextEditingController searchController = TextEditingController(); - String searchQuery = ''; - - @override - void dispose() { - searchController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - // Riverpod을 통해 친구 목록 프로바이더 구독 - final friendListAsync = ref.watch(friendListProvider); - - return Scaffold( - backgroundColor: Colors.white, - appBar: AppBar( - backgroundColor: Colors.white, - elevation: 0, - centerTitle: true, - title: const Text('친구', style: AppTypography.h3), - actions: [ - IconButton( - icon: SvgPicture.asset('assets/images/icons/friend_add_icon.svg'), - onPressed: () async { - // 1. async 키워드 추가 - // 2. await를 사용하여 FriendAddScreen이 닫힐 때까지 기다림 - await Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const FriendAddScreen(), - ), - ); - - // 3. 화면이 닫히고 돌아오면 친구 목록 Provider를 강제로 새로고침 - ref.invalidate(friendListProvider); - }, - ), - ], - ), - body: Column( - children: [ - // 검색창 (friend_add_screen.dart 스타일로 수정됨) - Padding( - padding: const EdgeInsets.all(20), - child: Container( - height: 40, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - border: Border.all(color: AppColors.gray4), // 연한 회색 테두리 - ), - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/icons/search_icon.svg', - width: 18, - colorFilter: const ColorFilter.mode( - AppColors.gray3, - BlendMode.srcIn, - ), - ), - const SizedBox(width: 8), - Expanded( - child: TextField( - controller: searchController, - onChanged: (value) => setState(() => searchQuery = value), - decoration: const InputDecoration( - hintText: '친구 검색', - hintStyle: AppTypography.b2, - border: InputBorder.none, // 기본 TextField 테두리 제거 - isDense: true, // 텍스트 필드 내부 여백 최소화 (중앙 정렬 도움) - ), - style: AppTypography.b1, - ), - ), - ], - ), - ), - ), - - // 친구 목록 섹션 - Expanded( - child: friendListAsync.when( - data: (totalFriends) { - // 1. 필터링 및 2. 정렬 로직 적용 - final filteredFriends = totalFriends.where((friend) { - final name = friend.nickname.toLowerCase(); - final query = searchQuery.toLowerCase(); - return name.contains(query) || - KoreanStringUtils.getChoseongString(name).contains(query); - }).toList(); - - // 가나다순 정렬 추가 - filteredFriends.sort( - (a, b) => KoreanStringUtils.compareKoreanFirst( - a.nickname, - b.nickname, - ), - ); - - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 20, - vertical: 8, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - '친구 ${filteredFriends.length}', - style: AppTypography.b2, - ), - GestureDetector( - onTap: () async { - // 1. async 추가 - // 2. await로 편집 화면이 닫힐 때까지 대기 - await Navigator.push( - context, - MaterialPageRoute( - builder: (context) => FriendEditScreen( - initialFriends: totalFriends, - ), - ), - ); - - // 3. 편집 화면에서 돌아오면 친구 목록 새로고침 (삭제 반영) - ref.invalidate(friendListProvider); - }, - child: Text( - '편집', - style: AppTypography.c1.copyWith( - color: AppColors.gray2, - ), - ), - ), - ], - ), - ), - Expanded( - child: RefreshIndicator( - color: AppColors.primaryAble, - onRefresh: () async { - // 스크롤을 당기면 데이터를 강제로 다시 불러옵니다. - return await ref.refresh(friendListProvider.future); - }, - child: filteredFriends.isEmpty - ? SingleChildScrollView( - physics: - const AlwaysScrollableScrollPhysics(), // 친구가 없어도 스크롤을 당길 수 있게 설정 - child: SizedBox( - height: - MediaQuery.of(context).size.height * 0.5, - child: const Center(child: Text('친구가 없습니다.')), - ), - ) - : ListView.builder( - physics: - const AlwaysScrollableScrollPhysics(), // 스크롤이 가능하도록 설정 - padding: const EdgeInsets.symmetric( - horizontal: 20, - ), - itemCount: filteredFriends.length, - itemBuilder: (context, index) => - buildFriendTile(filteredFriends[index]), - ), - ), - ), - ], - ); - }, - loading: () => const Center(child: CircularProgressIndicator()), - error: (err, stack) => - const Center(child: Text('친구 목록을 불러오지 못했습니다.')), - ), - ), - ], - ), - ); - } - - Widget buildFriendTile(Friend friend) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Row( - children: [ - // 프로필 이미지 (NetworkImage 대응) - Container( - width: 44, - height: 44, - decoration: BoxDecoration( - color: const Color(0x7FDFE1DC), - shape: BoxShape.circle, - image: - friend.profileImageUrl != null && - friend.profileImageUrl!.startsWith('http') - ? DecorationImage( - image: NetworkImage(friend.profileImageUrl!), - fit: BoxFit.cover, - ) - : (friend.profileImageUrl != null - ? DecorationImage( - image: AssetImage(friend.profileImageUrl!), - fit: BoxFit.cover, - ) - : null), - ), - child: friend.profileImageUrl == null - ? Center( - child: SvgPicture.asset( - 'assets/images/icons/default_profile_icon.svg', - width: 24, - ), - ) - : null, - ), - const SizedBox(width: 12), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - friend.nickname, - style: AppTypography.h3.copyWith(fontSize: 15), - ), - Text( - "칭호 없음", // Swagger 모델에 맞게 수정 필요 시 변경 - style: AppTypography.c1.copyWith(color: AppColors.gray2), - ), - ], - ), - ], - ), - ); - } -} diff --git a/lib/features/social/views/received_request_view.dart b/lib/features/social/views/received_request_view.dart new file mode 100644 index 0000000..5c6b2d0 --- /dev/null +++ b/lib/features/social/views/received_request_view.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import '../../../../core/theme/app_typography.dart'; +import '../provider/friend_request_provider.dart'; // 이전 단계에서 생성한 Provider 보낸 요청 카드 UI 위젯 +import '../widgets/animated_toast.dart'; +import '../widgets/received_request_card.dart'; + +class ReceivedRequestView extends ConsumerWidget { + const ReceivedRequestView({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + // 1. 상태 구독 + final receivedRequestsAsync = ref.watch(receivedRequestsProvider); + + return Container( + color: const Color(0x7FDFE1DC), + child: receivedRequestsAsync.when( + data: (requests) { + if (requests.isEmpty) { + return const Center( + child: Text('받은 요청이 없습니다.', style: AppTypography.b2), + ); + } + return RefreshIndicator( + color: AppColors.primaryAble, + onRefresh: () async { + // 새로고침 시 Provider의 Future를 다시 호출하여 최신 데이터 가져오기 + return await ref.refresh(receivedRequestsProvider.future); + }, + child: ListView.builder( + padding: const EdgeInsets.all(16), + itemCount: requests.length, + itemBuilder: (context, index) { + final req = requests[index]; + return ReceivedRequestCard( + request: req, + onAccept: () async { + try { + await ref + .read(receivedRequestsProvider.notifier) + .acceptRequest(req.requestId); + if (context.mounted) { + displayToast( + context, + '${req.user.nickname} 님과 친구가 되었습니다!', + ); + } + } catch (e) { + if (context.mounted) { + displayToast(context, '수락 처리에 실패했습니다.'); + } + } + }, + onReject: () async { + try { + await ref + .read(receivedRequestsProvider.notifier) + .rejectRequest(req.requestId); + if (context.mounted) displayToast(context, '요청을 거절했습니다.'); + } catch (e) { + if (context.mounted) { + displayToast(context, '거절 처리에 실패했습니다.'); + } + } + }, + ); + }, + // 항상 스크롤 가능하도록 설정 (요청이 1개 이하일 때도 당겨서 새로고침 가능) + physics: const AlwaysScrollableScrollPhysics(), + ), + ); + }, + loading: () => const Center(child: CircularProgressIndicator()), + error: (err, stack) => const Center(child: Text('데이터를 불러오는데 실패했습니다.')), + ), + ); + } +} diff --git a/lib/features/social/views/sent_request_view.dart b/lib/features/social/views/sent_request_view.dart new file mode 100644 index 0000000..cd89158 --- /dev/null +++ b/lib/features/social/views/sent_request_view.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../../../../core/theme/app_typography.dart'; +import '../provider/friend_request_provider.dart'; +import '../widgets/animated_toast.dart'; +import '../widgets/sent_request_card.dart'; + +class SentRequestView extends ConsumerWidget { + const SentRequestView({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final sentRequestsAsync = ref.watch(sentRequestsProvider); + + return Container( + color: const Color(0x7FDFE1DC), + child: sentRequestsAsync.when( + data: (requests) { + if (requests.isEmpty) { + return const Center( + child: Text('보낸 요청이 없습니다.', style: AppTypography.b2), + ); + } + return ListView.builder( + padding: const EdgeInsets.all(16), + itemCount: requests.length, + itemBuilder: (context, index) { + final req = requests[index]; + return SentRequestCard( + request: req, + onCancel: () async { + try { + await ref + .read(sentRequestsProvider.notifier) + .cancelRequest(req.requestId); + if (context.mounted) { + displayToast(context, '친구 신청을 취소했습니다.'); + } + } catch (e) { + if (context.mounted) displayToast(context, '취소에 실패했습니다.'); + } + }, + ); + }, + ); + }, + loading: () => const Center(child: CircularProgressIndicator()), + error: (err, stack) => const Center(child: Text('데이터를 불러오는데 실패했습니다.')), + ), + ); + } +} diff --git a/lib/features/social/views/user_search_view.dart b/lib/features/social/views/user_search_view.dart new file mode 100644 index 0000000..f296ad9 --- /dev/null +++ b/lib/features/social/views/user_search_view.dart @@ -0,0 +1,152 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import '../../../../core/theme/app_colors.dart'; +import '../../../../core/theme/app_typography.dart'; +import '../models/user_search_card.dart'; +import '../provider/user_search_provider.dart'; +import '../widgets/animated_toast.dart'; +import '../widgets/user_search_tile.dart'; + +class UserSearchView extends ConsumerStatefulWidget { + const UserSearchView({super.key}); + + @override + ConsumerState createState() => _UserSearchViewState(); +} + +class _UserSearchViewState extends ConsumerState { + final TextEditingController searchController = TextEditingController(); + bool isSearchPerformed = false; // 검색창에 입력 후 엔터를 쳤는지 여부만 관리 + + @override + void dispose() { + searchController.dispose(); + super.dispose(); + } + + Future performSearch() async { + if (searchController.text.trim().isEmpty) return; + + setState(() => isSearchPerformed = true); + + // 비즈니스 로직은 Provider에게 위임 + await ref + .read(userSearchProvider.notifier) + .searchUsers(searchController.text); + } + + Future sendFriendRequestAction(UserSearchCard card) async { + try { + await ref.read(userSearchProvider.notifier).sendFriendRequest(card); + if (mounted) { + displayToast(context, '${card.user.nickname} 님에게 친구 신청을 보냈습니다!'); + } + } catch (e) { + if (mounted) { + displayToast(context, '이미 신청되었거나 신청에 실패했습니다.'); + } + } + } + + @override + Widget build(BuildContext context) { + // 1. 검색 상태 구독 + final searchState = ref.watch(userSearchProvider); + + return Column( + children: [ + _buildSearchInputSection(), + + // 2. 검색 상태에 따른 UI 렌더링 + Expanded( + child: searchState.when( + loading: () => const Center(child: CircularProgressIndicator()), + error: (error, stack) { + // 검색 에러 시 토스트는 유지하되 화면에는 에러 문구 표시 + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) displayToast(context, '검색 중 오류가 발생했습니다.'); + }); + return const Center(child: Text('검색 결과가 없거나 오류가 발생했습니다.')); + }, + data: (results) { + if (!isSearchPerformed) { + return const SizedBox.expand(); + } + return Column( + children: [ + _buildResultCountHeader(results.length), + Expanded(child: _buildSearchResultList(results)), + ], + ); + }, + ), + ), + ], + ); + } + + Widget _buildSearchInputSection() { + return Padding( + padding: const EdgeInsets.all(20), + child: Container( + height: 40, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + border: Border.all(color: AppColors.gray4), + ), + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/icons/search_icon.svg', + width: 18, + colorFilter: const ColorFilter.mode( + AppColors.gray3, + BlendMode.srcIn, + ), + ), + const SizedBox(width: 8), + Expanded( + child: TextField( + controller: searchController, + onSubmitted: (_) => performSearch(), + textInputAction: TextInputAction.search, + decoration: const InputDecoration( + hintText: '닉네임을 검색하세요', + hintStyle: AppTypography.b2, + border: InputBorder.none, + isDense: true, + ), + style: AppTypography.b1, + ), + ), + ], + ), + ), + ); + } + + Widget _buildResultCountHeader(int count) { + return Container( + width: double.infinity, + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), + child: Text('검색 결과 $count명', style: AppTypography.b2), + ); + } + + Widget _buildSearchResultList(List results) { + return ListView.builder( + padding: const EdgeInsets.symmetric(horizontal: 20), + itemCount: results.length, + itemBuilder: (context, index) { + final card = results[index]; + return UserSearchTile( + searchCard: card, + onRequest: () => sendFriendRequestAction(card), + ); + }, + ); + } +} diff --git a/lib/features/social/widgets/animated_toast.dart b/lib/features/social/widgets/animated_toast.dart new file mode 100644 index 0000000..8239528 --- /dev/null +++ b/lib/features/social/widgets/animated_toast.dart @@ -0,0 +1,108 @@ +import 'package:flutter/material.dart'; +import '../../../core/theme/app_typography.dart'; + +// 토스트를 띄우기 위한 공통 함수 +void displayToast(BuildContext context, String message) { + final overlay = Overlay.of(context); + late OverlayEntry overlayEntry; + + overlayEntry = OverlayEntry( + builder: (context) => AnimatedToast( + message: message, + onDismissed: () { + overlayEntry.remove(); + }, + ), + ); + + overlay.insert(overlayEntry); +} + +class AnimatedToast extends StatefulWidget { + final String message; + final VoidCallback onDismissed; + + const AnimatedToast({ + super.key, + required this.message, + required this.onDismissed, + }); + + @override + State createState() => _AnimatedToastState(); +} + +class _AnimatedToastState extends State + with SingleTickerProviderStateMixin { + late AnimationController controller; + late Animation slideAnimation; + late Animation opacityAnimation; + + @override + void initState() { + super.initState(); + controller = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 500), + ); + + slideAnimation = Tween( + begin: const Offset(0, 0.5), + end: Offset.zero, + ).animate(CurvedAnimation(parent: controller, curve: Curves.easeOutQuart)); + + opacityAnimation = Tween( + begin: 0.0, + end: 1.0, + ).animate(CurvedAnimation(parent: controller, curve: Curves.easeIn)); + + controller.forward().then((_) async { + await Future.delayed(const Duration(seconds: 2)); + if (mounted) { + await controller.reverse(); + widget.onDismissed(); + } + }); + } + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Positioned( + bottom: 60, + left: 20, + right: 20, + child: IgnorePointer( + child: Material( + color: Colors.transparent, + child: FadeTransition( + opacity: opacityAnimation, + child: SlideTransition( + position: slideAnimation, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 24, + vertical: 16, + ), + decoration: BoxDecoration( + color: const Color(0xCC1A1D1B), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + widget.message, + textAlign: TextAlign.center, + style: AppTypography.b1.copyWith(color: Colors.white), + ), + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/features/social/widgets/delete_confirm_dialog.dart b/lib/features/social/widgets/delete_confirm_dialog.dart new file mode 100644 index 0000000..27c8727 --- /dev/null +++ b/lib/features/social/widgets/delete_confirm_dialog.dart @@ -0,0 +1,79 @@ +import 'package:flutter/material.dart'; +import '../../../../core/theme/app_colors.dart'; +import '../../../../core/theme/app_typography.dart'; + +class DeleteConfirmDialog extends StatelessWidget { + final String userNickname; + final VoidCallback onDelete; + + const DeleteConfirmDialog({ + super.key, + required this.userNickname, + required this.onDelete, + }); + + @override + Widget build(BuildContext context) { + return Dialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), + backgroundColor: Colors.white, + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text('친구 삭제', style: AppTypography.h2), + const SizedBox(height: 12), + Text( + '$userNickname 님을 삭제하시겠습니까?', + style: AppTypography.b2.copyWith(color: AppColors.gray2), + textAlign: TextAlign.center, + ), + const SizedBox(height: 24), + Row( + children: [ + Expanded( + child: GestureDetector( + onTap: () => Navigator.pop(context), + child: Container( + height: 48, + decoration: BoxDecoration( + color: const Color(0x7FDFE1DC), + borderRadius: BorderRadius.circular(10), + ), + child: const Center( + child: Text('취소', style: AppTypography.b1), + ), + ), + ), + ), + const SizedBox(width: 10), + Expanded( + child: GestureDetector( + onTap: onDelete, + child: Container( + height: 48, + decoration: BoxDecoration( + color: const Color(0x7FDFE1DC), + borderRadius: BorderRadius.circular(10), + ), + child: Center( + child: Text( + '삭제하기', + style: AppTypography.b1.copyWith( + color: AppColors.notification, + fontWeight: FontWeight.w600, + ), + ), + ), + ), + ), + ), + ], + ), + ], + ), + ), + ); + } +} diff --git a/lib/features/social/widgets/friend_edit_tile.dart b/lib/features/social/widgets/friend_edit_tile.dart new file mode 100644 index 0000000..57860f8 --- /dev/null +++ b/lib/features/social/widgets/friend_edit_tile.dart @@ -0,0 +1,82 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import '../../../../core/theme/app_colors.dart'; +import '../../../../core/theme/app_typography.dart'; +import '../../../shared/models/user.dart'; + +class FriendEditTile extends StatelessWidget { + final User user; + final VoidCallback onDeleteTap; + + const FriendEditTile({ + super.key, + required this.user, + required this.onDeleteTap, + }); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + children: [ + _buildProfileCircle(user.profileUrl, 44), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + user.nickname, + style: AppTypography.h3.copyWith(fontSize: 15), + ), + Text( + "해냄 메이트", // 추후 칭호 연동 + style: AppTypography.c1.copyWith(color: AppColors.gray2), + ), + ], + ), + ), + IconButton( + onPressed: onDeleteTap, + icon: SvgPicture.asset( + 'assets/images/icons/big_trash_icon.svg', + width: 24, + colorFilter: const ColorFilter.mode( + AppColors.notification, + BlendMode.srcIn, + ), + ), + ), + ], + ), + ); + } + + Widget _buildProfileCircle(String? imageUrl, double size) { + return Container( + width: size, + height: size, + decoration: BoxDecoration( + color: const Color(0x7FDFE1DC), + shape: BoxShape.circle, + image: imageUrl != null && imageUrl.startsWith('http') + ? DecorationImage(image: NetworkImage(imageUrl), fit: BoxFit.cover) + : (imageUrl != null + ? DecorationImage( + image: AssetImage(imageUrl), + fit: BoxFit.cover, + ) + : null), + ), + child: imageUrl == null + ? Center( + child: SvgPicture.asset( + 'assets/images/icons/default_profile_icon.svg', + width: size, + ), + ) + : null, + ); + } +} diff --git a/lib/features/social/widgets/friend_list_tile.dart b/lib/features/social/widgets/friend_list_tile.dart new file mode 100644 index 0000000..c78e64e --- /dev/null +++ b/lib/features/social/widgets/friend_list_tile.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import '../../../../core/theme/app_colors.dart'; +import '../../../../core/theme/app_typography.dart'; +import '../../../shared/models/user.dart'; + +class FriendListTile extends StatelessWidget { + final User user; + + const FriendListTile({super.key, required this.user}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + children: [ + _buildProfileCircle(user.profileUrl, 44), + const SizedBox(width: 12), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + user.nickname, + style: AppTypography.h3.copyWith(fontSize: 15), + ), + // 칭호를 보여주는 위젯 + Text( + "해냄 메이트", // 추후 칭호 기능 추가 시 연동 + style: AppTypography.c1.copyWith(color: AppColors.gray2), + ), + ], + ), + ], + ), + ); + } + + // 프로필 사진을 원형으로 보여주는 위젯 + Widget _buildProfileCircle(String? imageUrl, double size) { + return Container( + width: size, + height: size, + decoration: BoxDecoration( + color: const Color(0x7FDFE1DC), + shape: BoxShape.circle, + image: imageUrl != null && imageUrl.startsWith('http') + ? DecorationImage(image: NetworkImage(imageUrl), fit: BoxFit.cover) + : (imageUrl != null + ? DecorationImage( + image: AssetImage(imageUrl), + fit: BoxFit.cover, + ) + : null), + ), + child: imageUrl == null + ? Center( + child: SvgPicture.asset( + 'assets/images/icons/default_profile_icon.svg', + width: size, + ), + ) + : null, + ); + } +} diff --git a/lib/features/social/widgets/received_request_card.dart b/lib/features/social/widgets/received_request_card.dart new file mode 100644 index 0000000..456636f --- /dev/null +++ b/lib/features/social/widgets/received_request_card.dart @@ -0,0 +1,132 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:intl/intl.dart'; +import '../../../../core/theme/app_colors.dart'; +import '../../../../core/theme/app_typography.dart'; +import '../models/friend_request_card.dart'; + +class ReceivedRequestCard extends StatelessWidget { + final FriendRequestCard request; + final VoidCallback onAccept; + final VoidCallback onReject; + + const ReceivedRequestCard({ + super.key, + required this.request, + required this.onAccept, + required this.onReject, + }); + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 12), + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + ), + child: Column( + children: [ + Row( + children: [ + _buildProfileCircle(request.user.profileUrl, 48), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(request.user.nickname, style: AppTypography.h3), + Text( + "함께 아는 친구 0명", // 추후 데이터 연동 필요 + style: AppTypography.c1.copyWith(color: AppColors.gray2), + ), + Text( + DateFormat('yyyy년 MM월 dd일').format(request.requestDate), + style: AppTypography.c2.copyWith(color: AppColors.gray3), + ), + ], + ), + ), + ], + ), + const SizedBox(height: 16), + Row( + children: [ + Expanded( + child: _buildActionButton( + label: '거절', + bg: const Color(0x7FDFE1DC), + text: AppColors.gray2, + onTap: onReject, + ), + ), + const SizedBox(width: 10), + Expanded( + child: _buildActionButton( + label: '수락', + bg: AppColors.primaryAble, + text: Colors.white, + onTap: onAccept, + ), + ), + ], + ), + ], + ), + ); + } + + Widget _buildActionButton({ + required String label, + required Color bg, + required Color text, + required VoidCallback onTap, + }) { + return GestureDetector( + onTap: onTap, + child: Container( + height: 48, + decoration: BoxDecoration( + color: bg, + borderRadius: BorderRadius.circular(10), + ), + alignment: Alignment.center, + child: Text( + label, + style: AppTypography.b1.copyWith( + color: text, + fontWeight: FontWeight.w500, + ), + ), + ), + ); + } + + Widget _buildProfileCircle(String? imageUrl, double size) { + return Container( + width: size, + height: size, + decoration: BoxDecoration( + color: const Color(0x7FDFE1DC), + shape: BoxShape.circle, + image: imageUrl != null && imageUrl.startsWith('http') + ? DecorationImage(image: NetworkImage(imageUrl), fit: BoxFit.cover) + : (imageUrl != null + ? DecorationImage( + image: AssetImage(imageUrl), + fit: BoxFit.cover, + ) + : null), + ), + child: imageUrl == null + ? Center( + child: SvgPicture.asset( + 'assets/images/icons/default_profile_icon.svg', + width: size, + ), + ) + : null, + ); + } +} diff --git a/lib/features/social/widgets/sent_request_card.dart b/lib/features/social/widgets/sent_request_card.dart new file mode 100644 index 0000000..2d59e20 --- /dev/null +++ b/lib/features/social/widgets/sent_request_card.dart @@ -0,0 +1,120 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:intl/intl.dart'; +import '../../../../core/theme/app_colors.dart'; +import '../../../../core/theme/app_typography.dart'; +import '../models/friend_request_card.dart'; + +class SentRequestCard extends StatelessWidget { + final FriendRequestCard request; + final VoidCallback onCancel; + + const SentRequestCard({ + super.key, + required this.request, + required this.onCancel, + }); + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 12), + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + _buildProfileCircle(request.user.profileUrl, 48), + const SizedBox(width: 12), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(request.user.nickname, style: AppTypography.h3), + Text( + DateFormat('yyyy년 MM월 dd일').format(request.requestDate), + style: AppTypography.c2.copyWith( + color: AppColors.gray3, + ), + ), + ], + ), + ], + ), + _buildBadge('대기 중'), + ], + ), + const SizedBox(height: 16), + GestureDetector( + onTap: onCancel, + child: Container( + width: double.infinity, + height: 48, + decoration: BoxDecoration( + color: const Color(0x7FDFE1DC), + borderRadius: BorderRadius.circular(10), + ), + alignment: Alignment.center, + child: Text( + '요청 취소', + style: AppTypography.b1.copyWith( + color: AppColors.gray2, + fontWeight: FontWeight.w500, + ), + ), + ), + ), + ], + ), + ); + } + + Widget _buildBadge(String text) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + decoration: BoxDecoration( + color: const Color(0xFFE8F5E9), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + text, + style: const TextStyle(color: Color(0xFF444444), fontSize: 12), + ), + ); + } + + Widget _buildProfileCircle(String? imageUrl, double size) { + // ReceivedRequestCard와 동일한 프로필 이미지 로직 적용 + return Container( + width: size, + height: size, + decoration: BoxDecoration( + color: const Color(0x7FDFE1DC), + shape: BoxShape.circle, + image: imageUrl != null && imageUrl.startsWith('http') + ? DecorationImage(image: NetworkImage(imageUrl), fit: BoxFit.cover) + : (imageUrl != null + ? DecorationImage( + image: AssetImage(imageUrl), + fit: BoxFit.cover, + ) + : null), + ), + child: imageUrl == null + ? Center( + child: SvgPicture.asset( + 'assets/images/icons/default_profile_icon.svg', + width: size, + ), + ) + : null, + ); + } +} diff --git a/lib/features/social/widgets/user_search_tile.dart b/lib/features/social/widgets/user_search_tile.dart new file mode 100644 index 0000000..c51e214 --- /dev/null +++ b/lib/features/social/widgets/user_search_tile.dart @@ -0,0 +1,100 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import '../../../../core/theme/app_colors.dart'; +import '../../../../core/theme/app_typography.dart'; +import '../models/user_search_card.dart'; + +class UserSearchTile extends StatelessWidget { + final UserSearchCard searchCard; + final VoidCallback onRequest; + + const UserSearchTile({ + super.key, + required this.searchCard, + required this.onRequest, + }); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 12), + child: Row( + children: [ + _buildProfileCircle(searchCard.user.profileUrl, 44), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + searchCard.user.nickname, + style: AppTypography.h3.copyWith(fontSize: 15), + ), + Text( + "해냄 메이트", // 추후 칭호 기능 추가 시 연동 + style: AppTypography.c1.copyWith(color: AppColors.gray2), + ), + ], + ), + ), + _buildRequestButton(), + ], + ), + ); + } + + Widget _buildRequestButton() { + // 1. 이미 친구인 경우 버튼을 숨김 + if (searchCard.state == FriendState.friend) { + return const SizedBox.shrink(); + } + + // 2. 신청 대기 상태 확인 + final isRequested = searchCard.state == FriendState.pending; + + return GestureDetector( + onTap: isRequested ? null : onRequest, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + decoration: BoxDecoration( + color: isRequested ? AppColors.disable : AppColors.primaryAble, + borderRadius: BorderRadius.circular(8), + ), + child: Text( + isRequested ? '신청됨' : '친구 신청', + style: AppTypography.c1.copyWith( + color: isRequested ? AppColors.gray2 : Colors.white, + fontWeight: FontWeight.w500, + ), + ), + ), + ); + } + + Widget _buildProfileCircle(String? imageUrl, double size) { + return Container( + width: size, + height: size, + decoration: BoxDecoration( + color: const Color(0x7FDFE1DC), + shape: BoxShape.circle, + image: imageUrl != null && imageUrl.startsWith('http') + ? DecorationImage(image: NetworkImage(imageUrl), fit: BoxFit.cover) + : (imageUrl != null + ? DecorationImage( + image: AssetImage(imageUrl), + fit: BoxFit.cover, + ) + : null), + ), + child: imageUrl == null + ? Center( + child: SvgPicture.asset( + 'assets/images/icons/default_profile_icon.svg', + width: size, + ), + ) + : null, + ); + } +} diff --git a/lib/main.dart b/lib/main.dart index 5ef7a7b..61676a0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:haenaem/features/social/screens/social_screen.dart'; +import 'package:haenaem/features/social/screens/social_main_screen.dart'; import 'package:haenaem/features/user/screens/my_page_screen.dart'; import 'package:intl/date_symbol_data_local.dart'; @@ -72,7 +72,7 @@ class MyApp extends StatelessWidget { supportedLocales: const [Locale('ko', 'KR')], locale: const Locale('ko', 'KR'), // 앱 기본 언어를 한국어로 설정 //home: const ChallengeCreatePage(), - home: const AuthGate(), + //home: const AuthGate(), ); } } From 11edb823f6fb458aca1596d1539be5c2b290e7e6 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Sun, 15 Mar 2026 02:54:44 +0900 Subject: [PATCH 038/134] =?UTF-8?q?refactor:=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20=EC=9B=90=ED=98=95=20=EC=9C=84=EC=A0=AF=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../social/provider/friend_list_provider.dart | 1 + .../provider/friend_request_provider.dart | 1 + .../social/provider/user_search_provider.dart | 1 + .../social/screens/friend_add_screen.dart | 4 +- .../social/screens/friend_edit_screen.dart | 3 +- .../social/screens/social_main_screen.dart | 6 ++- .../social/views/received_request_view.dart | 1 + .../social/views/sent_request_view.dart | 1 + .../social/views/user_search_view.dart | 1 + .../social/widgets/animated_toast.dart | 2 + .../social/widgets/delete_confirm_dialog.dart | 2 + .../social/widgets/friend_edit_tile.dart | 34 +++------------ .../social/widgets/friend_list_tile.dart | 36 +++------------- .../social/widgets/received_request_card.dart | 41 ++++-------------- .../social/widgets/sent_request_card.dart | 43 +++++-------------- .../social/widgets/user_search_tile.dart | 10 +++-- lib/shared/widgets/user_profile_circle.dart | 40 +++++++++++++++++ 17 files changed, 98 insertions(+), 129 deletions(-) create mode 100644 lib/shared/widgets/user_profile_circle.dart diff --git a/lib/features/social/provider/friend_list_provider.dart b/lib/features/social/provider/friend_list_provider.dart index 881698f..5b70236 100644 --- a/lib/features/social/provider/friend_list_provider.dart +++ b/lib/features/social/provider/friend_list_provider.dart @@ -1,3 +1,4 @@ +// 최초 작성자: 정승빈 // 친구 목록 상태 및 편집 로직 import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../data/social_repository.dart'; diff --git a/lib/features/social/provider/friend_request_provider.dart b/lib/features/social/provider/friend_request_provider.dart index d789125..20d1278 100644 --- a/lib/features/social/provider/friend_request_provider.dart +++ b/lib/features/social/provider/friend_request_provider.dart @@ -1,3 +1,4 @@ +// 최초 작성자: 정승빈 // 받은/보낸 요청 상태 관리 import 'package:flutter/foundation.dart'; import 'package:dio/dio.dart'; diff --git a/lib/features/social/provider/user_search_provider.dart b/lib/features/social/provider/user_search_provider.dart index cf016d3..d77bd4b 100644 --- a/lib/features/social/provider/user_search_provider.dart +++ b/lib/features/social/provider/user_search_provider.dart @@ -1,3 +1,4 @@ +// 최초 작성자: 정승빈 // 유저 검색 상태 관리 import 'package:flutter/foundation.dart'; import 'package:dio/dio.dart'; diff --git a/lib/features/social/screens/friend_add_screen.dart b/lib/features/social/screens/friend_add_screen.dart index 1d2d81e..7845ab3 100644 --- a/lib/features/social/screens/friend_add_screen.dart +++ b/lib/features/social/screens/friend_add_screen.dart @@ -1,4 +1,4 @@ -/// 최초 작성자: 정승빈 +// 최초 작성자: 정승빈 import 'package:flutter/material.dart'; import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; @@ -16,7 +16,7 @@ class FriendAddScreen extends StatelessWidget { Widget build(BuildContext context) { return DefaultTabController( length: 3, - initialIndex: initialTabIndex, + initialIndex: initialTabIndex, // 초기 탭 인덱스 설정 child: Scaffold( backgroundColor: Colors.white, appBar: AppBar( diff --git a/lib/features/social/screens/friend_edit_screen.dart b/lib/features/social/screens/friend_edit_screen.dart index 5ed48cd..efbf14d 100644 --- a/lib/features/social/screens/friend_edit_screen.dart +++ b/lib/features/social/screens/friend_edit_screen.dart @@ -1,4 +1,4 @@ -/// 최초 작성자: 정승빈 +// 최초 작성자: 정승빈 import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -81,6 +81,7 @@ class _FriendEditScreenState extends ConsumerState { if (!mounted) return; + // 삭제 성공 시 로컬 리스트에서 제거 및 UI 업데이트 setState(() { totalList.removeWhere((u) => u.nickname == user.nickname); filterList(searchController.text); diff --git a/lib/features/social/screens/social_main_screen.dart b/lib/features/social/screens/social_main_screen.dart index e12bbcc..d3da24d 100644 --- a/lib/features/social/screens/social_main_screen.dart +++ b/lib/features/social/screens/social_main_screen.dart @@ -1,4 +1,4 @@ -/// 최초 작성자: 정승빈 +// 최초 작성자: 정승빈 import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -71,6 +71,7 @@ class _SocialMainScreenState extends ConsumerState { // 스크롤을 당기면 데이터를 강제로 다시 불러옵니다. return await ref.refresh(friendListProvider.future); }, + // 친구 목록이 비어있을 때 빈 상태 표시, 그렇지 않으면 친구 목록 표시 child: filteredFriends.isEmpty ? _buildEmptyState() : _buildFriendList(filteredFriends), @@ -89,6 +90,7 @@ class _SocialMainScreenState extends ConsumerState { ); } + // AppBar 위젯을 별도의 메서드로 분리 PreferredSizeWidget _buildAppBar(BuildContext context) { return AppBar( backgroundColor: Colors.white, @@ -113,6 +115,7 @@ class _SocialMainScreenState extends ConsumerState { ); } + // 검색 바 위젯 Widget _buildSearchBar() { return Padding( padding: const EdgeInsets.all(20), @@ -153,6 +156,7 @@ class _SocialMainScreenState extends ConsumerState { ); } + // 친구 목록 헤더 위젯 Widget _buildListHeader(int count, List totalFriends) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), diff --git a/lib/features/social/views/received_request_view.dart b/lib/features/social/views/received_request_view.dart index 5c6b2d0..ec0d311 100644 --- a/lib/features/social/views/received_request_view.dart +++ b/lib/features/social/views/received_request_view.dart @@ -1,3 +1,4 @@ +// 최초 작성자: 정승빈 import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/core/theme/app_colors.dart'; diff --git a/lib/features/social/views/sent_request_view.dart b/lib/features/social/views/sent_request_view.dart index cd89158..2079c59 100644 --- a/lib/features/social/views/sent_request_view.dart +++ b/lib/features/social/views/sent_request_view.dart @@ -1,3 +1,4 @@ +// 최초 작성자: 정승빈 import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../../core/theme/app_typography.dart'; diff --git a/lib/features/social/views/user_search_view.dart b/lib/features/social/views/user_search_view.dart index f296ad9..c7c7831 100644 --- a/lib/features/social/views/user_search_view.dart +++ b/lib/features/social/views/user_search_view.dart @@ -1,3 +1,4 @@ +// 최초 작성자: 정승빈 import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; diff --git a/lib/features/social/widgets/animated_toast.dart b/lib/features/social/widgets/animated_toast.dart index 8239528..1059467 100644 --- a/lib/features/social/widgets/animated_toast.dart +++ b/lib/features/social/widgets/animated_toast.dart @@ -1,3 +1,5 @@ +// 최초 작성자: 정승빈 + import 'package:flutter/material.dart'; import '../../../core/theme/app_typography.dart'; diff --git a/lib/features/social/widgets/delete_confirm_dialog.dart b/lib/features/social/widgets/delete_confirm_dialog.dart index 27c8727..acf282e 100644 --- a/lib/features/social/widgets/delete_confirm_dialog.dart +++ b/lib/features/social/widgets/delete_confirm_dialog.dart @@ -1,3 +1,5 @@ +// 최초 작성자: 정승빈 + import 'package:flutter/material.dart'; import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; diff --git a/lib/features/social/widgets/friend_edit_tile.dart b/lib/features/social/widgets/friend_edit_tile.dart index 57860f8..fbfd37f 100644 --- a/lib/features/social/widgets/friend_edit_tile.dart +++ b/lib/features/social/widgets/friend_edit_tile.dart @@ -1,8 +1,13 @@ +// 최초 작성자: 정승빈 + import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; + import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; + import '../../../shared/models/user.dart'; +import 'package:haenaem/shared/widgets/user_profile_circle.dart'; class FriendEditTile extends StatelessWidget { final User user; @@ -20,7 +25,7 @@ class FriendEditTile extends StatelessWidget { padding: const EdgeInsets.symmetric(vertical: 8), child: Row( children: [ - _buildProfileCircle(user.profileUrl, 44), + UserProfileCircle(imageUrl: user.profileUrl, size: 44), const SizedBox(width: 12), Expanded( child: Column( @@ -52,31 +57,4 @@ class FriendEditTile extends StatelessWidget { ), ); } - - Widget _buildProfileCircle(String? imageUrl, double size) { - return Container( - width: size, - height: size, - decoration: BoxDecoration( - color: const Color(0x7FDFE1DC), - shape: BoxShape.circle, - image: imageUrl != null && imageUrl.startsWith('http') - ? DecorationImage(image: NetworkImage(imageUrl), fit: BoxFit.cover) - : (imageUrl != null - ? DecorationImage( - image: AssetImage(imageUrl), - fit: BoxFit.cover, - ) - : null), - ), - child: imageUrl == null - ? Center( - child: SvgPicture.asset( - 'assets/images/icons/default_profile_icon.svg', - width: size, - ), - ) - : null, - ); - } } diff --git a/lib/features/social/widgets/friend_list_tile.dart b/lib/features/social/widgets/friend_list_tile.dart index c78e64e..f43316e 100644 --- a/lib/features/social/widgets/friend_list_tile.dart +++ b/lib/features/social/widgets/friend_list_tile.dart @@ -1,8 +1,12 @@ +// 최초 작성자: 정승빈 + import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; + import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; + import '../../../shared/models/user.dart'; +import 'package:haenaem/shared/widgets/user_profile_circle.dart'; class FriendListTile extends StatelessWidget { final User user; @@ -15,7 +19,7 @@ class FriendListTile extends StatelessWidget { padding: const EdgeInsets.symmetric(vertical: 8), child: Row( children: [ - _buildProfileCircle(user.profileUrl, 44), + UserProfileCircle(imageUrl: user.profileUrl, size: 44), const SizedBox(width: 12), Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -35,32 +39,4 @@ class FriendListTile extends StatelessWidget { ), ); } - - // 프로필 사진을 원형으로 보여주는 위젯 - Widget _buildProfileCircle(String? imageUrl, double size) { - return Container( - width: size, - height: size, - decoration: BoxDecoration( - color: const Color(0x7FDFE1DC), - shape: BoxShape.circle, - image: imageUrl != null && imageUrl.startsWith('http') - ? DecorationImage(image: NetworkImage(imageUrl), fit: BoxFit.cover) - : (imageUrl != null - ? DecorationImage( - image: AssetImage(imageUrl), - fit: BoxFit.cover, - ) - : null), - ), - child: imageUrl == null - ? Center( - child: SvgPicture.asset( - 'assets/images/icons/default_profile_icon.svg', - width: size, - ), - ) - : null, - ); - } } diff --git a/lib/features/social/widgets/received_request_card.dart b/lib/features/social/widgets/received_request_card.dart index 456636f..0152278 100644 --- a/lib/features/social/widgets/received_request_card.dart +++ b/lib/features/social/widgets/received_request_card.dart @@ -1,9 +1,13 @@ +// 최초 작성자: 정승빈 + import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; import 'package:intl/intl.dart'; -import '../../../../core/theme/app_colors.dart'; -import '../../../../core/theme/app_typography.dart'; -import '../models/friend_request_card.dart'; + +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; +import 'package:haenaem/shared/widgets/user_profile_circle.dart'; + +import 'package:haenaem/features/social/models/friend_request_card.dart'; class ReceivedRequestCard extends StatelessWidget { final FriendRequestCard request; @@ -30,7 +34,7 @@ class ReceivedRequestCard extends StatelessWidget { children: [ Row( children: [ - _buildProfileCircle(request.user.profileUrl, 48), + UserProfileCircle(imageUrl: request.user.profileUrl, size: 48), const SizedBox(width: 12), Expanded( child: Column( @@ -102,31 +106,4 @@ class ReceivedRequestCard extends StatelessWidget { ), ); } - - Widget _buildProfileCircle(String? imageUrl, double size) { - return Container( - width: size, - height: size, - decoration: BoxDecoration( - color: const Color(0x7FDFE1DC), - shape: BoxShape.circle, - image: imageUrl != null && imageUrl.startsWith('http') - ? DecorationImage(image: NetworkImage(imageUrl), fit: BoxFit.cover) - : (imageUrl != null - ? DecorationImage( - image: AssetImage(imageUrl), - fit: BoxFit.cover, - ) - : null), - ), - child: imageUrl == null - ? Center( - child: SvgPicture.asset( - 'assets/images/icons/default_profile_icon.svg', - width: size, - ), - ) - : null, - ); - } } diff --git a/lib/features/social/widgets/sent_request_card.dart b/lib/features/social/widgets/sent_request_card.dart index 2d59e20..d32a32c 100644 --- a/lib/features/social/widgets/sent_request_card.dart +++ b/lib/features/social/widgets/sent_request_card.dart @@ -1,8 +1,12 @@ +// 최초 작성자: 정승빈 + import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; import 'package:intl/intl.dart'; -import '../../../../core/theme/app_colors.dart'; -import '../../../../core/theme/app_typography.dart'; + +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; + +import 'package:haenaem/shared/widgets/user_profile_circle.dart'; import '../models/friend_request_card.dart'; class SentRequestCard extends StatelessWidget { @@ -32,7 +36,10 @@ class SentRequestCard extends StatelessWidget { children: [ Row( children: [ - _buildProfileCircle(request.user.profileUrl, 48), + UserProfileCircle( + imageUrl: request.user.profileUrl, + size: 48, + ), const SizedBox(width: 12), Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -89,32 +96,4 @@ class SentRequestCard extends StatelessWidget { ), ); } - - Widget _buildProfileCircle(String? imageUrl, double size) { - // ReceivedRequestCard와 동일한 프로필 이미지 로직 적용 - return Container( - width: size, - height: size, - decoration: BoxDecoration( - color: const Color(0x7FDFE1DC), - shape: BoxShape.circle, - image: imageUrl != null && imageUrl.startsWith('http') - ? DecorationImage(image: NetworkImage(imageUrl), fit: BoxFit.cover) - : (imageUrl != null - ? DecorationImage( - image: AssetImage(imageUrl), - fit: BoxFit.cover, - ) - : null), - ), - child: imageUrl == null - ? Center( - child: SvgPicture.asset( - 'assets/images/icons/default_profile_icon.svg', - width: size, - ), - ) - : null, - ); - } } diff --git a/lib/features/social/widgets/user_search_tile.dart b/lib/features/social/widgets/user_search_tile.dart index c51e214..0f4b534 100644 --- a/lib/features/social/widgets/user_search_tile.dart +++ b/lib/features/social/widgets/user_search_tile.dart @@ -1,8 +1,12 @@ +// 최초 작성자: 정승빈 + import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import '../../../../core/theme/app_colors.dart'; -import '../../../../core/theme/app_typography.dart'; -import '../models/user_search_card.dart'; + +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; + +import 'package:haenaem/features/social/models/user_search_card.dart'; class UserSearchTile extends StatelessWidget { final UserSearchCard searchCard; diff --git a/lib/shared/widgets/user_profile_circle.dart b/lib/shared/widgets/user_profile_circle.dart new file mode 100644 index 0000000..7ced4cc --- /dev/null +++ b/lib/shared/widgets/user_profile_circle.dart @@ -0,0 +1,40 @@ +// 최초 작성자: 정승빈 +// 사용자 프로필 사진을 원형으로 보여주는 위젯입니다. 이미지 URL이 제공되지 않으면 기본 아이콘이 표시됩니다. + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class UserProfileCircle extends StatelessWidget { + final String? imageUrl; + final double size; + + const UserProfileCircle({super.key, this.imageUrl, required this.size}); + + @override + Widget build(BuildContext context) { + return Container( + width: size, + height: size, + decoration: BoxDecoration( + color: const Color(0x7FDFE1DC), + shape: BoxShape.circle, + image: imageUrl != null && imageUrl!.startsWith('http') + ? DecorationImage(image: NetworkImage(imageUrl!), fit: BoxFit.cover) + : (imageUrl != null + ? DecorationImage( + image: AssetImage(imageUrl!), + fit: BoxFit.cover, + ) + : null), + ), + child: imageUrl == null + ? Center( + child: SvgPicture.asset( + 'assets/images/icons/default_profile_icon.svg', + width: size, + ), + ) + : null, + ); + } +} From 6443b1c8f0900dc08e1cd30661cf9c1631016a9b Mon Sep 17 00:00:00 2001 From: Seungvin Date: Sun, 15 Mar 2026 02:56:00 +0900 Subject: [PATCH 039/134] =?UTF-8?q?refactor:=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20=EC=9B=90=ED=98=95=20=EC=9C=84=EC=A0=AF=20=EB=B6=84=EB=A6=AC?= =?UTF-8?q?2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../social/widgets/user_search_tile.dart | 31 ++----------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/lib/features/social/widgets/user_search_tile.dart b/lib/features/social/widgets/user_search_tile.dart index 0f4b534..5888281 100644 --- a/lib/features/social/widgets/user_search_tile.dart +++ b/lib/features/social/widgets/user_search_tile.dart @@ -1,11 +1,11 @@ // 최초 작성자: 정승빈 import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; +import 'package:haenaem/shared/widgets/user_profile_circle.dart'; import 'package:haenaem/features/social/models/user_search_card.dart'; class UserSearchTile extends StatelessWidget { @@ -24,7 +24,7 @@ class UserSearchTile extends StatelessWidget { padding: const EdgeInsets.symmetric(vertical: 12), child: Row( children: [ - _buildProfileCircle(searchCard.user.profileUrl, 44), + UserProfileCircle(imageUrl: searchCard.user.profileUrl, size: 44), const SizedBox(width: 12), Expanded( child: Column( @@ -74,31 +74,4 @@ class UserSearchTile extends StatelessWidget { ), ); } - - Widget _buildProfileCircle(String? imageUrl, double size) { - return Container( - width: size, - height: size, - decoration: BoxDecoration( - color: const Color(0x7FDFE1DC), - shape: BoxShape.circle, - image: imageUrl != null && imageUrl.startsWith('http') - ? DecorationImage(image: NetworkImage(imageUrl), fit: BoxFit.cover) - : (imageUrl != null - ? DecorationImage( - image: AssetImage(imageUrl), - fit: BoxFit.cover, - ) - : null), - ), - child: imageUrl == null - ? Center( - child: SvgPicture.asset( - 'assets/images/icons/default_profile_icon.svg', - width: size, - ), - ) - : null, - ); - } } From a137e89d87134a57705c986c66e02df1c50eceb9 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Sun, 15 Mar 2026 03:13:06 +0900 Subject: [PATCH 040/134] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=ED=83=80=EC=9D=BC=20=ED=85=9C=ED=94=8C?= =?UTF-8?q?=EB=A6=BF=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../social/widgets/friend_edit_tile.dart | 46 +++++----------- .../social/widgets/friend_list_tile.dart | 29 +--------- .../social/widgets/user_search_tile.dart | 30 ++--------- lib/shared/widgets/user_list_tile.dart | 54 +++++++++++++++++++ 4 files changed, 73 insertions(+), 86 deletions(-) create mode 100644 lib/shared/widgets/user_list_tile.dart diff --git a/lib/features/social/widgets/friend_edit_tile.dart b/lib/features/social/widgets/friend_edit_tile.dart index fbfd37f..b4996a3 100644 --- a/lib/features/social/widgets/friend_edit_tile.dart +++ b/lib/features/social/widgets/friend_edit_tile.dart @@ -4,10 +4,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import '../../../../core/theme/app_colors.dart'; -import '../../../../core/theme/app_typography.dart'; import '../../../shared/models/user.dart'; -import 'package:haenaem/shared/widgets/user_profile_circle.dart'; +import 'package:haenaem/shared/widgets/user_list_tile.dart'; class FriendEditTile extends StatelessWidget { final User user; @@ -21,39 +20,18 @@ class FriendEditTile extends StatelessWidget { @override Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Row( - children: [ - UserProfileCircle(imageUrl: user.profileUrl, size: 44), - const SizedBox(width: 12), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - user.nickname, - style: AppTypography.h3.copyWith(fontSize: 15), - ), - Text( - "해냄 메이트", // 추후 칭호 연동 - style: AppTypography.c1.copyWith(color: AppColors.gray2), - ), - ], - ), + return UserListTile( + user: user, + trailing: IconButton( + onPressed: onDeleteTap, + icon: SvgPicture.asset( + 'assets/images/icons/big_trash_icon.svg', + width: 24, + colorFilter: const ColorFilter.mode( + AppColors.notification, + BlendMode.srcIn, ), - IconButton( - onPressed: onDeleteTap, - icon: SvgPicture.asset( - 'assets/images/icons/big_trash_icon.svg', - width: 24, - colorFilter: const ColorFilter.mode( - AppColors.notification, - BlendMode.srcIn, - ), - ), - ), - ], + ), ), ); } diff --git a/lib/features/social/widgets/friend_list_tile.dart b/lib/features/social/widgets/friend_list_tile.dart index f43316e..d26d311 100644 --- a/lib/features/social/widgets/friend_list_tile.dart +++ b/lib/features/social/widgets/friend_list_tile.dart @@ -2,11 +2,8 @@ import 'package:flutter/material.dart'; -import '../../../../core/theme/app_colors.dart'; -import '../../../../core/theme/app_typography.dart'; - import '../../../shared/models/user.dart'; -import 'package:haenaem/shared/widgets/user_profile_circle.dart'; +import 'package:haenaem/shared/widgets/user_list_tile.dart'; class FriendListTile extends StatelessWidget { final User user; @@ -15,28 +12,6 @@ class FriendListTile extends StatelessWidget { @override Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Row( - children: [ - UserProfileCircle(imageUrl: user.profileUrl, size: 44), - const SizedBox(width: 12), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - user.nickname, - style: AppTypography.h3.copyWith(fontSize: 15), - ), - // 칭호를 보여주는 위젯 - Text( - "해냄 메이트", // 추후 칭호 기능 추가 시 연동 - style: AppTypography.c1.copyWith(color: AppColors.gray2), - ), - ], - ), - ], - ), - ); + return UserListTile(user: user); } } diff --git a/lib/features/social/widgets/user_search_tile.dart b/lib/features/social/widgets/user_search_tile.dart index 5888281..6f04148 100644 --- a/lib/features/social/widgets/user_search_tile.dart +++ b/lib/features/social/widgets/user_search_tile.dart @@ -5,8 +5,8 @@ import 'package:flutter/material.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:haenaem/shared/widgets/user_profile_circle.dart'; import 'package:haenaem/features/social/models/user_search_card.dart'; +import 'package:haenaem/shared/widgets/user_list_tile.dart'; class UserSearchTile extends StatelessWidget { final UserSearchCard searchCard; @@ -20,30 +20,10 @@ class UserSearchTile extends StatelessWidget { @override Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 12), - child: Row( - children: [ - UserProfileCircle(imageUrl: searchCard.user.profileUrl, size: 44), - const SizedBox(width: 12), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - searchCard.user.nickname, - style: AppTypography.h3.copyWith(fontSize: 15), - ), - Text( - "해냄 메이트", // 추후 칭호 기능 추가 시 연동 - style: AppTypography.c1.copyWith(color: AppColors.gray2), - ), - ], - ), - ), - _buildRequestButton(), - ], - ), + return UserListTile( + user: searchCard.user, + padding: const EdgeInsets.symmetric(vertical: 12), // 여기만 12 + trailing: _buildRequestButton(), ); } diff --git a/lib/shared/widgets/user_list_tile.dart b/lib/shared/widgets/user_list_tile.dart new file mode 100644 index 0000000..d563614 --- /dev/null +++ b/lib/shared/widgets/user_list_tile.dart @@ -0,0 +1,54 @@ +// 최초 작성자: 정승빈 +// 유저 목록 타일 템플릿 + +import 'package:flutter/material.dart'; + +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; +import 'package:haenaem/shared/models/user.dart'; +import 'package:haenaem/shared/widgets/user_profile_circle.dart'; + +class UserListTile extends StatelessWidget { + final User user; + final Widget? trailing; // 오른쪽 끝에 달릴 위젯 (버튼, 아이콘 등) + final EdgeInsetsGeometry padding; // 위아래 여백 조정을 위해 추가 + + const UserListTile({ + super.key, + required this.user, + this.trailing, + this.padding = const EdgeInsets.symmetric(vertical: 8), // 기본값 8 + }); + + @override + Widget build(BuildContext context) { + return Padding( + padding: padding, + child: Row( + children: [ + UserProfileCircle(imageUrl: user.profileUrl, size: 44), + const SizedBox(width: 12), + Expanded( + // 오른쪽 위젯이 공간을 침범하지 않게 방어 + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + user.nickname, + style: AppTypography.b1.copyWith(color: AppColors.black), + ), + Text( + "해냄 메이트", + // TODO 추후 칭호 기능 연동 시 User 모델에서 받아오도록 수정 + style: AppTypography.c1.copyWith(color: AppColors.gray2), + ), + ], + ), + ), + // trailing으로 전달받은 위젯이 있으면 화면에 그려줌 + if (trailing != null) trailing!, + ], + ), + ); + } +} From 68baaed7059134cc9cda0d34416b7d89fbb7dff0 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Sun, 15 Mar 2026 03:16:11 +0900 Subject: [PATCH 041/134] =?UTF-8?q?fix:=20=EB=B3=B4=EB=82=B8=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=EC=B9=B4=EB=93=9C=20'=EB=8C=80=EA=B8=B0=EC=A4=91'?= =?UTF-8?q?=20=ED=91=9C=EC=8B=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../social/widgets/sent_request_card.dart | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lib/features/social/widgets/sent_request_card.dart b/lib/features/social/widgets/sent_request_card.dart index d32a32c..d160f18 100644 --- a/lib/features/social/widgets/sent_request_card.dart +++ b/lib/features/social/widgets/sent_request_card.dart @@ -55,7 +55,6 @@ class SentRequestCard extends StatelessWidget { ), ], ), - _buildBadge('대기 중'), ], ), const SizedBox(height: 16), @@ -82,18 +81,4 @@ class SentRequestCard extends StatelessWidget { ), ); } - - Widget _buildBadge(String text) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), - decoration: BoxDecoration( - color: const Color(0xFFE8F5E9), - borderRadius: BorderRadius.circular(8), - ), - child: Text( - text, - style: const TextStyle(color: Color(0xFF444444), fontSize: 12), - ), - ); - } } From 794c9a4f2ecad4a3cb94ba3d6eddfb9757616dd5 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Sun, 15 Mar 2026 03:20:41 +0900 Subject: [PATCH 042/134] =?UTF-8?q?refactor:=20=ED=86=A0=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=A9=94=EC=84=B8=EC=A7=80=20=EC=BD=94=EB=93=9C=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20shared/widgets=20=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/social/screens/friend_edit_screen.dart | 2 +- lib/features/social/views/received_request_view.dart | 2 +- lib/features/social/views/sent_request_view.dart | 2 +- lib/features/social/views/user_search_view.dart | 2 +- lib/{features/social => shared}/widgets/animated_toast.dart | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename lib/{features/social => shared}/widgets/animated_toast.dart (98%) diff --git a/lib/features/social/screens/friend_edit_screen.dart b/lib/features/social/screens/friend_edit_screen.dart index efbf14d..0d49262 100644 --- a/lib/features/social/screens/friend_edit_screen.dart +++ b/lib/features/social/screens/friend_edit_screen.dart @@ -7,7 +7,7 @@ import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; import '../../../core/utils/korean_string_utils.dart'; import '../../../shared/models/user.dart'; -import '../widgets/animated_toast.dart'; +import '../../../shared/widgets/animated_toast.dart'; import '../provider/friend_list_provider.dart'; import '../widgets/delete_confirm_dialog.dart'; import '../widgets/friend_edit_tile.dart'; diff --git a/lib/features/social/views/received_request_view.dart b/lib/features/social/views/received_request_view.dart index ec0d311..c3076eb 100644 --- a/lib/features/social/views/received_request_view.dart +++ b/lib/features/social/views/received_request_view.dart @@ -4,7 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; import '../provider/friend_request_provider.dart'; // 이전 단계에서 생성한 Provider 보낸 요청 카드 UI 위젯 -import '../widgets/animated_toast.dart'; +import '../../../shared/widgets/animated_toast.dart'; import '../widgets/received_request_card.dart'; class ReceivedRequestView extends ConsumerWidget { diff --git a/lib/features/social/views/sent_request_view.dart b/lib/features/social/views/sent_request_view.dart index 2079c59..65b878f 100644 --- a/lib/features/social/views/sent_request_view.dart +++ b/lib/features/social/views/sent_request_view.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../../core/theme/app_typography.dart'; import '../provider/friend_request_provider.dart'; -import '../widgets/animated_toast.dart'; +import '../../../shared/widgets/animated_toast.dart'; import '../widgets/sent_request_card.dart'; class SentRequestView extends ConsumerWidget { diff --git a/lib/features/social/views/user_search_view.dart b/lib/features/social/views/user_search_view.dart index c7c7831..93bb7f8 100644 --- a/lib/features/social/views/user_search_view.dart +++ b/lib/features/social/views/user_search_view.dart @@ -7,7 +7,7 @@ import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; import '../models/user_search_card.dart'; import '../provider/user_search_provider.dart'; -import '../widgets/animated_toast.dart'; +import '../../../shared/widgets/animated_toast.dart'; import '../widgets/user_search_tile.dart'; class UserSearchView extends ConsumerStatefulWidget { diff --git a/lib/features/social/widgets/animated_toast.dart b/lib/shared/widgets/animated_toast.dart similarity index 98% rename from lib/features/social/widgets/animated_toast.dart rename to lib/shared/widgets/animated_toast.dart index 1059467..f681511 100644 --- a/lib/features/social/widgets/animated_toast.dart +++ b/lib/shared/widgets/animated_toast.dart @@ -1,7 +1,7 @@ // 최초 작성자: 정승빈 import 'package:flutter/material.dart'; -import '../../../core/theme/app_typography.dart'; +import '../../core/theme/app_typography.dart'; // 토스트를 띄우기 위한 공통 함수 void displayToast(BuildContext context, String message) { From 22e1e3afebb369bade17ddcfa4996ab76d970281 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Sun, 15 Mar 2026 03:35:38 +0900 Subject: [PATCH 043/134] =?UTF-8?q?refactor:=20=EA=B2=80=EC=83=89=EC=B0=BD?= =?UTF-8?q?=20=EC=9C=84=EC=A0=AF=20=EB=B6=84=EB=A6=AC=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../social/screens/friend_edit_screen.dart | 41 ++---------- .../social/screens/social_main_screen.dart | 38 ++--------- .../social/views/user_search_view.dart | 41 ++---------- lib/shared/widgets/custom_search_bar.dart | 65 +++++++++++++++++++ 4 files changed, 81 insertions(+), 104 deletions(-) create mode 100644 lib/shared/widgets/custom_search_bar.dart diff --git a/lib/features/social/screens/friend_edit_screen.dart b/lib/features/social/screens/friend_edit_screen.dart index 0d49262..217660b 100644 --- a/lib/features/social/screens/friend_edit_screen.dart +++ b/lib/features/social/screens/friend_edit_screen.dart @@ -1,7 +1,6 @@ // 최초 작성자: 정승빈 import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_svg/flutter_svg.dart'; import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; @@ -11,6 +10,7 @@ import '../../../shared/widgets/animated_toast.dart'; import '../provider/friend_list_provider.dart'; import '../widgets/delete_confirm_dialog.dart'; import '../widgets/friend_edit_tile.dart'; +import 'package:haenaem/shared/widgets/custom_search_bar.dart'; class FriendEditScreen extends ConsumerStatefulWidget { final List initialFriends; // 초기 친구 목록을 전달받는 매개변수 @@ -130,44 +130,15 @@ class _FriendEditScreenState extends ConsumerState { ); } + // 검색창 영역 빌드 // 검색창 영역 빌드 Widget _buildSearchHeader() { return Padding( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), - child: Container( - height: 40, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(10), - border: Border.all(color: AppColors.gray4), - ), - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/icons/search_icon.svg', - width: 18, - colorFilter: const ColorFilter.mode( - AppColors.gray3, - BlendMode.srcIn, - ), - ), - const SizedBox(width: 8), - Expanded( - child: TextField( - controller: searchController, - onChanged: filterList, - decoration: const InputDecoration( - hintText: '친구 검색', - hintStyle: AppTypography.b2, - border: InputBorder.none, - isDense: true, - ), - style: AppTypography.b2, - ), - ), - ], - ), + child: CustomSearchBar( + controller: searchController, + hintText: '친구 검색', + onChanged: filterList, ), ); } diff --git a/lib/features/social/screens/social_main_screen.dart b/lib/features/social/screens/social_main_screen.dart index d3da24d..fea851e 100644 --- a/lib/features/social/screens/social_main_screen.dart +++ b/lib/features/social/screens/social_main_screen.dart @@ -11,6 +11,7 @@ import '../provider/friend_list_provider.dart'; import '../widgets/friend_list_tile.dart'; import 'friend_add_screen.dart'; import 'friend_edit_screen.dart'; +import 'package:haenaem/shared/widgets/custom_search_bar.dart'; class SocialMainScreen extends ConsumerStatefulWidget { const SocialMainScreen({super.key}); @@ -119,39 +120,10 @@ class _SocialMainScreenState extends ConsumerState { Widget _buildSearchBar() { return Padding( padding: const EdgeInsets.all(20), - child: Container( - height: 40, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - border: Border.all(color: AppColors.gray4), - ), - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/icons/search_icon.svg', - width: 18, - colorFilter: const ColorFilter.mode( - AppColors.gray3, - BlendMode.srcIn, - ), - ), - const SizedBox(width: 8), - Expanded( - child: TextField( - controller: searchController, - onChanged: (value) => setState(() => searchQuery = value), - decoration: const InputDecoration( - hintText: '친구 검색', - hintStyle: AppTypography.b2, - border: InputBorder.none, - isDense: true, - ), - style: AppTypography.b1, - ), - ), - ], - ), + child: CustomSearchBar( + controller: searchController, + hintText: '친구 검색', + onChanged: (value) => setState(() => searchQuery = value), ), ); } diff --git a/lib/features/social/views/user_search_view.dart b/lib/features/social/views/user_search_view.dart index 93bb7f8..f1f4d9f 100644 --- a/lib/features/social/views/user_search_view.dart +++ b/lib/features/social/views/user_search_view.dart @@ -1,14 +1,13 @@ // 최초 작성자: 정승빈 import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; import '../models/user_search_card.dart'; import '../provider/user_search_provider.dart'; import '../../../shared/widgets/animated_toast.dart'; import '../widgets/user_search_tile.dart'; +import 'package:haenaem/shared/widgets/custom_search_bar.dart'; class UserSearchView extends ConsumerStatefulWidget { const UserSearchView({super.key}); @@ -91,40 +90,10 @@ class _UserSearchViewState extends ConsumerState { Widget _buildSearchInputSection() { return Padding( padding: const EdgeInsets.all(20), - child: Container( - height: 40, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - border: Border.all(color: AppColors.gray4), - ), - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/icons/search_icon.svg', - width: 18, - colorFilter: const ColorFilter.mode( - AppColors.gray3, - BlendMode.srcIn, - ), - ), - const SizedBox(width: 8), - Expanded( - child: TextField( - controller: searchController, - onSubmitted: (_) => performSearch(), - textInputAction: TextInputAction.search, - decoration: const InputDecoration( - hintText: '닉네임을 검색하세요', - hintStyle: AppTypography.b2, - border: InputBorder.none, - isDense: true, - ), - style: AppTypography.b1, - ), - ), - ], - ), + child: CustomSearchBar( + controller: searchController, + hintText: '닉네임을 검색하세요', + onSubmitted: (_) => performSearch(), // onChanged 대신 엔터를 쳤을 때 작동 ), ); } diff --git a/lib/shared/widgets/custom_search_bar.dart b/lib/shared/widgets/custom_search_bar.dart new file mode 100644 index 0000000..1d2bd20 --- /dev/null +++ b/lib/shared/widgets/custom_search_bar.dart @@ -0,0 +1,65 @@ +// 최초 작성자: 정승빈 +// 검색창 위젯 + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; + +class CustomSearchBar extends StatelessWidget { + final TextEditingController controller; + final String hintText; + final ValueChanged? onChanged; + final ValueChanged? onSubmitted; + final TextInputAction textInputAction; + + const CustomSearchBar({ + super.key, + required this.controller, + this.hintText = '검색', + this.onChanged, + this.onSubmitted, + this.textInputAction = TextInputAction.search, + }); + + @override + Widget build(BuildContext context) { + return Container( + height: 40, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + border: Border.all(color: AppColors.gray4), + ), + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/icons/search_icon.svg', + width: 18, + colorFilter: const ColorFilter.mode( + AppColors.gray3, + BlendMode.srcIn, + ), + ), + const SizedBox(width: 8), + Expanded( + child: TextField( + controller: controller, + onChanged: onChanged, + onSubmitted: onSubmitted, + textInputAction: textInputAction, + decoration: InputDecoration( + hintText: hintText, + hintStyle: AppTypography.b2, + border: InputBorder.none, + isDense: true, + ), + style: AppTypography.b1, // 텍스트 크기 통일 + ), + ), + ], + ), + ); + } +} From 01752e7f3ee0373beeff913836a6ea810656a573 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Sun, 15 Mar 2026 03:44:27 +0900 Subject: [PATCH 044/134] =?UTF-8?q?feat:=20=EB=B0=9B=EC=9D=80=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=EB=B7=B0=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EC=83=88?= =?UTF-8?q?=EB=A1=9C=EA=B3=A0=EC=B9=A8=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../social/views/received_request_view.dart | 2 +- .../social/views/sent_request_view.dart | 50 +++++++++++-------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/lib/features/social/views/received_request_view.dart b/lib/features/social/views/received_request_view.dart index c3076eb..9a13cf2 100644 --- a/lib/features/social/views/received_request_view.dart +++ b/lib/features/social/views/received_request_view.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; -import '../provider/friend_request_provider.dart'; // 이전 단계에서 생성한 Provider 보낸 요청 카드 UI 위젯 +import '../provider/friend_request_provider.dart'; import '../../../shared/widgets/animated_toast.dart'; import '../widgets/received_request_card.dart'; diff --git a/lib/features/social/views/sent_request_view.dart b/lib/features/social/views/sent_request_view.dart index 65b878f..b06c751 100644 --- a/lib/features/social/views/sent_request_view.dart +++ b/lib/features/social/views/sent_request_view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../../core/theme/app_typography.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; import '../provider/friend_request_provider.dart'; import '../../../shared/widgets/animated_toast.dart'; import '../widgets/sent_request_card.dart'; @@ -22,27 +23,36 @@ class SentRequestView extends ConsumerWidget { child: Text('보낸 요청이 없습니다.', style: AppTypography.b2), ); } - return ListView.builder( - padding: const EdgeInsets.all(16), - itemCount: requests.length, - itemBuilder: (context, index) { - final req = requests[index]; - return SentRequestCard( - request: req, - onCancel: () async { - try { - await ref - .read(sentRequestsProvider.notifier) - .cancelRequest(req.requestId); - if (context.mounted) { - displayToast(context, '친구 신청을 취소했습니다.'); - } - } catch (e) { - if (context.mounted) displayToast(context, '취소에 실패했습니다.'); - } - }, - ); + return RefreshIndicator( + color: AppColors.primaryAble, + onRefresh: () async { + // 새로고침 시 Provider의 Future를 다시 호출하여 최신 데이터 가져오기 + return await ref.refresh(sentRequestsProvider.future); }, + child: ListView.builder( + padding: const EdgeInsets.all(16), + itemCount: requests.length, + itemBuilder: (context, index) { + final req = requests[index]; + return SentRequestCard( + request: req, + onCancel: () async { + try { + await ref + .read(sentRequestsProvider.notifier) + .cancelRequest(req.requestId); + if (context.mounted) { + displayToast(context, '친구 신청을 취소했습니다.'); + } + } catch (e) { + if (context.mounted) displayToast(context, '취소에 실패했습니다.'); + } + }, + ); + }, + // 항상 스크롤 가능하도록 설정 (요청이 1개 이하일 때도 당겨서 새로고침 가능) + physics: const AlwaysScrollableScrollPhysics(), + ), ); }, loading: () => const Center(child: CircularProgressIndicator()), From e280e0f803a7fe331472d381a478ed0a1edcbf6b Mon Sep 17 00:00:00 2001 From: Seungvin Date: Sun, 15 Mar 2026 21:55:13 +0900 Subject: [PATCH 045/134] =?UTF-8?q?fix:=20=EC=9C=A0=EC=A0=80=20=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EC=B9=9C=EA=B5=AC?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20=ED=8E=B8=EC=A7=91=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/social/screens/social_main_screen.dart | 4 ++++ lib/main.dart | 2 +- lib/shared/models/user.dart | 10 ++++++---- lib/shared/widgets/user_list_tile.dart | 2 ++ lib/shared/widgets/user_profile_circle.dart | 3 +++ 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/features/social/screens/social_main_screen.dart b/lib/features/social/screens/social_main_screen.dart index fea851e..1c69b8d 100644 --- a/lib/features/social/screens/social_main_screen.dart +++ b/lib/features/social/screens/social_main_screen.dart @@ -108,6 +108,8 @@ class _SocialMainScreenState extends ConsumerState { MaterialPageRoute(builder: (context) => const FriendAddScreen()), ); + if (!mounted) return; + // 화면이 닫히고 돌아오면 친구 목록 Provider를 강제로 새로고침 ref.invalidate(friendListProvider); }, @@ -147,6 +149,8 @@ class _SocialMainScreenState extends ConsumerState { ), ); + if (!mounted) return; + // 편집 화면에서 돌아오면 친구 목록 새로고침 (삭제 반영) ref.invalidate(friendListProvider); }, diff --git a/lib/main.dart b/lib/main.dart index 61676a0..432bda4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -72,7 +72,7 @@ class MyApp extends StatelessWidget { supportedLocales: const [Locale('ko', 'KR')], locale: const Locale('ko', 'KR'), // 앱 기본 언어를 한국어로 설정 //home: const ChallengeCreatePage(), - //home: const AuthGate(), + home: const AuthGate(), ); } } diff --git a/lib/shared/models/user.dart b/lib/shared/models/user.dart index ca93ced..2618915 100644 --- a/lib/shared/models/user.dart +++ b/lib/shared/models/user.dart @@ -2,7 +2,7 @@ // 사용자 정보를 저장하는 모델 클래스 class User { - final String id; + final int id; final String? profileUrl; final String nickname; @@ -11,14 +11,16 @@ class User { // API 데이터와 모델 클래스 데이터 매핑 factory User.fromJson(Map json) { return User( - id: json['id'] as String, - profileUrl: json['profile_url'] as String?, + id: json['id'] is int + ? json['id'] + : int.tryParse(json['id'].toString()) ?? 0, + profileUrl: json['profileImageUrl'] as String?, nickname: json['nickname'] as String, ); } // 특정 필드만 변경하여 새 User 객체를 반환하는 메서드 - User copyWith({String? id, String? profileUrl, String? nickname}) { + User copyWith({int? id, String? profileUrl, String? nickname}) { return User( id: id ?? this.id, profileUrl: profileUrl ?? this.profileUrl, diff --git a/lib/shared/widgets/user_list_tile.dart b/lib/shared/widgets/user_list_tile.dart index d563614..1903563 100644 --- a/lib/shared/widgets/user_list_tile.dart +++ b/lib/shared/widgets/user_list_tile.dart @@ -37,11 +37,13 @@ class UserListTile extends StatelessWidget { user.nickname, style: AppTypography.b1.copyWith(color: AppColors.black), ), + /* Text( "해냄 메이트", // TODO 추후 칭호 기능 연동 시 User 모델에서 받아오도록 수정 style: AppTypography.c1.copyWith(color: AppColors.gray2), ), + */ ], ), ), diff --git a/lib/shared/widgets/user_profile_circle.dart b/lib/shared/widgets/user_profile_circle.dart index 7ced4cc..a140d65 100644 --- a/lib/shared/widgets/user_profile_circle.dart +++ b/lib/shared/widgets/user_profile_circle.dart @@ -12,6 +12,9 @@ class UserProfileCircle extends StatelessWidget { @override Widget build(BuildContext context) { + // 🔥 디버깅용 콘솔 출력 추가: 어떤 URL 값이 들어오는지 확인 + debugPrint('UserProfileCircle - 전달받은 imageUrl: $imageUrl'); + return Container( width: size, height: size, From e21a4206d47c4fa8b9b2253570985a1ea1d28ce3 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Mon, 16 Mar 2026 03:01:15 +0900 Subject: [PATCH 046/134] =?UTF-8?q?refactor:=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20=ED=8E=B8=EC=A7=91=20=EC=8A=A4=ED=81=AC=EB=A6=B0=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=B9=84=EC=A6=88=EB=8B=88=EC=A6=88=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=B6=84=EB=A6=AC,=20=EC=B1=8C=EB=A6=B0=EC=A7=80?= =?UTF-8?q?=20=EC=B9=B4=EB=93=9C=20UI=20=ED=86=B5=ED=95=A9=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/provider/user_profile_provider.dart | 74 ++++ .../provider/user_profile_provider.g.dart | 26 ++ .../user/screens/challenge_list_screen.dart | 294 +-------------- .../user/screens/profile_edit_screen.dart | 77 ++-- .../user/widgets/challenge_section.dart | 352 +----------------- .../user/widgets/my_challenge_card.dart | 194 ++++++++++ 6 files changed, 329 insertions(+), 688 deletions(-) create mode 100644 lib/features/user/provider/user_profile_provider.dart create mode 100644 lib/features/user/provider/user_profile_provider.g.dart create mode 100644 lib/features/user/widgets/my_challenge_card.dart diff --git a/lib/features/user/provider/user_profile_provider.dart b/lib/features/user/provider/user_profile_provider.dart new file mode 100644 index 0000000..33791e7 --- /dev/null +++ b/lib/features/user/provider/user_profile_provider.dart @@ -0,0 +1,74 @@ +// 최초 작성자: 정승빈 +// 프로필 조회, 수정, 이미지 업로드/삭제 로직 전담 (Fat UI 해결) +// 최초 작성자: 정승빈 +import 'dart:io'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import '../data/user_repository.dart'; +import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; // myProfileProvider 무효화를 위해 +import 'tag_provider.dart'; + +part 'user_profile_provider.g.dart'; + +@riverpod +class UserProfile extends _$UserProfile { + @override + FutureOr build() { + // 초기 상태는 아무 작업도 하지 않은 상태 + } + + // 1. 프로필 이미지 즉시 삭제 + Future deleteProfileImage() async { + state = const AsyncValue.loading(); + try { + await ref.read(userRepositoryProvider).deleteProfileImage(); + ref.invalidate(myProfileProvider); // 마이페이지 프로필 상태 갱신 + state = const AsyncValue.data(null); + } catch (e, stack) { + state = AsyncValue.error(e, stack); + rethrow; + } + } + + // 2. 프로필 최종 저장 (닉네임, 한줄소개, 새 이미지, 태그) + Future updateProfile({ + required String currentNickname, + required String newNickname, + required String currentIntro, + required String newIntro, + File? newImageFile, + }) async { + state = const AsyncValue.loading(); + try { + final userRepo = ref.read(userRepositoryProvider); + final tagNotifier = ref.read(tagProvider.notifier); + + // 1) 닉네임 변경 + if (newNickname != currentNickname) { + await userRepo.updateNickname(newNickname); + } + + // 2) 한 줄 소개 변경 + if (newIntro != currentIntro) { + await userRepo.updateIntroduction(newIntro); + } + + // 3) 프로필 이미지 변경 + if (newImageFile != null) { + await userRepo.uploadProfileImage(newImageFile); + } + + // 4) 태그 업데이트 + final tagSuccess = await tagNotifier.updateInterestTags(); + if (!tagSuccess) { + throw Exception('태그 수정 중 오류가 발생했습니다.'); + } + + // 5) 성공 시 마이페이지 갱신 + ref.invalidate(myProfileProvider); + state = const AsyncValue.data(null); + } catch (e, stack) { + state = AsyncValue.error(e, stack); + rethrow; // UI에서 예외 메시지를 띄우기 위해 에러를 위로 던짐 + } + } +} diff --git a/lib/features/user/provider/user_profile_provider.g.dart b/lib/features/user/provider/user_profile_provider.g.dart new file mode 100644 index 0000000..9939d5d --- /dev/null +++ b/lib/features/user/provider/user_profile_provider.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user_profile_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$userProfileHash() => r'63c409bf957bfbccdab141e1a960bb512bf8193e'; + +/// See also [UserProfile]. +@ProviderFor(UserProfile) +final userProfileProvider = + AutoDisposeAsyncNotifierProvider.internal( + UserProfile.new, + name: r'userProfileProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$userProfileHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$UserProfile = AutoDisposeAsyncNotifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/user/screens/challenge_list_screen.dart b/lib/features/user/screens/challenge_list_screen.dart index 1c489ab..c86f39c 100644 --- a/lib/features/user/screens/challenge_list_screen.dart +++ b/lib/features/user/screens/challenge_list_screen.dart @@ -1,23 +1,19 @@ -/// 최초 작성자: 정승빈 -/// 작성일: 2026-02-03 -library; - +// 최초 작성자: 정승빈 import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; +import '../widgets/my_challenge_card.dart'; // 💡 공통 카드 위젯 추가 -/// 클래스의 용도: 챌린지 목록을 진행중, 완료, 실패 탭으로 구분하여 보여주는 화면 +// 클래스의 용도: 챌린지 목록을 진행중, 완료, 실패 탭으로 구분하여 보여주는 화면 class ChallengeListScreen extends ConsumerWidget { const ChallengeListScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { - // 세 가지 API 모두 구독 (전체 목록을 위해 onlyTwo: false) final inProgressAsync = ref.watch( myInProgressChallengesProvider(onlyTwo: false), ); @@ -57,7 +53,6 @@ class ChallengeListScreen extends ConsumerWidget { color: AppColors.gray5, child: TabBarView( children: [ - // 1. 진행중 탭 inProgressAsync.when( data: (list) => _buildFilteredListView(list, "IN_PROGRESS"), @@ -65,14 +60,12 @@ class ChallengeListScreen extends ConsumerWidget { const Center(child: CircularProgressIndicator()), error: (err, __) => Center(child: Text('로드 실패: $err')), ), - // 2. 완료 탭 successAsync.when( data: (list) => _buildFilteredListView(list, "SUCCESS"), loading: () => const Center(child: CircularProgressIndicator()), error: (err, __) => Center(child: Text('로드 실패: $err')), ), - // 3. 실패 탭 failedAsync.when( data: (list) => _buildFilteredListView(list, "FAIL"), loading: () => @@ -108,7 +101,6 @@ class ChallengeListScreen extends ConsumerWidget { ); } - // 상태별 리스트 필터링 및 출력 Widget _buildFilteredListView( List list, String tabStatus, @@ -127,285 +119,7 @@ class ChallengeListScreen extends ConsumerWidget { padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), itemCount: filtered.length, separatorBuilder: (_, __) => const SizedBox(height: 12), - itemBuilder: (context, index) => _buildFullChallengeCard(filtered[index]), - ); - } - - // 마이페이지와 디자인을 통일한 챌린지 카드 - Widget _buildFullChallengeCard(ChallengeInProgressModel item) { - final serverStatus = item.status.toUpperCase(); - - // 1. 실패 상태일 때 (빨간 테마 + 실패일 + 최대 일수 + 불 아이콘) - if (serverStatus == "FAIL" || serverStatus == "FAILED") { - return _buildSyncFailedCard(item); - } - - // 2. 완료 상태일 때 (초록 테마 + 완료일 + 총 진행일 + 불 아이콘) - if (serverStatus == "SUCCESS") { - return _buildSyncSuccessCard(item); - } - - // 3. 진행 중일 때 (기본 디자인) - return _buildSyncInProgressCard(item); - } - - Widget _buildSyncFailedCard(ChallengeInProgressModel item) { - const Color failColor = AppColors.notification; - return Container( - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - border: Border.all(color: AppColors.gray5, width: 0.69), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Flexible( - child: Text( - item.title, - style: AppTypography.b3.copyWith( - color: AppColors.black, - ), - overflow: TextOverflow.ellipsis, // 길면 생략 - maxLines: 1, - ), - ), - const SizedBox(width: 7.35), - _buildStatusBadge('실패', failColor), - ], - ), - const SizedBox(height: 2), - Text( - '실패일 ${item.endDate.replaceAll('-', '/')}', - style: AppTypography.b2.copyWith(color: AppColors.gray2), - ), - const SizedBox(height: 2), - Row( - children: [ - SvgPicture.asset( - 'assets/images/icons/small_fire_icon.svg', - width: 16, - ), - const SizedBox(width: 2), - Text( - '최대 ${item.duringDate}일', - style: AppTypography.b2.copyWith( - color: AppColors.black, - ), - ), - ], - ), - ], - ), - ), - _buildProgressText(item.progress, failColor), - ], - ), - const SizedBox(height: 8), - _buildGaugeBar(item.progress, failColor), - ], - ), - ); - } - - Widget _buildSyncSuccessCard(ChallengeInProgressModel item) { - const Color successColor = AppColors.primaryAble; - return Container( - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - border: Border.all(color: AppColors.gray5, width: 0.69), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Flexible( - child: Text( - item.title, - style: AppTypography.b3.copyWith( - color: AppColors.black, - ), - overflow: TextOverflow.ellipsis, // 길면 생략 - maxLines: 1, - ), - ), - const SizedBox(width: 7.35), - _buildStatusBadge('완료', successColor), - ], - ), - const SizedBox(height: 2), - Text( - '완료일 ${item.endDate.replaceAll('-', '/')}', - style: AppTypography.b2.copyWith(color: AppColors.gray2), - ), - const SizedBox(height: 2), - Row( - children: [ - SvgPicture.asset( - 'assets/images/icons/small_fire_icon.svg', - width: 16, - ), - const SizedBox(width: 2), - Text( - '총 ${item.duringDate}일', - style: AppTypography.b2.copyWith( - color: AppColors.black, - ), - ), - ], - ), - ], - ), - ), - _buildProgressText(item.progress, successColor), - ], - ), - const SizedBox(height: 8), - _buildGaugeBar(item.progress, successColor), - ], - ), - ); - } - - Widget _buildSyncInProgressCard(ChallengeInProgressModel item) { - const Color inProgressColor = AppColors.blue; - return Container( - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Flexible( - child: Text( - item.title, - style: AppTypography.b3.copyWith( - color: AppColors.black, - ), - overflow: TextOverflow.ellipsis, // 길면 생략 - maxLines: 1, - ), - ), - const SizedBox(width: 7.35), - _buildStatusBadge('진행중', inProgressColor), - ], - ), - const SizedBox(height: 3), - Text( - item.dateInfo, - style: AppTypography.b2.copyWith(color: AppColors.gray2), - ), - ], - ), - ), - _buildProgressText(item.progress, inProgressColor), - ], - ), - const SizedBox(height: 8), - _buildInProgressInfoRow(item), - const SizedBox(height: 8), - _buildGaugeBar(item.progress, inProgressColor), - ], - ), - ); - } - // --- 헬퍼 위젯들 --- - - Widget _buildStatusBadge(String text, Color color) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), - decoration: ShapeDecoration( - color: color.withOpacity(0.1), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), - ), - child: Text(text, style: AppTypography.c1.copyWith(color: color)), - ); - } - - Widget _buildProgressText(double progress, Color color) { - return Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Text( - '${(progress * 100).toInt()}%', - style: AppTypography.h2.copyWith(color: color), - ), - Text('달성률', style: AppTypography.c1.copyWith(color: AppColors.gray2)), - ], - ); - } - - Widget _buildInProgressInfoRow(ChallengeInProgressModel item) { - return Row( - children: [ - SvgPicture.asset('assets/images/icons/small_fire_icon.svg', width: 16), - const SizedBox(width: 4), - Text( - '${item.duringDate}일째', - style: AppTypography.b2.copyWith(color: AppColors.black), - ), - const SizedBox(width: 12), - SvgPicture.asset( - 'assets/images/icons/mini_success_icon.svg', - width: 16, - ), - const SizedBox(width: 4), - Text( - item.countInfo, - style: AppTypography.b2.copyWith(color: AppColors.black), - ), - ], - ); - } - - Widget _buildGaugeBar(double progress, Color color) { - return ClipRRect( - borderRadius: BorderRadius.circular(23), - child: LinearProgressIndicator( - value: progress, - minHeight: 4, - backgroundColor: AppColors.gray5, - valueColor: AlwaysStoppedAnimation(color), - ), + itemBuilder: (context, index) => MyChallengeCard(item: filtered[index]), ); } } diff --git a/lib/features/user/screens/profile_edit_screen.dart b/lib/features/user/screens/profile_edit_screen.dart index c3d2315..81725af 100644 --- a/lib/features/user/screens/profile_edit_screen.dart +++ b/lib/features/user/screens/profile_edit_screen.dart @@ -1,4 +1,5 @@ // 최초 작성자 : 김채영 +// 최초 작성자 : 김채영, 리팩토링: 정승빈 import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -7,15 +8,14 @@ import 'package:image_picker/image_picker.dart'; import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; import 'package:haenaem/features/user/models/user_model.dart'; -import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/shared/models/tag_data.dart'; import 'package:haenaem/shared/widgets/app_tag_chip.dart'; import 'package:haenaem/shared/widgets/image_source_sheet.dart'; import '../../../../shared/widgets/bottom_action_button.dart'; import 'package:haenaem/features/auth/signup/screens/profile_image_edit_screen.dart'; import '../widgets/profile_image_menu.dart'; -import '../data/user_repository.dart'; import '../provider/tag_provider.dart'; +import '../provider/user_profile_provider.dart'; // 프로필 편집 화면 class ProfileEditScreen extends ConsumerStatefulWidget { @@ -31,7 +31,7 @@ class _ProfileEditScreenState extends ConsumerState { late TextEditingController _introController; bool _showImageMenu = false; // 이미지 관리 메뉴 노출 상태 File? _selectedImageFile; - bool _isImageDeleted = false; // 이미지 삭제 여부를 추적하는 상태 추가 + bool _isImageDeleted = false; // 이미지 삭제 여부를 추적하는 상태 final ImagePicker _picker = ImagePicker(); bool _isDuplicate = false; bool _isInvalidFormat = false; @@ -45,7 +45,7 @@ class _ProfileEditScreenState extends ConsumerState { _nicknameController.addListener(_validateNickname); _introController.addListener(() => setState(() {})); - // 2. 💡 추가: 화면 진입 시 tagProvider 초기화 호출 + // 화면 진입 시 tagProvider 초기화 호출 Future.microtask(() => ref.read(tagProvider.notifier).initialize()); } @@ -56,7 +56,7 @@ class _ProfileEditScreenState extends ConsumerState { super.dispose(); } - // --- 💡 이미지 소스 선택 (카메라/갤러리) --- + // --- 이미지 소스 선택 (카메라/갤러리) --- void _showImageSourceSheet() { setState(() => _showImageMenu = false); // 팝업 메뉴 닫기 showModalBottomSheet( @@ -68,7 +68,7 @@ class _ProfileEditScreenState extends ConsumerState { ); } - // --- 💡 이미지 가져오기 및 편집 화면 이동 --- + // --- 이미지 가져오기 및 편집 화면 이동 --- Future _getImage(ImageSource source) async { final XFile? pickedFile = await _picker.pickImage(source: source); @@ -93,22 +93,21 @@ class _ProfileEditScreenState extends ConsumerState { } } - // --- 💡 이미지 삭제 API 연동 --- + // --- 💡 이미지 삭제: 로직을 Provider로 위임 --- Future _handleDeleteImage() async { try { - await ref.read(userRepositoryProvider).deleteProfileImage(); + await ref.read(userProfileProvider.notifier).deleteProfileImage(); setState(() { _selectedImageFile = null; _isImageDeleted = true; _showImageMenu = false; }); - ref.invalidate(myProfileProvider); } catch (e) { debugPrint('삭제 실패: $e'); } } - // 💡 닉네임 실시간 유효성 검사 (회원가입 로직 이식) + // 닉네임 실시간 유효성 검사 void _validateNickname() { final text = _nicknameController.text; setState(() { @@ -123,38 +122,20 @@ class _ProfileEditScreenState extends ConsumerState { }); } - // --- 💡 최종 저장 로직 (POST 이미지 포함) --- + // --- 💡 최종 저장: 복잡한 API 호출을 모두 Provider로 위임 --- Future _handleSave() async { try { - final userRepo = ref.read(userRepositoryProvider); - final tagNotifier = ref.read(tagProvider.notifier); - - // 로딩바 등을 보여줄 수 있는 로직 추가 가능 (예: 다이얼로그) - - // 1. 닉네임 변경 체크 및 실행 - if (_nicknameController.text != widget.profile.nickname) { - await userRepo.updateNickname(_nicknameController.text); - } - - // 2. 💡 한 줄 소개 변경 체크 및 실행 - if (_introController.text != widget.profile.introduction) { - await userRepo.updateIntroduction(_introController.text); - } - - // 3. 이미지 변경 체크 및 실행 - if (_selectedImageFile != null) { - await userRepo.uploadProfileImage(_selectedImageFile!); - } - - final tagSuccess = await tagNotifier.updateInterestTags(); - - if (!tagSuccess) { - throw Exception('태그 수정 중 오류가 발생했습니다.'); - } + await ref + .read(userProfileProvider.notifier) + .updateProfile( + currentNickname: widget.profile.nickname, + newNickname: _nicknameController.text, + currentIntro: widget.profile.introduction, + newIntro: _introController.text, + newImageFile: _selectedImageFile, + ); - // 4. 모든 작업 성공 시 처리 if (mounted) { - ref.invalidate(myProfileProvider); // 마이페이지 정보 갱신 Navigator.pop(context); ScaffoldMessenger.of( context, @@ -162,7 +143,7 @@ class _ProfileEditScreenState extends ConsumerState { } } catch (e) { final errorMsg = e.toString(); - // 닉네임 중복 등의 에러는 기존처럼 setState로 에러 메시지 노출 + // 닉네임 중복 에러 처리 if (errorMsg.contains('DUPLICATE')) { setState(() => _isDuplicate = true); } else { @@ -178,14 +159,19 @@ class _ProfileEditScreenState extends ConsumerState { @override Widget build(BuildContext context) { final tagState = ref.watch(tagProvider); + final profileEditState = ref.watch(userProfileProvider); // 💡 프로필 저장 상태 구독 + final selectedTagsFromProvider = tagState.tags; final bool isNicknameValid = _nicknameController.text.isNotEmpty && !_isInvalidFormat; + + // 💡 Provider가 작업 중(loading)일 때는 저장 버튼을 비활성화하여 중복 터치 방지 final bool isEnabled = isNicknameValid && selectedTagsFromProvider.length >= 2 && selectedTagsFromProvider.length <= 6 && - !tagState.isLoading; + !tagState.isLoading && + !profileEditState.isLoading; return Scaffold( backgroundColor: Colors.white, @@ -221,7 +207,6 @@ class _ProfileEditScreenState extends ConsumerState { ), ), - // 💡 닫기 레이어와 팝업 메뉴를 본문(Layer 1) 안의 Stack으로 옮겼습니다. if (_showImageMenu) ...[ Positioned.fill( child: GestureDetector( @@ -262,7 +247,6 @@ class _ProfileEditScreenState extends ConsumerState { ); } - // --- 프로필 이미지 섹션 (Positioned 포함) --- Widget _buildProfileImageSection() { return Center( child: SizedBox( @@ -283,10 +267,8 @@ class _ProfileEditScreenState extends ConsumerState { 'assets/images/placeholders/default_profile.svg', ) // 1순위: 삭제됨 : _selectedImageFile != null - ? Image.file( - _selectedImageFile!, - fit: BoxFit.cover, - ) // 2순위: 새로 고름 + ? Image.file(_selectedImageFile!, fit: BoxFit.cover) + // 2순위: 새로 고름 : widget.profile.profileImageUrl.isNotEmpty ? Image.network( widget.profile.profileImageUrl, @@ -317,9 +299,6 @@ class _ProfileEditScreenState extends ConsumerState { ); } - // --- 입력 필드 및 태그 섹션 로직 --- - - // --- 💡 닉네임 입력 필드 (에러 메시지 포함하도록 수정) --- Widget _buildNicknameSection() { String? errorMessage; if (_isInvalidFormat) { diff --git a/lib/features/user/widgets/challenge_section.dart b/lib/features/user/widgets/challenge_section.dart index bc5725d..14654cd 100644 --- a/lib/features/user/widgets/challenge_section.dart +++ b/lib/features/user/widgets/challenge_section.dart @@ -7,8 +7,8 @@ import '../../../core/theme/app_typography.dart'; import '../../challenge/models/challenge_model.dart'; import '../../challenge/provider/challenge_provider.dart'; import '../screens/challenge_list_screen.dart'; +import 'my_challenge_card.dart'; // 💡 공통 카드 위젯 추가 (위치가 widgets 내부일 경우 경로 주의) -// 챌린지 로직 (탭 전환, 리스트 필터링, 카드 디자인) class ChallengeSection extends ConsumerStatefulWidget { const ChallengeSection({super.key}); @@ -189,8 +189,8 @@ class _ChallengeSectionState extends ConsumerState { final isLast = entry.key == (list.length - 1); return Column( children: [ - _buildChallengeCard(entry.value), - if (!isLast) Divider(height: 1, color: AppColors.gray5), + MyChallengeCard(item: entry.value), + if (!isLast) const Divider(height: 1, color: AppColors.gray5), ], ); }).toList(), @@ -209,350 +209,4 @@ class _ChallengeSectionState extends ConsumerState { return ref.watch(myFailedChallengesProvider(onlyTwo: true)); } } - - // --- 개별 챌린지 카드 UI --- - Widget _buildChallengeCard(ChallengeInProgressModel item) { - final serverStatus = item.status.toUpperCase(); - - // 실패한 챌린지일 경우 전용 UI를 반환 - if (serverStatus == "FAIL" || serverStatus == "FAILED") { - return _buildFailedChallengeCard(item); - } - - // 완료 상태일 때 - if (serverStatus == "SUCCESS") { - return _buildSuccessChallengeCard(item); - } - - final Color themeColor = _getTabColor(selectedTab); - - String statusText = '진행중'; - if (serverStatus == "SUCCESS") - statusText = '완료'; - else if (serverStatus == "FAIL" || serverStatus == "FAILED") - statusText = '실패'; - - return Container( - width: double.infinity, - padding: const EdgeInsets.all(16), - color: Colors.transparent, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, // 추가 - children: [ - Flexible( - child: Text( - item.title, - style: AppTypography.b3.copyWith( - color: AppColors.black, - ), - overflow: TextOverflow.ellipsis, - maxLines: 1, - ), - ), - const SizedBox(width: 7.35), - _buildStatusBadge(statusText, themeColor), - ], - ), - - const SizedBox(height: 3), - Text( - item.dateInfo, - style: AppTypography.b2.copyWith(color: AppColors.gray2), - ), - ], - ), - ), - _buildProgressText(item.progress, themeColor), - ], - ), - const SizedBox(height: 8), - _buildInfoRow(item, serverStatus), - const SizedBox(height: 8), - LinearProgressIndicator( - value: item.progress, - backgroundColor: AppColors.gray5, - color: themeColor, - minHeight: 4, - borderRadius: BorderRadius.circular(2), - ), - ], - ), - ); - } - - // 완료 전용 카드 UI - Widget _buildSuccessChallengeCard(ChallengeInProgressModel item) { - const Color successColor = AppColors.primaryAble; - Color gray5 = AppColors.gray5; - - return Container( - width: double.infinity, - padding: const EdgeInsets.all(16), - decoration: ShapeDecoration( - color: Colors.white, - shape: RoundedRectangleBorder( - side: BorderSide(width: 0.69, color: gray5), - borderRadius: BorderRadius.circular(12), - ), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // 왼쪽 정보 영역 - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Flexible( - child: Text( - item.title, - style: AppTypography.b3.copyWith( - color: AppColors.black, - ), - overflow: TextOverflow.ellipsis, - maxLines: 1, - ), - ), - const SizedBox(width: 7.35), - _buildStatusBadge('완료', successColor), - ], - ), - const SizedBox(height: 2), - // 완료일 데이터 바인딩 - Text( - '완료일 ${item.endDate.replaceAll('-', '/')}', - style: AppTypography.b2.copyWith(color: AppColors.gray2), - ), - const SizedBox(height: 2), - // 총 진행 일수 + 불 아이콘 - Row( - children: [ - SvgPicture.asset( - 'assets/images/icons/small_fire_icon.svg', - width: 16, - height: 16, - ), - const SizedBox(width: 2), - Text( - '총 ${item.duringDate}일', - style: AppTypography.b2.copyWith( - color: AppColors.black, - ), - ), - ], - ), - ], - ), - ), - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Text( - '${(item.progress * 100).toInt()}%', - textAlign: TextAlign.right, - style: AppTypography.h2.copyWith(color: successColor), - ), - Text( - '달성률', - textAlign: TextAlign.right, - style: AppTypography.c1.copyWith(color: AppColors.gray2), - ), - ], - ), - ], - ), - const SizedBox(height: 8), - // 하단 게이지 바 - ClipRRect( - borderRadius: BorderRadius.circular(23), - child: LinearProgressIndicator( - value: item.progress, - minHeight: 4, - backgroundColor: gray5, - valueColor: const AlwaysStoppedAnimation(successColor), - ), - ), - ], - ), - ); - } - - // 실패 전용 카드 UI - Widget _buildFailedChallengeCard(ChallengeInProgressModel item) { - const Color failColor = AppColors.notification; - Color gray5 = AppColors.gray5; - - return Container( - width: double.infinity, - padding: const EdgeInsets.all(16), - decoration: ShapeDecoration( - color: Colors.white, - shape: RoundedRectangleBorder( - side: BorderSide(width: 0.69, color: gray5), - borderRadius: BorderRadius.circular(12), - ), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // 1. 왼쪽 정보 영역 - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Flexible( - child: Text( - item.title, - style: AppTypography.b3.copyWith( - color: AppColors.black, - ), - overflow: TextOverflow.ellipsis, - maxLines: 1, - ), - ), - const SizedBox(width: 7.35), - _buildStatusBadge('실패', failColor), - ], - ), - const SizedBox(height: 2), - // 실패일 데이터 바인딩 - Text( - '실패일 ${item.endDate.replaceAll('-', '/')}', - style: AppTypography.b2.copyWith(color: AppColors.gray2), - ), - const SizedBox(height: 2), - // 누적 진행일 데이터 바인딩 - Row( - children: [ - SvgPicture.asset( - 'assets/images/icons/small_fire_icon.svg', // 불 아이콘 경로 확인 필요 - width: 16, - height: 16, - ), - const SizedBox(width: 2), // 아이콘과 텍스트 사이 간격 2 - Text( - '최대 ${item.duringDate}일', - style: AppTypography.b2.copyWith( - color: AppColors.black, - ), - ), - ], - ), - ], - ), - ), - // 2. 오른쪽 달성률 영역 - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Text( - '${(item.progress * 100).toInt()}%', - textAlign: TextAlign.right, - style: AppTypography.h2.copyWith( - color: AppColors.notification, - ), - ), - Text( - '달성률', - textAlign: TextAlign.right, - style: AppTypography.c1.copyWith(color: AppColors.gray2), - ), - ], - ), - ], - ), - const SizedBox(height: 8), - // 3. 하단 게이지 바 (Gauge) - ClipRRect( - borderRadius: BorderRadius.circular(23), - child: LinearProgressIndicator( - value: item.progress, - minHeight: 4, - backgroundColor: gray5, - valueColor: const AlwaysStoppedAnimation(failColor), - ), - ), - ], - ), - ); - } - - Widget _buildStatusBadge(String text, Color color) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), - decoration: ShapeDecoration( - color: color.withOpacity(0.1), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), - ), - child: Text(text, style: AppTypography.c1.copyWith(color: color)), - ); - } - - Widget _buildProgressText(double progress, Color color) { - return Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Text( - '${(progress * 100).toInt()}%', - style: AppTypography.h2.copyWith(color: color), - ), - Text('달성률', style: AppTypography.c1.copyWith(color: AppColors.gray2)), - ], - ); - } - - Widget _buildInfoRow(ChallengeInProgressModel item, String status) { - return Row( - children: [ - SvgPicture.asset('assets/images/icons/small_fire_icon.svg', width: 16), - const SizedBox(width: 2), - Text( - '${item.duringDate}일째', - style: AppTypography.b2.copyWith(color: AppColors.black), - ), - const SizedBox(width: 12), - if (status == "IN_PROGRESS") ...[ - SvgPicture.asset( - 'assets/images/icons/mini_success_icon.svg', - width: 16, - ), - const SizedBox(width: 2), - Text( - item.countInfo, - style: AppTypography.b2.copyWith(color: AppColors.black), - ), - ], - ], - ); - } } diff --git a/lib/features/user/widgets/my_challenge_card.dart b/lib/features/user/widgets/my_challenge_card.dart new file mode 100644 index 0000000..e5bf813 --- /dev/null +++ b/lib/features/user/widgets/my_challenge_card.dart @@ -0,0 +1,194 @@ +// 최초 작성자: 정승빈 +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import '../../../../core/theme/app_colors.dart'; +import '../../../../core/theme/app_typography.dart'; +import '../../challenge/models/challenge_model.dart'; + +class MyChallengeCard extends StatelessWidget { + final ChallengeInProgressModel item; + + const MyChallengeCard({super.key, required this.item}); + + @override + Widget build(BuildContext context) { + final serverStatus = item.status.toUpperCase(); + + if (serverStatus == "FAIL" || serverStatus == "FAILED") { + return _buildCard( + statusText: '실패', + themeColor: AppColors.notification, + dateLabel: '실패일', + duringLabel: '최대', + showBorder: true, + ); + } + + if (serverStatus == "SUCCESS") { + return _buildCard( + statusText: '완료', + themeColor: AppColors.primaryAble, + dateLabel: '완료일', + duringLabel: '총', + showBorder: true, + ); + } + + // 기본: 진행중 + return _buildCard( + statusText: '진행중', + themeColor: AppColors.blue, + dateLabel: '', + duringLabel: '', + showBorder: false, + ); + } + + // 통합된 카드 빌더 (상태에 따라 컬러와 텍스트만 바뀜) + Widget _buildCard({ + required String statusText, + required Color themeColor, + required String dateLabel, + required String duringLabel, + required bool showBorder, + }) { + final bool isInProgress = statusText == '진행중'; + + return Container( + width: double.infinity, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + border: showBorder + ? Border.all(color: AppColors.gray5, width: 0.69) + : null, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Flexible( + child: Text( + item.title, + style: AppTypography.b3.copyWith( + color: AppColors.black, + ), + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ), + const SizedBox(width: 7.35), + _buildStatusBadge(statusText, themeColor), + ], + ), + const SizedBox(height: 3), + // 날짜 정보 + Text( + isInProgress + ? item.dateInfo + : '$dateLabel ${item.endDate.replaceAll('-', '/')}', + style: AppTypography.b2.copyWith(color: AppColors.gray2), + ), + if (!isInProgress) const SizedBox(height: 2), + // 불 아이콘 및 기간 정보 (완료/실패 시에만 아래로 내려감, 진행중은 _buildInfoRow에서 처리) + if (!isInProgress) + Row( + children: [ + SvgPicture.asset( + 'assets/images/icons/small_fire_icon.svg', + width: 16, + ), + const SizedBox(width: 2), + Text( + '$duringLabel ${item.duringDate}일', + style: AppTypography.b2.copyWith( + color: AppColors.black, + ), + ), + ], + ), + ], + ), + ), + _buildProgressText(item.progress, themeColor), + ], + ), + const SizedBox(height: 8), + if (isInProgress) _buildInProgressInfoRow(item), + if (isInProgress) const SizedBox(height: 8), + _buildGaugeBar(item.progress, themeColor), + ], + ), + ); + } + + Widget _buildStatusBadge(String text, Color color) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + decoration: ShapeDecoration( + color: color.withOpacity(0.1), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + ), + child: Text(text, style: AppTypography.c1.copyWith(color: color)), + ); + } + + Widget _buildProgressText(double progress, Color color) { + return Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + '${(progress * 100).toInt()}%', + style: AppTypography.h2.copyWith(color: color), + ), + Text('달성률', style: AppTypography.c1.copyWith(color: AppColors.gray2)), + ], + ); + } + + Widget _buildInProgressInfoRow(ChallengeInProgressModel item) { + return Row( + children: [ + SvgPicture.asset('assets/images/icons/small_fire_icon.svg', width: 16), + const SizedBox(width: 4), + Text( + '${item.duringDate}일째', + style: AppTypography.b2.copyWith(color: AppColors.black), + ), + const SizedBox(width: 12), + SvgPicture.asset( + 'assets/images/icons/mini_success_icon.svg', + width: 16, + ), + const SizedBox(width: 4), + Text( + item.countInfo, + style: AppTypography.b2.copyWith(color: AppColors.black), + ), + ], + ); + } + + Widget _buildGaugeBar(double progress, Color color) { + return ClipRRect( + borderRadius: BorderRadius.circular(23), + child: LinearProgressIndicator( + value: progress, + minHeight: 4, + backgroundColor: AppColors.gray5, + valueColor: AlwaysStoppedAnimation(color), + ), + ); + } +} From 34695aa21f586a5496f0d554aea8399c1f718549 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Mon, 16 Mar 2026 03:06:04 +0900 Subject: [PATCH 047/134] =?UTF-8?q?refactor:=20=EC=BB=AC=EB=9F=AC=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=ED=91=9C=EA=B8=B0=EB=B2=95=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/core/theme/app_colors.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/core/theme/app_colors.dart b/lib/core/theme/app_colors.dart index 341f0f3..12bebaf 100644 --- a/lib/core/theme/app_colors.dart +++ b/lib/core/theme/app_colors.dart @@ -9,7 +9,8 @@ class AppColors { static const Color gray2 = Color(0xFF616161); static const Color gray3 = Color(0xFF8c8c8c); static const Color gray4 = Color(0xFFD9D9D9); - static final Color gray5 = const Color(0xFFd9d9d9).withValues(alpha: 0.5); + static const Color gray5 = Color(0x7Fd9d9d9); + //static final Color gray5 = const Color(0xFFd9d9d9).withValues(alpha: 0.5); // Green - primary static const Color primaryAble = Color(0xff009951); From e6c2607b0c52edfa5a423320d32ba8cb05c56eec Mon Sep 17 00:00:00 2001 From: Seungvin Date: Mon, 16 Mar 2026 03:23:21 +0900 Subject: [PATCH 048/134] =?UTF-8?q?refactor:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=A9=94=EC=9D=B8=ED=99=94=EB=A9=B4?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20=EC=84=B9?= =?UTF-8?q?=EC=85=98=20view,=20=EC=84=A4=EC=A0=95=EB=A9=94=EB=89=B4=20view?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...e_screen.dart => my_page_main_screen.dart} | 82 +++++-------------- .../my_challenge_section_view.dart} | 12 +-- .../user/views/my_page_menu_view.dart | 52 ++++++++++++ .../profile_header_view.dart} | 4 +- 4 files changed, 80 insertions(+), 70 deletions(-) rename lib/features/user/screens/{my_page_screen.dart => my_page_main_screen.dart} (58%) rename lib/features/user/{widgets/challenge_section.dart => views/my_challenge_section_view.dart} (93%) create mode 100644 lib/features/user/views/my_page_menu_view.dart rename lib/features/user/{widgets/profile_header.dart => views/profile_header_view.dart} (97%) diff --git a/lib/features/user/screens/my_page_screen.dart b/lib/features/user/screens/my_page_main_screen.dart similarity index 58% rename from lib/features/user/screens/my_page_screen.dart rename to lib/features/user/screens/my_page_main_screen.dart index ff38ae0..61183b8 100644 --- a/lib/features/user/screens/my_page_screen.dart +++ b/lib/features/user/screens/my_page_main_screen.dart @@ -1,34 +1,25 @@ -/// 최초 작성자: 정승빈 -/// 작성일: 2026-01-18 -library; +// 최초 작성자: 정승빈 import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:haenaem/features/user/screens/push_notification_settings_screen.dart'; import '../../../../core/theme/app_colors.dart'; -import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_typography.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import 'package:haenaem/features/notification/services/fcm_service.dart'; -import 'package:haenaem/shared/models/tag_data.dart'; -import 'withdrawal_screen.dart'; -import 'challenge_list_screen.dart'; -import 'profile_edit_screen.dart'; -import '../widgets/profile_header.dart'; -import '../widgets/my_page_menu_item.dart'; -import '../widgets/challenge_section.dart'; -import '../widgets/logout_dialog.dart'; +import 'profile_edit_screen.dart'; // 4단계에서 경로 수정 예정 +import '../views/profile_header_view.dart'; +import '../views/my_challenge_section_view.dart'; +import '../views/my_page_menu_view.dart'; -class MyPageScreen extends ConsumerStatefulWidget { - const MyPageScreen({super.key}); +class MyPageMainScreen extends ConsumerStatefulWidget { + const MyPageMainScreen({super.key}); @override - ConsumerState createState() => _MyPageScreenState(); + ConsumerState createState() => _MyPageMainScreenState(); } -class _MyPageScreenState extends ConsumerState { +class _MyPageMainScreenState extends ConsumerState { @override Widget build(BuildContext context) { final profileAsync = ref.watch(myProfileProvider); @@ -43,10 +34,11 @@ class _MyPageScreenState extends ConsumerState { children: [ const SizedBox(height: 20), + // 1. 프로필 헤더 뷰 profileAsync.when( loading: () => const Center(child: CircularProgressIndicator()), error: (err, stack) => const Center(child: Text('데이터 로드 실패')), - data: (profile) => ProfileHeader( + data: (profile) => ProfileHeaderView( nickname: profile.nickname, introduction: profile.introduction, profileImageUrl: profile.profileImageUrl, @@ -55,10 +47,15 @@ class _MyPageScreenState extends ConsumerState { ), const SizedBox(height: 40), - const ChallengeSection(), // 챌린지 섹션 위젯 + + // 2. 나의 챌린지 뷰 + const MyChallengeSectionView(), const SizedBox(height: 24), - _buildMenuSection(context), + + // 3. 하단 설정 메뉴 뷰 + const MyPageMenuView(), + const SizedBox(height: 30), ], ), @@ -95,7 +92,7 @@ class _MyPageScreenState extends ConsumerState { ), ); } else { - // 데이터 로딩 중이거나 에러 시 알림 (선택 사항) + // 데이터 로딩 중이거나 에러 시 알림 ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('프로필 정보를 불러오는 중입니다.')), ); @@ -115,45 +112,4 @@ class _MyPageScreenState extends ConsumerState { ), ); } - - Widget _buildMenuSection(BuildContext context) { - return Column( - children: [ - MyPageMenuItem( - title: '푸시 알림 설정', - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const PushNotificationSettingsScreen(), - ), - ); - }, - ), - const SizedBox(height: 10), - MyPageMenuItem( - title: '로그아웃', - onTap: () { - // 분리된 LogoutDialog 호출 - showDialog( - context: context, - builder: (context) => const LogoutDialog(), - ); - }, - ), - const SizedBox(height: 10), - MyPageMenuItem( - title: '회원 탈퇴', - textColor: AppColors.notification, - showArrow: true, - onTap: () { - Navigator.push( - context, - MaterialPageRoute(builder: (context) => const WithdrawalScreen()), - ); - }, - ), - ], - ); - } } diff --git a/lib/features/user/widgets/challenge_section.dart b/lib/features/user/views/my_challenge_section_view.dart similarity index 93% rename from lib/features/user/widgets/challenge_section.dart rename to lib/features/user/views/my_challenge_section_view.dart index 14654cd..5c29207 100644 --- a/lib/features/user/widgets/challenge_section.dart +++ b/lib/features/user/views/my_challenge_section_view.dart @@ -7,16 +7,18 @@ import '../../../core/theme/app_typography.dart'; import '../../challenge/models/challenge_model.dart'; import '../../challenge/provider/challenge_provider.dart'; import '../screens/challenge_list_screen.dart'; -import 'my_challenge_card.dart'; // 💡 공통 카드 위젯 추가 (위치가 widgets 내부일 경우 경로 주의) +import '../widgets/my_challenge_card.dart'; // 💡 공통 카드 위젯 추가 (위치가 widgets 내부일 경우 경로 주의) -class ChallengeSection extends ConsumerStatefulWidget { - const ChallengeSection({super.key}); +class MyChallengeSectionView extends ConsumerStatefulWidget { + const MyChallengeSectionView({super.key}); @override - ConsumerState createState() => _ChallengeSectionState(); + ConsumerState createState() => + _MyChallengeSectionViewState(); } -class _ChallengeSectionState extends ConsumerState { +class _MyChallengeSectionViewState + extends ConsumerState { // 섹션 내부에서 탭 상태 관리 MyPageTab selectedTab = MyPageTab.inProgress; diff --git a/lib/features/user/views/my_page_menu_view.dart b/lib/features/user/views/my_page_menu_view.dart new file mode 100644 index 0000000..b6c5c88 --- /dev/null +++ b/lib/features/user/views/my_page_menu_view.dart @@ -0,0 +1,52 @@ +// 최초 작성자: 정승빈 +import 'package:flutter/material.dart'; +import '../../../../core/theme/app_colors.dart'; +import '../screens/push_notification_settings_screen.dart'; // 4단계에서 경로 수정 예정 +import '../screens/withdrawal_screen.dart'; // 4단계에서 경로 수정 예정 +import '../widgets/my_page_menu_item.dart'; +import '../widgets/logout_dialog.dart'; + +class MyPageMenuView extends StatelessWidget { + const MyPageMenuView({super.key}); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + MyPageMenuItem( + title: '푸시 알림 설정', + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const PushNotificationSettingsScreen(), + ), + ); + }, + ), + const SizedBox(height: 10), + MyPageMenuItem( + title: '로그아웃', + onTap: () { + showDialog( + context: context, + builder: (context) => const LogoutDialog(), + ); + }, + ), + const SizedBox(height: 10), + MyPageMenuItem( + title: '회원 탈퇴', + textColor: AppColors.notification, + showArrow: true, + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const WithdrawalScreen()), + ); + }, + ), + ], + ); + } +} diff --git a/lib/features/user/widgets/profile_header.dart b/lib/features/user/views/profile_header_view.dart similarity index 97% rename from lib/features/user/widgets/profile_header.dart rename to lib/features/user/views/profile_header_view.dart index f1de06d..24fb502 100644 --- a/lib/features/user/widgets/profile_header.dart +++ b/lib/features/user/views/profile_header_view.dart @@ -7,13 +7,13 @@ import '../../../shared/models/tag_data.dart'; import '../../../shared/widgets/tag_badge.dart'; // 이미지, 닉네임, 소개글, 그리고 복잡했던 태그 정렬 로직 -class ProfileHeader extends StatelessWidget { +class ProfileHeaderView extends StatelessWidget { final String nickname; final String introduction; final String profileImageUrl; final List tags; - const ProfileHeader({ + const ProfileHeaderView({ super.key, required this.nickname, required this.introduction, From 3dd512092ae7c37818ffe4fdb9b7047db6cc66b2 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Mon, 16 Mar 2026 03:29:54 +0900 Subject: [PATCH 049/134] =?UTF-8?q?refactor:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EA=B4=80=EB=A0=A8=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=B0=20=EC=BD=94=EB=93=9C=20=ED=8C=8C=EC=9D=BC=EB=93=A4=20?= =?UTF-8?q?=ED=8F=B4=EB=8D=94=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge_list_screen.dart | 6 +- .../user/screens/my_page_main_screen.dart | 2 +- .../{ => profile}/profile_edit_screen.dart | 12 +- .../push_notification_settings_screen.dart | 8 +- .../{ => settings}/withdrawal_screen.dart | 6 +- .../user/views/my_challenge_section_view.dart | 2 +- .../user/views/my_page_menu_view.dart | 4 +- .../user/widgets/challenge_section.dart | 212 ++++++++++++++++++ 8 files changed, 232 insertions(+), 20 deletions(-) rename lib/features/user/screens/{ => challenge}/challenge_list_screen.dart (95%) rename lib/features/user/screens/{ => profile}/profile_edit_screen.dart (98%) rename lib/features/user/screens/{ => settings}/push_notification_settings_screen.dart (96%) rename lib/features/user/screens/{ => settings}/withdrawal_screen.dart (98%) create mode 100644 lib/features/user/widgets/challenge_section.dart diff --git a/lib/features/user/screens/challenge_list_screen.dart b/lib/features/user/screens/challenge/challenge_list_screen.dart similarity index 95% rename from lib/features/user/screens/challenge_list_screen.dart rename to lib/features/user/screens/challenge/challenge_list_screen.dart index c86f39c..675350c 100644 --- a/lib/features/user/screens/challenge_list_screen.dart +++ b/lib/features/user/screens/challenge/challenge_list_screen.dart @@ -1,12 +1,12 @@ // 최초 작성자: 정승빈 import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import '../../../../core/theme/app_colors.dart'; -import '../../../../core/theme/app_typography.dart'; +import '../../../../../core/theme/app_colors.dart'; +import '../../../../../core/theme/app_typography.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import '../widgets/my_challenge_card.dart'; // 💡 공통 카드 위젯 추가 +import '../../widgets/my_challenge_card.dart'; // 💡 공통 카드 위젯 추가 // 클래스의 용도: 챌린지 목록을 진행중, 완료, 실패 탭으로 구분하여 보여주는 화면 class ChallengeListScreen extends ConsumerWidget { diff --git a/lib/features/user/screens/my_page_main_screen.dart b/lib/features/user/screens/my_page_main_screen.dart index 61183b8..d0c776b 100644 --- a/lib/features/user/screens/my_page_main_screen.dart +++ b/lib/features/user/screens/my_page_main_screen.dart @@ -7,7 +7,7 @@ import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import 'profile_edit_screen.dart'; // 4단계에서 경로 수정 예정 +import 'profile/profile_edit_screen.dart'; import '../views/profile_header_view.dart'; import '../views/my_challenge_section_view.dart'; import '../views/my_page_menu_view.dart'; diff --git a/lib/features/user/screens/profile_edit_screen.dart b/lib/features/user/screens/profile/profile_edit_screen.dart similarity index 98% rename from lib/features/user/screens/profile_edit_screen.dart rename to lib/features/user/screens/profile/profile_edit_screen.dart index 81725af..71d9c84 100644 --- a/lib/features/user/screens/profile_edit_screen.dart +++ b/lib/features/user/screens/profile/profile_edit_screen.dart @@ -5,17 +5,17 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:image_picker/image_picker.dart'; -import '../../../../core/theme/app_colors.dart'; -import '../../../../core/theme/app_typography.dart'; +import '../../../../../core/theme/app_colors.dart'; +import '../../../../../core/theme/app_typography.dart'; import 'package:haenaem/features/user/models/user_model.dart'; import 'package:haenaem/shared/models/tag_data.dart'; import 'package:haenaem/shared/widgets/app_tag_chip.dart'; import 'package:haenaem/shared/widgets/image_source_sheet.dart'; -import '../../../../shared/widgets/bottom_action_button.dart'; +import '../../../../../shared/widgets/bottom_action_button.dart'; import 'package:haenaem/features/auth/signup/screens/profile_image_edit_screen.dart'; -import '../widgets/profile_image_menu.dart'; -import '../provider/tag_provider.dart'; -import '../provider/user_profile_provider.dart'; +import '../../widgets/profile_image_menu.dart'; +import '../../provider/tag_provider.dart'; +import '../../provider/user_profile_provider.dart'; // 프로필 편집 화면 class ProfileEditScreen extends ConsumerStatefulWidget { diff --git a/lib/features/user/screens/push_notification_settings_screen.dart b/lib/features/user/screens/settings/push_notification_settings_screen.dart similarity index 96% rename from lib/features/user/screens/push_notification_settings_screen.dart rename to lib/features/user/screens/settings/push_notification_settings_screen.dart index 0c61216..2777d30 100644 --- a/lib/features/user/screens/push_notification_settings_screen.dart +++ b/lib/features/user/screens/settings/push_notification_settings_screen.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import '../../../core/theme/app_colors.dart'; -import '../../../core/theme/app_typography.dart'; -import '../../../shared/widgets/custom_switch.dart'; -import '../../notification/provider/push_notification_provider.dart'; +import '../../../../core/theme/app_colors.dart'; +import '../../../../core/theme/app_typography.dart'; +import '../../../../shared/widgets/custom_switch.dart'; +import '../../../notification/provider/push_notification_provider.dart'; // 푸시 알림 설정 화면 class PushNotificationSettingsScreen extends ConsumerWidget { diff --git a/lib/features/user/screens/withdrawal_screen.dart b/lib/features/user/screens/settings/withdrawal_screen.dart similarity index 98% rename from lib/features/user/screens/withdrawal_screen.dart rename to lib/features/user/screens/settings/withdrawal_screen.dart index 6c7b4a4..8dee71e 100644 --- a/lib/features/user/screens/withdrawal_screen.dart +++ b/lib/features/user/screens/settings/withdrawal_screen.dart @@ -3,9 +3,9 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import '../../../../core/theme/app_colors.dart'; -import '../../../../core/theme/app_typography.dart'; -import '../../auth/services/auth_service.dart'; +import '../../../../../core/theme/app_colors.dart'; +import '../../../../../core/theme/app_typography.dart'; +import '../../../auth/services/auth_service.dart'; import 'package:haenaem/features/auth/signup/screens/auth_gate.dart'; /// 클래스의 용도: 회원 탈퇴 안내 및 동의 확인, 탈퇴 처리를 수행하는 화면 diff --git a/lib/features/user/views/my_challenge_section_view.dart b/lib/features/user/views/my_challenge_section_view.dart index 5c29207..094e3b9 100644 --- a/lib/features/user/views/my_challenge_section_view.dart +++ b/lib/features/user/views/my_challenge_section_view.dart @@ -6,7 +6,7 @@ import '../../../core/theme/app_colors.dart'; import '../../../core/theme/app_typography.dart'; import '../../challenge/models/challenge_model.dart'; import '../../challenge/provider/challenge_provider.dart'; -import '../screens/challenge_list_screen.dart'; +import '../screens/challenge/challenge_list_screen.dart'; import '../widgets/my_challenge_card.dart'; // 💡 공통 카드 위젯 추가 (위치가 widgets 내부일 경우 경로 주의) class MyChallengeSectionView extends ConsumerStatefulWidget { diff --git a/lib/features/user/views/my_page_menu_view.dart b/lib/features/user/views/my_page_menu_view.dart index b6c5c88..8ffe451 100644 --- a/lib/features/user/views/my_page_menu_view.dart +++ b/lib/features/user/views/my_page_menu_view.dart @@ -1,8 +1,8 @@ // 최초 작성자: 정승빈 import 'package:flutter/material.dart'; import '../../../../core/theme/app_colors.dart'; -import '../screens/push_notification_settings_screen.dart'; // 4단계에서 경로 수정 예정 -import '../screens/withdrawal_screen.dart'; // 4단계에서 경로 수정 예정 +import '../screens/settings/push_notification_settings_screen.dart'; // 4단계에서 경로 수정 예정 +import '../screens/settings/withdrawal_screen.dart'; // 4단계에서 경로 수정 예정 import '../widgets/my_page_menu_item.dart'; import '../widgets/logout_dialog.dart'; diff --git a/lib/features/user/widgets/challenge_section.dart b/lib/features/user/widgets/challenge_section.dart new file mode 100644 index 0000000..9bca847 --- /dev/null +++ b/lib/features/user/widgets/challenge_section.dart @@ -0,0 +1,212 @@ +// 최초 작성자 : 김채영 +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../../../core/theme/app_colors.dart'; +import '../../../core/theme/app_typography.dart'; +import '../../challenge/models/challenge_model.dart'; +import '../../challenge/provider/challenge_provider.dart'; +import '../screens/challenge/challenge_list_screen.dart'; +import 'my_challenge_card.dart'; // 💡 공통 카드 위젯 추가 (위치가 widgets 내부일 경우 경로 주의) + +class ChallengeSection extends ConsumerStatefulWidget { + const ChallengeSection({super.key}); + + @override + ConsumerState createState() => _ChallengeSectionState(); +} + +class _ChallengeSectionState extends ConsumerState { + // 섹션 내부에서 탭 상태 관리 + MyPageTab selectedTab = MyPageTab.inProgress; + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + border: Border.all(color: AppColors.gray4, width: 1), + ), + clipBehavior: Clip.antiAlias, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + _buildHeader(), + const Divider(height: 1, color: AppColors.gray4), + _buildChallengeListArea(), + ], + ), + ); + } + + // --- 헤더 영역 (제목 + 더보기 + 탭) --- + Widget _buildHeader() { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + color: AppColors.gray5, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '나의 챌린지', + style: AppTypography.h3.copyWith(color: Colors.black), + ), + _buildMoreButton(), + ], + ), + const SizedBox(height: 8), + _buildStatusTabs(), + ], + ), + ); + } + + Widget _buildMoreButton() { + return InkWell( + onTap: () => Navigator.push( + context, + MaterialPageRoute(builder: (context) => const ChallengeListScreen()), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text('더보기', style: AppTypography.b1.copyWith(color: AppColors.gray3)), + SvgPicture.asset( + 'assets/images/icons/right_arrow_icon.svg', + width: 20, + height: 20, + ), + ], + ), + ); + } + + // --- 탭 버튼 영역 --- + Widget _buildStatusTabs() { + return Row( + children: [ + _buildTabButton( + '진행중', + MyPageTab.inProgress, + 'assets/images/icons/inprogress.svg', + ), + const SizedBox(width: 8), + _buildTabButton( + '완료', + MyPageTab.success, + 'assets/images/icons/success_check.svg', + ), + const SizedBox(width: 8), + _buildTabButton( + '실패', + MyPageTab.fail, + 'assets/images/icons/fail_circle.svg', + ), + ], + ); + } + + Widget _buildTabButton(String label, MyPageTab tab, String svgPath) { + final bool isSelected = selectedTab == tab; + final Color activeColor = _getTabColor(tab); + + return Expanded( + child: InkWell( + onTap: () => setState(() => selectedTab = tab), + child: Container( + padding: const EdgeInsets.symmetric(vertical: 6), + decoration: BoxDecoration( + color: isSelected ? activeColor : Colors.white, + borderRadius: BorderRadius.circular(9), + border: isSelected ? null : Border.all(color: AppColors.gray4), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + svgPath, + width: 16, + height: 16, + colorFilter: ColorFilter.mode( + isSelected ? Colors.white : AppColors.gray3, + BlendMode.srcIn, + ), + ), + const SizedBox(width: 4), + Text( + label, + style: AppTypography.b2.copyWith( + color: isSelected ? Colors.white : AppColors.gray3, + ), + ), + ], + ), + ), + ), + ); + } + + Color _getTabColor(MyPageTab tab) { + switch (tab) { + case MyPageTab.inProgress: + return AppColors.blue; + case MyPageTab.success: + return AppColors.primaryAble; + case MyPageTab.fail: + return AppColors.notification; + } + } + + // --- 챌린지 리스트 데이터 처리 영역 --- + Widget _buildChallengeListArea() { + final challengesAsync = _getChallengesProvider(); + + return challengesAsync.when( + loading: () => const Padding( + padding: EdgeInsets.all(30), + child: Center(child: CircularProgressIndicator()), + ), + error: (err, stack) => const Padding( + padding: EdgeInsets.all(20), + child: Center(child: Text('데이터 로드 실패')), + ), + data: (list) { + if (list.isEmpty) { + return Container( + height: 100, + alignment: Alignment.center, + child: const Text( + '해당하는 챌린지가 없습니다.', + style: TextStyle(color: AppColors.gray2), + ), + ); + } + return Column( + children: list.asMap().entries.map((entry) { + final isLast = entry.key == (list.length - 1); + return Column( + children: [ + MyChallengeCard(item: entry.value), + if (!isLast) const Divider(height: 1, color: AppColors.gray5), + ], + ); + }).toList(), + ); + }, + ); + } + + AsyncValue> _getChallengesProvider() { + switch (selectedTab) { + case MyPageTab.inProgress: + return ref.watch(myInProgressChallengesProvider(onlyTwo: true)); + case MyPageTab.success: + return ref.watch(mySuccessChallengesProvider(onlyTwo: true)); + case MyPageTab.fail: + return ref.watch(myFailedChallengesProvider(onlyTwo: true)); + } + } +} From 63eb93abf59543325f37384f40c320f52c93dbe5 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Mon, 16 Mar 2026 04:04:59 +0900 Subject: [PATCH 050/134] =?UTF-8?q?refactor:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EC=8A=A4=ED=81=AC=EB=A6=B0=20=EA=B3=B5?= =?UTF-8?q?=EC=9A=A9=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=9B=90=ED=98=95=20?= =?UTF-8?q?=EC=9C=84=EC=A0=AF=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/models/my_page_challenge_card.dart | 4 +- .../user/views/profile_header_view.dart | 19 +- .../user/widgets/challenge_section.dart | 212 ------------------ 3 files changed, 7 insertions(+), 228 deletions(-) delete mode 100644 lib/features/user/widgets/challenge_section.dart diff --git a/lib/features/user/models/my_page_challenge_card.dart b/lib/features/user/models/my_page_challenge_card.dart index 2770f6b..36a41ea 100644 --- a/lib/features/user/models/my_page_challenge_card.dart +++ b/lib/features/user/models/my_page_challenge_card.dart @@ -6,8 +6,8 @@ import 'package:haenaem/shared/models/home_challenge_card.dart'; enum ChallengeStatus { inProgress, // 진행중 - completed, // 완료 - failed, // 실패 + success, // 완료 + fail, // 실패 } class MyPageChallengeCard { diff --git a/lib/features/user/views/profile_header_view.dart b/lib/features/user/views/profile_header_view.dart index 24fb502..f2ae9e3 100644 --- a/lib/features/user/views/profile_header_view.dart +++ b/lib/features/user/views/profile_header_view.dart @@ -5,6 +5,7 @@ import '../../../core/theme/app_colors.dart'; import '../../../core/theme/app_typography.dart'; import '../../../shared/models/tag_data.dart'; import '../../../shared/widgets/tag_badge.dart'; +import 'package:haenaem/shared/widgets/user_profile_circle.dart'; // 이미지, 닉네임, 소개글, 그리고 복잡했던 태그 정렬 로직 class ProfileHeaderView extends StatelessWidget { @@ -40,20 +41,10 @@ class ProfileHeaderView extends StatelessWidget { } Widget _buildImage() { - return Container( - width: 150, - height: 150, - decoration: const BoxDecoration( - color: Color(0xFFDFE1DC), - shape: BoxShape.circle, - ), - child: ClipOval( - child: profileImageUrl.isNotEmpty - ? Image.network(profileImageUrl, fit: BoxFit.cover) - : SvgPicture.asset( - 'assets/images/placeholders/default_profile.svg', - ), - ), + return UserProfileCircle( + // URL이 비어있으면 null을 넘겨 UserProfileCircle이 기본 아이콘을 그리게 함. + imageUrl: profileImageUrl.isNotEmpty ? profileImageUrl : null, + size: 150, ); } diff --git a/lib/features/user/widgets/challenge_section.dart b/lib/features/user/widgets/challenge_section.dart deleted file mode 100644 index 9bca847..0000000 --- a/lib/features/user/widgets/challenge_section.dart +++ /dev/null @@ -1,212 +0,0 @@ -// 최초 작성자 : 김채영 -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import '../../../core/theme/app_colors.dart'; -import '../../../core/theme/app_typography.dart'; -import '../../challenge/models/challenge_model.dart'; -import '../../challenge/provider/challenge_provider.dart'; -import '../screens/challenge/challenge_list_screen.dart'; -import 'my_challenge_card.dart'; // 💡 공통 카드 위젯 추가 (위치가 widgets 내부일 경우 경로 주의) - -class ChallengeSection extends ConsumerStatefulWidget { - const ChallengeSection({super.key}); - - @override - ConsumerState createState() => _ChallengeSectionState(); -} - -class _ChallengeSectionState extends ConsumerState { - // 섹션 내부에서 탭 상태 관리 - MyPageTab selectedTab = MyPageTab.inProgress; - - @override - Widget build(BuildContext context) { - return Container( - width: double.infinity, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - border: Border.all(color: AppColors.gray4, width: 1), - ), - clipBehavior: Clip.antiAlias, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - _buildHeader(), - const Divider(height: 1, color: AppColors.gray4), - _buildChallengeListArea(), - ], - ), - ); - } - - // --- 헤더 영역 (제목 + 더보기 + 탭) --- - Widget _buildHeader() { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), - color: AppColors.gray5, - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - '나의 챌린지', - style: AppTypography.h3.copyWith(color: Colors.black), - ), - _buildMoreButton(), - ], - ), - const SizedBox(height: 8), - _buildStatusTabs(), - ], - ), - ); - } - - Widget _buildMoreButton() { - return InkWell( - onTap: () => Navigator.push( - context, - MaterialPageRoute(builder: (context) => const ChallengeListScreen()), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text('더보기', style: AppTypography.b1.copyWith(color: AppColors.gray3)), - SvgPicture.asset( - 'assets/images/icons/right_arrow_icon.svg', - width: 20, - height: 20, - ), - ], - ), - ); - } - - // --- 탭 버튼 영역 --- - Widget _buildStatusTabs() { - return Row( - children: [ - _buildTabButton( - '진행중', - MyPageTab.inProgress, - 'assets/images/icons/inprogress.svg', - ), - const SizedBox(width: 8), - _buildTabButton( - '완료', - MyPageTab.success, - 'assets/images/icons/success_check.svg', - ), - const SizedBox(width: 8), - _buildTabButton( - '실패', - MyPageTab.fail, - 'assets/images/icons/fail_circle.svg', - ), - ], - ); - } - - Widget _buildTabButton(String label, MyPageTab tab, String svgPath) { - final bool isSelected = selectedTab == tab; - final Color activeColor = _getTabColor(tab); - - return Expanded( - child: InkWell( - onTap: () => setState(() => selectedTab = tab), - child: Container( - padding: const EdgeInsets.symmetric(vertical: 6), - decoration: BoxDecoration( - color: isSelected ? activeColor : Colors.white, - borderRadius: BorderRadius.circular(9), - border: isSelected ? null : Border.all(color: AppColors.gray4), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SvgPicture.asset( - svgPath, - width: 16, - height: 16, - colorFilter: ColorFilter.mode( - isSelected ? Colors.white : AppColors.gray3, - BlendMode.srcIn, - ), - ), - const SizedBox(width: 4), - Text( - label, - style: AppTypography.b2.copyWith( - color: isSelected ? Colors.white : AppColors.gray3, - ), - ), - ], - ), - ), - ), - ); - } - - Color _getTabColor(MyPageTab tab) { - switch (tab) { - case MyPageTab.inProgress: - return AppColors.blue; - case MyPageTab.success: - return AppColors.primaryAble; - case MyPageTab.fail: - return AppColors.notification; - } - } - - // --- 챌린지 리스트 데이터 처리 영역 --- - Widget _buildChallengeListArea() { - final challengesAsync = _getChallengesProvider(); - - return challengesAsync.when( - loading: () => const Padding( - padding: EdgeInsets.all(30), - child: Center(child: CircularProgressIndicator()), - ), - error: (err, stack) => const Padding( - padding: EdgeInsets.all(20), - child: Center(child: Text('데이터 로드 실패')), - ), - data: (list) { - if (list.isEmpty) { - return Container( - height: 100, - alignment: Alignment.center, - child: const Text( - '해당하는 챌린지가 없습니다.', - style: TextStyle(color: AppColors.gray2), - ), - ); - } - return Column( - children: list.asMap().entries.map((entry) { - final isLast = entry.key == (list.length - 1); - return Column( - children: [ - MyChallengeCard(item: entry.value), - if (!isLast) const Divider(height: 1, color: AppColors.gray5), - ], - ); - }).toList(), - ); - }, - ); - } - - AsyncValue> _getChallengesProvider() { - switch (selectedTab) { - case MyPageTab.inProgress: - return ref.watch(myInProgressChallengesProvider(onlyTwo: true)); - case MyPageTab.success: - return ref.watch(mySuccessChallengesProvider(onlyTwo: true)); - case MyPageTab.fail: - return ref.watch(myFailedChallengesProvider(onlyTwo: true)); - } - } -} From 6bdfe1bede4d56716fe57467675dd3a753e4073e Mon Sep 17 00:00:00 2001 From: Seungvin Date: Mon, 16 Mar 2026 04:06:15 +0900 Subject: [PATCH 051/134] =?UTF-8?q?refactor:=20=ED=8C=8C=EC=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=EB=B3=80=ED=99=98=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=AC=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/app.dart | 4 ++-- lib/core/theme/app_colors.dart | 4 ++-- lib/features/main/screens/main_screen.dart | 4 ++-- lib/main.dart | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/app.dart b/lib/app.dart index af5c98e..4bceab8 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:haenaem/features/social/screens/social_main_screen.dart'; import 'features/challenge/create/screens/challenge_create_screen.dart'; -import 'features/user/screens/my_page_screen.dart'; +import 'features/user/screens/my_page_main_screen.dart'; import 'features/main/screens/main_screen.dart'; class App extends StatelessWidget { @@ -13,7 +13,7 @@ class App extends StatelessWidget { Widget build(BuildContext context) { return const MaterialApp( // theme:, - home: MyPageScreen(), + home: MyPageMainScreen(), //home: MainScreen(), //home: SocialScreen(), ); diff --git a/lib/core/theme/app_colors.dart b/lib/core/theme/app_colors.dart index 12bebaf..de842b2 100644 --- a/lib/core/theme/app_colors.dart +++ b/lib/core/theme/app_colors.dart @@ -18,8 +18,8 @@ class AppColors { static const Color disable = Color(0xffd9e0d7); // Mainlist - static Color success = const Color(0xffbbf4bd).withValues(alpha: 0.5); - static Color warning = const Color(0xffffd6c8).withValues(alpha: 0.5); + static const success = Color(0x7fbbf4bd); + static const warning = Color(0x7fffd6c8); static const Color fire = Color(0xFFFB7039); static const Color notification = Color(0xffD11E1B); diff --git a/lib/features/main/screens/main_screen.dart b/lib/features/main/screens/main_screen.dart index 75b39fc..014e7fe 100644 --- a/lib/features/main/screens/main_screen.dart +++ b/lib/features/main/screens/main_screen.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:haenaem/features/home/screens/home_screen.dart'; import 'package:haenaem/features/social/screens/social_main_screen.dart'; import '../widgets/bottom_nav_bar.dart'; -import 'package:haenaem/features/user/screens/my_page_screen.dart'; +import 'package:haenaem/features/user/screens/my_page_main_screen.dart'; import 'package:haenaem/features/feed/screens/feed_screen.dart'; // 내비게이션 바를 넣은 화면 @@ -23,7 +23,7 @@ class _MainScreenState extends State { const Center(child: Text("통계 화면")), const FeedScreen(), const SocialMainScreen(), - const MyPageScreen(), + const MyPageMainScreen(), ]; @override diff --git a/lib/main.dart b/lib/main.dart index 432bda4..c370526 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:haenaem/features/social/screens/social_main_screen.dart'; -import 'package:haenaem/features/user/screens/my_page_screen.dart'; +import 'package:haenaem/features/user/screens/my_page_main_screen.dart'; import 'package:intl/date_symbol_data_local.dart'; import 'package:haenaem/core/theme/app_theme.dart'; From 97e6049062adf4fe170a5d84322872331e474ca8 Mon Sep 17 00:00:00 2001 From: Chaeyeong_10 Date: Thu, 19 Mar 2026 11:11:05 +0900 Subject: [PATCH 052/134] =?UTF-8?q?feat:=20=EC=95=B1=20=EB=B0=B0=ED=8F=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/auth/signup/screens/tag_screen.dart | 2 +- .../create/widgets/challenge_tag_bottom_sheet.dart | 2 +- .../detail/widgets/challenge_detail_content.dart | 2 +- lib/features/challenge/model/challenge_model.dart | 8 ++++++-- lib/features/user/screens/my_page_screen.dart | 2 +- lib/features/user/screens/profile_edit_screen.dart | 2 +- lib/features/user/widgets/profile_header.dart | 2 +- lib/firebase_options.dart | 5 ++++- lib/shared/models/{tag_data.dart => tag_model.dart} | 0 9 files changed, 16 insertions(+), 9 deletions(-) rename lib/shared/models/{tag_data.dart => tag_model.dart} (100%) diff --git a/lib/features/auth/signup/screens/tag_screen.dart b/lib/features/auth/signup/screens/tag_screen.dart index 12d4142..a3d752b 100644 --- a/lib/features/auth/signup/screens/tag_screen.dart +++ b/lib/features/auth/signup/screens/tag_screen.dart @@ -7,7 +7,7 @@ import '../providers/signup_provider.dart'; import '../models/signup_state.dart'; import 'package:haenaem/features/auth/signup/widgets/signup_page_layout.dart'; import 'package:haenaem/shared/widgets/app_tag_chip.dart'; -import 'package:haenaem/shared/models/tag_data.dart'; +import 'package:haenaem/shared/models/tag_model.dart'; // 태그 설정 화면 class TagScreen extends ConsumerStatefulWidget { diff --git a/lib/features/challenge/create/widgets/challenge_tag_bottom_sheet.dart b/lib/features/challenge/create/widgets/challenge_tag_bottom_sheet.dart index 9c4a75d..fb775f0 100644 --- a/lib/features/challenge/create/widgets/challenge_tag_bottom_sheet.dart +++ b/lib/features/challenge/create/widgets/challenge_tag_bottom_sheet.dart @@ -9,7 +9,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/features/challenge/create/widgets/plus_button.dart'; import 'package:haenaem/shared/widgets/custom_bottom_sheet.dart'; import 'package:haenaem/shared/widgets/app_tag_chip.dart'; -import 'package:haenaem/shared/models/tag_data.dart'; +import 'package:haenaem/shared/models/tag_model.dart'; // 서버에서 태그 목록을 불러와 카테고리별로 표시하고 선택을 관리하는 바텀시트 class ChallengeTagBottomSheet extends ConsumerStatefulWidget { diff --git a/lib/features/challenge/detail/widgets/challenge_detail_content.dart b/lib/features/challenge/detail/widgets/challenge_detail_content.dart index 36e8083..dc2e060 100644 --- a/lib/features/challenge/detail/widgets/challenge_detail_content.dart +++ b/lib/features/challenge/detail/widgets/challenge_detail_content.dart @@ -4,7 +4,7 @@ import 'package:flutter_svg/svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/features/challenge/model/challenge_model.dart'; -import 'package:haenaem/shared/models/tag_data.dart'; +import 'package:haenaem/shared/models/tag_model.dart'; import 'package:haenaem/shared/widgets/tag_badge.dart'; class ChallengeDetailContent extends StatelessWidget { diff --git a/lib/features/challenge/model/challenge_model.dart b/lib/features/challenge/model/challenge_model.dart index 1bf9885..b22907e 100644 --- a/lib/features/challenge/model/challenge_model.dart +++ b/lib/features/challenge/model/challenge_model.dart @@ -373,7 +373,9 @@ class CertificationPostModel { List extractedImages = []; String dateStr = json['postDate'] ?? ""; - if (dateStr.isEmpty && json['createdAt'] != null) { + + if ((json['postDate'] == null || json['postDate'] == "") && + json['createdAt'] != null) { dateStr = json['createdAt'].toString().split('T').first; } @@ -395,7 +397,9 @@ class CertificationPostModel { return CertificationPostModel( postId: json['postId'] ?? 0, - postDate: json['postDate'] ?? dateStr, + postDate: (json['postDate'] != null && json['postDate'] != "") + ? json['postDate'] + : dateStr, challengeId: json['challengeId'] ?? 0, challengeTitle: json['challengeTitle'] ?? '제목 없음', totalSuccessDays: json['totalSuccessDays'] ?? 0, diff --git a/lib/features/user/screens/my_page_screen.dart b/lib/features/user/screens/my_page_screen.dart index ff38ae0..55393e2 100644 --- a/lib/features/user/screens/my_page_screen.dart +++ b/lib/features/user/screens/my_page_screen.dart @@ -12,7 +12,7 @@ import '../../../../core/theme/app_typography.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/features/notification/services/fcm_service.dart'; -import 'package:haenaem/shared/models/tag_data.dart'; +import 'package:haenaem/shared/models/tag_model.dart'; import 'withdrawal_screen.dart'; import 'challenge_list_screen.dart'; import 'profile_edit_screen.dart'; diff --git a/lib/features/user/screens/profile_edit_screen.dart b/lib/features/user/screens/profile_edit_screen.dart index 050d186..fdd06df 100644 --- a/lib/features/user/screens/profile_edit_screen.dart +++ b/lib/features/user/screens/profile_edit_screen.dart @@ -8,7 +8,7 @@ import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; import 'package:haenaem/features/user/model/user_model.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import 'package:haenaem/shared/models/tag_data.dart'; +import 'package:haenaem/shared/models/tag_model.dart'; import 'package:haenaem/shared/widgets/app_tag_chip.dart'; import 'package:haenaem/shared/widgets/image_source_sheet.dart'; import '../../../../shared/widgets/bottom_action_button.dart'; diff --git a/lib/features/user/widgets/profile_header.dart b/lib/features/user/widgets/profile_header.dart index f1de06d..a0f2d64 100644 --- a/lib/features/user/widgets/profile_header.dart +++ b/lib/features/user/widgets/profile_header.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import '../../../core/theme/app_colors.dart'; import '../../../core/theme/app_typography.dart'; -import '../../../shared/models/tag_data.dart'; +import '../../../shared/models/tag_model.dart'; import '../../../shared/widgets/tag_badge.dart'; // 이미지, 닉네임, 소개글, 그리고 복잡했던 태그 정렬 로직 diff --git a/lib/firebase_options.dart b/lib/firebase_options.dart index 096f66a..0c91cd0 100644 --- a/lib/firebase_options.dart +++ b/lib/firebase_options.dart @@ -47,6 +47,7 @@ class DefaultFirebaseOptions { projectId: 'haenaem-65e32', authDomain: 'haenaem-65e32.firebaseapp.com', storageBucket: 'haenaem-65e32.firebasestorage.app', + measurementId: 'G-RNH78P04WT', ); static const FirebaseOptions android = FirebaseOptions( @@ -82,5 +83,7 @@ class DefaultFirebaseOptions { projectId: 'haenaem-65e32', authDomain: 'haenaem-65e32.firebaseapp.com', storageBucket: 'haenaem-65e32.firebasestorage.app', + measurementId: 'G-1RWZ2HT5L8', ); -} + +} \ No newline at end of file diff --git a/lib/shared/models/tag_data.dart b/lib/shared/models/tag_model.dart similarity index 100% rename from lib/shared/models/tag_data.dart rename to lib/shared/models/tag_model.dart From d1a35f724e8dcf17febfb448becf1e140ffeec25 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 19 Mar 2026 14:53:45 +0900 Subject: [PATCH 053/134] =?UTF-8?q?feat:=20ChallengeCard=EC=9D=98=20isLead?= =?UTF-8?q?er=20=EB=B3=80=EC=88=98=20=EC=A0=9C=EC=99=B8=ED=95=98=EA=B3=A0?= =?UTF-8?q?=20=EB=AA=A8=EB=8D=B8=20=EC=97=B0=EA=B2=B0=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/models/home_challenge_card.dart | 67 --- lib/features/home/data/home_repository.dart | 41 ++ lib/features/home/data/home_repository.g.dart | 27 ++ lib/features/home/enums/challenge_status.dart | 6 - lib/features/home/models/home_response.dart | 25 ++ lib/features/home/provider/home_provider.dart | 28 ++ .../home/provider/home_provider.g.dart | 26 ++ lib/features/home/screens/home_screen.dart | 401 ++++-------------- ...hallenge_card.dart => challenge_card.dart} | 50 +-- lib/features/home/widgets/day_chip.dart | 82 ++++ lib/shared/models/challenge_base.dart | 10 +- lib/shared/models/home_challenge_card.dart | 25 +- pubspec.lock | 160 +++---- 13 files changed, 425 insertions(+), 523 deletions(-) delete mode 100644 lib/features/challenge/models/home_challenge_card.dart create mode 100644 lib/features/home/data/home_repository.dart create mode 100644 lib/features/home/data/home_repository.g.dart delete mode 100644 lib/features/home/enums/challenge_status.dart create mode 100644 lib/features/home/models/home_response.dart create mode 100644 lib/features/home/provider/home_provider.dart create mode 100644 lib/features/home/provider/home_provider.g.dart rename lib/features/home/widgets/{home_challenge_card.dart => challenge_card.dart} (77%) create mode 100644 lib/features/home/widgets/day_chip.dart diff --git a/lib/features/challenge/models/home_challenge_card.dart b/lib/features/challenge/models/home_challenge_card.dart deleted file mode 100644 index 3e5c328..0000000 --- a/lib/features/challenge/models/home_challenge_card.dart +++ /dev/null @@ -1,67 +0,0 @@ -import 'package:haenaem/shared/models/challenge_base.dart'; - -// 최초 작성자: 강선욱 -// 홈 화면 챌린지 카드 모델 -// ChallengeBase에 정의된 필드(id, title, isLeader)를 토대로 홈 화면에서 필요한 데이터로 구성 -class HomeChallengeCard { - final ChallengeBase challengeBase; // id, title, isLeader - final int streakCount; // 최근 인증 연속 일수 - final int participantCount; // 참여 인원 수 - final int successParticipantCount; // 인증 완료 인원 수 - final bool warning; // 챌린지 실패 여부 - final bool isDone; // 오늘 인증 완료 여부 - final DateTime endDate; // 챌린지 종료 날짜 - final int weeklyFrequency; // 주간 최소 인증 빈도 - final bool isStreak; // 연속 인증 중인지 여부 - - const HomeChallengeCard({ - required this.challengeBase, - required this.streakCount, - required this.participantCount, - required this.successParticipantCount, - required this.warning, - required this.isDone, - required this.endDate, - required this.weeklyFrequency, - required this.isStreak, - }); - - factory HomeChallengeCard.fromJson(Map json) { - return HomeChallengeCard( - challengeBase: ChallengeBase.fromJson(json), - streakCount: json['streak_count'] as int, - participantCount: json['participant_count'] as int, - successParticipantCount: json['success_participant_count'] as int, - warning: json['warning'] as bool, - isDone: json['is_done'] as bool, - endDate: DateTime.parse(json['end_date'] as String), - weeklyFrequency: json['weekly_frequency'] as int, - isStreak: json['is_streak'] as bool, - ); - } - - HomeChallengeCard copyWith({ - ChallengeBase? challengeBase, - int? streakCount, - int? participantCount, - int? successParticipantCount, - bool? warning, - bool? isDone, - DateTime? endDate, - int? weeklyFrequency, - bool? isStreak, - }) { - return HomeChallengeCard( - challengeBase: challengeBase ?? this.challengeBase, - streakCount: streakCount ?? this.streakCount, - participantCount: participantCount ?? this.participantCount, - successParticipantCount: - successParticipantCount ?? this.successParticipantCount, - warning: warning ?? this.warning, - isDone: isDone ?? this.isDone, - endDate: endDate ?? this.endDate, - weeklyFrequency: weeklyFrequency ?? this.weeklyFrequency, - isStreak: isStreak ?? this.isStreak, - ); - } -} diff --git a/lib/features/home/data/home_repository.dart b/lib/features/home/data/home_repository.dart new file mode 100644 index 0000000..4e390f1 --- /dev/null +++ b/lib/features/home/data/home_repository.dart @@ -0,0 +1,41 @@ +import 'package:flutter/foundation.dart'; +import 'package:dio/dio.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:haenaem/core/network/dio_provider.dart'; +import 'package:haenaem/features/home/models/home_response.dart'; + +part 'home_repository.g.dart'; + +class HomeRepository { + final Dio _dio; + + HomeRepository(this._dio); + + Future getHomeData(String date) async { + try { + final response = await _dio.get( + '/api/mainHome', + queryParameters: {'date': date}, + ); + + if (response.statusCode == 200) { + debugPrint('📥 [HomeRepository] 서버 응답 원본: ${response.data}'); + + // HomeResponse.fromJson 안에서 myChallenges, notificationNumber 분리 + return HomeResponse.fromJson(response.data); + } else { + throw Exception( + '홈 데이터를 불러오는데 실패했습니다. (Status: ${response.statusCode})', + ); + } + } on DioException catch (e) { + throw Exception('서버 연결 실패: ${e.response?.statusMessage}'); + } + } +} + +@riverpod +HomeRepository homeRepository(HomeRepositoryRef ref) { + final dio = ref.watch(dioProvider); + return HomeRepository(dio); +} diff --git a/lib/features/home/data/home_repository.g.dart b/lib/features/home/data/home_repository.g.dart new file mode 100644 index 0000000..2353bde --- /dev/null +++ b/lib/features/home/data/home_repository.g.dart @@ -0,0 +1,27 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'home_repository.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$homeRepositoryHash() => r'096aef80ffcb164251e7870b577c8951cdba9c43'; + +/// See also [homeRepository]. +@ProviderFor(homeRepository) +final homeRepositoryProvider = AutoDisposeProvider.internal( + homeRepository, + name: r'homeRepositoryProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$homeRepositoryHash, + dependencies: null, + allTransitiveDependencies: null, +); + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +typedef HomeRepositoryRef = AutoDisposeProviderRef; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/home/enums/challenge_status.dart b/lib/features/home/enums/challenge_status.dart deleted file mode 100644 index 9808ccd..0000000 --- a/lib/features/home/enums/challenge_status.dart +++ /dev/null @@ -1,6 +0,0 @@ -// 챌린지의 상태(완료, 실패 위기, 일반)를 정의하는 열거형 -enum ChallengeStatus { - completed, // 초록색 카드 - urgent, // 빨간색 카드 - normal, // 회색 카드 -} diff --git a/lib/features/home/models/home_response.dart b/lib/features/home/models/home_response.dart new file mode 100644 index 0000000..4613e83 --- /dev/null +++ b/lib/features/home/models/home_response.dart @@ -0,0 +1,25 @@ +import 'package:haenaem/shared/models/home_challenge_card.dart'; + +// 최초 작성자: 강선욱 +// API 응답을 담는 홈 전용 모델 +// myChallenges → List로 파싱 +// notificationNumber → 별도 관리 +class HomeResponse { + final List myChallenges; + final int notificationNumber; + + const HomeResponse({ + required this.myChallenges, + required this.notificationNumber, + }); + + factory HomeResponse.fromJson(Map json) { + final List challenges = json['myChallenges'] ?? []; + return HomeResponse( + myChallenges: challenges + .map((e) => HomeChallengeCard.fromJson(e)) + .toList(), + notificationNumber: json['notificationNumber'] as int, + ); + } +} diff --git a/lib/features/home/provider/home_provider.dart b/lib/features/home/provider/home_provider.dart new file mode 100644 index 0000000..ccae42d --- /dev/null +++ b/lib/features/home/provider/home_provider.dart @@ -0,0 +1,28 @@ +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:haenaem/features/home/data/home_repository.dart'; +import 'package:haenaem/features/home/models/home_response.dart'; + +part 'home_provider.g.dart'; + +@riverpod +class HomeNotifier extends _$HomeNotifier { + @override + FutureOr build() async { + return ref + .watch(homeRepositoryProvider) + .getHomeData(_getFormattedDate(DateTime.now())); + } + + Future refresh() async { + state = const AsyncValue.loading(); + state = await AsyncValue.guard( + () => ref + .read(homeRepositoryProvider) + .getHomeData(_getFormattedDate(DateTime.now())), + ); + } + + String _getFormattedDate(DateTime dateTime) { + return "${dateTime.year}-${dateTime.month.toString().padLeft(2, '0')}-${dateTime.day.toString().padLeft(2, '0')}"; + } +} diff --git a/lib/features/home/provider/home_provider.g.dart b/lib/features/home/provider/home_provider.g.dart new file mode 100644 index 0000000..b2a7cfd --- /dev/null +++ b/lib/features/home/provider/home_provider.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'home_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$homeNotifierHash() => r'79469b283e0bb3cd1f61eccb03f0923297609835'; + +/// See also [HomeNotifier]. +@ProviderFor(HomeNotifier) +final homeNotifierProvider = + AutoDisposeAsyncNotifierProvider.internal( + HomeNotifier.new, + name: r'homeNotifierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$homeNotifierHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$HomeNotifier = AutoDisposeAsyncNotifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/home/screens/home_screen.dart b/lib/features/home/screens/home_screen.dart index 49573ee..b806de2 100644 --- a/lib/features/home/screens/home_screen.dart +++ b/lib/features/home/screens/home_screen.dart @@ -1,23 +1,24 @@ -// 최초 작성자 : 강선욱 import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; // 추가 import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/features/challenge/create/screens/challenge_create_screen.dart'; -import 'package:haenaem/features/challenge/models/challenge_model.dart'; -import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import 'package:haenaem/features/challenge/detail/screens/challenge_main_screen.dart'; +import '../provider/home_provider.dart'; import 'package:haenaem/features/notification/screens/notification_main_screen.dart'; import 'package:haenaem/features/notification/provider/notification_provider.dart'; +import 'package:haenaem/shared/models/home_challenge_card.dart'; +import '../widgets/challenge_card.dart'; +import '../widgets/day_chip.dart'; +// 최초 작성자 : 강선욱 +// 홈 화면 빌드 클래스 class HomeScreen extends ConsumerWidget { const HomeScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { - final homeDataAsync = ref.watch(challengeHomeNotifierProvider); - final todayStatus = ref.watch(todayTotalStatusProvider); + final homeDataAsync = ref.watch(homeNotifierProvider); DateTime now = DateTime.now(); DateTime firstDayOfWeek = now.subtract(Duration(days: now.weekday % 7)); @@ -32,72 +33,78 @@ class HomeScreen extends ConsumerWidget { child: homeDataAsync.when( loading: () => const Center(child: CircularProgressIndicator()), error: (err, stack) => Center(child: Text('데이터 에러: $err')), - data: (data) => Stack( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - // 상단 바 - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 20, - vertical: 12, - ), - child: Row( - children: [ - Text(getFormattedDate(), style: AppTypography.h2), - const Spacer(), - // 알림 배지 (data.notificationNumber 사용) - _buildNotificationIcon( - context, - ref, - data.notificationNumber, - ), - ], - ), - ), - // 주간 캘린더 - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 20, - vertical: 4, + data: (data) { + // 모든 챌린지가 isDone이면 오늘 완료로 판단 + final todayIsDone = + data.myChallenges.isNotEmpty && + data.myChallenges.every((c) => c.isDone); + // 하나라도 warning이면 오늘 위험으로 판단 + final todayIsWarning = data.myChallenges.any((c) => c.warning); + + return Stack( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // 상단 바 + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 20, + vertical: 12, + ), + child: Row( + children: [ + Text(getFormattedDate(), style: AppTypography.h2), + const Spacer(), + // 알림 배지 (data.notificationNumber 사용) + _buildNotificationIcon( + context, + ref, + data.notificationNumber, + ), + ], + ), ), - child: Row( - children: weekDays.map((date) { - final isToday = - date.year == now.year && - date.month == now.month && - date.day == now.day; - return _DayChip( - date: date, - isSelected: isToday, - status: isToday - ? todayStatus - : ChallengeStatus.normal, - ); - }).toList(), + // 주간 캘린더 + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 20, + vertical: 4, + ), + child: Row( + children: weekDays.map((date) { + final isToday = + date.year == now.year && + date.month == now.month && + date.day == now.day; + return DayChip( + date: date, + isSelected: isToday, + isDone: isToday ? todayIsDone : false, + isWarning: isToday ? todayIsWarning : false, + ); + }).toList(), + ), ), - ), - const SizedBox(height: 24), - // 챌린지 리스트 (data.myChallenges 전달) - Expanded( - child: RefreshIndicator( - onRefresh: () => ref - .read(challengeHomeNotifierProvider.notifier) - .refresh(), - child: ChallengeListView( - challenges: - data.myChallenges, // List> - model: data, // getStatus 호출을 위해 모델 전달 + const SizedBox(height: 24), + // 챌린지 리스트 (data.myChallenges 전달) + Expanded( + child: RefreshIndicator( + onRefresh: () => + ref.read(homeNotifierProvider.notifier).refresh(), + child: ChallengeListView( + challenges: + data.myChallenges, // getStatus 호출을 위해 모델 전달 + ), ), ), - ), - ], - ), - // Floating Action Button - _buildFAB(context), - ], - ), + ], + ), + // Floating Action Button + _buildFAB(context), + ], + ); + }, ), ), ); @@ -134,7 +141,7 @@ class HomeScreen extends ConsumerWidget { // 처음 들어갈 때 안 읽은 알림이 있었거나 OR 안에서 챌린지 수락/거절을 했다면 새로고침! if (hasUnreadInitially || hasActionOccurred) { - ref.read(challengeHomeNotifierProvider.notifier).refresh(); + ref.read(homeNotifierProvider.notifier).refresh(); // 스위치는 다시 꺼줍니다 ref.read(needsHomeRefreshProvider.notifier).state = false; @@ -190,14 +197,9 @@ class HomeScreen extends ConsumerWidget { // 챌린지 리스트 뷰 class ChallengeListView extends StatelessWidget { - final List> challenges; - final ChallengeMainModel model; // 상태 계산 로직을 쓰기 위해 추가 + final List challenges; - const ChallengeListView({ - super.key, - required this.challenges, - required this.model, - }); + const ChallengeListView({super.key, required this.challenges}); @override Widget build(BuildContext context) { @@ -207,10 +209,7 @@ class ChallengeListView extends StatelessWidget { padding: const EdgeInsets.only(bottom: 100), itemCount: challenges.length, itemBuilder: (context, index) { - return ChallengeCard( - challenge: challenges[index], - status: model.getStatus(index), // 모델의 헬퍼 함수 활용 - ); + return ChallengeCard(challenge: challenges[index]); }, ); } @@ -234,245 +233,3 @@ class ChallengeListView extends StatelessWidget { ); } } - -// 챌린지 카드 -class ChallengeCard extends StatelessWidget { - final Map challenge; - final ChallengeStatus status; - - const ChallengeCard({ - super.key, - required this.challenge, - required this.status, - }); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => ChallengeMainScreen( - challengeId: challenge['challengeId'] ?? 0, - challengeTitle: challenge['title'], - ), - ), - ); - }, - child: Padding( - padding: const EdgeInsets.only(left: 20, right: 20, bottom: 12), - child: Container( - padding: const EdgeInsets.all(20), - decoration: BoxDecoration( - color: _getCardColor(status), - borderRadius: BorderRadius.circular(12), - ), - child: IntrinsicHeight( - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - challenge['title'] ?? '', - style: AppTypography.b1.copyWith( - fontWeight: FontWeight.bold, - fontSize: 16, - ), - ), - const SizedBox(height: 4), - _buildSuccessDays(), - const SizedBox(height: 4), - _buildBottomInfo(), - ], - ), - ), - _buildDivider(), - SizedBox(width: 44, child: Center(child: _buildStatusIcon())), - ], - ), - ), - ), - ), - ); - } - - Widget _buildSuccessDays() { - final during = challenge['duringDate'] ?? 0; - final isDone = challenge['doIt'] ?? false; - return Row( - children: [ - if (during >= 2 && isDone) - Padding( - padding: const EdgeInsets.only(right: 4), - child: SvgPicture.asset( - 'assets/images/icons/small_fire_icon.svg', - width: 16, - height: 16, - ), - ), - Text('$during일째', style: AppTypography.b2.copyWith(fontSize: 14)), - ], - ); - } - - Widget _buildBottomInfo() { - if (status == ChallengeStatus.urgent) { - return const Text( - '오늘 챌린지를 하지 않으면 실패해요!', - style: TextStyle(color: AppColors.notification, fontSize: 12), - ); - } - return Row( - children: [ - SvgPicture.asset( - 'assets/images/icons/mini_success_icon.svg', - width: 16, - height: 16, - ), - const SizedBox(width: 4), - Text( - '인증인원 ${challenge['todaySuccessCount']}/${challenge['participantNumber']}', - style: AppTypography.b2.copyWith(fontSize: 14), - ), - ], - ); - } - - Widget _buildDivider() { - return SizedBox( - width: 40, - child: Center( - child: CustomPaint( - size: const Size(1, double.infinity), - painter: VerticalDashPainter(), - ), - ), - ); - } - - Widget _buildStatusIcon() { - if (status == ChallengeStatus.completed) - return SvgPicture.asset('assets/images/icons/success_icon.svg'); - if (status == ChallengeStatus.urgent) - return SvgPicture.asset('assets/images/icons/warning_icon.svg'); - return const SizedBox(width: 24); - } - - Color _getCardColor(ChallengeStatus status) { - if (status == ChallengeStatus.completed) return AppColors.success; - if (status == ChallengeStatus.urgent) return AppColors.warning; - return AppColors.gray5; - } -} - -class VerticalDashPainter extends CustomPainter { - @override - void paint(Canvas canvas, Size size) { - double dashHeight = 5, dashSpace = 3, startY = 0; - // 캔버스의 중앙 X축 계산 - final double centerX = size.width / 2; - final paint = Paint() - ..color = AppColors - .gray3 // 점선 색상 농도 조절 - ..strokeWidth = 1; - - while (startY < size.height) { - // Offset의 X좌표를 centerX로 고정하여 직선도 유지 - canvas.drawLine( - Offset(centerX, startY), - Offset(centerX, startY + dashHeight), - paint, - ); - startY += dashHeight + dashSpace; - } - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => false; -} - -class _DayChip extends StatelessWidget { - final DateTime date; - final bool isSelected; - final ChallengeStatus status; // 추가됨 - - const _DayChip({ - required this.date, - this.isSelected = false, - this.status = ChallengeStatus.normal, - }); - - @override - Widget build(BuildContext context) { - const Color black = AppColors.black; - const Color gray2 = AppColors.gray2; - - // 요일 레이블 매핑 - const weekdayLabels = ['일', '월', '화', '수', '목', '금', '토']; - String label = weekdayLabels[date.weekday % 7]; - String day = date.day.toString(); - - // 테두리 결정 로직 - final bool showBorder = isSelected && status == ChallengeStatus.normal; - - return Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text(label, style: AppTypography.b1.copyWith(color: AppColors.black)), - const SizedBox(height: 8), - Container( - width: 40, - height: 40, - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 9), - decoration: ShapeDecoration( - color: getBackgroundColor(), - shape: RoundedRectangleBorder( - // 💡 오늘 날짜일 때만 테두리(Outside) 적용 - side: showBorder - ? const BorderSide( - width: 1, - strokeAlign: BorderSide.strokeAlignOutside, - color: gray2, - ) - : BorderSide.none, - borderRadius: BorderRadius.circular(5), - ), - ), - alignment: Alignment.center, - child: Text( - day, - style: TextStyle( - color: isSelected && status != ChallengeStatus.normal - ? Colors.white - : gray2, - fontSize: 14, - fontFamily: 'Pretendard', - fontWeight: isSelected ? FontWeight.w700 : FontWeight.w400, - height: 1.50, - ), - ), - ), - ], - ), - ); - } - - Color getBackgroundColor() { - if (!isSelected) return AppColors.gray5; - - // 💡 오늘일 경우: 상태에 따른 강조색 - switch (status) { - case ChallengeStatus.urgent: - return AppColors.notification; // 실패 위기 (빨강) - case ChallengeStatus.completed: - return AppColors.primaryAble; // 완료 (초록) - case ChallengeStatus.normal: - default: - return AppColors.gray5; // 미완료 상태인 오늘 (회색) - } - } -} diff --git a/lib/features/home/widgets/home_challenge_card.dart b/lib/features/home/widgets/challenge_card.dart similarity index 77% rename from lib/features/home/widgets/home_challenge_card.dart rename to lib/features/home/widgets/challenge_card.dart index 8a4528a..6b5bb4c 100644 --- a/lib/features/home/widgets/home_challenge_card.dart +++ b/lib/features/home/widgets/challenge_card.dart @@ -4,18 +4,18 @@ import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/shared/models/home_challenge_card.dart'; -import '../enums/challenge_status.dart'; import 'package:haenaem/features/challenge/detail/screens/challenge_main_screen.dart'; class ChallengeCard extends StatelessWidget { - final Map challenge; - final ChallengeStatus status; + final HomeChallengeCard challenge; - const ChallengeCard({ - super.key, - required this.challenge, - required this.status, - }); + const ChallengeCard({super.key, required this.challenge}); + + Color get _cardColor { + if (challenge.isDone) return AppColors.success; + if (challenge.warning) return AppColors.warning; + return AppColors.gray5; + } @override Widget build(BuildContext context) { @@ -25,8 +25,8 @@ class ChallengeCard extends StatelessWidget { context, MaterialPageRoute( builder: (context) => ChallengeMainScreen( - challengeId: challenge['challengeId'] ?? 0, - challengeTitle: challenge['title'], + challengeId: challenge.challengeBase.id, + challengeTitle: challenge.challengeBase.title, ), ), ); @@ -36,7 +36,7 @@ class ChallengeCard extends StatelessWidget { child: Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( - color: _getCardColor(status), + color: _cardColor, borderRadius: BorderRadius.circular(12), ), child: IntrinsicHeight( @@ -47,14 +47,14 @@ class ChallengeCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - challenge['title'] ?? '', + challenge.challengeBase.title, style: AppTypography.b1.copyWith( fontWeight: FontWeight.bold, fontSize: 16, ), ), const SizedBox(height: 4), - _buildSuccessDays(), + _buildStreakInfo(), const SizedBox(height: 4), _buildBottomInfo(), ], @@ -70,12 +70,12 @@ class ChallengeCard extends StatelessWidget { ); } - Widget _buildSuccessDays() { - final during = challenge['duringDate'] ?? 0; - final isDone = challenge['doIt'] ?? false; + Widget _buildStreakInfo() { + final streakCount = challenge.streakCount; + return Row( children: [ - if (during >= 2 && isDone) + if (streakCount > 0 && challenge.isDone) Padding( padding: const EdgeInsets.only(right: 4), child: SvgPicture.asset( @@ -84,13 +84,13 @@ class ChallengeCard extends StatelessWidget { height: 16, ), ), - Text('$during일째', style: AppTypography.b2.copyWith(fontSize: 14)), + Text('$streakCount일째', style: AppTypography.b2.copyWith(fontSize: 14)), ], ); } Widget _buildBottomInfo() { - if (status == ChallengeStatus.urgent) { + if (challenge.warning) { return const Text( '오늘 챌린지를 하지 않으면 실패해요!', style: TextStyle(color: AppColors.notification, fontSize: 12), @@ -105,7 +105,7 @@ class ChallengeCard extends StatelessWidget { ), const SizedBox(width: 4), Text( - '인증인원 ${challenge['todaySuccessCount']}/${challenge['participantNumber']}', + '인증인원 ${challenge.successParticipantCount}/${challenge.participantCount}', style: AppTypography.b2.copyWith(fontSize: 14), ), ], @@ -125,18 +125,12 @@ class ChallengeCard extends StatelessWidget { } Widget _buildStatusIcon() { - if (status == ChallengeStatus.completed) + if (challenge.isDone) return SvgPicture.asset('assets/images/icons/success_icon.svg'); - if (status == ChallengeStatus.urgent) + if (challenge.warning) return SvgPicture.asset('assets/images/icons/warning_icon.svg'); return const SizedBox(width: 24); } - - Color _getCardColor(ChallengeStatus status) { - if (status == ChallengeStatus.completed) return AppColors.success; - if (status == ChallengeStatus.urgent) return AppColors.warning; - return AppColors.gray5; - } } class VerticalDashPainter extends CustomPainter { diff --git a/lib/features/home/widgets/day_chip.dart b/lib/features/home/widgets/day_chip.dart new file mode 100644 index 0000000..7017992 --- /dev/null +++ b/lib/features/home/widgets/day_chip.dart @@ -0,0 +1,82 @@ +import 'package:flutter/material.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; +import 'package:haenaem/features/challenge/models/challenge_model.dart'; + +class DayChip extends StatelessWidget { + final DateTime date; + final bool isSelected; + final bool isDone; + final bool isWarning; + + const DayChip({ + super.key, + required this.date, + this.isSelected = false, + this.isDone = false, + this.isWarning = false, + }); + + @override + Widget build(BuildContext context) { + const Color gray2 = AppColors.gray2; + + // 요일 레이블 매핑 + const weekdayLabels = ['일', '월', '화', '수', '목', '금', '토']; + String label = weekdayLabels[date.weekday % 7]; + String day = date.day.toString(); + + // 테두리 결정 로직 + final bool showBorder = isSelected && !isDone && !isWarning; + + return Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(label, style: AppTypography.b1.copyWith(color: AppColors.black)), + const SizedBox(height: 8), + Container( + width: 40, + height: 40, + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 9), + decoration: ShapeDecoration( + color: getBackgroundColor(), + shape: RoundedRectangleBorder( + // 💡 오늘 날짜일 때만 테두리(Outside) 적용 + side: showBorder + ? const BorderSide( + width: 1, + strokeAlign: BorderSide.strokeAlignOutside, + color: gray2, + ) + : BorderSide.none, + borderRadius: BorderRadius.circular(5), + ), + ), + alignment: Alignment.center, + child: Text( + day, + style: TextStyle( + color: isSelected && (isDone || isWarning) + ? Colors.white + : gray2, + fontSize: 14, + fontFamily: 'Pretendard', + fontWeight: isSelected ? FontWeight.w700 : FontWeight.w400, + height: 1.50, + ), + ), + ), + ], + ), + ); + } + + Color getBackgroundColor() { + if (!isSelected) return AppColors.gray5; + + if (isWarning) return AppColors.notification; + if (isDone) return AppColors.primaryAble; + return AppColors.gray5; + } +} diff --git a/lib/shared/models/challenge_base.dart b/lib/shared/models/challenge_base.dart index fb1aa59..431d8e7 100644 --- a/lib/shared/models/challenge_base.dart +++ b/lib/shared/models/challenge_base.dart @@ -3,19 +3,19 @@ class ChallengeBase { final int id; final String title; - final bool isLeader; // 현재 로그인 중인 유저가 해당 챌린지의 방장인지 여부 + // final bool isLeader; // 현재 로그인 중인 유저가 해당 챌린지의 방장인지 여부 const ChallengeBase({ required this.id, required this.title, - required this.isLeader, + // required this.isLeader, }); factory ChallengeBase.fromJson(Map json) { return ChallengeBase( - id: json['id'] as int, + id: json['challengeId'] as int, title: json['title'] as String, - isLeader: json['is_leader'] as bool, + // isLeader: json['is_leader'] as bool, ); } @@ -23,7 +23,7 @@ class ChallengeBase { return ChallengeBase( id: id ?? this.id, title: title ?? this.title, - isLeader: isLeader ?? this.isLeader, + // isLeader: isLeader ?? this.isLeader, ); } } diff --git a/lib/shared/models/home_challenge_card.dart b/lib/shared/models/home_challenge_card.dart index a52d008..35415e2 100644 --- a/lib/shared/models/home_challenge_card.dart +++ b/lib/shared/models/home_challenge_card.dart @@ -10,9 +10,8 @@ class HomeChallengeCard { final int successParticipantCount; // 인증 완료 인원 수 final bool warning; // 챌린지 실패 여부 final bool isDone; // 오늘 인증 완료 여부 - final DateTime endDate; // 챌린지 종료 날짜 + final int dDay; // 챌린지 종료까지 남은 날짜 final int weeklyFrequency; // 주간 최소 인증 빈도 - final bool isStreak; // 연속 인증 중인지 여부 const HomeChallengeCard({ required this.challengeBase, @@ -21,22 +20,20 @@ class HomeChallengeCard { required this.successParticipantCount, required this.warning, required this.isDone, - required this.endDate, + required this.dDay, required this.weeklyFrequency, - required this.isStreak, }); factory HomeChallengeCard.fromJson(Map json) { return HomeChallengeCard( challengeBase: ChallengeBase.fromJson(json), - streakCount: json['streak_count'] as int, - participantCount: json['participant_count'] as int, - successParticipantCount: json['success_participant_count'] as int, + streakCount: json['currentStreak'] as int, + participantCount: json['participantNumber'] as int, + successParticipantCount: json['todaySuccessCount'] as int, warning: json['warning'] as bool, - isDone: json['is_done'] as bool, - endDate: DateTime.parse(json['end_date'] as String), - weeklyFrequency: json['weekly_frequency'] as int, - isStreak: json['is_streak'] as bool, + isDone: json['doIt'] as bool, + dDay: json['dueToDate'] as int, + weeklyFrequency: json['requiredWeeklyCount'] as int, ); } @@ -47,9 +44,8 @@ class HomeChallengeCard { int? successParticipantCount, bool? warning, bool? isDone, - DateTime? endDate, + int? dDay, int? weeklyFrequency, - bool? isStreak, }) { return HomeChallengeCard( challengeBase: challengeBase ?? this.challengeBase, @@ -59,9 +55,8 @@ class HomeChallengeCard { successParticipantCount ?? this.successParticipantCount, warning: warning ?? this.warning, isDone: isDone ?? this.isDone, - endDate: endDate ?? this.endDate, + dDay: dDay ?? this.dDay, weeklyFrequency: weeklyFrequency ?? this.weeklyFrequency, - isStreak: isStreak ?? this.isStreak, ); } } diff --git a/pubspec.lock b/pubspec.lock index 670a919..b8d10f1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: cd83f7d6bd4e4c0b0b4fef802e8796784032e1cc23d7b0e982cf5d05d9bbe182 + sha256: afe15ce18a287d2f89da95566e62892df339b1936bbe9b83587df45b944ee72a url: "https://pub.dev" source: hosted - version: "1.3.66" + version: "1.3.67" analyzer: dependency: transitive description: @@ -45,10 +45,10 @@ packages: dependency: transitive description: name: archive - sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" + sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff url: "https://pub.dev" source: hosted - version: "4.0.7" + version: "4.0.9" args: dependency: transitive description: @@ -77,10 +77,10 @@ packages: dependency: "direct main" description: name: audioplayers - sha256: "5441fa0ceb8807a5ad701199806510e56afde2b4913d9d17c2f19f2902cf0ae4" + sha256: a72dd459d1a48f61a6fb9c0134dba26597c9236af40639ff0eb70eb4e0baab70 url: "https://pub.dev" source: hosted - version: "6.5.1" + version: "6.6.0" audioplayers_android: dependency: transitive description: @@ -93,10 +93,10 @@ packages: dependency: transitive description: name: audioplayers_darwin - sha256: "0811d6924904ca13f9ef90d19081e4a87f7297ddc19fc3d31f60af1aaafee333" + sha256: c994b3bb3a921e4904ac40e013fbc94488e824fd7c1de6326f549943b0b44a91 url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "6.4.0" audioplayers_linux: dependency: transitive description: @@ -117,18 +117,18 @@ packages: dependency: transitive description: name: audioplayers_web - sha256: "1c0f17cec68455556775f1e50ca85c40c05c714a99c5eb1d2d57cc17ba5522d7" + sha256: faa8fa6587f996a6f604433b53af44c57a1407d4fe8dff5766cf63d6875e8de9 url: "https://pub.dev" source: hosted - version: "5.1.1" + version: "5.2.0" audioplayers_windows: dependency: transitive description: name: audioplayers_windows - sha256: "4048797865105b26d47628e6abb49231ea5de84884160229251f37dfcbe52fd7" + sha256: bafff2b38b6f6d331887558ba6e0a01c9c208d9dbb3ad0005234db065122a734 url: "https://pub.dev" source: hosted - version: "4.2.1" + version: "4.3.0" boolean_selector: dependency: transitive description: @@ -197,34 +197,34 @@ packages: dependency: transitive description: name: built_value - sha256: "7931c90b84bc573fef103548e354258ae4c9d28d140e41961df6843c5d60d4d8" + sha256: "6ae8a6435a8c6520c7077b107e77f1fb4ba7009633259a4d49a8afd8e7efc5e9" url: "https://pub.dev" source: hosted - version: "8.12.3" + version: "8.12.4" camera: dependency: "direct main" description: name: camera - sha256: eefad89f262a873f38d21e5eec853461737ea074d7c9ede39f3ceb135d201cab + sha256: "4142a19a38e388d3bab444227636610ba88982e36dff4552d5191a86f65dc437" url: "https://pub.dev" source: hosted - version: "0.11.3" + version: "0.11.4" camera_android_camerax: dependency: transitive description: name: camera_android_camerax - sha256: dba476d6c316671ae943f20ad7d02b3d363eed0dbfd25465bb92d42e35faacd8 + sha256: "8516fe308bc341a5067fb1a48edff0ddfa57c0d3cdcc9dbe7ceca3ba119e2577" url: "https://pub.dev" source: hosted - version: "0.6.28" + version: "0.6.30" camera_avfoundation: dependency: transitive description: name: camera_avfoundation - sha256: a600b60a7752cc5fa9de476cd0055539d7a3b9d62662f4f446bae49eba2267df + sha256: "11b4aee2f5e5e038982e152b4a342c749b414aa27857899d20f4323e94cb5f0b" url: "https://pub.dev" source: hosted - version: "0.9.22+9" + version: "0.9.23+2" camera_platform_interface: dependency: transitive description: @@ -245,10 +245,10 @@ packages: dependency: transitive description: name: characters - sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.4.0" checked_yaml: dependency: transitive description: @@ -309,10 +309,10 @@ packages: dependency: transitive description: name: cross_file - sha256: "701dcfc06da0882883a2657c445103380e53e647060ad8d9dfb710c100996608" + sha256: "28bb3ae56f117b5aec029d702a90f57d285cd975c3c5c281eaca38dbc47c5937" url: "https://pub.dev" source: hosted - version: "0.3.5+1" + version: "0.3.5+2" crypto: dependency: transitive description: @@ -365,18 +365,18 @@ packages: dependency: "direct main" description: name: dio - sha256: b9d46faecab38fc8cc286f80bc4d61a3bb5d4ac49e51ed877b4d6706efe57b25 + sha256: aff32c08f92787a557dd5c0145ac91536481831a01b4648136373cddb0e64f8c url: "https://pub.dev" source: hosted - version: "5.9.1" + version: "5.9.2" dio_web_adapter: dependency: transitive description: name: dio_web_adapter - sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" + sha256: "2f9e64323a7c3c7ef69567d5c800424a11f8337b8b228bad02524c9fb3c1f340" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" encrypt: dependency: transitive description: @@ -413,10 +413,10 @@ packages: dependency: transitive description: name: ffi - sha256: d07d37192dbf97461359c1518788f203b0c9102cfd2c35a716b823741219542c + sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45" url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.2.0" file: dependency: transitive description: @@ -461,10 +461,10 @@ packages: dependency: transitive description: name: firebase_core - sha256: "923085c881663ef685269b013e241b428e1fb03cdd0ebde265d9b40ff18abf80" + sha256: f0997fee80fbb6d2c658c5b88ae87ba1f9506b5b37126db64fc2e75d8e977fbb url: "https://pub.dev" source: hosted - version: "4.4.0" + version: "4.5.0" firebase_core_platform_interface: dependency: transitive description: @@ -477,34 +477,34 @@ packages: dependency: transitive description: name: firebase_core_web - sha256: "83e7356c704131ca4d8d8dd57e360d8acecbca38b1a3705c7ae46cc34c708084" + sha256: "856ca92bf2d75a63761286ab8e791bda3a85184c2b641764433b619647acfca6" url: "https://pub.dev" source: hosted - version: "3.4.0" + version: "3.5.0" firebase_messaging: dependency: "direct main" description: name: firebase_messaging - sha256: "06fad40ea14771e969a8f2bbce1944aa20ee2f4f57f4eca5b3ba346b65f3f644" + sha256: bd17823b70e629877904d384841cda72ed2cc197517404c0c90da5c0ba786a8c url: "https://pub.dev" source: hosted - version: "16.1.1" + version: "16.1.2" firebase_messaging_platform_interface: dependency: transitive description: name: firebase_messaging_platform_interface - sha256: "6c49e901c77e6e10e86d98e32056a087eb1ca1b93acdf58524f1961e617657b7" + sha256: "550435235cc7d53683f32bf0762c28ef8cfc20a8d36318a033676ae09526d7fb" url: "https://pub.dev" source: hosted - version: "4.7.6" + version: "4.7.7" firebase_messaging_web: dependency: transitive description: name: firebase_messaging_web - sha256: "2756f8fea583ffb9d294d15ddecb3a9ad429b023b70c9990c151fc92c54a32b3" + sha256: "6b1b93ed90309fbce91c219e3cd32aa831e8eccaf4a61f3afaea1625479275d2" url: "https://pub.dev" source: hosted - version: "4.1.2" + version: "4.1.3" fixnum: dependency: transitive description: @@ -689,18 +689,18 @@ packages: dependency: transitive description: name: google_sign_in_android - sha256: "5ec98ab35387c68c0050495bb211bd88375873723a80fae7c2e9266ea0bdd8bb" + sha256: f353140580797e01c1f35748810326f326664c52040b6f62d88e7d6d1cd30917 url: "https://pub.dev" source: hosted - version: "7.2.7" + version: "7.2.9" google_sign_in_ios: dependency: transitive description: name: google_sign_in_ios - sha256: "234fc2830b55d1bbeb7e05662967691f5994143ff43dc70d3f139d1bbb3b8fb2" + sha256: ac1e4c1205267cb7999d1d81333fccffdfda29e853f434bbaf71525498bb6950 url: "https://pub.dev" source: hosted - version: "6.2.5" + version: "6.3.0" google_sign_in_platform_interface: dependency: transitive description: @@ -713,10 +713,10 @@ packages: dependency: transitive description: name: google_sign_in_web - sha256: "2fc1f941e6443b2d6984f4056a727a3eaeab15d8ee99ba7125d79029be75a1da" + sha256: d473003eeca892f96a01a64fc803378be765071cb0c265ee872c7f8683245d14 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.3" graphs: dependency: transitive description: @@ -769,10 +769,10 @@ packages: dependency: "direct main" description: name: image - sha256: "492bd52f6c4fbb6ee41f781ff27765ce5f627910e1e0cbecfa3d9add5562604c" + sha256: f9881ff4998044947ec38d098bc7c8316ae1186fa786eddffdb867b9bc94dfce url: "https://pub.dev" source: hosted - version: "4.7.2" + version: "4.8.0" image_gallery_saver_plus: dependency: "direct main" description: @@ -793,10 +793,10 @@ packages: dependency: transitive description: name: image_picker_android - sha256: "518a16108529fc18657a3e6dde4a043dc465d16596d20ab2abd49a4cac2e703d" + sha256: eda9b91b7e266d9041084a42d605a74937d996b87083395c5e47835916a86156 url: "https://pub.dev" source: hosted - version: "0.8.13+13" + version: "0.8.13+14" image_picker_for_web: dependency: transitive description: @@ -809,10 +809,10 @@ packages: dependency: transitive description: name: image_picker_ios - sha256: "956c16a42c0c708f914021666ffcd8265dde36e673c9fa68c81f7d085d9774ad" + sha256: b9c4a438a9ff4f60808c9cf0039b93a42bb6c2211ef6ebb647394b2b3fa84588 url: "https://pub.dev" source: hosted - version: "0.8.13+3" + version: "0.8.13+6" image_picker_linux: dependency: transitive description: @@ -873,10 +873,10 @@ packages: dependency: transitive description: name: json_annotation - sha256: "805fa86df56383000f640384b282ce0cb8431f1a7a2396de92fb66186d8c57df" + sha256: cb09e7dac6210041fad964ed7fbee004f14258b4eca4040f72d1234062ace4c8 url: "https://pub.dev" source: hosted - version: "4.10.0" + version: "4.11.0" kakao_flutter_sdk: dependency: "direct main" description: @@ -993,18 +993,18 @@ packages: dependency: transitive description: name: matcher - sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.18" + version: "0.12.17" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.13.0" + version: "0.11.1" meta: dependency: transitive description: @@ -1105,18 +1105,18 @@ packages: dependency: transitive description: name: petitparser - sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1" + sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675" url: "https://pub.dev" source: hosted - version: "7.0.1" + version: "7.0.2" photo_manager: dependency: "direct main" description: name: photo_manager - sha256: "807688e3221e90fb02a4466746edd9cb9a0de025f8754c819f96604c00f6f1f5" + sha256: fb3bc8ea653370f88742b3baa304700107c83d12748aa58b2b9f2ed3ef15e6c2 url: "https://pub.dev" source: hosted - version: "3.8.3" + version: "3.9.0" photo_manager_image_provider: dependency: "direct main" description: @@ -1161,10 +1161,10 @@ packages: dependency: transitive description: name: posix - sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" + sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07" url: "https://pub.dev" source: hosted - version: "6.0.3" + version: "6.5.0" pub_semver: dependency: transitive description: @@ -1326,10 +1326,10 @@ packages: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" url: "https://pub.dev" source: hosted - version: "1.10.1" + version: "1.10.2" stack_trace: dependency: transitive description: @@ -1398,10 +1398,10 @@ packages: dependency: transitive description: name: test_api - sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 url: "https://pub.dev" source: hosted - version: "0.7.9" + version: "0.7.7" timing: dependency: transitive description: @@ -1446,10 +1446,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" + sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2" url_launcher_windows: dependency: transitive description: @@ -1462,18 +1462,18 @@ packages: dependency: transitive description: name: uuid - sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8 + sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489" url: "https://pub.dev" source: hosted - version: "4.5.2" + version: "4.5.3" vector_graphics: dependency: transitive description: name: vector_graphics - sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6 + sha256: "7076216a10d5c390315fbe536a30f1254c341e7543e6c4c8a815e591307772b1" url: "https://pub.dev" source: hosted - version: "1.1.19" + version: "1.1.20" vector_graphics_codec: dependency: transitive description: @@ -1486,10 +1486,10 @@ packages: dependency: transitive description: name: vector_graphics_compiler - sha256: "201e876b5d52753626af64b6359cd13ac6011b80728731428fd34bc840f71c9b" + sha256: "5a88dd14c0954a5398af544651c7fb51b457a2a556949bfb25369b210ef73a74" url: "https://pub.dev" source: hosted - version: "1.1.20" + version: "1.2.0" vector_math: dependency: transitive description: @@ -1566,10 +1566,10 @@ packages: dependency: transitive description: name: webview_flutter_wkwebview - sha256: fc0af89d403e1c053f03d023d97550412fa79f35332e2939514c82e6fe633198 + sha256: "2df8fd9ada04d699b9db8e79aa783a16e5d89b69e5b74009b87e16b59912cf98" url: "https://pub.dev" source: hosted - version: "3.23.8" + version: "3.24.0" win32: dependency: transitive description: @@ -1603,5 +1603,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.9.2 <4.0.0" - flutter: ">=3.35.0" + dart: ">=3.10.0 <4.0.0" + flutter: ">=3.38.0" From ef8f269f1c8f7e41db61cf827d926792554f111e Mon Sep 17 00:00:00 2001 From: Chaeyeong_10 Date: Thu, 19 Mar 2026 18:44:26 +0900 Subject: [PATCH 054/134] =?UTF-8?q?refactor:=20=EC=A0=84=EC=97=AD=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=20=EC=83=81=ED=83=9C=20=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EB=8F=84=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/auth/services/auth_service.dart | 7 ++--- .../auth/signup/screens/auth_gate.dart | 17 +++++++----- .../widgets/challenge_detail_content.dart | 7 +---- lib/features/user/provider/user_provider.dart | 26 +++++++++++++++++++ .../user/provider/user_provider.g.dart | 26 +++++++++++++++++++ lib/main.dart | 7 ----- pubspec.lock | 24 ++++++++--------- pubspec.yaml | 5 ++-- 8 files changed, 83 insertions(+), 36 deletions(-) create mode 100644 lib/features/user/provider/user_provider.dart create mode 100644 lib/features/user/provider/user_provider.g.dart diff --git a/lib/features/auth/services/auth_service.dart b/lib/features/auth/services/auth_service.dart index 40bafbd..c0f496e 100644 --- a/lib/features/auth/services/auth_service.dart +++ b/lib/features/auth/services/auth_service.dart @@ -23,16 +23,17 @@ class AuthService { // 카카오 설정 정보 static const String kakaoRestApiKey = '9fdd13c0777c415d8fa4055b5b26a6c5'; static const String kakaoNativeAppKey = '05a36f172ea2945260862834654385ea'; - // static const String kakaoRedirectUri = - // 'https://hanaem.onrender.com/api/oauth/kakao/token'; static const String kakaoRedirectUri = - 'kakao9fdd13c0777c415d8fa4055b5b26a6c5://oauth'; + 'https://hanaem.onrender.com/api/oauth/kakao/token'; + //static const String kakaoRedirectUri = + //'kakao9fdd13c0777c415d8fa4055b5b26a6c5://oauth'; static final Dio _dio = Dio( BaseOptions(baseUrl: 'https://hanaem.onrender.com'), ); // 카카오 로그인 + static Future?> signInWithKakao() async { try { // 구글과 동일하게 인가 요청을 보냅니다. diff --git a/lib/features/auth/signup/screens/auth_gate.dart b/lib/features/auth/signup/screens/auth_gate.dart index 46fb919..fc96797 100644 --- a/lib/features/auth/signup/screens/auth_gate.dart +++ b/lib/features/auth/signup/screens/auth_gate.dart @@ -7,6 +7,7 @@ import 'package:haenaem/features/auth/login/login_screen.dart'; import 'signup_main_screen.dart'; import 'package:haenaem/features/user/data/user_repository.dart'; import 'package:haenaem/features/user/models/user_model.dart'; +import 'package:haenaem/features/user/provider/user_provider.dart'; import 'package:haenaem/features/notification/services/fcm_service.dart'; // 앱을 껐다 켰을 때 저장된 토큰을 확인 @@ -39,22 +40,26 @@ class AuthGate extends ConsumerWidget { // 프로필 정보가 있고, 특정 필드(예: 태그)가 비어있다면 가입 미완료로 간주 final profile = profileSnapshot.data; + + // 가입 미완료 판별 로직 if (profile == null || profile.tags.isEmpty) { - debugPrint("⚠️ 가입 미완료 유저 감지: 회원가입 화면으로 이동"); - return const SignupMainScreen(); // 닉네임 설정부터 다시! + debugPrint("⚠️ 가입 미완료 유저: 회원가입 화면으로 안내"); + return const SignupMainScreen(); } - // 가입 완료가 확인되어 메인으로 가기 전, FCM 토큰을 업데이트 + // 성공적으로 정보를 가져왔다면 전역 Provider에 저장 + // 프레임 렌더링 후에 상태를 업데이트하도록 처리 WidgetsBinding.instance.addPostFrameCallback((_) { + ref.read(currentUserProvider.notifier).setUser(profile); + // FCM 초기화 등 추가 작업 ref.read(fcmServiceProvider).initialize(); }); - return const MainScreen(); // 모든 정보가 있을 때만 홈으로! + return const MainScreen(); }, ); } - - // 2. 토큰이 없는 경우 + // 토큰이 없는 경우 (로그아웃 상태) return const LoginScreen(); }, ); diff --git a/lib/features/challenge/detail/widgets/challenge_detail_content.dart b/lib/features/challenge/detail/widgets/challenge_detail_content.dart index c7a0ca4..ce36691 100644 --- a/lib/features/challenge/detail/widgets/challenge_detail_content.dart +++ b/lib/features/challenge/detail/widgets/challenge_detail_content.dart @@ -3,13 +3,8 @@ import 'package:intl/intl.dart'; import 'package:flutter_svg/svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -<<<<<<< HEAD -import 'package:haenaem/features/challenge/model/challenge_model.dart'; -import 'package:haenaem/shared/models/tag_model.dart'; -======= import 'package:haenaem/features/challenge/models/challenge_model.dart'; -import 'package:haenaem/shared/models/tag_data.dart'; ->>>>>>> origin/refactor +import 'package:haenaem/shared/models/tag_model.dart'; import 'package:haenaem/shared/widgets/tag_badge.dart'; class ChallengeDetailContent extends StatelessWidget { diff --git a/lib/features/user/provider/user_provider.dart b/lib/features/user/provider/user_provider.dart new file mode 100644 index 0000000..1f8f974 --- /dev/null +++ b/lib/features/user/provider/user_provider.dart @@ -0,0 +1,26 @@ +// 최초 작성자 : 김채영 +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import '../models/user_model.dart'; +import 'package:haenaem/shared/models/user.dart'; + +part 'user_provider.g.dart'; + +// 앱 전체에서 현재 로그인한 사용자의 정보를 관리하는 전역 상태 클래스 + +@Riverpod(keepAlive: true) // 앱이 켜져 있는 동안 데이터를 계속 유지 +class CurrentUser extends _$CurrentUser { + @override + UserProfileModel? build() { + return null; // 초기값은 로그인 전이므로 null + } + + // 사용자 정보 업데이트 (로그인 시 호출) + void setUser(UserProfileModel user) { + state = user; + } + + // 로그아웃 시 호출 + void clearUser() { + state = null; + } +} diff --git a/lib/features/user/provider/user_provider.g.dart b/lib/features/user/provider/user_provider.g.dart new file mode 100644 index 0000000..71fd79c --- /dev/null +++ b/lib/features/user/provider/user_provider.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$currentUserHash() => r'cb6fcdfff246718015359e838194b2d6d2dc0c92'; + +/// See also [CurrentUser]. +@ProviderFor(CurrentUser) +final currentUserProvider = + NotifierProvider.internal( + CurrentUser.new, + name: r'currentUserProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$currentUserHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$CurrentUser = Notifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/main.dart b/lib/main.dart index 432bda4..8e18cbd 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,14 +3,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:haenaem/features/social/screens/social_main_screen.dart'; -import 'package:haenaem/features/user/screens/my_page_screen.dart'; - import 'package:intl/date_symbol_data_local.dart'; import 'package:haenaem/core/theme/app_theme.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:haenaem/features/main/screens/main_screen.dart'; import 'package:haenaem/features/auth/signup/screens/auth_gate.dart'; import 'package:firebase_core/firebase_core.dart'; @@ -22,9 +18,6 @@ void main() async { // 플러터 엔진 초기화 확인 WidgetsFlutterBinding.ensureInitialized(); - // 비동기 초기화 - WidgetsFlutterBinding.ensureInitialized(); - // 저장소 인스턴스 생성 const storage = FlutterSecureStorage(); diff --git a/pubspec.lock b/pubspec.lock index 670a919..cf45d0f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -170,7 +170,7 @@ packages: source: hosted version: "2.5.4" build_runner: - dependency: "direct main" + dependency: "direct dev" description: name: build_runner sha256: "382a4d649addbfb7ba71a3631df0ec6a45d5ab9b098638144faf27f02778eb53" @@ -245,10 +245,10 @@ packages: dependency: transitive description: name: characters - sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.4.0" checked_yaml: dependency: transitive description: @@ -993,26 +993,26 @@ packages: dependency: transitive description: name: matcher - sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.18" + version: "0.12.17" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.13.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.16.0" mime: dependency: transitive description: @@ -1206,7 +1206,7 @@ packages: source: hosted version: "2.6.1" riverpod_generator: - dependency: "direct main" + dependency: "direct dev" description: name: riverpod_generator sha256: "44a0992d54473eb199ede00e2260bd3c262a86560e3c6f6374503d86d0580e36" @@ -1398,10 +1398,10 @@ packages: dependency: transitive description: name: test_api - sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.9" + version: "0.7.6" timing: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 51842e2..229ef59 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -52,8 +52,7 @@ dependencies: flutter_secure_storage: ^10.0.0 flutter_riverpod: ^2.5.1 riverpod_annotation: ^2.3.5 - build_runner: ^2.4.8 - riverpod_generator: ^2.4.0 + extended_image: ^10.0.1 firebase_messaging: ^16.1.1 kakao_flutter_sdk: ^1.10.0 @@ -67,6 +66,8 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter + build_runner: ^2.4.8 + riverpod_generator: ^2.4.0 # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is From 49e11eed1b03f33151d1eb438a085a9367aa777a Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 19 Mar 2026 19:05:54 +0900 Subject: [PATCH 055/134] =?UTF-8?q?chore:=20merge=ED=95=9C=20=EA=B1=B0=20?= =?UTF-8?q?=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pubspec.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index cf45d0f..06063a9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1009,10 +1009,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" mime: dependency: transitive description: @@ -1398,10 +1398,10 @@ packages: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 url: "https://pub.dev" source: hosted - version: "0.7.6" + version: "0.7.7" timing: dependency: transitive description: From d5ba32f2d095d6c827acdcd73e523ff5ce26e12f Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 19 Mar 2026 20:06:36 +0900 Subject: [PATCH 056/134] =?UTF-8?q?feat:=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20?= =?UTF-8?q?=EC=B9=B4=EB=93=9C=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .metadata | 10 ++-- lib/features/home/screens/home_screen.dart | 8 ++- lib/features/home/widgets/challenge_card.dart | 60 ++++++++++++------- 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/.metadata b/.metadata index 3803806..defd946 100644 --- a/.metadata +++ b/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled and should not be manually edited. version: - revision: "a402d9a4376add5bc2d6b1e33e53edaae58c07f8" + revision: "b45fa18946ecc2d9b4009952c636ba7e2ffbb787" channel: "stable" project_type: app @@ -13,11 +13,11 @@ project_type: app migration: platforms: - platform: root - create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 - base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + create_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 + base_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 - platform: android - create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 - base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + create_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 + base_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 # User provided section diff --git a/lib/features/home/screens/home_screen.dart b/lib/features/home/screens/home_screen.dart index b806de2..4fec223 100644 --- a/lib/features/home/screens/home_screen.dart +++ b/lib/features/home/screens/home_screen.dart @@ -48,9 +48,11 @@ class HomeScreen extends ConsumerWidget { children: [ // 상단 바 Padding( - padding: const EdgeInsets.symmetric( - horizontal: 20, - vertical: 12, + padding: const EdgeInsets.only( + left: 32, + right: 20, + top: 12, + bottom: 12, ), child: Row( children: [ diff --git a/lib/features/home/widgets/challenge_card.dart b/lib/features/home/widgets/challenge_card.dart index 6b5bb4c..21fa447 100644 --- a/lib/features/home/widgets/challenge_card.dart +++ b/lib/features/home/widgets/challenge_card.dart @@ -54,9 +54,14 @@ class ChallengeCard extends StatelessWidget { ), ), const SizedBox(height: 4), - _buildStreakInfo(), + _buildFrequencyAndDDayInfo(), const SizedBox(height: 4), - _buildBottomInfo(), + _buildStreakAndParticipantInfo(), + + if (challenge.warning) ...[ + const SizedBox(height: 4), + _buildWarningText(), + ], ], ), ), @@ -70,26 +75,18 @@ class ChallengeCard extends StatelessWidget { ); } - Widget _buildStreakInfo() { - final streakCount = challenge.streakCount; - - return Row( - children: [ - if (streakCount > 0 && challenge.isDone) - Padding( - padding: const EdgeInsets.only(right: 4), - child: SvgPicture.asset( - 'assets/images/icons/small_fire_icon.svg', - width: 16, - height: 16, - ), - ), - Text('$streakCount일째', style: AppTypography.b2.copyWith(fontSize: 14)), - ], + Widget _buildFrequencyAndDDayInfo() { + final frequencyText = challenge.weeklyFrequency == 7 + ? '매일' + : '주 ${challenge.weeklyFrequency}회'; + final dDayText = challenge.dDay == 0 ? '오늘 종료' : 'D-${challenge.dDay}'; + return Text( + '$frequencyText, $dDayText', + style: AppTypography.b2.copyWith(fontSize: 14), ); } - Widget _buildBottomInfo() { + Widget _buildStreakAndParticipantInfo() { if (challenge.warning) { return const Text( '오늘 챌린지를 하지 않으면 실패해요!', @@ -98,6 +95,22 @@ class ChallengeCard extends StatelessWidget { } return Row( children: [ + // 스트릭 정보: streakCount > 0 && isDone일 때 불꽃 아이콘 표시 + if (challenge.streakCount > 0 && challenge.isDone) + Padding( + padding: const EdgeInsets.only(right: 4), + child: SvgPicture.asset( + 'assets/images/icons/small_fire_icon.svg', + width: 16, + height: 16, + ), + ), + Text( + '${challenge.streakCount}일째', + style: AppTypography.b2.copyWith(fontSize: 14), + ), + const SizedBox(width: 12), + // 인증인원 정보 SvgPicture.asset( 'assets/images/icons/mini_success_icon.svg', width: 16, @@ -105,13 +118,20 @@ class ChallengeCard extends StatelessWidget { ), const SizedBox(width: 4), Text( - '인증인원 ${challenge.successParticipantCount}/${challenge.participantCount}', + '${challenge.successParticipantCount}/${challenge.participantCount}명', style: AppTypography.b2.copyWith(fontSize: 14), ), ], ); } + Widget _buildWarningText() { + return const Text( + '오늘 챌린지를 하지 않으면 실패해요!', + style: TextStyle(color: AppColors.notification, fontSize: 12), + ); + } + Widget _buildDivider() { return SizedBox( width: 40, From 2daf0af98ccf37bfce6bb96a04109a43759557b3 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Fri, 20 Mar 2026 19:05:57 +0900 Subject: [PATCH 057/134] =?UTF-8?q?feat:=20=ED=83=AD=20=EB=B0=94=20?= =?UTF-8?q?=EA=B3=B5=EC=9C=A0=20=EC=9C=84=EC=A0=AF=20=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/shared/widgets/custom_tab_bar.dart | 116 +++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 lib/shared/widgets/custom_tab_bar.dart diff --git a/lib/shared/widgets/custom_tab_bar.dart b/lib/shared/widgets/custom_tab_bar.dart new file mode 100644 index 0000000..01f20b8 --- /dev/null +++ b/lib/shared/widgets/custom_tab_bar.dart @@ -0,0 +1,116 @@ +// 최초 작성자: 강선욱 +// 공통 탭바 위젯 +// - TabController 생성 및 관리 +// - 공통 TabBar 스타일 적용 +// - TabBarView 포함 +// - 현재 탭 재탭 시 스크롤 최상단 이동 (scrollControllers 전달 시에만 동작) + +import 'package:flutter/material.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; + +class CustomTabBar extends StatefulWidget { + // 탭 항목 텍스트 목록 + final List tabs; + + // 각 탭에 해당하는 view들 리스트 + final List children; + + // 초기 탭 인덱스 (기본값: 0) + // 화면 진입시 가장 먼저 보이는 탭 설정 + final int initialIndex; + + // 탭 변경 시 호출되는 콜백 + final void Function(int index)? onTabChanged; + + // 현재 탭 재탭 시 스크롤을 최상단으로 올릴 ScrollController 목록 + // tabs 리스트와 동일한 순서로 전달해야 함 + // null이면 스크롤 동작 비활성화 + final List? scrollControllers; + + const CustomTabBar({ + super.key, + required this.tabs, + required this.children, + this.initialIndex = 0, + this.onTabChanged, + this.scrollControllers, + }) : assert( + scrollControllers == null || scrollControllers.length == tabs.length, + 'scrollControllers 길이는 tabs 길이와 동일해야 합니다.', + ); + + @override + State createState() => _CustomTabBarState(); +} + +class _CustomTabBarState extends State + with SingleTickerProviderStateMixin { + late TabController _tabController; + + @override + void initState() { + super.initState(); + _tabController = TabController( + length: widget.tabs.length, + vsync: this, + initialIndex: widget.initialIndex, + ); + + _tabController.addListener(() { + if (!_tabController.indexIsChanging) { + widget.onTabChanged?.call(_tabController.index); + } + }); + } + + @override + void dispose() { + _tabController.dispose(); + super.dispose(); + } + + void _scrollToTop(int index) { + final controllers = widget.scrollControllers; + if (controllers == null) return; + + final controller = controllers[index]; + if (controller.hasClients) { + controller.animateTo( + 0, + duration: const Duration(milliseconds: 600), + curve: Curves.easeInOut, + ); + } + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + TabBar( + controller: _tabController, + labelColor: AppColors.primaryAble, + unselectedLabelColor: AppColors.gray2, + indicatorColor: AppColors.primaryAble, + indicatorWeight: 1, + indicatorSize: TabBarIndicatorSize.tab, + labelStyle: AppTypography.b1.copyWith(color: AppColors.primaryAble), + tabs: widget.tabs.map((t) => Tab(text: t)).toList(), + onTap: (index) { + // 이미 선택된 탭을 다시 눌렀을 때 스크롤 최상단 이동 + if (_tabController.index == index) { + _scrollToTop(index); + } + }, + ), + Expanded( + child: TabBarView( + controller: _tabController, + children: widget.children, + ), + ), + ], + ); + } +} From 959ccfc9ccec43db4e9428e815d8fea0b657ce70 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Fri, 20 Mar 2026 19:45:32 +0900 Subject: [PATCH 058/134] =?UTF-8?q?refactor:=20challengeMainScreen?= =?UTF-8?q?=EC=97=90=20=EA=B3=B5=EC=9C=A0=20=ED=83=AD=20=EB=B0=94=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/screens/challenge_main_screen.dart | 78 ++++--------------- 1 file changed, 17 insertions(+), 61 deletions(-) diff --git a/lib/features/challenge/detail/screens/challenge_main_screen.dart b/lib/features/challenge/detail/screens/challenge_main_screen.dart index f0884fe..a85bd48 100644 --- a/lib/features/challenge/detail/screens/challenge_main_screen.dart +++ b/lib/features/challenge/detail/screens/challenge_main_screen.dart @@ -9,6 +9,7 @@ import 'package:haenaem/features/challenge/widgets/challenge_popup_menu.dart'; import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/challenge/widgets/challenge_create_success_dialog.dart'; import 'package:haenaem/shared/widgets/bottom_action_button.dart'; +import 'package:haenaem/shared/widgets/custom_tab_bar.dart'; import 'package:haenaem/features/challenge/verification/screens/challenge_verification_screen.dart'; import 'package:haenaem/features/challenge/detail/screens/member_ranking_screen.dart'; @@ -36,9 +37,8 @@ class ChallengeMainScreen extends ConsumerStatefulWidget { _ChallengeDetailScreenState(); } -class _ChallengeDetailScreenState extends ConsumerState - with SingleTickerProviderStateMixin { - late TabController _tabController; +class _ChallengeDetailScreenState extends ConsumerState { + int _currentTabIndex = 1; // 스크롤 컨트롤러들 final ScrollController _infoScrollController = ScrollController(); @@ -48,14 +48,6 @@ class _ChallengeDetailScreenState extends ConsumerState @override void initState() { super.initState(); - // 탭 3개: 소개(0), 내 현황(1), 멤버 현황(2) - _tabController = TabController(length: 3, vsync: this, initialIndex: 1); - - _tabController.addListener(() { - if (!_tabController.indexIsChanging) { - setState(() {}); // 인덱스 변경 완료 시 UI 업데이트 - } - }); // 챌린지 생성 직후라면 생성 성공 다이얼로그 실행 if (widget.isJustCreated && widget.createdData != null) { @@ -64,18 +56,8 @@ class _ChallengeDetailScreenState extends ConsumerState showDialog( context: context, barrierColor: const Color(0x7F1A1D1B), - builder: (context) => ChallengeCreateSuccessDialog( - // [수정 1] friends 파라미터 삭제 (이제 필요 없음) - // friends: widget.createdData!.friends, - - // [수정 2] challengeId 추가 (필수) - // 주의: createdData 객체 안에 있는 ID 변수명을 정확히 적어주세요. (예: .id 또는 .challengeId) - // challengeId: widget.createdData!.id, - - // // 기존 유지 - // challengeLink: widget.createdData!.challengeLink, - createdData: widget.createdData!, - ), + builder: (context) => + ChallengeCreateSuccessDialog(createdData: widget.createdData!), ); }); } @@ -83,23 +65,12 @@ class _ChallengeDetailScreenState extends ConsumerState @override void dispose() { - _tabController.dispose(); _infoScrollController.dispose(); _calendarScrollController.dispose(); _memberScrollController.dispose(); super.dispose(); } - void _scrollToTop(ScrollController controller) { - if (controller.hasClients) { - controller.animateTo( - 0, - duration: const Duration(milliseconds: 600), - curve: Curves.easeInOut, - ); - } - } - @override Widget build(BuildContext context) { // 공통 데이터 로드 (방장 여부 등 확인용) @@ -144,23 +115,18 @@ class _ChallengeDetailScreenState extends ConsumerState error: (_, __) => const SizedBox(), ), ], - bottom: TabBar( - controller: _tabController, - labelColor: AppColors.primaryAble, - unselectedLabelColor: AppColors.gray2, - indicatorColor: AppColors.primaryAble, - indicatorWeight: 1, - indicatorSize: TabBarIndicatorSize.tab, - labelStyle: AppTypography.b1.copyWith(color: AppColors.primaryAble), - tabs: const [ - Tab(text: '소개'), - Tab(text: '내 현황'), - Tab(text: '멤버 현황'), - ], - ), ), - body: TabBarView( - controller: _tabController, + body: CustomTabBar( + initialIndex: 1, + tabs: const ['소개', '내 현황', '멤버 현황'], + scrollControllers: [ + _infoScrollController, + _calendarScrollController, + _memberScrollController, + ], + onTabChanged: (index) { + setState(() => _currentTabIndex = index); + }, children: [ InformationView( challengeId: widget.challengeId, @@ -183,7 +149,7 @@ class _ChallengeDetailScreenState extends ConsumerState Widget _buildBottomButton() { // 0: 소개, 1: 내 현황 -> '인증하기' // 2: 멤버 현황 -> '내 순위 확인하기' - final bool isMemberTab = _tabController.index == 2; + final bool isMemberTab = _currentTabIndex == 2; return BottomActionButton( // 1. 텍스트 분기 @@ -221,14 +187,4 @@ class _ChallengeDetailScreenState extends ConsumerState }, ); } - - void _scrollToMyRank() { - // MemberView에서 내 순위를 찾는 로직을 구현하거나 - // scrollController를 통해 하단으로 이동시키는 로직 등을 수행합니다. - _memberScrollController.animateTo( - 500, // 예시 값 - duration: const Duration(milliseconds: 500), - curve: Curves.easeOut, - ); - } } From 9b30968319ecd7e3daf550766ce4c9cf7594c330 Mon Sep 17 00:00:00 2001 From: Chaeyeong_10 Date: Fri, 20 Mar 2026 20:28:50 +0900 Subject: [PATCH 059/134] =?UTF-8?q?feat:=EC=B9=B4=EC=B9=B4=EC=98=A4=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/src/main/AndroidManifest.xml | 77 +++++------- lib/features/auth/login/login_screen.dart | 113 ++++++++++++++++-- lib/features/auth/services/auth_service.dart | 94 ++++++++++----- macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 36 +++++- pubspec.yaml | 4 +- 6 files changed, 238 insertions(+), 88 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 752019b..184b666 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,22 +1,33 @@ - - + - - + + + + + + + + + + + + + + + - - @@ -29,56 +40,28 @@ android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> - + + android:resource="@style/NormalTheme" /> - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - + \ No newline at end of file diff --git a/lib/features/auth/login/login_screen.dart b/lib/features/auth/login/login_screen.dart index ed46901..69d44cc 100644 --- a/lib/features/auth/login/login_screen.dart +++ b/lib/features/auth/login/login_screen.dart @@ -1,5 +1,10 @@ // 최초 작성자 : 김채영 +import 'dart:convert'; +import 'dart:math'; import 'package:flutter/material.dart'; +import 'package:url_launcher/url_launcher.dart'; +import 'package:crypto/crypto.dart'; // PKCE 해싱용 +import 'package:webview_flutter/webview_flutter.dart'; // 웹뷰용 import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; @@ -60,14 +65,38 @@ class LoginScreen extends StatelessWidget { textColor: Colors.black, iconPath: 'assets/images/icons/kakao_logo.svg', onTap: () async { - // 1. 인가 코드와 Verifier 가져오기 - final authResult = await AuthService.signInWithKakao(); + // 1. PKCE 데이터 및 URL 준비 (AuthService 이용) + final pkce = AuthService.generatePkcePair(); + final authUrl = AuthService.getKakaoAuthUrl( + pkce['challenge']!, + ); + String? kakaoAuthCode; - if (authResult != null && context.mounted) { - // 2. 백엔드가 정의한 @RequestBody 형식으로 쏘기 + if (!context.mounted) return; + + // 2. 웹뷰 실행 (UI 부분이라 Screen에 두는 게 적절합니다) + await showModalBottomSheet( + context: context, + isScrollControlled: true, + useSafeArea: true, + backgroundColor: Colors.transparent, + builder: (ctx) => Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(ctx).viewInsets.bottom, + ), + child: _buildKakaoWebView( + context: ctx, + authUrl: authUrl, + onCodeCaptured: (code) => kakaoAuthCode = code, + ), + ), + ); + + // 3. 획득한 코드가 있다면 백엔드로 전송 + if (kakaoAuthCode != null && context.mounted) { await AuthService.sendKakaoAuthToBackend( - code: authResult['code']!, - codeVerifier: authResult['codeVerifier']!, + code: kakaoAuthCode!, + codeVerifier: pkce['codeVerifier']!, // 원본 열쇠 전송 context: context, ); } @@ -87,7 +116,7 @@ class LoginScreen extends StatelessWidget { if (authResult != null) { await AuthService.sendTokenToBackend( code: authResult['code']!, - codeVerifier: authResult['codeVerifier']!, + codeVerifier: authResult['code_verifier']!, context: context, ); } @@ -165,4 +194,74 @@ class LoginScreen extends StatelessWidget { ), ); } + + Widget _buildKakaoWebView({ + required BuildContext context, + required String authUrl, + required Function(String) onCodeCaptured, + }) { + late final WebViewController controller; + + controller = WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setUserAgent( + "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36", + ) + ..setNavigationDelegate( + NavigationDelegate( + onNavigationRequest: (NavigationRequest request) async { + final url = request.url; + + // 2️⃣ 카카오톡 앱 호출 주소 처리 + if (url.startsWith('kakaotalk://') || url.startsWith('intent://')) { + try { + debugPrint('📱 카카오톡 앱 실행 시도: $url'); + + // intent:// 스킴인 경우 안드로이드용 특수 처리가 필요할 수 있지만, + // url_launcher가 대부분 해결해줍니다. + final canLaunch = await canLaunchUrl(Uri.parse(url)); + if (canLaunch) { + await launchUrl( + Uri.parse(url), + mode: LaunchMode.externalApplication, + ); + return NavigationDecision.prevent; + } + } catch (e) { + debugPrint('🚨 앱 실행 실패: $e'); + // 앱 실행 실패 시 웹에서 로그인하도록 유지 (prevent 하지 않음) + } + } + + // 리다이렉트 및 기타 주소 처리 + if (!url.startsWith('http://') && !url.startsWith('https://')) { + return NavigationDecision.prevent; + } + return NavigationDecision.navigate; + }, + onPageStarted: (url) { + // ✅ AuthService.kakaoRedirectUri(ngrok 주소)로 시작하는지 감시 + if (url.startsWith(AuthService.kakaoRedirectUri)) { + debugPrint('🎣 ngrok 리다이렉트 감지!'); + final uri = Uri.parse(url); + final code = uri.queryParameters['code']; + if (code != null) { + onCodeCaptured(code); + Navigator.pop(context); + } + } + }, + ), + ) + ..loadRequest(Uri.parse(authUrl)); + + return Container( + height: MediaQuery.of(context).size.height * 0.9, + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.vertical(top: Radius.circular(20)), + ), + child: WebViewWidget(controller: controller), + ); + } } diff --git a/lib/features/auth/services/auth_service.dart b/lib/features/auth/services/auth_service.dart index c0f496e..142116e 100644 --- a/lib/features/auth/services/auth_service.dart +++ b/lib/features/auth/services/auth_service.dart @@ -1,5 +1,8 @@ // 최초 작성자: 김채영 import 'package:flutter/material.dart'; +import 'dart:convert'; +import 'dart:math'; +import 'package:crypto/crypto.dart'; import 'package:flutter_appauth/flutter_appauth.dart'; import 'package:dio/dio.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; // 토큰 저장을 위해 필요 @@ -23,46 +26,74 @@ class AuthService { // 카카오 설정 정보 static const String kakaoRestApiKey = '9fdd13c0777c415d8fa4055b5b26a6c5'; static const String kakaoNativeAppKey = '05a36f172ea2945260862834654385ea'; - static const String kakaoRedirectUri = - 'https://hanaem.onrender.com/api/oauth/kakao/token'; + // static const String kakaoRedirectUri = + // 'https://hanaem.onrender.com/api/oauth/kakao/token'; + // static const String kakaoRedirectUri = + // 'https://hanaem.onrender.com/oauth/kakao/callback'; + //static const String kakaoRedirectUri = //'kakao9fdd13c0777c415d8fa4055b5b26a6c5://oauth'; + // ♥️ 로컬 서버로 테스트 + static const String kakaoRedirectUri = + 'https://ungenially-undebatable-sindy.ngrok-free.dev/oauth/kakao/callback'; + + // static final Dio _dio = Dio( + // BaseOptions(baseUrl: 'https://hanaem.onrender.com'), + // ); + + // ♥️ 로컬 서버로 테스트 static final Dio _dio = Dio( - BaseOptions(baseUrl: 'https://hanaem.onrender.com'), + BaseOptions( + baseUrl: 'https://ungenially-undebatable-sindy.ngrok-free.dev', + headers: { + 'ngrok-skip-browser-warning': 'true', + 'Content-Type': 'application/json', + }, + ), ); - // 카카오 로그인 - - static Future?> signInWithKakao() async { - try { - // 구글과 동일하게 인가 요청을 보냅니다. - final AuthorizationResponse result = await _appAuth.authorize( - AuthorizationRequest( - kakaoRestApiKey, // clientId 자리에 REST API 키 사용 - kakaoRedirectUri, - serviceConfiguration: const AuthorizationServiceConfiguration( - authorizationEndpoint: 'https://kauth.kakao.com/oauth/authorize', - tokenEndpoint: 'https://kauth.kakao.com/oauth/token', - ), - scopes: ['profile_nickname', 'profile_image'], // 필요한 권한 - ), - ); + // 1. PKCE 쌍 생성 (RFC 7636 표준 방식) + static Map generatePkcePair() { + // 1-1. Verifier 생성: 표준에 정의된 [A-Z, a-z, 0-9, -, ., _, ~] 문자만 사용 + const chars = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~'; + final random = Random.secure(); + + // 64자리의 무작위 문자열 생성 (표준 범위 43~128자 준수) + final verifier = List.generate( + 64, + (_) => chars[random.nextInt(chars.length)], + ).join(); + debugPrint("verifier 생성: $verifier"); + + // 1-2. Challenge 생성: Verifier를 SHA256으로 해싱 후 Base64Url 인코딩 + final bytes = utf8.encode(verifier); // plain string을 바이트로 변환 + final digest = sha256.convert(bytes); // SHA256 해싱 + + // Base64UrlEncode 후 패딩(=) 제거 및 특수문자 치환 + final challenge = base64UrlEncode( + digest.bytes, + ).replaceAll('=', '').replaceAll('+', '-').replaceAll('/', '_'); + debugPrint('🔒 생성된 Challenge: $challenge'); + + return {'codeVerifier': verifier, 'challenge': challenge}; + } - if (result.authorizationCode != null && result.codeVerifier != null) { - debugPrint('✅ 카카오 인가 코드 획득 성공'); - return { - "code": result.authorizationCode!, - "codeVerifier": result.codeVerifier!, - }; - } - } catch (e) { - debugPrint('🚨 카카오 PKCE 인증 에러: $e'); - } - return null; + // 2. 카카오 인증 URL 생성 + static String getKakaoAuthUrl(String challenge) { + final clientId = kakaoRestApiKey; + final redirectUri = Uri.encodeComponent(kakaoRedirectUri); + + return 'https://kauth.kakao.com/oauth/authorize' + '?client_id=$clientId' + '&redirect_uri=$redirectUri' + '&response_type=code' + '&code_challenge=$challenge' + '&code_challenge_method=S256'; } - // 서버 통신 부분 (백엔드 엔드포인트에 맞춰 수정 필요) + // 서버 통신 부분 static Future sendKakaoAuthToBackend({ required String code, required String codeVerifier, @@ -70,6 +101,7 @@ class AuthService { }) async { try { debugPrint("🚀 서버로 카카오 인가 데이터 전송 시작..."); + debugPrint("서버 전송 verifier: $codeVerifier"); final response = await _dio.post( '/api/oauth/kakao/token', diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 922e5f2..1bd911d 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -16,6 +16,7 @@ import path_provider_foundation import photo_manager import share_plus import shared_preferences_foundation +import url_launcher_macos import webview_flutter_wkwebview func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { @@ -30,5 +31,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { PhotoManagerPlugin.register(with: registry.registrar(forPlugin: "PhotoManagerPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) WebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "WebViewFlutterPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index cf45d0f..8a985ab 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -314,7 +314,7 @@ packages: source: hosted version: "0.3.5+1" crypto: - dependency: transitive + dependency: "direct main" description: name: crypto sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf @@ -1426,6 +1426,30 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.1" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 + url: "https://pub.dev" + source: hosted + version: "6.3.2" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "767344bf3063897b5cf0db830e94f904528e6dd50a6dfaf839f0abf509009611" + url: "https://pub.dev" + source: hosted + version: "6.3.28" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: cfde38aa257dae62ffe79c87fab20165dfdf6988c1d31b58ebf59b9106062aad + url: "https://pub.dev" + source: hosted + version: "6.3.6" url_launcher_linux: dependency: transitive description: @@ -1434,6 +1458,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.2.2" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" + url: "https://pub.dev" + source: hosted + version: "3.2.5" url_launcher_platform_interface: dependency: transitive description: @@ -1539,7 +1571,7 @@ packages: source: hosted version: "3.0.3" webview_flutter: - dependency: transitive + dependency: "direct main" description: name: webview_flutter sha256: a3da219916aba44947d3a5478b1927876a09781174b5a2b67fa5be0555154bf9 diff --git a/pubspec.yaml b/pubspec.yaml index 229ef59..eee493a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -52,10 +52,12 @@ dependencies: flutter_secure_storage: ^10.0.0 flutter_riverpod: ^2.5.1 riverpod_annotation: ^2.3.5 - + crypto: ^3.0.7 + webview_flutter: ^4.13.1 extended_image: ^10.0.1 firebase_messaging: ^16.1.1 kakao_flutter_sdk: ^1.10.0 + url_launcher: ^6.3.2 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. From b3fc0d113c305391695c59f5a07a30fc9713feaa Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Fri, 20 Mar 2026 21:15:55 +0900 Subject: [PATCH 060/134] =?UTF-8?q?refactor:=20post.dart=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20shared/models=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/{features/feed => shared}/models/post.dart | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/{features/feed => shared}/models/post.dart (100%) diff --git a/lib/features/feed/models/post.dart b/lib/shared/models/post.dart similarity index 100% rename from lib/features/feed/models/post.dart rename to lib/shared/models/post.dart From 398698b7ca65367746aca1342110a382caef21b3 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Fri, 20 Mar 2026 22:43:12 +0900 Subject: [PATCH 061/134] =?UTF-8?q?refactor:=20id=20int=ED=83=80=EC=9E=85?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/shared/models/post.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/shared/models/post.dart b/lib/shared/models/post.dart index e6c4055..f7a6979 100644 --- a/lib/shared/models/post.dart +++ b/lib/shared/models/post.dart @@ -4,7 +4,7 @@ import 'package:haenaem/shared/models/user.dart'; // 인증글 모델 클래스 // User에 정의된 필드(id, profileUrl, nickname)를 작성자 정보로 재사용 class Post { - final String id; // 인증글 id + final int id; // 인증글 id final String title; // 인증글 제목 final String content; // 인증글 내용 final String? pictureUrl; // 인증글 사진 주소 @@ -28,7 +28,7 @@ class Post { factory Post.fromJson(Map json) { return Post( - id: json['id'] as String, + id: json['id'] as int, title: json['title'] as String, content: json['content'] as String, pictureUrl: json['picture_url'] as String?, @@ -41,7 +41,7 @@ class Post { } Post copyWith({ - String? id, + int? id, String? title, String? content, String? pictureUrl, From 50ffae5ab7bf21c4edac2442767df7fe2901adc2 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Fri, 20 Mar 2026 22:43:46 +0900 Subject: [PATCH 062/134] =?UTF-8?q?feat:=20calendar=5Fgrid=20=EC=9C=84?= =?UTF-8?q?=EC=A0=AF=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/widgets/calendar_grid.dart | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 lib/features/challenge/detail/widgets/calendar_grid.dart diff --git a/lib/features/challenge/detail/widgets/calendar_grid.dart b/lib/features/challenge/detail/widgets/calendar_grid.dart new file mode 100644 index 0000000..53bfc57 --- /dev/null +++ b/lib/features/challenge/detail/widgets/calendar_grid.dart @@ -0,0 +1,149 @@ +import 'package:flutter/material.dart'; +import 'package:collection/collection.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/shared/models/post.dart'; +import 'package:haenaem/features/feed/screens/post_detail_screen.dart'; + +// 최초 작성자 : 강선욱 +// 챌린지 인증 달력 그리드 위젯 +// - 특정 연월의 날짜를 7열 그리드로 표시 +// - 인증한 날짜는 초록색으로 표시되며, 사진이 있으면 썸네일로 표시 +// - 인증한 날짜 셀을 탭하면 해당 포스트 상세 화면으로 이동 + +class CalendarGrid extends StatelessWidget { + /// 현재 표시 중인 연월 + final DateTime focusedDay; + + /// 해당 월의 포스트 목록 (post_provider에서 전달) + final List posts; + + const CalendarGrid({ + super.key, + required this.focusedDay, + required this.posts, + }); + + @override + Widget build(BuildContext context) { + // 해당 월 1일의 요일 (0: 일요일 기준으로 맞추기 위해 % 7 처리) + // ex) 1일이 화요일이면 skipDays = 2 → 앞에 빈 셀 2개 추가 + final int skipDays = + DateTime(focusedDay.year, focusedDay.month, 1).weekday % 7; + + // 해당 월의 마지막 날짜 + // ex) 3월이면 31, 4월이면 30 + final int lastDayOfMonth = DateTime( + focusedDay.year, + focusedDay.month + 1, + 0, + ).day; + + final now = DateTime.now(); + + return GridView.builder( + padding: EdgeInsets.zero, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + // 빈 셀(skipDays) + 실제 날짜 셀(lastDayOfMonth) + itemCount: skipDays + lastDayOfMonth, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 7, // 일~토 7열 + mainAxisSpacing: 10, + crossAxisSpacing: 10, + ), + itemBuilder: (context, index) { + // 1일 이전 빈 셀 처리 + if (index < skipDays) return const SizedBox(); + + final int day = index - skipDays + 1; + + // 오늘 날짜 여부 확인 (테두리 표시용) + final bool isToday = + now.year == focusedDay.year && + now.month == focusedDay.month && + now.day == day; + + // 해당 날짜에 인증 포스트가 있는지 확인 + final Post? post = posts.firstWhereOrNull( + (p) => + p.date.year == focusedDay.year && + p.date.month == focusedDay.month && + p.date.day == day, + ); + final bool isCertified = post != null; + + return _CalendarCell( + day: day, + isToday: isToday, + isCertified: isCertified, + imageUrl: post?.pictureUrl, + // 인증한 날짜만 탭 가능, 포스트 상세 화면으로 이동 + onTap: isCertified + ? () => Navigator.push( + context, + MaterialPageRoute( + builder: (_) => PostDetailScreen(postId: post.id), + ), + ) + : null, + ); + }, + ); + } +} + +/// 달력 개별 셀 위젯 +/// +/// - 인증 여부에 따라 배경색 및 썸네일 표시 +/// - 오늘 날짜이고 미인증이면 회색 테두리 표시 +class _CalendarCell extends StatelessWidget { + final int day; + final bool isToday; + final bool isCertified; + + /// 인증 사진 URL (없으면 단색 배경으로 표시) + final String? imageUrl; + final VoidCallback? onTap; + + const _CalendarCell({ + required this.day, + required this.isToday, + required this.isCertified, + this.imageUrl, + this.onTap, + }); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + alignment: Alignment.center, + decoration: BoxDecoration( + // 인증: 초록색 / 미인증: 회색 + color: isCertified ? AppColors.primaryAble : AppColors.gray5, + borderRadius: BorderRadius.circular(5), + // 오늘이면서 미인증인 경우 테두리 표시 + border: (isToday && !isCertified) + ? Border.all(color: AppColors.gray2, width: 1) + : null, + // 인증 사진이 있으면 썸네일로 표시 + image: (isCertified && imageUrl != null) + ? DecorationImage( + image: NetworkImage(imageUrl!), + fit: BoxFit.cover, + ) + : null, + ), + child: Text( + '$day', + style: TextStyle( + // 인증: 흰색 / 미인증: 회색 + color: isCertified ? Colors.white : AppColors.gray2, + fontWeight: isToday ? FontWeight.bold : FontWeight.normal, + ), + ), + ), + ); + } +} From 4fd83f12835b490fdda6c86319ebe523ff343371 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 21 Mar 2026 01:09:13 +0900 Subject: [PATCH 063/134] =?UTF-8?q?feat:=20=EC=97=B0=EC=86=8D=20=EC=9D=BC?= =?UTF-8?q?=EC=88=98=20=EB=84=98=EA=B2=A8=EC=A3=BC=EA=B8=B0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/home/widgets/challenge_card.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/features/home/widgets/challenge_card.dart b/lib/features/home/widgets/challenge_card.dart index 21fa447..77eb124 100644 --- a/lib/features/home/widgets/challenge_card.dart +++ b/lib/features/home/widgets/challenge_card.dart @@ -27,6 +27,7 @@ class ChallengeCard extends StatelessWidget { builder: (context) => ChallengeMainScreen( challengeId: challenge.challengeBase.id, challengeTitle: challenge.challengeBase.title, + streakCount: challenge.streakCount, ), ), ); From 3d17342809eada4aa78b1e20307426cb8f9133dd Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 21 Mar 2026 01:10:16 +0900 Subject: [PATCH 064/134] =?UTF-8?q?feat:=20=EB=82=B4=20=ED=98=84=ED=99=A9?= =?UTF-8?q?=EC=9A=A9=20CalendarPost=20model=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/models/calendar_post.dart | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 lib/features/challenge/detail/models/calendar_post.dart diff --git a/lib/features/challenge/detail/models/calendar_post.dart b/lib/features/challenge/detail/models/calendar_post.dart new file mode 100644 index 0000000..b06b72f --- /dev/null +++ b/lib/features/challenge/detail/models/calendar_post.dart @@ -0,0 +1,26 @@ +// 최초 작성자 : 강선욱 +// 캘린더 달력 셀 및 인증글 목록 렌더링에 필요한 최소 데이터 모델 +// 상세 페이지 진입 시에는 postId만 넘기고 Post 모델을 별도로 조회 + +class CalendarPost { + final int postId; + final String postDate; + final String? imageUrl; + final String content; + + const CalendarPost({ + required this.postId, + required this.postDate, + this.imageUrl, + required this.content, + }); + + factory CalendarPost.fromJson(Map json) { + return CalendarPost( + postId: json['postId'] as int, + postDate: json['postDate'] as String, + imageUrl: json['imageUrl'] as String?, + content: json['content'] as String, + ); + } +} From 8290044fbfc626824fbf0ab03cfae11f35e3d417 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 21 Mar 2026 01:11:41 +0900 Subject: [PATCH 065/134] =?UTF-8?q?refactor:=20model=20=ED=8F=B4=EB=8D=94?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=20models=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/detail/data/ranking_repository.dart | 2 +- .../challenge/detail/{model => models}/ranking_model.dart | 0 lib/features/challenge/detail/provider/ranking_provider.dart | 2 +- .../challenge/detail/screens/member_ranking_screen.dart | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename lib/features/challenge/detail/{model => models}/ranking_model.dart (100%) diff --git a/lib/features/challenge/detail/data/ranking_repository.dart b/lib/features/challenge/detail/data/ranking_repository.dart index 2bb13eb..442bace 100644 --- a/lib/features/challenge/detail/data/ranking_repository.dart +++ b/lib/features/challenge/detail/data/ranking_repository.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:haenaem/core/network/dio_provider.dart'; -import '../model/ranking_model.dart'; +import '../models/ranking_model.dart'; part 'ranking_repository.g.dart'; diff --git a/lib/features/challenge/detail/model/ranking_model.dart b/lib/features/challenge/detail/models/ranking_model.dart similarity index 100% rename from lib/features/challenge/detail/model/ranking_model.dart rename to lib/features/challenge/detail/models/ranking_model.dart diff --git a/lib/features/challenge/detail/provider/ranking_provider.dart b/lib/features/challenge/detail/provider/ranking_provider.dart index 96e25f1..2591ccd 100644 --- a/lib/features/challenge/detail/provider/ranking_provider.dart +++ b/lib/features/challenge/detail/provider/ranking_provider.dart @@ -3,7 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../data/ranking_repository.dart'; -import '../model/ranking_model.dart'; +import '../models/ranking_model.dart'; part 'ranking_provider.g.dart'; diff --git a/lib/features/challenge/detail/screens/member_ranking_screen.dart b/lib/features/challenge/detail/screens/member_ranking_screen.dart index bc86580..8947eee 100644 --- a/lib/features/challenge/detail/screens/member_ranking_screen.dart +++ b/lib/features/challenge/detail/screens/member_ranking_screen.dart @@ -5,7 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/features/challenge/detail/provider/ranking_provider.dart'; -import 'package:haenaem/features/challenge/detail/model/ranking_model.dart'; +import 'package:haenaem/features/challenge/detail/models/ranking_model.dart'; class MemberRankingScreen extends ConsumerWidget { final int challengeId; From 682f806ce42faf51936647c734bc392ebe37e03f Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Sat, 21 Mar 2026 02:43:25 +0900 Subject: [PATCH 066/134] =?UTF-8?q?refactor:=20=EC=BA=98=EB=A6=B0=EB=8D=94?= =?UTF-8?q?=20=ED=99=94=EB=A9=B4=EC=9A=A9=20CalendarPostCard=20=EC=9C=84?= =?UTF-8?q?=EC=A0=AF=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/detail/views/calendar_view.dart | 199 +++--------------- .../detail/widgets/calendar_post_card.dart | 89 ++++++++ 2 files changed, 113 insertions(+), 175 deletions(-) create mode 100644 lib/features/challenge/detail/widgets/calendar_post_card.dart diff --git a/lib/features/challenge/detail/views/calendar_view.dart b/lib/features/challenge/detail/views/calendar_view.dart index 7264945..033a73d 100644 --- a/lib/features/challenge/detail/views/calendar_view.dart +++ b/lib/features/challenge/detail/views/calendar_view.dart @@ -3,9 +3,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:collection/collection.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; +import '../provider/post_provider.dart'; +import '../widgets/calendar_grid.dart'; +import '../models/calendar_post.dart'; +import '../widgets/calendar_post_card.dart'; import 'package:intl/intl.dart'; import 'package:haenaem/features/feed/screens/post_detail_screen.dart'; @@ -13,11 +16,15 @@ import 'package:haenaem/features/challenge/models/challenge_model.dart'; class CalendarView extends ConsumerStatefulWidget { final int challengeId; + final String? challengeTitle; + final int streakCount; final ScrollController scrollController; const CalendarView({ super.key, required this.challengeId, + required this.challengeTitle, + required this.streakCount, required this.scrollController, }); @@ -48,16 +55,16 @@ class _CalendarViewState extends ConsumerState { challengeCalendarDataProvider(widget.challengeId), ); - final photosAsync = ref.watch( - challengeCalendarPhotosProvider( - challengeId: widget.challengeId, - year: _focusedDay.year, - month: _focusedDay.month, - ), - ); + // final photosAsync = ref.watch( + // challengeCalendarPhotosProvider( + // challengeId: widget.challengeId, + // year: _focusedDay.year, + // month: _focusedDay.month, + // ), + // ); final postsAsync = ref.watch( - challengePostsProvider( + monthlyChallengePostsProvider( challengeId: widget.challengeId, year: _focusedDay.year, month: _focusedDay.month, @@ -82,16 +89,14 @@ class _CalendarViewState extends ConsumerState { const SizedBox(height: 10), _buildWeekdayHeader(), const SizedBox(height: 10), - photosAsync.when( - data: (photos) { - final allPosts = postsAsync.value ?? []; - return _buildCalendarGrid(_focusedDay, photos, allPosts); - }, + postsAsync.when( + data: (posts) => + CalendarGrid(focusedDay: _focusedDay, posts: posts), loading: () => const SizedBox( height: 200, child: Center(child: CircularProgressIndicator()), ), - error: (e, s) => const Text('달력을 불러오지 못했습니다.'), + error: (e, s) => Text('달력을 불러오지 못했습니다. $e'), ), const SizedBox(height: 20), _buildPostsHeader(postsAsync), @@ -104,11 +109,11 @@ class _CalendarViewState extends ConsumerState { physics: const NeverScrollableScrollPhysics(), itemCount: posts.length, itemBuilder: (context, index) => - _buildCertCard(context, post: posts[index]), + CalendarPostCard(post: posts[index]), ); }, loading: () => const Center(child: CircularProgressIndicator()), - error: (e, s) => const Text('인증글 로드 중 에러'), + error: (e, s) => Text('인증글 로드 중 에러 $e'), ), ], ), @@ -122,7 +127,7 @@ class _CalendarViewState extends ConsumerState { children: [ _buildStatCard(data.totalSuccessDays.toString(), '완료 일수'), const SizedBox(width: 12), - _buildStatCard(data.currentStreakDays.toString(), '연속 일수'), + _buildStatCard(widget.streakCount.toString(), '연속 일수'), ], ); } @@ -239,90 +244,7 @@ class _CalendarViewState extends ConsumerState { ); } - Widget _buildCalendarGrid( - DateTime date, - List photos, - List allPosts, - ) { - final int skipDays = DateTime(date.year, date.month, 1).weekday % 7; - final int lastDayOfMonth = DateTime(date.year, date.month + 1, 0).day; - final now = DateTime.now(); - - return GridView.builder( - padding: EdgeInsets.zero, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemCount: skipDays + lastDayOfMonth, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 7, - mainAxisSpacing: 10, - crossAxisSpacing: 10, - ), - itemBuilder: (context, index) { - if (index < skipDays) return const SizedBox(); - int day = index - skipDays + 1; - final bool isToday = - now.year == date.year && now.month == date.month && now.day == day; - final String targetDateStr = - "${date.year}-${date.month.toString().padLeft(2, '0')}-${day.toString().padLeft(2, '0')}"; - - final photoData = photos.firstWhereOrNull( - (p) => p.postDate == targetDateStr, - ); - bool isCertified = photoData != null && photoData.postId != -1; - - final CertificationPostModel? fullPost = isCertified - ? allPosts.firstWhereOrNull((p) => p.postId == photoData.postId) ?? - allPosts.firstWhereOrNull((p) => p.postDate == targetDateStr) - : null; - - return GestureDetector( - onTap: (isCertified && fullPost != null) - ? () => Navigator.push( - context, - MaterialPageRoute( - builder: (_) => PostDetailScreen( - postId: fullPost.postId, - post: fullPost, - ), - ), - ) - : null, - child: Container( - alignment: Alignment.center, - decoration: BoxDecoration( - color: isCertified - ? AppColors.primaryAble - : (isToday ? AppColors.gray5 : AppColors.gray5), - borderRadius: BorderRadius.circular(5), - border: (isToday && !isCertified) - ? Border.all(color: AppColors.gray2, width: 1) - : null, - image: (isCertified && photoData.imageUrl != null) - ? DecorationImage( - image: NetworkImage(photoData.imageUrl!), - fit: BoxFit.cover, - ) - : null, - ), - child: Text( - '$day', - style: TextStyle( - color: isCertified - ? Colors.white - : (isToday ? AppColors.gray2 : AppColors.gray2), - fontWeight: isToday ? FontWeight.bold : FontWeight.normal, - ), - ), - ), - ); - }, - ); - } - - Widget _buildPostsHeader( - AsyncValue> postsAsync, - ) { + Widget _buildPostsHeader(AsyncValue> postsAsync) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -342,77 +264,4 @@ class _CalendarViewState extends ConsumerState { padding: EdgeInsets.symmetric(vertical: 40), child: Text('이번 달 인증글이 없습니다.', style: TextStyle(color: AppColors.gray2)), ); - - Widget _buildCertCard( - BuildContext context, { - required CertificationPostModel post, - }) { - final String formattedDate = (post.postDate.isNotEmpty) - ? DateFormat('M월 d일').format(DateTime.parse(post.postDate)) - : ""; - return GestureDetector( - onTap: () => Navigator.push( - context, - MaterialPageRoute( - builder: (_) => PostDetailScreen(post: post, postId: post.postId), - ), - ), - child: Container( - margin: const EdgeInsets.only(bottom: 15), - padding: const EdgeInsets.all(13), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: AppColors.gray4), - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (post.imageUrl != null) ...[ - ClipRRect( - borderRadius: BorderRadius.circular(8), - child: Image.network( - post.imageUrl!, - width: 80, - height: 80, - fit: BoxFit.cover, - ), - ), - const SizedBox(width: 12), - ], - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - SvgPicture.asset( - 'assets/images/icons/green_calendar.svg', - width: 12, - height: 12, - ), - const SizedBox(width: 4), - Text( - formattedDate, - style: AppTypography.c1.copyWith( - color: AppColors.primaryAble, - ), - ), - ], - ), - const SizedBox(height: 4), - Text( - post.content, - style: AppTypography.b2.copyWith(color: AppColors.black), - maxLines: 3, - overflow: TextOverflow.ellipsis, - ), - ], - ), - ), - ], - ), - ), - ); - } } diff --git a/lib/features/challenge/detail/widgets/calendar_post_card.dart b/lib/features/challenge/detail/widgets/calendar_post_card.dart new file mode 100644 index 0000000..52f7143 --- /dev/null +++ b/lib/features/challenge/detail/widgets/calendar_post_card.dart @@ -0,0 +1,89 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; +import 'package:haenaem/features/challenge/detail/models/calendar_post.dart'; +import 'package:haenaem/features/feed/screens/post_detail_screen.dart'; +import 'package:intl/intl.dart'; + +// 최초 작성자 : 강선욱 +// 캘린지 인증글 카드 위젯 +// - 인증글 사진, 날짜, 내용을 표시 +// - 탭 시 포스트 상세 화면으로 이동 +class CalendarPostCard extends StatelessWidget { + final CalendarPost post; + + const CalendarPostCard({super.key, required this.post}); + + @override + Widget build(BuildContext context) { + final String formattedDate = DateFormat( + 'M월 d일', + ).format(DateTime.parse(post.postDate)); + + return GestureDetector( + onTap: () => Navigator.push( + context, + MaterialPageRoute( + builder: (_) => PostDetailScreen(postId: post.postId), + ), + ), + child: Container( + margin: const EdgeInsets.only(bottom: 15), + padding: const EdgeInsets.all(13), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColors.gray4), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (post.imageUrl != null) ...[ + ClipRRect( + borderRadius: BorderRadius.circular(8), + child: Image.network( + post.imageUrl!, + width: 80, + height: 80, + fit: BoxFit.cover, + ), + ), + const SizedBox(width: 12), + ], + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + SvgPicture.asset( + 'assets/images/icons/green_calendar.svg', + width: 12, + height: 12, + ), + const SizedBox(width: 4), + Text( + formattedDate, + style: AppTypography.c1.copyWith( + color: AppColors.primaryAble, + ), + ), + ], + ), + const SizedBox(height: 4), + Text( + post.content, + style: AppTypography.b2.copyWith(color: AppColors.black), + maxLines: 3, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ], + ), + ), + ); + } +} From a4e288425120765e6fa20c8681f1f30dd0e72f40 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Mon, 23 Mar 2026 14:30:40 +0900 Subject: [PATCH 067/134] =?UTF-8?q?refactor:=20challenge=5Finvite=5Fcard?= =?UTF-8?q?=EC=97=90=20invite=5Fchallenge=5Fcard=20=EB=AA=A8=EB=8D=B8=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/challenge_detail_repository.dart | 37 +++ .../data/challenge_detail_repository.g.dart | 30 ++ .../detail/data/post_repository.dart | 47 +++ .../detail/data/post_repository.g.dart | 27 ++ .../provider/challenge_detail_provider.dart | 17 ++ .../provider/challenge_detail_provider.g.dart | 155 ++++++++++ .../detail/provider/post_provider.dart | 23 ++ .../detail/provider/post_provider.g.dart | 199 +++++++++++++ .../widgets/challenge_invite_card.dart | 52 ++-- .../widgets/challenge_detail_content.dart | 278 ++++++++++++++++++ 10 files changed, 836 insertions(+), 29 deletions(-) create mode 100644 lib/features/challenge/detail/data/challenge_detail_repository.dart create mode 100644 lib/features/challenge/detail/data/challenge_detail_repository.g.dart create mode 100644 lib/features/challenge/detail/data/post_repository.dart create mode 100644 lib/features/challenge/detail/data/post_repository.g.dart create mode 100644 lib/features/challenge/detail/provider/challenge_detail_provider.dart create mode 100644 lib/features/challenge/detail/provider/challenge_detail_provider.g.dart create mode 100644 lib/features/challenge/detail/provider/post_provider.dart create mode 100644 lib/features/challenge/detail/provider/post_provider.g.dart create mode 100644 lib/shared/widgets/challenge_detail_content.dart diff --git a/lib/features/challenge/detail/data/challenge_detail_repository.dart b/lib/features/challenge/detail/data/challenge_detail_repository.dart new file mode 100644 index 0000000..cdb7bd1 --- /dev/null +++ b/lib/features/challenge/detail/data/challenge_detail_repository.dart @@ -0,0 +1,37 @@ +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:haenaem/shared/models/challenge_detail.dart'; +import 'package:haenaem/core/network/dio_provider.dart'; + +part 'challenge_detail_repository.g.dart'; + +// 최초 작성자 : 강선욱 +class ChallengeDetailRepository { + final Dio _dio; + + ChallengeDetailRepository(this._dio); + + // 챌린지 상세 정보 조회 + Future getChallengeDetail(int challengeId) async { + try { + final response = await _dio.get('/api/challenge/$challengeId'); + + if (response.statusCode == 200) { + return ChallengeDetail.fromJson(response.data as Map); + } else { + throw Exception('챌린지 상세 조회 실패'); + } + } on DioException catch (e) { + debugPrint('❌ 챌린지 상세 API 에러: ${e.response?.data}'); + throw Exception('챌린지 정보를 불러오지 못했습니다.'); + } + } +} + +@riverpod +ChallengeDetailRepository challengeDetailRepository(Ref ref) { + final dio = ref.watch(dioProvider); + return ChallengeDetailRepository(dio); +} diff --git a/lib/features/challenge/detail/data/challenge_detail_repository.g.dart b/lib/features/challenge/detail/data/challenge_detail_repository.g.dart new file mode 100644 index 0000000..fb94c20 --- /dev/null +++ b/lib/features/challenge/detail/data/challenge_detail_repository.g.dart @@ -0,0 +1,30 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'challenge_detail_repository.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$challengeDetailRepositoryHash() => + r'35839152b7ee466aa92d997b5a78dc80fe68f52d'; + +/// See also [challengeDetailRepository]. +@ProviderFor(challengeDetailRepository) +final challengeDetailRepositoryProvider = + AutoDisposeProvider.internal( + challengeDetailRepository, + name: r'challengeDetailRepositoryProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$challengeDetailRepositoryHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +typedef ChallengeDetailRepositoryRef = + AutoDisposeProviderRef; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/challenge/detail/data/post_repository.dart b/lib/features/challenge/detail/data/post_repository.dart new file mode 100644 index 0000000..8d915ae --- /dev/null +++ b/lib/features/challenge/detail/data/post_repository.dart @@ -0,0 +1,47 @@ +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import '../models/calendar_post.dart'; +import 'package:haenaem/core/network/dio_provider.dart'; + +part 'post_repository.g.dart'; + +// 최초 작성자 : 강선욱 +class PostRepository { + final Dio _dio; + + PostRepository(this._dio); + + // 챌린지의 특정 연월 인증 포스트 목록 조회 + Future> getChallengePosts({ + required int challengeId, + required int year, + required int month, + }) async { + try { + final response = await _dio.get( + '/api/challenges/$challengeId/calendar/posts', + queryParameters: {'year': year, 'month': month, 'page': 0}, + ); + + if (response.statusCode == 200) { + final List content = response.data['content'] ?? []; + return content + .map((e) => CalendarPost.fromJson(e as Map)) + .toList(); + } else { + throw Exception('인증글 목록 조회 실패'); + } + } on DioException catch (e) { + debugPrint('❌ 인증글 API 에러: ${e.response?.data}'); + return []; + } + } +} + +@riverpod +PostRepository postRepository(Ref ref) { + final dio = ref.watch(dioProvider); + return PostRepository(dio); +} diff --git a/lib/features/challenge/detail/data/post_repository.g.dart b/lib/features/challenge/detail/data/post_repository.g.dart new file mode 100644 index 0000000..bdb359a --- /dev/null +++ b/lib/features/challenge/detail/data/post_repository.g.dart @@ -0,0 +1,27 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'post_repository.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$postRepositoryHash() => r'b2ee3bdc546e5c693abd9df6300a6e2ff6089c2c'; + +/// See also [postRepository]. +@ProviderFor(postRepository) +final postRepositoryProvider = AutoDisposeProvider.internal( + postRepository, + name: r'postRepositoryProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$postRepositoryHash, + dependencies: null, + allTransitiveDependencies: null, +); + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +typedef PostRepositoryRef = AutoDisposeProviderRef; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/challenge/detail/provider/challenge_detail_provider.dart b/lib/features/challenge/detail/provider/challenge_detail_provider.dart new file mode 100644 index 0000000..302e3a7 --- /dev/null +++ b/lib/features/challenge/detail/provider/challenge_detail_provider.dart @@ -0,0 +1,17 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:haenaem/shared/models/challenge_detail.dart'; +import 'package:haenaem/features/challenge/detail/data/challenge_detail_repository.dart'; + +part 'challenge_detail_provider.g.dart'; + +// 최초 작성자 : 강선욱 +// 챌린지 상세 정보 provider +@riverpod +Future challengeDetail( + Ref ref, { + required int challengeId, +}) async { + final repository = ref.watch(challengeDetailRepositoryProvider); + return repository.getChallengeDetail(challengeId); +} diff --git a/lib/features/challenge/detail/provider/challenge_detail_provider.g.dart b/lib/features/challenge/detail/provider/challenge_detail_provider.g.dart new file mode 100644 index 0000000..210a8b5 --- /dev/null +++ b/lib/features/challenge/detail/provider/challenge_detail_provider.g.dart @@ -0,0 +1,155 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'challenge_detail_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$challengeDetailHash() => r'ea0b246d99206d198ec31081a6a32ee83aaee20c'; + +/// Copied from Dart SDK +class _SystemHash { + _SystemHash._(); + + static int combine(int hash, int value) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + value); + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); + return hash ^ (hash >> 6); + } + + static int finish(int hash) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); + // ignore: parameter_assignments + hash = hash ^ (hash >> 11); + return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); + } +} + +/// See also [challengeDetail]. +@ProviderFor(challengeDetail) +const challengeDetailProvider = ChallengeDetailFamily(); + +/// See also [challengeDetail]. +class ChallengeDetailFamily extends Family> { + /// See also [challengeDetail]. + const ChallengeDetailFamily(); + + /// See also [challengeDetail]. + ChallengeDetailProvider call({required int challengeId}) { + return ChallengeDetailProvider(challengeId: challengeId); + } + + @override + ChallengeDetailProvider getProviderOverride( + covariant ChallengeDetailProvider provider, + ) { + return call(challengeId: provider.challengeId); + } + + static const Iterable? _dependencies = null; + + @override + Iterable? get dependencies => _dependencies; + + static const Iterable? _allTransitiveDependencies = null; + + @override + Iterable? get allTransitiveDependencies => + _allTransitiveDependencies; + + @override + String? get name => r'challengeDetailProvider'; +} + +/// See also [challengeDetail]. +class ChallengeDetailProvider + extends AutoDisposeFutureProvider { + /// See also [challengeDetail]. + ChallengeDetailProvider({required int challengeId}) + : this._internal( + (ref) => challengeDetail( + ref as ChallengeDetailRef, + challengeId: challengeId, + ), + from: challengeDetailProvider, + name: r'challengeDetailProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$challengeDetailHash, + dependencies: ChallengeDetailFamily._dependencies, + allTransitiveDependencies: + ChallengeDetailFamily._allTransitiveDependencies, + challengeId: challengeId, + ); + + ChallengeDetailProvider._internal( + super._createNotifier, { + required super.name, + required super.dependencies, + required super.allTransitiveDependencies, + required super.debugGetCreateSourceHash, + required super.from, + required this.challengeId, + }) : super.internal(); + + final int challengeId; + + @override + Override overrideWith( + FutureOr Function(ChallengeDetailRef provider) create, + ) { + return ProviderOverride( + origin: this, + override: ChallengeDetailProvider._internal( + (ref) => create(ref as ChallengeDetailRef), + from: from, + name: null, + dependencies: null, + allTransitiveDependencies: null, + debugGetCreateSourceHash: null, + challengeId: challengeId, + ), + ); + } + + @override + AutoDisposeFutureProviderElement createElement() { + return _ChallengeDetailProviderElement(this); + } + + @override + bool operator ==(Object other) { + return other is ChallengeDetailProvider && other.challengeId == challengeId; + } + + @override + int get hashCode { + var hash = _SystemHash.combine(0, runtimeType.hashCode); + hash = _SystemHash.combine(hash, challengeId.hashCode); + + return _SystemHash.finish(hash); + } +} + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +mixin ChallengeDetailRef on AutoDisposeFutureProviderRef { + /// The parameter `challengeId` of this provider. + int get challengeId; +} + +class _ChallengeDetailProviderElement + extends AutoDisposeFutureProviderElement + with ChallengeDetailRef { + _ChallengeDetailProviderElement(super.provider); + + @override + int get challengeId => (origin as ChallengeDetailProvider).challengeId; +} + +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/challenge/detail/provider/post_provider.dart b/lib/features/challenge/detail/provider/post_provider.dart new file mode 100644 index 0000000..8b45e14 --- /dev/null +++ b/lib/features/challenge/detail/provider/post_provider.dart @@ -0,0 +1,23 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import '../models/calendar_post.dart'; +import '../data/post_repository.dart'; + +part 'post_provider.g.dart'; + +// 최초 작성자 : 강선욱 +// 내현황 탭 달력, 인증글 리스트 데이터 불러오기 +@riverpod +Future> monthlyChallengePosts( + Ref ref, { + required int challengeId, + required int year, + required int month, +}) async { + final repository = ref.watch(postRepositoryProvider); + return repository.getChallengePosts( + challengeId: challengeId, + year: year, + month: month, + ); +} diff --git a/lib/features/challenge/detail/provider/post_provider.g.dart b/lib/features/challenge/detail/provider/post_provider.g.dart new file mode 100644 index 0000000..d209d1b --- /dev/null +++ b/lib/features/challenge/detail/provider/post_provider.g.dart @@ -0,0 +1,199 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'post_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$monthlyChallengePostsHash() => + r'dfcde62130fba3d3465ea6297f7d4b4c294b58f9'; + +/// Copied from Dart SDK +class _SystemHash { + _SystemHash._(); + + static int combine(int hash, int value) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + value); + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); + return hash ^ (hash >> 6); + } + + static int finish(int hash) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); + // ignore: parameter_assignments + hash = hash ^ (hash >> 11); + return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); + } +} + +/// See also [monthlyChallengePosts]. +@ProviderFor(monthlyChallengePosts) +const monthlyChallengePostsProvider = MonthlyChallengePostsFamily(); + +/// See also [monthlyChallengePosts]. +class MonthlyChallengePostsFamily + extends Family>> { + /// See also [monthlyChallengePosts]. + const MonthlyChallengePostsFamily(); + + /// See also [monthlyChallengePosts]. + MonthlyChallengePostsProvider call({ + required int challengeId, + required int year, + required int month, + }) { + return MonthlyChallengePostsProvider( + challengeId: challengeId, + year: year, + month: month, + ); + } + + @override + MonthlyChallengePostsProvider getProviderOverride( + covariant MonthlyChallengePostsProvider provider, + ) { + return call( + challengeId: provider.challengeId, + year: provider.year, + month: provider.month, + ); + } + + static const Iterable? _dependencies = null; + + @override + Iterable? get dependencies => _dependencies; + + static const Iterable? _allTransitiveDependencies = null; + + @override + Iterable? get allTransitiveDependencies => + _allTransitiveDependencies; + + @override + String? get name => r'monthlyChallengePostsProvider'; +} + +/// See also [monthlyChallengePosts]. +class MonthlyChallengePostsProvider + extends AutoDisposeFutureProvider> { + /// See also [monthlyChallengePosts]. + MonthlyChallengePostsProvider({ + required int challengeId, + required int year, + required int month, + }) : this._internal( + (ref) => monthlyChallengePosts( + ref as MonthlyChallengePostsRef, + challengeId: challengeId, + year: year, + month: month, + ), + from: monthlyChallengePostsProvider, + name: r'monthlyChallengePostsProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$monthlyChallengePostsHash, + dependencies: MonthlyChallengePostsFamily._dependencies, + allTransitiveDependencies: + MonthlyChallengePostsFamily._allTransitiveDependencies, + challengeId: challengeId, + year: year, + month: month, + ); + + MonthlyChallengePostsProvider._internal( + super._createNotifier, { + required super.name, + required super.dependencies, + required super.allTransitiveDependencies, + required super.debugGetCreateSourceHash, + required super.from, + required this.challengeId, + required this.year, + required this.month, + }) : super.internal(); + + final int challengeId; + final int year; + final int month; + + @override + Override overrideWith( + FutureOr> Function(MonthlyChallengePostsRef provider) + create, + ) { + return ProviderOverride( + origin: this, + override: MonthlyChallengePostsProvider._internal( + (ref) => create(ref as MonthlyChallengePostsRef), + from: from, + name: null, + dependencies: null, + allTransitiveDependencies: null, + debugGetCreateSourceHash: null, + challengeId: challengeId, + year: year, + month: month, + ), + ); + } + + @override + AutoDisposeFutureProviderElement> createElement() { + return _MonthlyChallengePostsProviderElement(this); + } + + @override + bool operator ==(Object other) { + return other is MonthlyChallengePostsProvider && + other.challengeId == challengeId && + other.year == year && + other.month == month; + } + + @override + int get hashCode { + var hash = _SystemHash.combine(0, runtimeType.hashCode); + hash = _SystemHash.combine(hash, challengeId.hashCode); + hash = _SystemHash.combine(hash, year.hashCode); + hash = _SystemHash.combine(hash, month.hashCode); + + return _SystemHash.finish(hash); + } +} + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +mixin MonthlyChallengePostsRef + on AutoDisposeFutureProviderRef> { + /// The parameter `challengeId` of this provider. + int get challengeId; + + /// The parameter `year` of this provider. + int get year; + + /// The parameter `month` of this provider. + int get month; +} + +class _MonthlyChallengePostsProviderElement + extends AutoDisposeFutureProviderElement> + with MonthlyChallengePostsRef { + _MonthlyChallengePostsProviderElement(super.provider); + + @override + int get challengeId => (origin as MonthlyChallengePostsProvider).challengeId; + @override + int get year => (origin as MonthlyChallengePostsProvider).year; + @override + int get month => (origin as MonthlyChallengePostsProvider).month; +} + +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/notification/widgets/challenge_invite_card.dart b/lib/features/notification/widgets/challenge_invite_card.dart index 7f0769c..8d6ac5d 100644 --- a/lib/features/notification/widgets/challenge_invite_card.dart +++ b/lib/features/notification/widgets/challenge_invite_card.dart @@ -4,34 +4,26 @@ import 'package:flutter/material.dart'; import '../../../core/theme/app_colors.dart'; import '../../../core/theme/app_typography.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import '../models/invite_challenge_card.dart'; import '../screens/challenge_invite_detail_screen.dart'; class ChallengeInviteCard extends StatelessWidget { - final int challengeId; - final String inviterName; - final String? inviterProfileImageUrl; - final String challengeName; - final int participantCount; - final String dDay; - final List labels; + final InviteChallengecard inviteChallenge; final VoidCallback onAccept; // 수락 함수 final VoidCallback onReject; // 거절 함수 const ChallengeInviteCard({ super.key, - required this.challengeId, - required this.inviterName, - this.inviterProfileImageUrl, - required this.challengeName, - required this.participantCount, - required this.dDay, - required this.labels, + required this.inviteChallenge, required this.onAccept, required this.onReject, }); @override Widget build(BuildContext context) { + final challengeInfo = inviteChallenge.challengeInfo; + final inviterUser = inviteChallenge.inviterUser; + return Container( margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), // 디자인 가이드에 맞춘 패딩 적용 @@ -67,7 +59,7 @@ class ChallengeInviteCard extends StatelessWidget { _buildIconBox(), const SizedBox(width: 6), Text( - '$inviterName님의 초대', + '${inviterUser.nickname}님의 초대', style: AppTypography.b2.copyWith( color: AppColors.gray1, // 디자인 코드 참조 ), @@ -76,7 +68,7 @@ class ChallengeInviteCard extends StatelessWidget { ), ), Text( - challengeName, + challengeInfo.base.title, style: AppTypography.b3.copyWith(color: AppColors.black), overflow: TextOverflow.ellipsis, ), @@ -95,14 +87,14 @@ class ChallengeInviteCard extends StatelessWidget { ), ), Text( - '${participantCount.toString()}명', + '${challengeInfo.participantCount.toString()}명', style: AppTypography.b2.copyWith( color: AppColors.gray2, ), ), const SizedBox(width: 16), Text( - '완료까지 $dDay', + '완료까지 ${challengeInfo.dDay}', style: AppTypography.b2.copyWith( color: AppColors.gray2, ), @@ -114,7 +106,7 @@ class ChallengeInviteCard extends StatelessWidget { Wrap( spacing: 6, // 태그 사이 간격 // runSpacing: 8, // 줄 바꿈 시 간격 (필요 시 활성화) - children: labels.map((label) { + children: challengeInfo.tags.map((label) { return Container( padding: const EdgeInsets.symmetric( horizontal: 10, @@ -142,15 +134,15 @@ class ChallengeInviteCard extends StatelessWidget { alignment: Alignment.center, child: IconButton( onPressed: () { - print("====> 이동하려는 챌린지 ID: $challengeId"); + print("====> 이동하려는 챌린지 ID: ${challengeInfo.base.id}"); Navigator.push( context, MaterialPageRoute( builder: (context) => ChallengeInviteDetailScreen( - challengeId: challengeId, - inviterName: inviterName, - inviterProfileImageUrl: inviterProfileImageUrl, + challengeId: challengeInfo.base.id, + inviterName: inviterUser.nickname, + inviterProfileImageUrl: inviterUser.profileUrl, ), ), ); @@ -231,20 +223,22 @@ class ChallengeInviteCard extends StatelessWidget { color: AppColors.gray5, shape: BoxShape.circle, image: - inviterProfileImageUrl != null && - inviterProfileImageUrl!.startsWith('http') + inviteChallenge.inviterUser.profileUrl != null && + inviteChallenge.inviterUser.profileUrl!.startsWith('http') ? DecorationImage( - image: NetworkImage(inviterProfileImageUrl!), + image: NetworkImage(inviteChallenge.inviterUser.profileUrl!), fit: BoxFit.cover, ) - : (inviterProfileImageUrl != null + : (inviteChallenge.inviterUser.profileUrl != null ? DecorationImage( - image: AssetImage(inviterProfileImageUrl!), + image: AssetImage( + inviteChallenge.inviterUser.profileUrl!, + ), fit: BoxFit.cover, ) : null), ), - child: inviterProfileImageUrl == null + child: inviteChallenge.inviterUser.profileUrl == null ? Center( child: SvgPicture.asset( 'assets/images/icons/default_profile_icon.svg', diff --git a/lib/shared/widgets/challenge_detail_content.dart b/lib/shared/widgets/challenge_detail_content.dart new file mode 100644 index 0000000..3d22990 --- /dev/null +++ b/lib/shared/widgets/challenge_detail_content.dart @@ -0,0 +1,278 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; +import 'package:haenaem/shared/models/challenge_detail.dart'; +import 'package:haenaem/shared/widgets/user_profile_circle.dart'; +// import 'package:haenaem/features/challenge/models/challenge_model.dart'; +// import 'package:haenaem/shared/models/tag_model.dart'; +import 'package:haenaem/shared/widgets/tag_badge.dart'; + +class ChallengeDetailContent extends StatelessWidget { + final ChallengeDetail challenge; + final String? title; + final ScrollController scrollController; + final bool showTitle; + + const ChallengeDetailContent({ + super.key, + required this.challenge, + required this.title, + required this.scrollController, + this.showTitle = true, + }); + + @override + Widget build(BuildContext context) { + // 1. 날짜 데이터 가공 + String formattedStart = DateFormat( + 'yyyy년 MM월 dd일', + ).format(challenge.startDate); + String formattedEnd = DateFormat('yyyy년 MM월 dd일').format(challenge.endDate); + + // 2. D-Day 계산 로직 + String dDayString = ""; + final DateTime targetDay = DateTime( + challenge.endDate.year, + challenge.endDate.month, + challenge.endDate.day, + ); + final DateTime today = DateTime.now(); + final DateTime currentDay = DateTime(today.year, today.month, today.day); + final int difference = targetDay.difference(currentDay).inDays; + + if (difference == 0) { + dDayString = "(D-Day)"; + } else if (difference > 0) { + dDayString = "(D-$difference)"; + } else { + dDayString = "(종료됨)"; + } + + // 인증 빈도 텍스트 가공 로직 + String frequencyText = challenge.weeklyFrequency == 7 + ? '매일' + : '주 ${challenge.weeklyFrequency}회'; + + // TagMapper 기준 정렬 로직 + // final List sortedTags = List.from(challenge.tags); + // final priorityList = TagMapper.tagInternalOrder.values + // .expand((e) => e) + // .toList(); + + // sortedTags.sort((a, b) { + // final indexA = priorityList.indexOf(a.tag); + // final indexB = priorityList.indexOf(b.tag); + // return (indexA == -1 ? 99 : indexA).compareTo(indexB == -1 ? 99 : indexB); + // }); + + return SingleChildScrollView( + controller: scrollController, + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 24), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 챌린지 제목 + if (showTitle) ...[ + Text( + title ?? '챌린지 소개', + style: AppTypography.h3.copyWith(color: AppColors.black), + ), + const SizedBox(height: 24), + ], + + _buildInfoSection('챌린지 시작일', formattedStart), + _buildInfoSection('챌린지 마감일', '$formattedEnd $dDayString'), + _buildInfoSection('인증 빈도', frequencyText), + _buildInfoSection( + '인증 방식', + challenge.photoRequired ? '사진 첨부 필수' : '사진 첨부 선택', + ), + + // 태그 섹션 + Text( + '챌린지 태그', + style: AppTypography.b1.copyWith(color: AppColors.gray2), + ), + const SizedBox(height: 8), + + challenge.tags.isEmpty + ? Text( + "-", + style: AppTypography.b1.copyWith(color: AppColors.gray3), + ) + : Wrap( + spacing: 8, + runSpacing: 10, + children: challenge.tags + .map((tag) => TagBadge(label: tag)) + .toList(), + ), + + // 가로 스크롤 대신 Wrap을 사용하여 정돈된 느낌을 줍니다. + // challenge.tags.isEmpty + // ? Text( + // "-", + // style: AppTypography.b1.copyWith(color: AppColors.gray3), + // ) + // : Wrap( + // spacing: 8, + // runSpacing: 10, + // children: sortedTags.map((tagObj) { + // // 💡 AppTagChip 대신 새로 만든 TagBadge를 사용합니다. + // return TagBadge(label: tagObj.tag); + // }).toList(), + // ), + const _CustomDivider(), + + // 챌린지 설명 + Text( + '챌린지 설명', + style: AppTypography.b1.copyWith(color: AppColors.gray2), + ), + const SizedBox(height: 8), + Text( + challenge.description, + style: AppTypography.b1.copyWith( + color: AppColors.black, + height: 1.5, + ), + ), + + const _CustomDivider(), + + // 방장 정보 + Text('방장', style: AppTypography.b1.copyWith(color: AppColors.gray2)), + const SizedBox(height: 12), + Row( + children: [ + UserProfileCircle( + imageUrl: challenge.leader.profileUrl, + size: 36, + ), + const SizedBox(width: 12), + Text( + challenge.leader.nickname, + style: AppTypography.b1.copyWith(color: AppColors.black), + ), + ], + ), + + const _CustomDivider(), + + // 참여자 수 + Row( + children: [ + const Icon(Icons.person, size: 18, color: AppColors.black), + const SizedBox(width: 4), + Text( + '참여자 수', + style: AppTypography.b1.copyWith(color: AppColors.gray2), + ), + ], + ), + const SizedBox(height: 4), + Text( + '${challenge.participantCount}명', + style: AppTypography.b1.copyWith(color: AppColors.black), + ), + + const _CustomDivider(), + + // 오늘의 인증자 + Text( + '오늘의 인증자', + style: AppTypography.b1.copyWith(color: AppColors.gray2), + ), + const SizedBox(height: 12), + challenge.todaySuccessUsers.isEmpty + ? Text( + '아직 오늘의 인증자가 없습니다.', + style: AppTypography.b1.copyWith(color: AppColors.gray2), + ) + : SingleChildScrollView( + scrollDirection: Axis.horizontal, + clipBehavior: Clip.none, + child: Row( + children: challenge.todaySuccessUsers.map((user) { + return Padding( + padding: const EdgeInsets.only(right: 15), + child: Column( + children: [ + UserProfileCircle( + imageUrl: user.profileUrl, + size: 36, + ), + const SizedBox(height: 6), + SizedBox( + width: 50, + child: Text( + user.nickname, + style: AppTypography.c1.copyWith( + color: AppColors.black, + ), + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ); + }).toList(), + ), + ), + const SizedBox(height: 40), + ], + ), + ); + } + + // --- 내부 컴포넌트 메서드 --- + + Widget _buildInfoSection(String title, String content) { + return Padding( + padding: const EdgeInsets.only(bottom: 24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(title, style: AppTypography.b1.copyWith(color: AppColors.gray2)), + const SizedBox(height: 4), + Text( + content, + style: AppTypography.b1.copyWith(color: AppColors.black), + ), + ], + ), + ); + } + + Widget _buildProfileImage(String imageUrl) { + return SizedBox( + width: 36, + height: 36, + child: ClipOval( + child: imageUrl.isNotEmpty + ? Image.network( + imageUrl, + fit: BoxFit.cover, + errorBuilder: (context, error, stackTrace) => SvgPicture.asset( + 'assets/images/icons/default_profile_icon.svg', + ), + ) + : SvgPicture.asset('assets/images/icons/default_profile_icon.svg'), + ), + ); + } +} + +class _CustomDivider extends StatelessWidget { + const _CustomDivider(); + @override + Widget build(BuildContext context) { + return const Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: Divider(height: 1, thickness: 1, color: AppColors.gray4), + ); + } +} From 1cf4b8430c00a1fa918356fe61ef4d9bf97739f9 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 24 Mar 2026 00:24:33 +0900 Subject: [PATCH 068/134] =?UTF-8?q?feat:=20=EC=88=98=EC=A0=95=EB=90=9C=20A?= =?UTF-8?q?PI=EC=97=90=20=EB=A7=9E=EA=B2=8C=20invite=5Fchallenge=5Fcard=20?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/notification_repository.dart | 8 +- .../models/invite_challenge_card.dart | 93 ++++++++++++++++--- .../views/challenge_invites_view.dart | 8 +- 3 files changed, 88 insertions(+), 21 deletions(-) diff --git a/lib/features/notification/data/notification_repository.dart b/lib/features/notification/data/notification_repository.dart index 6806c9e..196b131 100644 --- a/lib/features/notification/data/notification_repository.dart +++ b/lib/features/notification/data/notification_repository.dart @@ -91,7 +91,13 @@ class NotificationRepository { final response = await dio.get('/api/challenges/invites'); // 응답이 배열(List) 형태 final List data = response.data; - return data.map((e) => InviteChallengecard.fromJson(e)).toList(); + return data + .map( + (e) => InviteChallengecard.fromResponse( + InviteResponse.fromJson(e as Map), + ), + ) + .toList(); } on DioException catch (e) { print('❌ [초대 조회 에러]: ${e.response?.data}'); throw Exception('초대 목록을 불러오는데 실패했습니다.'); diff --git a/lib/features/notification/models/invite_challenge_card.dart b/lib/features/notification/models/invite_challenge_card.dart index 2247936..8bc4550 100644 --- a/lib/features/notification/models/invite_challenge_card.dart +++ b/lib/features/notification/models/invite_challenge_card.dart @@ -2,29 +2,96 @@ // 챌린지 초대 목록 아이템 모델 import 'package:haenaem/shared/models/user.dart'; import 'package:haenaem/shared/models/search_challenge_card.dart'; +import 'package:haenaem/shared/models/challenge_base.dart'; -class InviteChallengecard { - final SearchChallengeCard challengeInfo; // 초대된 챌린지의 상세정보 - final User inviterUser; // 초대한 유저의 정보 (ID, 프로필 URL, 닉네임 포함) +// API 응답 원본 데이터를 담는 모델 +class InviteResponse { + final int inviterId; + final String inviterNickname; + final String? profileImageUrl; + final int challengeId; + final String challengeTitle; + final int participantCount; + final int remainingDays; + final List tags; - InviteChallengecard({required this.challengeInfo, required this.inviterUser}); + InviteResponse({ + required this.inviterId, + required this.inviterNickname, + this.profileImageUrl, + required this.challengeId, + required this.challengeTitle, + required this.participantCount, + required this.remainingDays, + required this.tags, + }); - // 서버에서 받은 JSON 데이터를 [InviteChallengecard] 객체로 변환하는 팩토리 생성자 - factory InviteChallengecard.fromJson(Map json) { - String? rawProfileUrl = json['profileUrl']; + factory InviteResponse.fromJson(Map json) { + String? rawProfileUrl = json['profileImageUrl'] as String?; // URL이 null이 아니고, 공백을 제거했을 때 빈 문자열("")이라면 null로 간주 // (서버에서 잘못된 빈 값이 넘어올 경우를 대비한 방어 코드) if (rawProfileUrl != null && rawProfileUrl.trim().isEmpty) { rawProfileUrl = null; } - return InviteChallengecard( - challengeInfo: SearchChallengeCard.fromJson(json), - inviterUser: User( - id: json['inviterId'] ?? 0, - nickname: json['inviterNickname'] ?? '알 수 없음', - profileUrl: rawProfileUrl, // 빈 문자열이면 null로 처리 + return InviteResponse( + inviterId: json['inviterId'] as int, + inviterNickname: json['inviterNickname'] as String, + profileImageUrl: rawProfileUrl, + challengeId: json['challengeId'] as int, + challengeTitle: json['challengeTitle'] as String, + participantCount: json['participantCount'] as int, + remainingDays: json['remainingDays'] as int, + tags: List.from(json['tags'] as List), + ); + } + + // InviteResponse → User 변환 + // User.fromJson() 대신 직접 생성: 초대 API 필드명이 User.fromJson()의 기대 키('id', 'nickname')와 다르기 때문 + User toUser() { + return User( + id: inviterId, // 'inviterId' → User.id + nickname: inviterNickname, // 'inviterNickname' → User.nickname + profileUrl: profileImageUrl, // 'profileImageUrl' → User.profileUrl + ); + } + + // InviteResponse → SearchChallengeCard 변환 + // SearchChallengeCard.fromJson() 대신 직접 생성: 초대 API 필드명이 + // SearchChallengeCard.fromJson()의 기대 키('participant_count', 'end_date', 'tag')와 다르기 때문 + SearchChallengeCard toChallengeCard() { + return SearchChallengeCard( + base: ChallengeBase( + id: challengeId, // 'challengeId' → ChallengeBase.id + title: challengeTitle, // 'challengeTitle' → ChallengeBase.title ), + participantCount: + participantCount, // 'participantCount' → SearchChallengeCard.participantCount + dDay: DateTime.now().add( + Duration(days: remainingDays), + ), // 'remainingDays'(int) → DateTime + tags: tags, // 'tags' → SearchChallengeCard.tags + ); + } +} + +// 챌린지 초대 카드 모델 (User + SearchChallengeCard) +class InviteChallengecard { + final SearchChallengeCard challengeInfo; // 초대된 챌린지의 상세정보 + final User inviterUser; // 초대한 유저의 정보 (ID, 프로필 URL, 닉네임 포함) + + InviteChallengecard({required this.challengeInfo, required this.inviterUser}); + + /// InviteResponse를 InviteChallengecard로 변환하는 팩토리 생성자 + factory InviteChallengecard.fromResponse(InviteResponse response) { + return InviteChallengecard( + inviterUser: response.toUser(), + challengeInfo: response.toChallengeCard(), ); } + + // JSON에서 바로 변환하는 팩토리 생성자 (InviteResponse를 거쳐 변환) + factory InviteChallengecard.fromJson(Map json) { + return InviteChallengecard.fromResponse(InviteResponse.fromJson(json)); + } } diff --git a/lib/features/notification/views/challenge_invites_view.dart b/lib/features/notification/views/challenge_invites_view.dart index 2f8393d..b9a11a2 100644 --- a/lib/features/notification/views/challenge_invites_view.dart +++ b/lib/features/notification/views/challenge_invites_view.dart @@ -36,13 +36,7 @@ class ChallengeInvitesView extends ConsumerWidget { final invite = state.invites[index]; return ChallengeInviteCard( - challengeId: invite.challengeInfo.base.id, - inviterName: invite.inviterUser.nickname, - inviterProfileImageUrl: invite.inviterUser.profileUrl, - challengeName: invite.challengeInfo.base.title, - participantCount: invite.challengeInfo.participantCount, - dDay: 'D-${invite.challengeInfo.dDay}', - labels: invite.challengeInfo.tags, + inviteChallenge: invite, // 수락 콜백 연결 onAccept: () async { try { From fa01d6ced77760a1081f04f5896baacaeb65b25d Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 24 Mar 2026 00:41:12 +0900 Subject: [PATCH 069/134] =?UTF-8?q?feat:=20calendar=5Fpost=20=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/models/calendar_post.dart | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 lib/features/challenge/detail/models/calendar_post.dart diff --git a/lib/features/challenge/detail/models/calendar_post.dart b/lib/features/challenge/detail/models/calendar_post.dart new file mode 100644 index 0000000..b06b72f --- /dev/null +++ b/lib/features/challenge/detail/models/calendar_post.dart @@ -0,0 +1,26 @@ +// 최초 작성자 : 강선욱 +// 캘린더 달력 셀 및 인증글 목록 렌더링에 필요한 최소 데이터 모델 +// 상세 페이지 진입 시에는 postId만 넘기고 Post 모델을 별도로 조회 + +class CalendarPost { + final int postId; + final String postDate; + final String? imageUrl; + final String content; + + const CalendarPost({ + required this.postId, + required this.postDate, + this.imageUrl, + required this.content, + }); + + factory CalendarPost.fromJson(Map json) { + return CalendarPost( + postId: json['postId'] as int, + postDate: json['postDate'] as String, + imageUrl: json['imageUrl'] as String?, + content: json['content'] as String, + ); + } +} From 16308fae8115c375b1226322eebefc6fd1bcf7f0 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 24 Mar 2026 00:42:05 +0900 Subject: [PATCH 070/134] =?UTF-8?q?refactor:=20ranking=5Fmodel.dart=20?= =?UTF-8?q?=ED=8F=B4=EB=8D=94=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/detail/{model => models}/ranking_model.dart | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/features/challenge/detail/{model => models}/ranking_model.dart (100%) diff --git a/lib/features/challenge/detail/model/ranking_model.dart b/lib/features/challenge/detail/models/ranking_model.dart similarity index 100% rename from lib/features/challenge/detail/model/ranking_model.dart rename to lib/features/challenge/detail/models/ranking_model.dart From 598a68da1c194b19efdcc33cb984fd76811fd6cd Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 24 Mar 2026 01:24:04 +0900 Subject: [PATCH 071/134] =?UTF-8?q?refactor:=20ranking=20model=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/detail/data/ranking_repository.dart | 2 +- lib/features/challenge/detail/provider/ranking_provider.dart | 2 +- .../challenge/detail/screens/member_ranking_screen.dart | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/features/challenge/detail/data/ranking_repository.dart b/lib/features/challenge/detail/data/ranking_repository.dart index 2bb13eb..442bace 100644 --- a/lib/features/challenge/detail/data/ranking_repository.dart +++ b/lib/features/challenge/detail/data/ranking_repository.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:haenaem/core/network/dio_provider.dart'; -import '../model/ranking_model.dart'; +import '../models/ranking_model.dart'; part 'ranking_repository.g.dart'; diff --git a/lib/features/challenge/detail/provider/ranking_provider.dart b/lib/features/challenge/detail/provider/ranking_provider.dart index 96e25f1..2591ccd 100644 --- a/lib/features/challenge/detail/provider/ranking_provider.dart +++ b/lib/features/challenge/detail/provider/ranking_provider.dart @@ -3,7 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../data/ranking_repository.dart'; -import '../model/ranking_model.dart'; +import '../models/ranking_model.dart'; part 'ranking_provider.g.dart'; diff --git a/lib/features/challenge/detail/screens/member_ranking_screen.dart b/lib/features/challenge/detail/screens/member_ranking_screen.dart index bc86580..8947eee 100644 --- a/lib/features/challenge/detail/screens/member_ranking_screen.dart +++ b/lib/features/challenge/detail/screens/member_ranking_screen.dart @@ -5,7 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/features/challenge/detail/provider/ranking_provider.dart'; -import 'package:haenaem/features/challenge/detail/model/ranking_model.dart'; +import 'package:haenaem/features/challenge/detail/models/ranking_model.dart'; class MemberRankingScreen extends ConsumerWidget { final int challengeId; From 03e40119613a544293acf7b2f36d919ff8a6935c Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 24 Mar 2026 01:24:36 +0900 Subject: [PATCH 072/134] =?UTF-8?q?refactor:=20search=20challenge=20card?= =?UTF-8?q?=20=EB=AA=A8=EB=8D=B8=20dDay=20int=EA=B0=92=EC=9C=BC=EB=A1=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/shared/models/search_challenge_card.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/shared/models/search_challenge_card.dart b/lib/shared/models/search_challenge_card.dart index 7b05a91..bb3d501 100644 --- a/lib/shared/models/search_challenge_card.dart +++ b/lib/shared/models/search_challenge_card.dart @@ -6,7 +6,7 @@ import 'package:haenaem/shared/models/challenge_base.dart'; class SearchChallengeCard { final ChallengeBase base; // 챌린지 기본 정보 (id, title, isLeader) final int participantCount; // 챌린지 참여자 수 - final DateTime dDay; // 챌린지 종료 D-Day + final int dDay; // 챌린지 종료 D-Day final List tags; // 챌린지 태그 리스트 const SearchChallengeCard({ @@ -20,7 +20,7 @@ class SearchChallengeCard { return SearchChallengeCard( base: ChallengeBase.fromJson(json), participantCount: json['participant_count'] as int, - dDay: DateTime.parse(json['end_date'] as String), + dDay: json['end_date'] as int, tags: List.from(json['tag'] as List), ); } @@ -28,7 +28,7 @@ class SearchChallengeCard { SearchChallengeCard copyWith({ ChallengeBase? base, int? participantCount, - DateTime? dDay, + int? dDay, List? tags, }) { return SearchChallengeCard( From aa6897de75b967ea9693c1901d9cff6be516c338 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 24 Mar 2026 01:29:38 +0900 Subject: [PATCH 073/134] =?UTF-8?q?refactor:=20=EC=B1=8C=EB=A6=B0=EC=A7=80?= =?UTF-8?q?=20=EC=B4=88=EB=8C=80=20=EC=B9=B4=EB=93=9C=20dDay=20=ED=91=9C?= =?UTF-8?q?=ED=98=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/notification/widgets/challenge_invite_card.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/features/notification/widgets/challenge_invite_card.dart b/lib/features/notification/widgets/challenge_invite_card.dart index 8d6ac5d..1ef5df6 100644 --- a/lib/features/notification/widgets/challenge_invite_card.dart +++ b/lib/features/notification/widgets/challenge_invite_card.dart @@ -94,7 +94,9 @@ class ChallengeInviteCard extends StatelessWidget { ), const SizedBox(width: 16), Text( - '완료까지 ${challengeInfo.dDay}', + challengeInfo.dDay == 0 + ? '오늘 완료' + : '완료까지 ${challengeInfo.dDay}일', style: AppTypography.b2.copyWith( color: AppColors.gray2, ), From c1e609c83933a4af9e80bc4344c7f1515e46f55b Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 24 Mar 2026 01:30:27 +0900 Subject: [PATCH 074/134] =?UTF-8?q?fix:=20dDay=20=ED=91=9C=ED=98=84=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/notification/models/invite_challenge_card.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/features/notification/models/invite_challenge_card.dart b/lib/features/notification/models/invite_challenge_card.dart index 8bc4550..bb8f2a1 100644 --- a/lib/features/notification/models/invite_challenge_card.dart +++ b/lib/features/notification/models/invite_challenge_card.dart @@ -67,9 +67,7 @@ class InviteResponse { ), participantCount: participantCount, // 'participantCount' → SearchChallengeCard.participantCount - dDay: DateTime.now().add( - Duration(days: remainingDays), - ), // 'remainingDays'(int) → DateTime + dDay: remainingDays, tags: tags, // 'tags' → SearchChallengeCard.tags ); } From 3d7c60a5e93a3bfc5c46312c4a478d75d4d141b0 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 24 Mar 2026 01:34:43 +0900 Subject: [PATCH 075/134] =?UTF-8?q?fix:=20challenge=20invite=20card=20=20?= =?UTF-8?q?=EB=94=94=EC=9E=90=EC=9D=B8=EB=8C=80=EB=A1=9C=20=EB=8B=A4?= =?UTF-8?q?=EC=8B=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/notification/widgets/challenge_invite_card.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/features/notification/widgets/challenge_invite_card.dart b/lib/features/notification/widgets/challenge_invite_card.dart index 1ef5df6..3bffeb5 100644 --- a/lib/features/notification/widgets/challenge_invite_card.dart +++ b/lib/features/notification/widgets/challenge_invite_card.dart @@ -96,7 +96,7 @@ class ChallengeInviteCard extends StatelessWidget { Text( challengeInfo.dDay == 0 ? '오늘 완료' - : '완료까지 ${challengeInfo.dDay}일', + : '완료까지 D-${challengeInfo.dDay}', style: AppTypography.b2.copyWith( color: AppColors.gray2, ), From 3ab8b2d2461a1ec1223cbeffe8682a376baa3672 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 26 Mar 2026 10:49:48 +0900 Subject: [PATCH 076/134] =?UTF-8?q?feat:=20ChallengeMainScreen=EC=97=90=20?= =?UTF-8?q?streakCount=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/create/screens/challenge_create_screen.dart | 4 +++- .../challenge/detail/screens/challenge_main_screen.dart | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/features/challenge/create/screens/challenge_create_screen.dart b/lib/features/challenge/create/screens/challenge_create_screen.dart index 70b64c7..15cbe67 100644 --- a/lib/features/challenge/create/screens/challenge_create_screen.dart +++ b/lib/features/challenge/create/screens/challenge_create_screen.dart @@ -150,7 +150,9 @@ class _ChallengeCreateScreenState extends ConsumerState { Navigator.pushReplacement( context, MaterialPageRoute( - builder: (context) => ChallengeMainScreen(challengeId: response.id), + builder: (context) => + // 챌린지 생성 직후는 streakCount가 무조건 0이므로 하드코딩 + ChallengeMainScreen(challengeId: response.id), ), ); } else if (mounted) { diff --git a/lib/features/challenge/detail/screens/challenge_main_screen.dart b/lib/features/challenge/detail/screens/challenge_main_screen.dart index a85bd48..a15272b 100644 --- a/lib/features/challenge/detail/screens/challenge_main_screen.dart +++ b/lib/features/challenge/detail/screens/challenge_main_screen.dart @@ -21,6 +21,7 @@ import 'package:haenaem/features/challenge/detail/views/member_view.dart'; class ChallengeMainScreen extends ConsumerStatefulWidget { final int challengeId; final String? challengeTitle; + final int streakCount; final bool isJustCreated; final ChallengeCreateResponse? createdData; @@ -28,6 +29,7 @@ class ChallengeMainScreen extends ConsumerStatefulWidget { super.key, required this.challengeId, this.challengeTitle, + this.streakCount = 0, this.isJustCreated = false, this.createdData, }); @@ -134,6 +136,7 @@ class _ChallengeDetailScreenState extends ConsumerState { ), CalendarView( challengeId: widget.challengeId, + streakCount: widget.streakCount, scrollController: _calendarScrollController, ), MemberView( From ea5ce29dbb36c38a783238dbcf0a62549f2522d7 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 26 Mar 2026 10:50:00 +0900 Subject: [PATCH 077/134] =?UTF-8?q?calendar=5Fgrid=20=EC=9C=84=EC=A0=AF=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/detail/views/calendar_view.dart | 2 -- .../detail/widgets/calendar_grid.dart | 18 +++++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/features/challenge/detail/views/calendar_view.dart b/lib/features/challenge/detail/views/calendar_view.dart index 033a73d..e1f0d72 100644 --- a/lib/features/challenge/detail/views/calendar_view.dart +++ b/lib/features/challenge/detail/views/calendar_view.dart @@ -16,14 +16,12 @@ import 'package:haenaem/features/challenge/models/challenge_model.dart'; class CalendarView extends ConsumerStatefulWidget { final int challengeId; - final String? challengeTitle; final int streakCount; final ScrollController scrollController; const CalendarView({ super.key, required this.challengeId, - required this.challengeTitle, required this.streakCount, required this.scrollController, }); diff --git a/lib/features/challenge/detail/widgets/calendar_grid.dart b/lib/features/challenge/detail/widgets/calendar_grid.dart index 53bfc57..b050209 100644 --- a/lib/features/challenge/detail/widgets/calendar_grid.dart +++ b/lib/features/challenge/detail/widgets/calendar_grid.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:collection/collection.dart'; import 'package:haenaem/core/theme/app_colors.dart'; -import 'package:haenaem/shared/models/post.dart'; +import '../models/calendar_post.dart'; import 'package:haenaem/features/feed/screens/post_detail_screen.dart'; // 최초 작성자 : 강선욱 @@ -15,7 +15,7 @@ class CalendarGrid extends StatelessWidget { final DateTime focusedDay; /// 해당 월의 포스트 목록 (post_provider에서 전달) - final List posts; + final List posts; const CalendarGrid({ super.key, @@ -63,12 +63,12 @@ class CalendarGrid extends StatelessWidget { now.month == focusedDay.month && now.day == day; + final String targetDateStr = + "${focusedDay.year}-${focusedDay.month.toString().padLeft(2, '0')}-${day.toString().padLeft(2, '0')}"; + // 해당 날짜에 인증 포스트가 있는지 확인 - final Post? post = posts.firstWhereOrNull( - (p) => - p.date.year == focusedDay.year && - p.date.month == focusedDay.month && - p.date.day == day, + final CalendarPost? post = posts.firstWhereOrNull( + (p) => p.postDate == targetDateStr, ); final bool isCertified = post != null; @@ -76,13 +76,13 @@ class CalendarGrid extends StatelessWidget { day: day, isToday: isToday, isCertified: isCertified, - imageUrl: post?.pictureUrl, + imageUrl: post?.imageUrl, // 인증한 날짜만 탭 가능, 포스트 상세 화면으로 이동 onTap: isCertified ? () => Navigator.push( context, MaterialPageRoute( - builder: (_) => PostDetailScreen(postId: post.id), + builder: (_) => PostDetailScreen(postId: post.postId), ), ) : null, From 8be4f794f6fdfa0eb918d4b0231a982bb6fb7fef Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 26 Mar 2026 11:26:27 +0900 Subject: [PATCH 078/134] =?UTF-8?q?fix:=20=ED=99=88=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20=EC=B9=B4=EB=93=9C=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/detail/screens/challenge_main_screen.dart | 1 + lib/features/home/widgets/challenge_card.dart | 6 ------ 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/features/challenge/detail/screens/challenge_main_screen.dart b/lib/features/challenge/detail/screens/challenge_main_screen.dart index a15272b..0d68db5 100644 --- a/lib/features/challenge/detail/screens/challenge_main_screen.dart +++ b/lib/features/challenge/detail/screens/challenge_main_screen.dart @@ -29,6 +29,7 @@ class ChallengeMainScreen extends ConsumerStatefulWidget { super.key, required this.challengeId, this.challengeTitle, + // 새로 가입, 생성한 챌린지는 streakCount가 0 this.streakCount = 0, this.isJustCreated = false, this.createdData, diff --git a/lib/features/home/widgets/challenge_card.dart b/lib/features/home/widgets/challenge_card.dart index 77eb124..166c1a0 100644 --- a/lib/features/home/widgets/challenge_card.dart +++ b/lib/features/home/widgets/challenge_card.dart @@ -88,12 +88,6 @@ class ChallengeCard extends StatelessWidget { } Widget _buildStreakAndParticipantInfo() { - if (challenge.warning) { - return const Text( - '오늘 챌린지를 하지 않으면 실패해요!', - style: TextStyle(color: AppColors.notification, fontSize: 12), - ); - } return Row( children: [ // 스트릭 정보: streakCount > 0 && isDone일 때 불꽃 아이콘 표시 From 1dd4d4bd0551cb1f685e2f736d6ba720fbc33981 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 26 Mar 2026 12:31:22 +0900 Subject: [PATCH 079/134] =?UTF-8?q?feat:=20=EC=97=B0=EC=86=8D=20=EC=9D=BC?= =?UTF-8?q?=EC=88=98,=20=EC=B4=9D=20=EC=9D=B8=EC=A6=9D=20=ED=9A=9F?= =?UTF-8?q?=EC=88=98=20=EC=A0=9C=EA=B3=B5=ED=95=98=EB=8A=94=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=EB=B0=94=EC=9D=B4=EB=8D=94=EB=8F=84=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/data/stats_repository.dart | 26 +++ .../detail/data/stats_repository.g.dart | 27 ++++ .../detail/models/challenge_stats.dart | 16 ++ .../detail/provider/stats_provider.dart | 12 ++ .../detail/provider/stats_provider.g.dart | 151 ++++++++++++++++++ .../challenge/detail/views/calendar_view.dart | 146 +++++++++-------- .../detail/views/information_view.dart | 2 - 7 files changed, 304 insertions(+), 76 deletions(-) create mode 100644 lib/features/challenge/detail/data/stats_repository.dart create mode 100644 lib/features/challenge/detail/data/stats_repository.g.dart create mode 100644 lib/features/challenge/detail/models/challenge_stats.dart create mode 100644 lib/features/challenge/detail/provider/stats_provider.dart create mode 100644 lib/features/challenge/detail/provider/stats_provider.g.dart diff --git a/lib/features/challenge/detail/data/stats_repository.dart b/lib/features/challenge/detail/data/stats_repository.dart new file mode 100644 index 0000000..46cf996 --- /dev/null +++ b/lib/features/challenge/detail/data/stats_repository.dart @@ -0,0 +1,26 @@ +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:haenaem/core/network/dio_provider.dart'; +import '../models/challenge_stats.dart'; + +part 'stats_repository.g.dart'; + +class StatsRepository { + final Dio _dio; + + StatsRepository(this._dio); + + // 실제 API 연동 로직 (Dio 사용 예시) + Future getChallengeStats(int challengeId) async { + final response = await _dio.get('/api/challenges/$challengeId/calendar'); + return ChallengeStats.fromJson(response.data); + } +} + +@riverpod +StatsRepository statsRepository(Ref ref) { + final dio = ref.watch(dioProvider); + return StatsRepository(dio); +} diff --git a/lib/features/challenge/detail/data/stats_repository.g.dart b/lib/features/challenge/detail/data/stats_repository.g.dart new file mode 100644 index 0000000..b2e519e --- /dev/null +++ b/lib/features/challenge/detail/data/stats_repository.g.dart @@ -0,0 +1,27 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'stats_repository.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$statsRepositoryHash() => r'0ddd170cf84c35353413a686df99dfdcd859a7c1'; + +/// See also [statsRepository]. +@ProviderFor(statsRepository) +final statsRepositoryProvider = AutoDisposeProvider.internal( + statsRepository, + name: r'statsRepositoryProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$statsRepositoryHash, + dependencies: null, + allTransitiveDependencies: null, +); + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +typedef StatsRepositoryRef = AutoDisposeProviderRef; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/challenge/detail/models/challenge_stats.dart b/lib/features/challenge/detail/models/challenge_stats.dart new file mode 100644 index 0000000..4062c0d --- /dev/null +++ b/lib/features/challenge/detail/models/challenge_stats.dart @@ -0,0 +1,16 @@ +class ChallengeStats { + final int totalSuccessDays; + final int currentStreakDays; + + ChallengeStats({ + required this.totalSuccessDays, + required this.currentStreakDays, + }); + + factory ChallengeStats.fromJson(Map json) { + return ChallengeStats( + totalSuccessDays: json['totalSuccessDays'] ?? 0, + currentStreakDays: json['currentStreakDays'] ?? 0, + ); + } +} diff --git a/lib/features/challenge/detail/provider/stats_provider.dart b/lib/features/challenge/detail/provider/stats_provider.dart new file mode 100644 index 0000000..e1d0c51 --- /dev/null +++ b/lib/features/challenge/detail/provider/stats_provider.dart @@ -0,0 +1,12 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import '../data/stats_repository.dart'; +import '../models/challenge_stats.dart'; + +part 'stats_provider.g.dart'; + +@riverpod +Future challengeStats(Ref ref, int challengeId) async { + final repository = ref.watch(statsRepositoryProvider); + return repository.getChallengeStats(challengeId); +} diff --git a/lib/features/challenge/detail/provider/stats_provider.g.dart b/lib/features/challenge/detail/provider/stats_provider.g.dart new file mode 100644 index 0000000..fcf3be3 --- /dev/null +++ b/lib/features/challenge/detail/provider/stats_provider.g.dart @@ -0,0 +1,151 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'stats_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$challengeStatsHash() => r'ab18d5fc2d586a987b36fe8fec664ea5a49f175b'; + +/// Copied from Dart SDK +class _SystemHash { + _SystemHash._(); + + static int combine(int hash, int value) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + value); + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); + return hash ^ (hash >> 6); + } + + static int finish(int hash) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); + // ignore: parameter_assignments + hash = hash ^ (hash >> 11); + return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); + } +} + +/// See also [challengeStats]. +@ProviderFor(challengeStats) +const challengeStatsProvider = ChallengeStatsFamily(); + +/// See also [challengeStats]. +class ChallengeStatsFamily extends Family> { + /// See also [challengeStats]. + const ChallengeStatsFamily(); + + /// See also [challengeStats]. + ChallengeStatsProvider call(int challengeId) { + return ChallengeStatsProvider(challengeId); + } + + @override + ChallengeStatsProvider getProviderOverride( + covariant ChallengeStatsProvider provider, + ) { + return call(provider.challengeId); + } + + static const Iterable? _dependencies = null; + + @override + Iterable? get dependencies => _dependencies; + + static const Iterable? _allTransitiveDependencies = null; + + @override + Iterable? get allTransitiveDependencies => + _allTransitiveDependencies; + + @override + String? get name => r'challengeStatsProvider'; +} + +/// See also [challengeStats]. +class ChallengeStatsProvider extends AutoDisposeFutureProvider { + /// See also [challengeStats]. + ChallengeStatsProvider(int challengeId) + : this._internal( + (ref) => challengeStats(ref as ChallengeStatsRef, challengeId), + from: challengeStatsProvider, + name: r'challengeStatsProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$challengeStatsHash, + dependencies: ChallengeStatsFamily._dependencies, + allTransitiveDependencies: + ChallengeStatsFamily._allTransitiveDependencies, + challengeId: challengeId, + ); + + ChallengeStatsProvider._internal( + super._createNotifier, { + required super.name, + required super.dependencies, + required super.allTransitiveDependencies, + required super.debugGetCreateSourceHash, + required super.from, + required this.challengeId, + }) : super.internal(); + + final int challengeId; + + @override + Override overrideWith( + FutureOr Function(ChallengeStatsRef provider) create, + ) { + return ProviderOverride( + origin: this, + override: ChallengeStatsProvider._internal( + (ref) => create(ref as ChallengeStatsRef), + from: from, + name: null, + dependencies: null, + allTransitiveDependencies: null, + debugGetCreateSourceHash: null, + challengeId: challengeId, + ), + ); + } + + @override + AutoDisposeFutureProviderElement createElement() { + return _ChallengeStatsProviderElement(this); + } + + @override + bool operator ==(Object other) { + return other is ChallengeStatsProvider && other.challengeId == challengeId; + } + + @override + int get hashCode { + var hash = _SystemHash.combine(0, runtimeType.hashCode); + hash = _SystemHash.combine(hash, challengeId.hashCode); + + return _SystemHash.finish(hash); + } +} + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +mixin ChallengeStatsRef on AutoDisposeFutureProviderRef { + /// The parameter `challengeId` of this provider. + int get challengeId; +} + +class _ChallengeStatsProviderElement + extends AutoDisposeFutureProviderElement + with ChallengeStatsRef { + _ChallengeStatsProviderElement(super.provider); + + @override + int get challengeId => (origin as ChallengeStatsProvider).challengeId; +} + +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/challenge/detail/views/calendar_view.dart b/lib/features/challenge/detail/views/calendar_view.dart index e1f0d72..92508a9 100644 --- a/lib/features/challenge/detail/views/calendar_view.dart +++ b/lib/features/challenge/detail/views/calendar_view.dart @@ -4,15 +4,11 @@ import 'package:flutter_svg/svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import '../provider/post_provider.dart'; +import '../provider/stats_provider.dart'; import '../widgets/calendar_grid.dart'; import '../models/calendar_post.dart'; import '../widgets/calendar_post_card.dart'; -import 'package:intl/intl.dart'; - -import 'package:haenaem/features/feed/screens/post_detail_screen.dart'; -import 'package:haenaem/features/challenge/models/challenge_model.dart'; class CalendarView extends ConsumerStatefulWidget { final int challengeId; @@ -49,83 +45,88 @@ class _CalendarViewState extends ConsumerState { @override Widget build(BuildContext context) { // 1. 데이터 구독 - final calendarDataAsync = ref.watch( - challengeCalendarDataProvider(widget.challengeId), + final statsAsync = ref.watch(challengeStatsProvider(widget.challengeId)); + + final postsProvider = monthlyChallengePostsProvider( + challengeId: widget.challengeId, + year: _focusedDay.year, + month: _focusedDay.month, ); - // final photosAsync = ref.watch( - // challengeCalendarPhotosProvider( - // challengeId: widget.challengeId, - // year: _focusedDay.year, - // month: _focusedDay.month, - // ), - // ); + final postsAsync = ref.watch(postsProvider); - final postsAsync = ref.watch( - monthlyChallengePostsProvider( - challengeId: widget.challengeId, - year: _focusedDay.year, - month: _focusedDay.month, + // 2. 통합 로딩/에러/데이터 처리 + return statsAsync.when( + loading: () => const Scaffold( + backgroundColor: Colors.white, + body: Center(child: CircularProgressIndicator()), ), - ); + error: (e, s) => Scaffold(body: Center(child: Text('통계 로드 실패: $e'))), + data: (stats) => postsAsync.when( + loading: () => const Scaffold( + backgroundColor: Colors.white, + body: Center(child: CircularProgressIndicator()), + ), + error: (e, s) => Scaffold(body: Center(child: Text('인증글 로드 실패: $e'))), + data: (posts) { + return Scaffold( + backgroundColor: Colors.white, + // [추가] 당겨서 새로고침 위젯 + body: RefreshIndicator( + onRefresh: () async { + ref.invalidate(challengeStatsProvider(widget.challengeId)); + ref.invalidate(postsProvider); - // 2. UI 구성 - return calendarDataAsync.when( - loading: () => const Center(child: CircularProgressIndicator()), - error: (err, stack) => Center(child: Text('에러 발생: $err')), - data: (summaryData) => Scaffold( - backgroundColor: Colors.white, - body: SingleChildScrollView( - controller: widget.scrollController, - // 하단 버튼 높이만큼 여유 공간을 주어 마지막 리스트가 가려지지 않게 합니다. - padding: const EdgeInsets.fromLTRB(20, 20, 20, 120), - child: Column( - children: [ - _buildStatCards(summaryData), - const SizedBox(height: 20), - _buildCalendarHeader(_focusedDay), - const SizedBox(height: 10), - _buildWeekdayHeader(), - const SizedBox(height: 10), - postsAsync.when( - data: (posts) => + // 두 데이터가 로드될 때까지 대기 + await Future.wait([ + ref.read(challengeStatsProvider(widget.challengeId).future), + ref.read(postsProvider.future), + ]); + }, + child: SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + controller: widget.scrollController, + padding: const EdgeInsets.fromLTRB(20, 20, 20, 120), + child: Column( + children: [ + _buildStatCards( + stats.totalSuccessDays, + stats.currentStreakDays, + ), + const SizedBox(height: 20), + _buildCalendarHeader(_focusedDay), + const SizedBox(height: 10), + _buildWeekdayHeader(), + const SizedBox(height: 10), CalendarGrid(focusedDay: _focusedDay, posts: posts), - loading: () => const SizedBox( - height: 200, - child: Center(child: CircularProgressIndicator()), + const SizedBox(height: 20), + _buildPostsHeaderForData(posts.length), + const SizedBox(height: 16), + posts.isEmpty + ? _buildEmptyState() + : ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: posts.length, + itemBuilder: (context, index) => + CalendarPostCard(post: posts[index]), + ), + ], ), - error: (e, s) => Text('달력을 불러오지 못했습니다. $e'), ), - const SizedBox(height: 20), - _buildPostsHeader(postsAsync), - const SizedBox(height: 16), - postsAsync.when( - data: (posts) { - if (posts.isEmpty) return _buildEmptyState(); - return ListView.builder( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemCount: posts.length, - itemBuilder: (context, index) => - CalendarPostCard(post: posts[index]), - ); - }, - loading: () => const Center(child: CircularProgressIndicator()), - error: (e, s) => Text('인증글 로드 중 에러 $e'), - ), - ], - ), - ), + ), + ); + }, ), ); } - Widget _buildStatCards(ChallengeCalendarModel data) { + Widget _buildStatCards(int totalSuccessDays, int currentStreakDays) { return Row( children: [ - _buildStatCard(data.totalSuccessDays.toString(), '완료 일수'), + _buildStatCard(totalSuccessDays.toString(), '완료 일수'), const SizedBox(width: 12), - _buildStatCard(widget.streakCount.toString(), '연속 일수'), + _buildStatCard(currentStreakDays.toString(), '연속 일수'), ], ); } @@ -242,17 +243,14 @@ class _CalendarViewState extends ConsumerState { ); } - Widget _buildPostsHeader(AsyncValue> postsAsync) { + Widget _buildPostsHeaderForData(int count) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text('내 인증글', style: AppTypography.b1), - postsAsync.maybeWhen( - data: (posts) => Text( - '총 ${posts.length}개', - style: AppTypography.c1.copyWith(color: AppColors.gray2), - ), - orElse: () => const SizedBox(), + Text( + '총 $count개', + style: AppTypography.c1.copyWith(color: AppColors.gray2), ), ], ); diff --git a/lib/features/challenge/detail/views/information_view.dart b/lib/features/challenge/detail/views/information_view.dart index 906d682..21e6366 100644 --- a/lib/features/challenge/detail/views/information_view.dart +++ b/lib/features/challenge/detail/views/information_view.dart @@ -1,9 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:flutter_svg/svg.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/features/challenge/detail/widgets/challenge_detail_content.dart'; From 41f853516e96131a52bb08d9596fd797d3ba4137 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 26 Mar 2026 12:40:27 +0900 Subject: [PATCH 080/134] =?UTF-8?q?feat:=20=EC=A3=BC=EC=84=9D=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=ED=95=98=EA=B3=A0=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20import=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/detail/data/stats_repository.dart | 1 - lib/features/challenge/detail/models/challenge_stats.dart | 3 +++ lib/features/challenge/detail/views/calendar_view.dart | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/features/challenge/detail/data/stats_repository.dart b/lib/features/challenge/detail/data/stats_repository.dart index 46cf996..9f3a58f 100644 --- a/lib/features/challenge/detail/data/stats_repository.dart +++ b/lib/features/challenge/detail/data/stats_repository.dart @@ -1,5 +1,4 @@ import 'package:dio/dio.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:haenaem/core/network/dio_provider.dart'; diff --git a/lib/features/challenge/detail/models/challenge_stats.dart b/lib/features/challenge/detail/models/challenge_stats.dart index 4062c0d..55c87a8 100644 --- a/lib/features/challenge/detail/models/challenge_stats.dart +++ b/lib/features/challenge/detail/models/challenge_stats.dart @@ -1,3 +1,6 @@ +// 최초 작성자: 강선욱 +// 챌린지 총 인증 횟수, 연속 인증 횟수 관리 모델 + class ChallengeStats { final int totalSuccessDays; final int currentStreakDays; diff --git a/lib/features/challenge/detail/views/calendar_view.dart b/lib/features/challenge/detail/views/calendar_view.dart index 92508a9..5a61025 100644 --- a/lib/features/challenge/detail/views/calendar_view.dart +++ b/lib/features/challenge/detail/views/calendar_view.dart @@ -7,7 +7,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../provider/post_provider.dart'; import '../provider/stats_provider.dart'; import '../widgets/calendar_grid.dart'; -import '../models/calendar_post.dart'; import '../widgets/calendar_post_card.dart'; class CalendarView extends ConsumerStatefulWidget { From af27370a0b502d2fffb9778dfc1cdb7afbaded83 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 26 Mar 2026 16:01:00 +0900 Subject: [PATCH 081/134] =?UTF-8?q?refactor:=20=EC=B1=8C=EB=A6=B0=EC=A7=80?= =?UTF-8?q?=20=EC=9D=B8=EC=A6=9D=ED=95=98=EA=B8=B0,=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=20=ED=99=94=EB=A9=B4=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/detail/views/calendar_view.dart | 2 +- .../data/verification_repository.dart | 110 +++++ .../data/verification_repository.g.dart | 30 ++ .../provider/verification_provider.dart | 102 ++++ .../provider/verification_provider.g.dart | 67 +++ .../challenge_verification_screen.dart | 82 ++-- .../widgets/ChallengeFeedPopupMenu.dart | 458 +++++++++--------- lib/features/feed/widgets/feed_post_card.dart | 2 +- lib/features/home/screens/home_screen.dart | 2 +- lib/shared/models/post.dart | 33 +- .../provider/challenge_detail_provider.dart | 0 .../provider/challenge_detail_provider.g.dart | 0 .../provider/home_provider.dart | 0 .../provider/home_provider.g.dart | 0 .../provider/post_provider.dart | 4 +- .../provider/post_provider.g.dart | 0 16 files changed, 615 insertions(+), 277 deletions(-) create mode 100644 lib/features/challenge/verification/data/verification_repository.dart create mode 100644 lib/features/challenge/verification/data/verification_repository.g.dart create mode 100644 lib/features/challenge/verification/provider/verification_provider.dart create mode 100644 lib/features/challenge/verification/provider/verification_provider.g.dart rename lib/{features/challenge/detail => shared}/provider/challenge_detail_provider.dart (100%) rename lib/{features/challenge/detail => shared}/provider/challenge_detail_provider.g.dart (100%) rename lib/{features/home => shared}/provider/home_provider.dart (100%) rename lib/{features/home => shared}/provider/home_provider.g.dart (100%) rename lib/{features/challenge/detail => shared}/provider/post_provider.dart (80%) rename lib/{features/challenge/detail => shared}/provider/post_provider.g.dart (100%) diff --git a/lib/features/challenge/detail/views/calendar_view.dart b/lib/features/challenge/detail/views/calendar_view.dart index 5a61025..eb30520 100644 --- a/lib/features/challenge/detail/views/calendar_view.dart +++ b/lib/features/challenge/detail/views/calendar_view.dart @@ -4,7 +4,7 @@ import 'package:flutter_svg/svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import '../provider/post_provider.dart'; +import '../../../../shared/provider/post_provider.dart'; import '../provider/stats_provider.dart'; import '../widgets/calendar_grid.dart'; import '../widgets/calendar_post_card.dart'; diff --git a/lib/features/challenge/verification/data/verification_repository.dart b/lib/features/challenge/verification/data/verification_repository.dart new file mode 100644 index 0000000..2d8d6b0 --- /dev/null +++ b/lib/features/challenge/verification/data/verification_repository.dart @@ -0,0 +1,110 @@ +import 'dart:io'; +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; +import 'package:http_parser/http_parser.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:haenaem/core/network/dio_provider.dart'; +import 'package:haenaem/shared/models/post.dart'; // [추가] 통합된 Post 모델 임포트 + +part 'verification_repository.g.dart'; + +class VerificationRepository { + final Dio _dio; + + VerificationRepository(this._dio); + + // 이미지를 서버에 임시 업로드하고 AI 검증을 요청 + Future verifyImage(File imageFile, int challengeId) async { + try { + final formData = FormData.fromMap({ + "image": await MultipartFile.fromFile( + imageFile.path, + filename: imageFile.path.split('/').last, + contentType: MediaType('image', 'jpeg'), + ), + }); + + final response = await _dio.post( + '/api/image/verify', + data: formData, + queryParameters: {'challengeId': challengeId}, + ); + + if (response.statusCode == 200 || response.statusCode == 204) { + debugPrint('✅ 이미지 검증 및 임시 업로드 성공: ${response.data}'); + return response.data?['tempImageId']; + } + return null; + } on DioException catch (e) { + debugPrint('❌ 이미지 검증 에러: ${e.response?.data}'); + return null; + } catch (e) { + debugPrint('❌ 알 수 없는 에러 발생: $e'); + return null; + } + } + + // 검증된 이미지 ID들과 함께 인증글을 최종 생성 + Future createArticle({ + required int challengeId, + required String content, + required List tempImageIds, + }) async { + try { + final response = await _dio.post( + '/api/articles', + data: { + "content": content, + "challengeId": challengeId, + "tempImageIds": tempImageIds, + }, + ); + + if (response.statusCode == 201 || response.statusCode == 200) { + // [변경] CertificationPostModel -> Post + return Post.fromJson(response.data); + } else { + throw Exception('인증글 생성 실패: ${response.statusCode}'); + } + } on DioException catch (e) { + debugPrint('❌ 인증글 생성 에러: ${e.response?.data}'); + throw Exception(e.response?.data?['message'] ?? '게시글 업로드 실패'); + } + } + + // 기존 인증글을 수정합니다. + Future updateArticle({ + required int postId, + required String content, + required List deleteImageIds, + required List tempImageIds, + }) async { + try { + final response = await _dio.patch( + '/api/articles/$postId', + data: { + "content": content, + "deleteImageIds": deleteImageIds, + "tempImageIds": tempImageIds, + }, + ); + + if (response.statusCode == 200) { + debugPrint('✅ 인증글 수정 성공: ${response.data}'); + // [변경] CertificationPostModel -> Post + return Post.fromJson(response.data); + } else { + throw Exception('수정 실패: ${response.statusCode}'); + } + } on DioException catch (e) { + debugPrint('❌ 수정 에러 상세: ${e.response?.data}'); + throw Exception(e.response?.data?['message'] ?? '수정 중 오류 발생'); + } + } +} + +@riverpod +VerificationRepository verificationRepository(VerificationRepositoryRef ref) { + final dio = ref.watch(dioProvider); + return VerificationRepository(dio); +} diff --git a/lib/features/challenge/verification/data/verification_repository.g.dart b/lib/features/challenge/verification/data/verification_repository.g.dart new file mode 100644 index 0000000..dc1bb99 --- /dev/null +++ b/lib/features/challenge/verification/data/verification_repository.g.dart @@ -0,0 +1,30 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'verification_repository.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$verificationRepositoryHash() => + r'0275cb8f6d58c04031052100873fe37c04c8edc3'; + +/// See also [verificationRepository]. +@ProviderFor(verificationRepository) +final verificationRepositoryProvider = + AutoDisposeProvider.internal( + verificationRepository, + name: r'verificationRepositoryProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$verificationRepositoryHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +typedef VerificationRepositoryRef = + AutoDisposeProviderRef; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/challenge/verification/provider/verification_provider.dart b/lib/features/challenge/verification/provider/verification_provider.dart new file mode 100644 index 0000000..0e3aa27 --- /dev/null +++ b/lib/features/challenge/verification/provider/verification_provider.dart @@ -0,0 +1,102 @@ +import 'dart:io'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import '../data/verification_repository.dart'; +import 'package:haenaem/shared/models/post.dart'; +import 'package:haenaem/shared/provider/post_provider.dart'; +import 'package:haenaem/shared/provider/home_provider.dart'; + +part 'verification_provider.g.dart'; + +// 인증 이미지 검증 +@riverpod +class ImageVerifyNotifier extends _$ImageVerifyNotifier { + @override + AsyncValue build() => const AsyncValue.data(null); + + Future verify(File file, int challengeId) async { + state = const AsyncValue.loading(); + + // [변경] 기존 challengeRepository 대신 신규 verificationRepository 사용 + final result = await AsyncValue.guard( + () => ref + .read(verificationRepositoryProvider) + .verifyImage(file, challengeId), + ); + + state = result; + return result.valueOrNull; + } +} + +// 인증글 생성 +@riverpod +class ArticleCreateNotifier extends _$ArticleCreateNotifier { + @override + AsyncValue build() => const AsyncValue.data(null); + + Future submitArticle({ + required int challengeId, + required String content, + required List tempImageIds, // 검증 완료된 ID 리스트 + }) async { + state = const AsyncValue.loading(); + + final result = await AsyncValue.guard( + () => ref + .read(verificationRepositoryProvider) + .createArticle( + challengeId: challengeId, + content: content, + tempImageIds: tempImageIds, + ), + ); + + state = result; + return !result.hasError; + } +} + +// 인증글 수정 +@riverpod +class ArticleUpdateNotifier extends _$ArticleUpdateNotifier { + @override + AsyncValue build() => const AsyncValue.data(null); + + Future editArticle({ + required int postId, + required int challengeId, + required String content, + List deleteImageIds = const [], + List tempImageIds = const [], // 새 이미지의 임시 ID 리스트 + }) async { + state = const AsyncValue.loading(); + + final result = await AsyncValue.guard( + () => ref + .read(verificationRepositoryProvider) + .updateArticle( + postId: postId, + content: content, + deleteImageIds: deleteImageIds, + tempImageIds: tempImageIds, + ), + ); + + if (!result.hasError) { + final now = DateTime.now(); + + // 수정 성공 시 관련 데이터 캐시 갱신 + ref.invalidate( + monthlyChallengePostsProvider( + challengeId: challengeId, + year: now.year, + month: now.month, + ), + ); + ref.invalidate(homeNotifierProvider); + } + + state = result; + return !result.hasError; + } +} diff --git a/lib/features/challenge/verification/provider/verification_provider.g.dart b/lib/features/challenge/verification/provider/verification_provider.g.dart new file mode 100644 index 0000000..603c421 --- /dev/null +++ b/lib/features/challenge/verification/provider/verification_provider.g.dart @@ -0,0 +1,67 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'verification_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$imageVerifyNotifierHash() => + r'4dffeb198fa09f19bfe619e052f6d84b73e4c845'; + +/// See also [ImageVerifyNotifier]. +@ProviderFor(ImageVerifyNotifier) +final imageVerifyNotifierProvider = + AutoDisposeNotifierProvider>.internal( + ImageVerifyNotifier.new, + name: r'imageVerifyNotifierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$imageVerifyNotifierHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$ImageVerifyNotifier = AutoDisposeNotifier>; +String _$articleCreateNotifierHash() => + r'62674cc4381f677055728b80c1f45660eb6582f6'; + +/// See also [ArticleCreateNotifier]. +@ProviderFor(ArticleCreateNotifier) +final articleCreateNotifierProvider = + AutoDisposeNotifierProvider< + ArticleCreateNotifier, + AsyncValue + >.internal( + ArticleCreateNotifier.new, + name: r'articleCreateNotifierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$articleCreateNotifierHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$ArticleCreateNotifier = AutoDisposeNotifier>; +String _$articleUpdateNotifierHash() => + r'2f43cae68e6da5d0acf33d13974ffef318f208c4'; + +/// See also [ArticleUpdateNotifier]. +@ProviderFor(ArticleUpdateNotifier) +final articleUpdateNotifierProvider = + AutoDisposeNotifierProvider< + ArticleUpdateNotifier, + AsyncValue + >.internal( + ArticleUpdateNotifier.new, + name: r'articleUpdateNotifierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$articleUpdateNotifierHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$ArticleUpdateNotifier = AutoDisposeNotifier>; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/challenge/verification/screens/challenge_verification_screen.dart b/lib/features/challenge/verification/screens/challenge_verification_screen.dart index b5a9404..90c3f6d 100644 --- a/lib/features/challenge/verification/screens/challenge_verification_screen.dart +++ b/lib/features/challenge/verification/screens/challenge_verification_screen.dart @@ -7,10 +7,15 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import 'package:haenaem/features/challenge/models/challenge_model.dart'; -import 'package:haenaem/features/challenge/models/image_model.dart'; -import 'package:intl/intl.dart'; + +import 'package:haenaem/shared/models/post.dart'; +import 'package:haenaem/shared/models/challenge_detail.dart'; +import '../provider/verification_provider.dart'; +import 'package:haenaem/shared/provider/challenge_detail_provider.dart'; +import 'package:haenaem/shared/provider/home_provider.dart'; +// import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; +// import 'package:haenaem/features/challenge/models/challenge_model.dart'; +// import 'package:haenaem/features/challenge/models/image_model.dart'; import '../../../../shared/widgets/challenge_label.dart'; import '../../../../shared/widgets/challenge_input_box.dart'; @@ -30,7 +35,7 @@ import 'package:haenaem/features/feed/models/feed_model.dart'; // 챌린지 인증하기 화면 class ChallengeVerificationScreen extends ConsumerStatefulWidget { final int challengeId; - final CertificationPostModel? existingPost; // 데이터가 있으면 수정 모드 + final Post? existingPost; // 데이터가 있으면 수정 모드 const ChallengeVerificationScreen({ super.key, @@ -610,7 +615,8 @@ class _ChallengeVerificationScreenState success = await ref .read(articleUpdateNotifierProvider.notifier) .editArticle( - postId: widget.existingPost!.postId, + postId: widget.existingPost!.id, + challengeId: widget.challengeId, content: content, deleteImageIds: _imageIdsToDelete, tempImageIds: _tempImageIds, // 💡 File 대신 ID 리스트 전달 @@ -629,37 +635,37 @@ class _ChallengeVerificationScreenState success = false; } - if (success && mounted) { - // 💡 [에러 해결] 이 프로바이더만 이름 없이 숫자만 넣습니다 (Positional) - ref.invalidate(challengeCalendarDataProvider(widget.challengeId)); - - // 💡 아래 프로바이더들은 정의된 대로 이름을 명시합니다 (Named) - ref.invalidate( - challengeCalendarPhotosProvider( - challengeId: widget.challengeId, - year: now.year, - month: now.month, - ), - ); - ref.invalidate( - challengePostsProvider( - challengeId: widget.challengeId, - year: now.year, - month: now.month, - ), - ); - - ref.invalidate(challengeHomeNotifierProvider); - - ScaffoldMessenger.of( - context, - ).showSnackBar(SnackBar(content: Text(isEditMode ? '수정 완료!' : '인증 완료!'))); - - Navigator.pop(context); - } else if (mounted) { - ScaffoldMessenger.of( - context, - ).showSnackBar(const SnackBar(content: Text('인증에 실패했습니다. 다시 시도해주세요.'))); - } + // if (success && mounted) { + // // 💡 [에러 해결] 이 프로바이더만 이름 없이 숫자만 넣습니다 (Positional) + // ref.invalidate(challengeCalendarDataProvider(widget.challengeId)); + + // // 💡 아래 프로바이더들은 정의된 대로 이름을 명시합니다 (Named) + // ref.invalidate( + // challengeCalendarPhotosProvider( + // challengeId: widget.challengeId, + // year: now.year, + // month: now.month, + // ), + // ); + // ref.invalidate( + // challengePostsProvider( + // challengeId: widget.challengeId, + // year: now.year, + // month: now.month, + // ), + // ); + + // ref.invalidate(homeNotifierProvider); + + // ScaffoldMessenger.of( + // context, + // ).showSnackBar(SnackBar(content: Text(isEditMode ? '수정 완료!' : '인증 완료!'))); + + // Navigator.pop(context); + // } else if (mounted) { + // ScaffoldMessenger.of( + // context, + // ).showSnackBar(const SnackBar(content: Text('인증에 실패했습니다. 다시 시도해주세요.'))); + // } } } diff --git a/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart b/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart index beb07ac..70f2795 100644 --- a/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart +++ b/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart @@ -1,229 +1,229 @@ -// 최초 작성자 : 강선욱 -import 'package:intl/intl.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:haenaem/core/theme/app_colors.dart'; -import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:haenaem/features/challenge/widgets/DeleteConfirmDialog.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:haenaem/features/challenge/models/challenge_model.dart'; -import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import 'edit_article_dialog.dart'; -import 'package:haenaem/features/challenge/verification/screens/challenge_verification_screen.dart'; - -// 인증글 다이얼로그 (내 인증글일 경우와 타인의 인증글일 경우) -class ChallengeFeedPopupMenu extends ConsumerWidget { - final CertificationPostModel post; // 인증글 데이터 - const ChallengeFeedPopupMenu({super.key, required this.post}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - // 1. 현재 로그인한 내 프로필 정보를 가져옵니다. - final myProfileAsync = ref.watch(myProfileProvider); - - // 2. 내 닉네임과 게시글 작성자 닉네임을 비교하여 '내 글' 여부 판단 - final bool isMine = post.author; - - // 2. [날짜 체크] 오늘 날짜 문자열(yyyy-MM-dd) 생성 - final String todayStr = DateFormat('yyyy-MM-dd').format(DateTime.now()); - - // 3. 게시글의 postDate와 오늘 날짜 비교 - final bool isToday = post.postDate.trim().startsWith(todayStr); - - // 💡 디버깅을 위해 로그를 한 번 찍어보세요. (문제 확인용) - debugPrint('🔍 비교 날짜 - 서버 데이터: "${post.postDate}", 오늘 날짜: "$todayStr"'); - debugPrint('🔍 판정 결과 - isMine: $isMine, isToday: $isToday'); - - return PopupMenuButton( - //popUpAnimationStyle: AnimationStyle.none, // 애니메이션 없이 즉시 노출 - padding: EdgeInsets.zero, - constraints: const BoxConstraints(maxWidth: 206), - offset: const Offset(0, 40), // 버튼 아래로 띄우기 - shape: RoundedRectangleBorder( - side: const BorderSide(width: 1, color: AppColors.gray4), - borderRadius: BorderRadius.circular(10), - ), - color: Colors.white, - elevation: 4, // 그림자 효과 - - icon: SvgPicture.asset( - 'assets/images/icons/dots_vert_icon.svg', - width: 24, - height: 24, - ), - - // 내 글이냐 아니냐에 따라 아이템 리스트만 교체 - itemBuilder: (context) { - if (isMine) { - if (isToday) { - // 📅 오늘 올린 글: 수정/삭제 가능 - return [ - _buildPopupItem( - '수정하기', - 'assets/images/icons/edit_icon.svg', - 'edit', - ), - _buildDivider(), - _buildPopupItem( - '삭제하기', - 'assets/images/icons/small_trash_icon.svg', - 'delete', - isDanger: true, - ), - ]; - } else { - // 🕰️ 지난 날짜 글: 내 글이라도 수정/삭제 불가 (대신 챌린지 보기만 노출) - // 자신이 쓴 글을 신고할 순 없으니 '챌린지 보기'만 넣어주는 게 자연스러워요! - return [ - _buildPopupItem( - '챌린지 보기', - 'assets/images/icons/eye.svg', - 'view_challenge', - ), - ]; - } - } else { - // ✨ 타인의 글: 기존과 동일 (보기/신고) - return [ - _buildPopupItem( - '챌린지 보기', - 'assets/images/icons/eye.svg', - 'view_challenge', - ), - _buildDivider(), - _buildPopupItem( - '신고하기', - 'assets/images/icons/complaint.svg', - 'report', - isDanger: true, - ), - ]; - } - }, - onSelected: (value) => _handleMenuSelection(context, ref, value), - ); - } - - PopupMenuItem _buildPopupItem( - String title, - String iconPath, - String value, { - bool isDanger = false, - }) { - final Color textColor = isDanger ? AppColors.notification : AppColors.black; - - return PopupMenuItem( - value: value, - height: 40, // 높이 조절 - padding: EdgeInsets.zero, - child: Container( - width: 200, - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), - child: Row( - children: [ - SizedBox( - width: 16, - height: 16, - child: SvgPicture.asset( - iconPath, - colorFilter: ColorFilter.mode(textColor, BlendMode.srcIn), - ), - ), - const SizedBox(width: 8), - Text( - title, - style: AppTypography.b2.copyWith(color: textColor, height: 1.5), - ), - ], - ), - ), - ); - } - - // 구분선 위젯 - PopupMenuEntry _buildDivider() { - return const PopupMenuDivider(height: 1); - } - - // 메뉴 선택 핸들러 - void _handleMenuSelection( - BuildContext context, - WidgetRef ref, - String value, - ) async { - FocusManager.instance.primaryFocus?.unfocus(); - - switch (value) { - case 'edit': - // 다이얼로그 대신 '인증하기' 화면으로 데이터와 함께 이동 - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => ChallengeVerificationScreen( - challengeId: post - .challengeId, // 챌린지 ID가 필요하다면 post 모델에 추가하거나 context에서 가져와야 함 - existingPost: post, // 현재 게시글 데이터를 전달하여 '수정 모드'로 진입 - ), - ), - ); - break; - case 'delete': - final bool? confirmed = await showDialog( - context: context, - barrierDismissible: false, - builder: (context) => const DeleteConfirmDialog( - title: '인증글 삭제', - message: '정말로 이 게시물을 삭제하시겠습니까?\n삭제된 게시물은 복구할 수 없습니다.', - ), - ); - - if (confirmed == true) { - try { - // 💡 삭제 시도 - final success = await ref - .read(articleDeleteNotifierProvider.notifier) - .removeArticle(post.postId); - - if (success && context.mounted) { - ScaffoldMessenger.of( - context, - ).showSnackBar(const SnackBar(content: Text("인증글이 삭제되었습니다."))); - - // 갱신 로직 - ref.invalidate(challengePostsProvider); - ref.invalidate(challengeCalendarPhotosProvider); - ref.invalidate(challengeCalendarDataProvider); - - // 만약 상세페이지라면 뒤로가기 - Navigator.pop(context); - } - } catch (e) { - // 💡 [핵심] 서버의 에러 메시지(PAST_POST_CANNOT_DELETE) 처리 - String errorMessage = "삭제에 실패했습니다."; - - if (e.toString().contains("PAST_POST_CANNOT_DELETE")) { - errorMessage = "지나간 날짜의 인증글은 삭제할 수 없습니다. ✊"; - } - - if (context.mounted) { - ScaffoldMessenger.of( - context, - ).showSnackBar(SnackBar(content: Text(errorMessage))); - } - } - } - break; - - case 'view_challenge': - // TODO: 챌린지 상세(소개) 페이지로 이동하거나 탭을 전환하는 로직 - debugPrint('🚀 [Action] 챌린지 보기 클릭'); - // TODO: Navigator.push(...) 혹은 현재 탭 전환 로직 추가 - break; - case 'complain': - ScaffoldMessenger.of( - context, - ).showSnackBar(const SnackBar(content: Text("신고가 접수되었습니다."))); - break; - } - } -} +// // 최초 작성자 : 강선욱 +// import 'package:intl/intl.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter_svg/flutter_svg.dart'; +// import 'package:haenaem/core/theme/app_colors.dart'; +// import 'package:haenaem/core/theme/app_typography.dart'; +// import 'package:haenaem/features/challenge/widgets/DeleteConfirmDialog.dart'; +// import 'package:flutter_riverpod/flutter_riverpod.dart'; +// import 'package:haenaem/features/challenge/models/challenge_model.dart'; +// import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; +// import 'edit_article_dialog.dart'; +// import 'package:haenaem/features/challenge/verification/screens/challenge_verification_screen.dart'; + +// // 인증글 다이얼로그 (내 인증글일 경우와 타인의 인증글일 경우) +// class ChallengeFeedPopupMenu extends ConsumerWidget { +// final CertificationPostModel post; // 인증글 데이터 +// const ChallengeFeedPopupMenu({super.key, required this.post}); + +// @override +// Widget build(BuildContext context, WidgetRef ref) { +// // 1. 현재 로그인한 내 프로필 정보를 가져옵니다. +// final myProfileAsync = ref.watch(myProfileProvider); + +// // 2. 내 닉네임과 게시글 작성자 닉네임을 비교하여 '내 글' 여부 판단 +// final bool isMine = post.author; + +// // 2. [날짜 체크] 오늘 날짜 문자열(yyyy-MM-dd) 생성 +// final String todayStr = DateFormat('yyyy-MM-dd').format(DateTime.now()); + +// // 3. 게시글의 postDate와 오늘 날짜 비교 +// final bool isToday = post.postDate.trim().startsWith(todayStr); + +// // 💡 디버깅을 위해 로그를 한 번 찍어보세요. (문제 확인용) +// debugPrint('🔍 비교 날짜 - 서버 데이터: "${post.postDate}", 오늘 날짜: "$todayStr"'); +// debugPrint('🔍 판정 결과 - isMine: $isMine, isToday: $isToday'); + +// return PopupMenuButton( +// //popUpAnimationStyle: AnimationStyle.none, // 애니메이션 없이 즉시 노출 +// padding: EdgeInsets.zero, +// constraints: const BoxConstraints(maxWidth: 206), +// offset: const Offset(0, 40), // 버튼 아래로 띄우기 +// shape: RoundedRectangleBorder( +// side: const BorderSide(width: 1, color: AppColors.gray4), +// borderRadius: BorderRadius.circular(10), +// ), +// color: Colors.white, +// elevation: 4, // 그림자 효과 + +// icon: SvgPicture.asset( +// 'assets/images/icons/dots_vert_icon.svg', +// width: 24, +// height: 24, +// ), + +// // 내 글이냐 아니냐에 따라 아이템 리스트만 교체 +// itemBuilder: (context) { +// if (isMine) { +// if (isToday) { +// // 📅 오늘 올린 글: 수정/삭제 가능 +// return [ +// _buildPopupItem( +// '수정하기', +// 'assets/images/icons/edit_icon.svg', +// 'edit', +// ), +// _buildDivider(), +// _buildPopupItem( +// '삭제하기', +// 'assets/images/icons/small_trash_icon.svg', +// 'delete', +// isDanger: true, +// ), +// ]; +// } else { +// // 🕰️ 지난 날짜 글: 내 글이라도 수정/삭제 불가 (대신 챌린지 보기만 노출) +// // 자신이 쓴 글을 신고할 순 없으니 '챌린지 보기'만 넣어주는 게 자연스러워요! +// return [ +// _buildPopupItem( +// '챌린지 보기', +// 'assets/images/icons/eye.svg', +// 'view_challenge', +// ), +// ]; +// } +// } else { +// // ✨ 타인의 글: 기존과 동일 (보기/신고) +// return [ +// _buildPopupItem( +// '챌린지 보기', +// 'assets/images/icons/eye.svg', +// 'view_challenge', +// ), +// _buildDivider(), +// _buildPopupItem( +// '신고하기', +// 'assets/images/icons/complaint.svg', +// 'report', +// isDanger: true, +// ), +// ]; +// } +// }, +// onSelected: (value) => _handleMenuSelection(context, ref, value), +// ); +// } + +// PopupMenuItem _buildPopupItem( +// String title, +// String iconPath, +// String value, { +// bool isDanger = false, +// }) { +// final Color textColor = isDanger ? AppColors.notification : AppColors.black; + +// return PopupMenuItem( +// value: value, +// height: 40, // 높이 조절 +// padding: EdgeInsets.zero, +// child: Container( +// width: 200, +// padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), +// child: Row( +// children: [ +// SizedBox( +// width: 16, +// height: 16, +// child: SvgPicture.asset( +// iconPath, +// colorFilter: ColorFilter.mode(textColor, BlendMode.srcIn), +// ), +// ), +// const SizedBox(width: 8), +// Text( +// title, +// style: AppTypography.b2.copyWith(color: textColor, height: 1.5), +// ), +// ], +// ), +// ), +// ); +// } + +// // 구분선 위젯 +// PopupMenuEntry _buildDivider() { +// return const PopupMenuDivider(height: 1); +// } + +// // 메뉴 선택 핸들러 +// void _handleMenuSelection( +// BuildContext context, +// WidgetRef ref, +// String value, +// ) async { +// FocusManager.instance.primaryFocus?.unfocus(); + +// switch (value) { +// case 'edit': +// // 다이얼로그 대신 '인증하기' 화면으로 데이터와 함께 이동 +// Navigator.push( +// context, +// MaterialPageRoute( +// builder: (context) => ChallengeVerificationScreen( +// challengeId: post +// .challengeId, // 챌린지 ID가 필요하다면 post 모델에 추가하거나 context에서 가져와야 함 +// existingPost: post, // 현재 게시글 데이터를 전달하여 '수정 모드'로 진입 +// ), +// ), +// ); +// break; +// case 'delete': +// final bool? confirmed = await showDialog( +// context: context, +// barrierDismissible: false, +// builder: (context) => const DeleteConfirmDialog( +// title: '인증글 삭제', +// message: '정말로 이 게시물을 삭제하시겠습니까?\n삭제된 게시물은 복구할 수 없습니다.', +// ), +// ); + +// if (confirmed == true) { +// try { +// // 💡 삭제 시도 +// final success = await ref +// .read(articleDeleteNotifierProvider.notifier) +// .removeArticle(post.postId); + +// if (success && context.mounted) { +// ScaffoldMessenger.of( +// context, +// ).showSnackBar(const SnackBar(content: Text("인증글이 삭제되었습니다."))); + +// // 갱신 로직 +// ref.invalidate(challengePostsProvider); +// ref.invalidate(challengeCalendarPhotosProvider); +// ref.invalidate(challengeCalendarDataProvider); + +// // 만약 상세페이지라면 뒤로가기 +// Navigator.pop(context); +// } +// } catch (e) { +// // 💡 [핵심] 서버의 에러 메시지(PAST_POST_CANNOT_DELETE) 처리 +// String errorMessage = "삭제에 실패했습니다."; + +// if (e.toString().contains("PAST_POST_CANNOT_DELETE")) { +// errorMessage = "지나간 날짜의 인증글은 삭제할 수 없습니다. ✊"; +// } + +// if (context.mounted) { +// ScaffoldMessenger.of( +// context, +// ).showSnackBar(SnackBar(content: Text(errorMessage))); +// } +// } +// } +// break; + +// case 'view_challenge': +// // TODO: 챌린지 상세(소개) 페이지로 이동하거나 탭을 전환하는 로직 +// debugPrint('🚀 [Action] 챌린지 보기 클릭'); +// // TODO: Navigator.push(...) 혹은 현재 탭 전환 로직 추가 +// break; +// case 'complain': +// ScaffoldMessenger.of( +// context, +// ).showSnackBar(const SnackBar(content: Text("신고가 접수되었습니다."))); +// break; +// } +// } +// } diff --git a/lib/features/feed/widgets/feed_post_card.dart b/lib/features/feed/widgets/feed_post_card.dart index 55bba0e..72fa200 100644 --- a/lib/features/feed/widgets/feed_post_card.dart +++ b/lib/features/feed/widgets/feed_post_card.dart @@ -78,7 +78,7 @@ class FeedPostCard extends ConsumerWidget { ], ), ), - ChallengeFeedPopupMenu(post: post), + // ChallengeFeedPopupMenu(post: post), ], ), ), diff --git a/lib/features/home/screens/home_screen.dart b/lib/features/home/screens/home_screen.dart index 4fec223..d51e073 100644 --- a/lib/features/home/screens/home_screen.dart +++ b/lib/features/home/screens/home_screen.dart @@ -4,7 +4,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/features/challenge/create/screens/challenge_create_screen.dart'; -import '../provider/home_provider.dart'; +import '../../../shared/provider/home_provider.dart'; import 'package:haenaem/features/notification/screens/notification_main_screen.dart'; import 'package:haenaem/features/notification/provider/notification_provider.dart'; import 'package:haenaem/shared/models/home_challenge_card.dart'; diff --git a/lib/shared/models/post.dart b/lib/shared/models/post.dart index f7a6979..dd60c58 100644 --- a/lib/shared/models/post.dart +++ b/lib/shared/models/post.dart @@ -1,4 +1,5 @@ import 'package:haenaem/shared/models/user.dart'; +import 'package:haenaem/features/challenge/models/image_model.dart'; // 최초 작성자: 강선욱 // 인증글 모델 클래스 @@ -7,7 +8,7 @@ class Post { final int id; // 인증글 id final String title; // 인증글 제목 final String content; // 인증글 내용 - final String? pictureUrl; // 인증글 사진 주소 + final List images; // 인증글 사진 final int likeCount; // 좋아요 수 final bool isLiked; // 현재 로그인 유저의 좋아요 여부 final int commentCount; // 댓글 수 @@ -18,7 +19,7 @@ class Post { required this.id, required this.title, required this.content, - this.pictureUrl, + required this.images, required this.likeCount, required this.isLiked, required this.commentCount, @@ -27,11 +28,18 @@ class Post { }); factory Post.fromJson(Map json) { + var imageList = json['images'] as List? ?? []; + List parsedImages = imageList + .map( + (imageJson) => PostImage.fromJson(imageJson as Map), + ) + .toList(); + return Post( id: json['id'] as int, title: json['title'] as String, content: json['content'] as String, - pictureUrl: json['picture_url'] as String?, + images: parsedImages, likeCount: json['like_count'] as int, isLiked: json['is_liked'] as bool, commentCount: json['comment_count'] as int, @@ -44,7 +52,7 @@ class Post { int? id, String? title, String? content, - String? pictureUrl, + List? images, int? likeCount, bool? isLiked, int? commentCount, @@ -55,7 +63,7 @@ class Post { id: id ?? this.id, title: title ?? this.title, content: content ?? this.content, - pictureUrl: pictureUrl ?? this.pictureUrl, + images: images ?? this.images, likeCount: likeCount ?? this.likeCount, isLiked: isLiked ?? this.isLiked, commentCount: commentCount ?? this.commentCount, @@ -64,3 +72,18 @@ class Post { ); } } + +// 인증글 사진 정보를 관리하는 클래스 +class PostImage { + final int imageId; + final String imageUrl; + + PostImage({required this.imageId, required this.imageUrl}); + + factory PostImage.fromJson(Map json) { + return PostImage( + imageId: json['imageId'] ?? 0, + imageUrl: json['imageUrl'] ?? '', + ); + } +} diff --git a/lib/features/challenge/detail/provider/challenge_detail_provider.dart b/lib/shared/provider/challenge_detail_provider.dart similarity index 100% rename from lib/features/challenge/detail/provider/challenge_detail_provider.dart rename to lib/shared/provider/challenge_detail_provider.dart diff --git a/lib/features/challenge/detail/provider/challenge_detail_provider.g.dart b/lib/shared/provider/challenge_detail_provider.g.dart similarity index 100% rename from lib/features/challenge/detail/provider/challenge_detail_provider.g.dart rename to lib/shared/provider/challenge_detail_provider.g.dart diff --git a/lib/features/home/provider/home_provider.dart b/lib/shared/provider/home_provider.dart similarity index 100% rename from lib/features/home/provider/home_provider.dart rename to lib/shared/provider/home_provider.dart diff --git a/lib/features/home/provider/home_provider.g.dart b/lib/shared/provider/home_provider.g.dart similarity index 100% rename from lib/features/home/provider/home_provider.g.dart rename to lib/shared/provider/home_provider.g.dart diff --git a/lib/features/challenge/detail/provider/post_provider.dart b/lib/shared/provider/post_provider.dart similarity index 80% rename from lib/features/challenge/detail/provider/post_provider.dart rename to lib/shared/provider/post_provider.dart index 8b45e14..8ac8bda 100644 --- a/lib/features/challenge/detail/provider/post_provider.dart +++ b/lib/shared/provider/post_provider.dart @@ -1,7 +1,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; -import '../models/calendar_post.dart'; -import '../data/post_repository.dart'; +import '../../features/challenge/detail/models/calendar_post.dart'; +import '../../features/challenge/detail/data/post_repository.dart'; part 'post_provider.g.dart'; diff --git a/lib/features/challenge/detail/provider/post_provider.g.dart b/lib/shared/provider/post_provider.g.dart similarity index 100% rename from lib/features/challenge/detail/provider/post_provider.g.dart rename to lib/shared/provider/post_provider.g.dart From 8cc00212d7b566ad4bf6744fab08c7bdd4f4b6c4 Mon Sep 17 00:00:00 2001 From: Chaeyeong_10 Date: Fri, 27 Mar 2026 16:34:57 +0900 Subject: [PATCH 082/134] =?UTF-8?q?chore:=20refactor=20=ED=95=A9=EC=B9=98?= =?UTF-8?q?=EA=B8=B0=20=EC=A0=84=20=ED=98=84=EC=9E=AC=20=EC=83=81=ED=83=9C?= =?UTF-8?q?=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/src/main/AndroidManifest.xml | 84 +++++++++++++------- lib/features/auth/login/login_screen.dart | 35 +++++++- lib/features/auth/services/auth_service.dart | 39 ++++----- 3 files changed, 107 insertions(+), 51 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 184b666..9dd7016 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,33 +1,22 @@ - + + + - - - - - - - - - - - - - - - + + + @@ -40,28 +29,63 @@ android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> - + + android:resource="@style/NormalTheme" + /> - + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/features/auth/login/login_screen.dart b/lib/features/auth/login/login_screen.dart index 69d44cc..1c605ea 100644 --- a/lib/features/auth/login/login_screen.dart +++ b/lib/features/auth/login/login_screen.dart @@ -116,7 +116,7 @@ class LoginScreen extends StatelessWidget { if (authResult != null) { await AuthService.sendTokenToBackend( code: authResult['code']!, - codeVerifier: authResult['code_verifier']!, + codeVerifier: authResult['codeVerifier']!, context: context, ); } @@ -209,9 +209,31 @@ class LoginScreen extends StatelessWidget { ) ..setNavigationDelegate( NavigationDelegate( + onWebResourceError: (WebResourceError error) { + debugPrint(''' + ⚠️ 웹뷰 로딩 에러 발생! + - 코드: ${error.errorCode} + - 설명: ${error.description} + - URL: ${error.url} + '''); + }, onNavigationRequest: (NavigationRequest request) async { final url = request.url; + // 📍 [중요] 주소 감지 로그 추가 + if (url.contains('/oauth/kakao/callback')) { + debugPrint('🎣 [감지 성공] 카카오 콜백 주소가 포착되었습니다!'); + final uri = Uri.parse(url); + final code = uri.queryParameters['code']; + + if (code != null) { + debugPrint('✅ 획득한 인가 코드: $code'); + onCodeCaptured(code); + Navigator.pop(context); // 웹뷰 닫기 + return NavigationDecision.prevent; // 페이지 이동 중단 + } + } + // 2️⃣ 카카오톡 앱 호출 주소 처리 if (url.startsWith('kakaotalk://') || url.startsWith('intent://')) { try { @@ -240,9 +262,10 @@ class LoginScreen extends StatelessWidget { return NavigationDecision.navigate; }, onPageStarted: (url) { - // ✅ AuthService.kakaoRedirectUri(ngrok 주소)로 시작하는지 감시 + debugPrint("🚀 웹뷰 로딩 시작됨: $url"); + // ✅ AuthService.kakaoRedirectUri로 시작하는지 감시 if (url.startsWith(AuthService.kakaoRedirectUri)) { - debugPrint('🎣 ngrok 리다이렉트 감지!'); + debugPrint('🎣 리다이렉트 감지!'); final uri = Uri.parse(url); final code = uri.queryParameters['code']; if (code != null) { @@ -251,10 +274,16 @@ class LoginScreen extends StatelessWidget { } } }, + onPageFinished: (url) { + debugPrint("✅ 웹뷰 로딩 완료됨: $url"); + }, ), ) ..loadRequest(Uri.parse(authUrl)); + // 📍 로드하기 직전에 실제 어떤 주소를 부르는지 확인! + debugPrint("🌍 웹뷰 로딩 시도 URL: $authUrl"); + return Container( height: MediaQuery.of(context).size.height * 0.9, decoration: const BoxDecoration( diff --git a/lib/features/auth/services/auth_service.dart b/lib/features/auth/services/auth_service.dart index 142116e..4c89e9c 100644 --- a/lib/features/auth/services/auth_service.dart +++ b/lib/features/auth/services/auth_service.dart @@ -28,31 +28,32 @@ class AuthService { static const String kakaoNativeAppKey = '05a36f172ea2945260862834654385ea'; // static const String kakaoRedirectUri = // 'https://hanaem.onrender.com/api/oauth/kakao/token'; - // static const String kakaoRedirectUri = - // 'https://hanaem.onrender.com/oauth/kakao/callback'; + + static const String kakaoRedirectUri = + 'https://hanaem.onrender.com/oauth/kakao/callback'; //static const String kakaoRedirectUri = //'kakao9fdd13c0777c415d8fa4055b5b26a6c5://oauth'; // ♥️ 로컬 서버로 테스트 - static const String kakaoRedirectUri = - 'https://ungenially-undebatable-sindy.ngrok-free.dev/oauth/kakao/callback'; - - // static final Dio _dio = Dio( - // BaseOptions(baseUrl: 'https://hanaem.onrender.com'), - // ); + // static const String kakaoRedirectUri = + // 'https://ungenially-undebatable-sindy.ngrok-free.dev/oauth/kakao/callback'; - // ♥️ 로컬 서버로 테스트 static final Dio _dio = Dio( - BaseOptions( - baseUrl: 'https://ungenially-undebatable-sindy.ngrok-free.dev', - headers: { - 'ngrok-skip-browser-warning': 'true', - 'Content-Type': 'application/json', - }, - ), + BaseOptions(baseUrl: 'https://hanaem.onrender.com'), ); + // ♥️ 로컬 서버로 테스트 + // static final Dio _dio = Dio( + // BaseOptions( + // baseUrl: 'https://ungenially-undebatable-sindy.ngrok-free.dev', + // headers: { + // 'ngrok-skip-browser-warning': 'true', + // 'Content-Type': 'application/json', + // }, + // ), + // ); + // 1. PKCE 쌍 생성 (RFC 7636 표준 방식) static Map generatePkcePair() { // 1-1. Verifier 생성: 표준에 정의된 [A-Z, a-z, 0-9, -, ., _, ~] 문자만 사용 @@ -65,7 +66,7 @@ class AuthService { 64, (_) => chars[random.nextInt(chars.length)], ).join(); - debugPrint("verifier 생성: $verifier"); + debugPrint("🔒 verifier 생성: $verifier"); // 1-2. Challenge 생성: Verifier를 SHA256으로 해싱 후 Base64Url 인코딩 final bytes = utf8.encode(verifier); // plain string을 바이트로 변환 @@ -314,10 +315,12 @@ class AuthService { debugPrint("🗑️ 회원 탈퇴 요청 시작"); // 서버에 계정 삭제 요청 (DELETE) // 리프레시 토큰뿐만 아니라 유저의 개인정보 등을 삭제하도록 서버에 명령합니다. - await _dio.delete( + final response = await _dio.delete( '/api/me', options: Options(headers: {'Authorization': 'Bearer $accessToken'}), ); + // 📍 서버가 진짜 뭐라고 대답했는지 찍어보기 + debugPrint("📥 탈퇴 응답 데이터: ${response.data}"); // 탈퇴 성공 후 클라이언트 데이터 정리 await _storage.deleteAll(); From e1a8e94ebfa6f51e3c82314d75a6ab051fbf98b4 Mon Sep 17 00:00:00 2001 From: Chaeyeong_10 Date: Sat, 28 Mar 2026 13:22:37 +0900 Subject: [PATCH 083/134] =?UTF-8?q?refactor:=20=EC=B9=B4=EC=B9=B4=EC=98=A4?= =?UTF-8?q?=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EA=B5=AC=ED=98=84=20=EB=B0=8F?= =?UTF-8?q?=20User=EC=99=80=20UserDetail=20=EB=AA=A8=EB=8D=B8=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/core/theme/app_theme.dart | 11 ++++ .../auth/signup/screens/auth_gate.dart | 10 ++-- .../screens/challenge_create_screen.dart | 9 ++-- .../create/widgets/ai_notice_box.dart | 6 +-- .../provider/challenge_provider.dart | 12 +++-- .../provider/challenge_provider.g.dart | 17 ------ .../widgets/ChallengeFeedPopupMenu.dart | 2 +- .../widgets/delete_challenge_dialog.dart | 4 ++ .../feed/screens/challenge_search_screen.dart | 16 +++--- lib/features/user/data/user_repository.dart | 21 ++++++-- lib/features/user/provider/tag_provider.dart | 7 ++- lib/features/user/provider/user_provider.dart | 43 ++++++++++++--- .../user/provider/user_provider.g.dart | 29 +++++++--- lib/features/user/screens/my_page_screen.dart | 54 ++++++++++++------- .../user/screens/profile_edit_screen.dart | 54 +++++++++++-------- lib/shared/models/user_detail.dart | 16 ++++++ pubspec.lock | 24 ++++----- 17 files changed, 219 insertions(+), 116 deletions(-) create mode 100644 lib/shared/models/user_detail.dart diff --git a/lib/core/theme/app_theme.dart b/lib/core/theme/app_theme.dart index bd20b5b..b162c05 100644 --- a/lib/core/theme/app_theme.dart +++ b/lib/core/theme/app_theme.dart @@ -1,6 +1,7 @@ // 최초 작성자: 김채영 import 'package:flutter/material.dart'; +import 'app_colors.dart'; class AppTheme { static ThemeData lightTheme = ThemeData( @@ -8,6 +9,16 @@ class AppTheme { fontFamily: 'Pretendard', scaffoldBackgroundColor: Colors.white, + // 스피너랑 커서 우리 앱 초록색으로 변경 + progressIndicatorTheme: const ProgressIndicatorThemeData( + color: AppColors.primaryAble, + ), + textSelectionTheme: TextSelectionThemeData( + cursorColor: AppColors.primaryAble, + selectionHandleColor: AppColors.primaryAble, + selectionColor: AppColors.primaryAble.withValues(alpha: 0.3), + ), + // 상단 AppBar 테마 설정 appBarTheme: const AppBarTheme( backgroundColor: Colors.white, diff --git a/lib/features/auth/signup/screens/auth_gate.dart b/lib/features/auth/signup/screens/auth_gate.dart index fc96797..e0fc9fb 100644 --- a/lib/features/auth/signup/screens/auth_gate.dart +++ b/lib/features/auth/signup/screens/auth_gate.dart @@ -6,7 +6,7 @@ import 'package:haenaem/features/main/screens/main_screen.dart'; import 'package:haenaem/features/auth/login/login_screen.dart'; import 'signup_main_screen.dart'; import 'package:haenaem/features/user/data/user_repository.dart'; -import 'package:haenaem/features/user/models/user_model.dart'; +import 'package:haenaem/shared/models/user.dart'; import 'package:haenaem/features/user/provider/user_provider.dart'; import 'package:haenaem/features/notification/services/fcm_service.dart'; @@ -29,7 +29,7 @@ class AuthGate extends ConsumerWidget { // 1. 토큰이 있는 경우 if (snapshot.hasData && snapshot.data != null) { // 💡 핵심: 서버에 내 프로필을 물어봐서 가입이 끝났는지 확인합니다. - return FutureBuilder( + return FutureBuilder( future: ref.read(userRepositoryProvider).getMyProfile(), builder: (context, profileSnapshot) { if (profileSnapshot.connectionState == ConnectionState.waiting) { @@ -39,10 +39,10 @@ class AuthGate extends ConsumerWidget { } // 프로필 정보가 있고, 특정 필드(예: 태그)가 비어있다면 가입 미완료로 간주 - final profile = profileSnapshot.data; + final user = profileSnapshot.data; // 가입 미완료 판별 로직 - if (profile == null || profile.tags.isEmpty) { + if (user == null) { debugPrint("⚠️ 가입 미완료 유저: 회원가입 화면으로 안내"); return const SignupMainScreen(); } @@ -50,7 +50,7 @@ class AuthGate extends ConsumerWidget { // 성공적으로 정보를 가져왔다면 전역 Provider에 저장 // 프레임 렌더링 후에 상태를 업데이트하도록 처리 WidgetsBinding.instance.addPostFrameCallback((_) { - ref.read(currentUserProvider.notifier).setUser(profile); + ref.read(currentUserProvider.notifier).setUser(user); // FCM 초기화 등 추가 작업 ref.read(fcmServiceProvider).initialize(); }); diff --git a/lib/features/challenge/create/screens/challenge_create_screen.dart b/lib/features/challenge/create/screens/challenge_create_screen.dart index 70b64c7..e1e2de5 100644 --- a/lib/features/challenge/create/screens/challenge_create_screen.dart +++ b/lib/features/challenge/create/screens/challenge_create_screen.dart @@ -4,6 +4,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:haenaem/features/home/provider/home_provider.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'dart:convert'; @@ -141,13 +142,15 @@ class _ChallengeCreateScreenState extends ConsumerState { // 3. 결과 처리 if (response != null && mounted) { // 현황 페이지로 이동하며 데이터 전달 - // pushReplacement를 쓰면 '만들기' 화면이 스택에서 제거되어 뒤로가기를 눌러도 다시 나오지 않습니다. - await Future.delayed(const Duration(seconds: 5)); debugPrint('✅ 5초 대기 후 이동 시도 - challengeId: ${response.id}'); debugPrint('✅ 생성된 실제 ID: ${response.id}'); + if (!mounted) return; - Navigator.pushReplacement( + ref.read(homeNotifierProvider.notifier).refresh(); + ref.invalidate(myInProgressChallengesProvider); + + await Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => ChallengeMainScreen(challengeId: response.id), diff --git a/lib/features/challenge/create/widgets/ai_notice_box.dart b/lib/features/challenge/create/widgets/ai_notice_box.dart index ab574a7..8ba4be5 100644 --- a/lib/features/challenge/create/widgets/ai_notice_box.dart +++ b/lib/features/challenge/create/widgets/ai_notice_box.dart @@ -12,7 +12,7 @@ class AiNoticeBox extends StatelessWidget { Widget build(BuildContext context) { return Container( width: double.infinity, - padding: const EdgeInsets.all(12), + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), @@ -30,10 +30,10 @@ class AiNoticeBox extends StatelessWidget { BlendMode.srcIn, ), ), - const SizedBox(width: 7), + const SizedBox(width: 5), Expanded( child: Text( - '정확한 인증을 위해 AI 검증 단계를 거치게 됩니다. \n환경에 따라 인식이 지연되거나 재촬영이 필요할 수 있습니다.', + '정확한 인증을 위해 AI 검증 단계를 거치게 됩니다.\n환경에 따라 인식이 지연되거나 재촬영이 필요할 수 있습니다.', style: AppTypography.c1.copyWith(color: AppColors.gray1), ), ), diff --git a/lib/features/challenge/provider/challenge_provider.dart b/lib/features/challenge/provider/challenge_provider.dart index 3fe2b0d..6454217 100644 --- a/lib/features/challenge/provider/challenge_provider.dart +++ b/lib/features/challenge/provider/challenge_provider.dart @@ -5,6 +5,7 @@ import '../data/challenge_repository.dart'; import 'package:haenaem/features/user/data/user_repository.dart'; import '../models/challenge_model.dart'; import 'package:haenaem/features/user/models/user_model.dart'; +import 'package:haenaem/shared/models/user.dart'; import 'dart:io'; part 'challenge_provider.g.dart'; @@ -457,11 +458,12 @@ class ChallengeDeleteNotifier extends _$ChallengeDeleteNotifier { } // 내페이지 사용자 프로필 정보 -@riverpod -Future myProfile(MyProfileRef ref) async { - final repository = ref.watch(userRepositoryProvider); - return repository.getMyProfile(); -} +// ♥️user_provider의 myprofile로 대체♥️ +// @riverpod +// Future myProfile(MyProfileRef ref) async { +// final repository = ref.watch(userRepositoryProvider); +// return repository.getMyProfile(); +// } // 내 페이지 - 나의 챌린지 - 진행중인 챌린지 @riverpod diff --git a/lib/features/challenge/provider/challenge_provider.g.dart b/lib/features/challenge/provider/challenge_provider.g.dart index db7d391..9fd33a6 100644 --- a/lib/features/challenge/provider/challenge_provider.g.dart +++ b/lib/features/challenge/provider/challenge_provider.g.dart @@ -913,23 +913,6 @@ class _ArticleCommentsProviderElement int get page => (origin as ArticleCommentsProvider).page; } -String _$myProfileHash() => r'0536f34717b179e7bf7ba33d770c66e3781de904'; - -/// See also [myProfile]. -@ProviderFor(myProfile) -final myProfileProvider = AutoDisposeFutureProvider.internal( - myProfile, - name: r'myProfileProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$myProfileHash, - dependencies: null, - allTransitiveDependencies: null, -); - -@Deprecated('Will be removed in 3.0. Use Ref instead') -// ignore: unused_element -typedef MyProfileRef = AutoDisposeFutureProviderRef; String _$myInProgressChallengesHash() => r'4f53f796e087c3f28343d446396e079ac6ab81dc'; diff --git a/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart b/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart index beb07ac..e6a2c99 100644 --- a/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart +++ b/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart @@ -19,7 +19,7 @@ class ChallengeFeedPopupMenu extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { // 1. 현재 로그인한 내 프로필 정보를 가져옵니다. - final myProfileAsync = ref.watch(myProfileProvider); + //final myProfileAsync = ref.watch(myProfileProvider); // 2. 내 닉네임과 게시글 작성자 닉네임을 비교하여 '내 글' 여부 판단 final bool isMine = post.author; diff --git a/lib/features/challenge/widgets/delete_challenge_dialog.dart b/lib/features/challenge/widgets/delete_challenge_dialog.dart index d15ee50..58d6ae9 100644 --- a/lib/features/challenge/widgets/delete_challenge_dialog.dart +++ b/lib/features/challenge/widgets/delete_challenge_dialog.dart @@ -5,6 +5,7 @@ import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../provider/challenge_provider.dart'; +import 'package:haenaem/features/home/provider/home_provider.dart'; // 방장용 : 챌린지 삭제 다이얼로그 class DeleteChallengeDialog extends ConsumerWidget { @@ -81,6 +82,9 @@ class DeleteChallengeDialog extends ConsumerWidget { if (success && context.mounted) { // 성공 시 모든 창을 닫고 홈으로 이동 + ref.read(homeNotifierProvider.notifier).refresh(); + // 내 페이지 진행중인 챌린지 상태 업데이트 + ref.invalidate(myInProgressChallengesProvider); Navigator.of( context, ).popUntil((route) => route.isFirst); diff --git a/lib/features/feed/screens/challenge_search_screen.dart b/lib/features/feed/screens/challenge_search_screen.dart index a7f89cf..aa88ae7 100644 --- a/lib/features/feed/screens/challenge_search_screen.dart +++ b/lib/features/feed/screens/challenge_search_screen.dart @@ -8,6 +8,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/user/models/user_model.dart'; +import 'package:haenaem/shared/models/user.dart'; +import 'package:haenaem/features/user/provider/user_provider.dart'; class ChallengeSearchScreen extends ConsumerStatefulWidget { const ChallengeSearchScreen({super.key}); @@ -23,7 +25,7 @@ class _ChallengeSearchScreenState extends ConsumerState { @override Widget build(BuildContext context) { // 사용자 프로필 정보 가져오기 (헤더 이름용) - final profileAsync = ref.watch(myProfileProvider); + final currentUser = ref.watch(currentUserProvider); // 검색어가 있을 때만 api 호출 final searchResults = ref.watch( @@ -107,7 +109,7 @@ class _ChallengeSearchScreenState extends ConsumerState { // 챌린지 카드 리스트 Expanded( child: _currentKeyword.isEmpty - ? _buildRecommendationSection(profileAsync) // 검색어 없을 때 + ? _buildRecommendationSection(currentUser) // 검색어 없을 때 : searchResults.when( data: (list) => list.isEmpty ? const Center(child: Text("검색 결과가 없습니다.")) @@ -135,14 +137,8 @@ class _ChallengeSearchScreenState extends ConsumerState { } // 추천 섹션 (기존 코드의 그라데이션 박스 부분 분리) - Widget _buildRecommendationSection( - AsyncValue profileAsync, - ) { - final userName = profileAsync.when( - data: (user) => user.nickname, - loading: () => "해냄", - error: (_, __) => "해냄", - ); + Widget _buildRecommendationSection(User? currentUser) { + final userName = currentUser?.nickname ?? "해냄"; return SingleChildScrollView( child: Column( diff --git a/lib/features/user/data/user_repository.dart b/lib/features/user/data/user_repository.dart index 06d6edc..16516e9 100644 --- a/lib/features/user/data/user_repository.dart +++ b/lib/features/user/data/user_repository.dart @@ -6,7 +6,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:haenaem/core/network/dio_provider.dart'; import 'package:haenaem/features/challenge/models/challenge_model.dart'; -import 'package:haenaem/features/user/models/user_model.dart'; +import 'package:haenaem/shared/models/user.dart'; +import 'package:haenaem/shared/models/user_detail.dart'; part 'user_repository.g.dart'; // 회원가입 + 내페이지 @@ -15,11 +16,25 @@ class UserRepository { UserRepository(this._dio); // 내 프로필 정보 조회 - Future getMyProfile() async { + Future getMyProfile() async { try { final response = await _dio.get('/api/users/me/profile'); if (response.statusCode == 200) { - return UserProfileModel.fromJson(response.data); + return User.fromJson(response.data); + } else { + throw Exception('프로필 정보를 불러오지 못했습니다.'); + } + } on DioException catch (e) { + throw Exception('네트워크 에러: ${e.message}'); + } + } + + // 마이페이지용 상세 프로필 조회 + Future getMyProfileDetail() async { + try { + final response = await _dio.get('/api/users/me/profile'); + if (response.statusCode == 200) { + return UserDetail.fromJson(response.data); // ✅ UserDetail로 파싱 } else { throw Exception('프로필 정보를 불러오지 못했습니다.'); } diff --git a/lib/features/user/provider/tag_provider.dart b/lib/features/user/provider/tag_provider.dart index 60b5bc7..69cf135 100644 --- a/lib/features/user/provider/tag_provider.dart +++ b/lib/features/user/provider/tag_provider.dart @@ -1,9 +1,8 @@ // 최초 작성자 : 김채영 import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; -import '../../challenge/data/challenge_repository.dart'; import '../../challenge/models/challenge_model.dart'; -import 'package:haenaem/features/user/models/user_model.dart'; +import 'package:haenaem/shared/models/user_detail.dart'; import 'package:haenaem/features/user/data/user_repository.dart'; import 'package:flutter/foundation.dart'; import '../../auth/signup/models/signup_state.dart'; @@ -30,11 +29,11 @@ class TagNotifier extends Notifier { // 전체 태그와 내 프로필 동시 로드 final results = await Future.wait([ repository.getAllTags(), - repository.getMyProfile(), // GET /api/users/me/profile + repository.getMyProfileDetail(), ]); _allServerTags = results[0] as List; - final profile = results[1] as UserProfileModel; // 프로필 모델 가정 + final profile = results[1] as UserDetail; // 프로필 모델 가정 _initialTagNames = List.from(profile.tags); diff --git a/lib/features/user/provider/user_provider.dart b/lib/features/user/provider/user_provider.dart index 1f8f974..7ba09f9 100644 --- a/lib/features/user/provider/user_provider.dart +++ b/lib/features/user/provider/user_provider.dart @@ -1,21 +1,21 @@ // 최초 작성자 : 김채영 import 'package:riverpod_annotation/riverpod_annotation.dart'; -import '../models/user_model.dart'; import 'package:haenaem/shared/models/user.dart'; +import 'package:haenaem/shared/models/user_detail.dart'; +import 'package:haenaem/features/user/data/user_repository.dart'; part 'user_provider.g.dart'; - // 앱 전체에서 현재 로그인한 사용자의 정보를 관리하는 전역 상태 클래스 @Riverpod(keepAlive: true) // 앱이 켜져 있는 동안 데이터를 계속 유지 class CurrentUser extends _$CurrentUser { @override - UserProfileModel? build() { - return null; // 초기값은 로그인 전이므로 null + User? build() { + return null; } - // 사용자 정보 업데이트 (로그인 시 호출) - void setUser(UserProfileModel user) { + // 로그인 시 호출 + void setUser(User user) { state = user; } @@ -23,4 +23,35 @@ class CurrentUser extends _$CurrentUser { void clearUser() { state = null; } + + // 닉네임만 업데이트 + void updateNickname(String nickname) { + state = state?.copyWith(nickname: nickname); + } + + // 프로필 이미지만 업데이트 + void updateProfileImage(String? profileUrl) { + state = state?.copyWith(profileUrl: profileUrl); + } +} + +@riverpod +class MyProfile extends _$MyProfile { + @override + FutureOr build() async { + final userRepo = ref.read(userRepositoryProvider); + return userRepo.getMyProfileDetail(); // ✅ 새 메서드 호출 + } + + // API 호출 없이 로컬 상세 정보만 업데이트 + void updateLocalDetail({String? introduction, List? tags}) { + state.whenData((current) { + state = AsyncData( + UserDetail( + introduction: introduction ?? current.introduction, + tags: tags ?? current.tags, + ), + ); + }); + } } diff --git a/lib/features/user/provider/user_provider.g.dart b/lib/features/user/provider/user_provider.g.dart index 71fd79c..6fb448f 100644 --- a/lib/features/user/provider/user_provider.g.dart +++ b/lib/features/user/provider/user_provider.g.dart @@ -6,21 +6,36 @@ part of 'user_provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$currentUserHash() => r'cb6fcdfff246718015359e838194b2d6d2dc0c92'; +String _$currentUserHash() => r'1cd77fb5bb48fa22fbd7a130413d96bac74fdc3d'; /// See also [CurrentUser]. @ProviderFor(CurrentUser) -final currentUserProvider = - NotifierProvider.internal( - CurrentUser.new, - name: r'currentUserProvider', +final currentUserProvider = NotifierProvider.internal( + CurrentUser.new, + name: r'currentUserProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$currentUserHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef _$CurrentUser = Notifier; +String _$myProfileHash() => r'4b209ac932e27d9c0deca6af80d9b5115cf82b65'; + +/// See also [MyProfile]. +@ProviderFor(MyProfile) +final myProfileProvider = + AutoDisposeAsyncNotifierProvider.internal( + MyProfile.new, + name: r'myProfileProvider', debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') ? null - : _$currentUserHash, + : _$myProfileHash, dependencies: null, allTransitiveDependencies: null, ); -typedef _$CurrentUser = Notifier; +typedef _$MyProfile = AutoDisposeAsyncNotifier; // ignore_for_file: type=lint // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/user/screens/my_page_screen.dart b/lib/features/user/screens/my_page_screen.dart index 55393e2..2a199e3 100644 --- a/lib/features/user/screens/my_page_screen.dart +++ b/lib/features/user/screens/my_page_screen.dart @@ -9,10 +9,12 @@ import 'package:haenaem/features/user/screens/push_notification_settings_screen. import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_typography.dart'; -import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/features/notification/services/fcm_service.dart'; -import 'package:haenaem/shared/models/tag_model.dart'; +import 'package:haenaem/features/user/provider/user_provider.dart'; +import 'package:haenaem/shared/models/user.dart'; +import 'package:haenaem/shared/models/user_detail.dart'; + import 'withdrawal_screen.dart'; import 'challenge_list_screen.dart'; import 'profile_edit_screen.dart'; @@ -31,11 +33,12 @@ class MyPageScreen extends ConsumerStatefulWidget { class _MyPageScreenState extends ConsumerState { @override Widget build(BuildContext context) { + final currentUser = ref.watch(currentUserProvider); final profileAsync = ref.watch(myProfileProvider); return Scaffold( backgroundColor: Colors.white, - appBar: _buildAppBar(), + appBar: _buildAppBar(currentUser), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 20.0), @@ -43,16 +46,29 @@ class _MyPageScreenState extends ConsumerState { children: [ const SizedBox(height: 20), - profileAsync.when( - loading: () => const Center(child: CircularProgressIndicator()), - error: (err, stack) => const Center(child: Text('데이터 로드 실패')), - data: (profile) => ProfileHeader( - nickname: profile.nickname, - introduction: profile.introduction, - profileImageUrl: profile.profileImageUrl, - tags: profile.tags, - ), - ), + if (currentUser != null) + profileAsync.when( + loading: () => ProfileHeader( + nickname: currentUser.nickname, // ✅ 닉네임/이미지는 currentUser에서 + profileImageUrl: currentUser.profileUrl ?? '', + introduction: '', + tags: const [], + ), + error: (_, __) => ProfileHeader( + nickname: currentUser.nickname, + profileImageUrl: currentUser.profileUrl ?? '', + introduction: '', + tags: const [], + ), + data: (UserDetail detail) => ProfileHeader( + nickname: currentUser.nickname, + profileImageUrl: currentUser.profileUrl ?? '', + introduction: detail.introduction, + tags: detail.tags, + ), + ) + else + const Center(child: CircularProgressIndicator()), const SizedBox(height: 40), const ChallengeSection(), // 챌린지 섹션 위젯 @@ -67,7 +83,7 @@ class _MyPageScreenState extends ConsumerState { ); } - PreferredSizeWidget _buildAppBar() { + PreferredSizeWidget _buildAppBar(User? currentUser) { return AppBar( backgroundColor: Colors.white, elevation: 0, @@ -84,14 +100,14 @@ class _MyPageScreenState extends ConsumerState { onTap: () { // 1. 현재 로드된 프로필 데이터를 가져옵니다. final profileData = ref.read(myProfileProvider).value; - - // 2. 데이터가 있을 때만 화면 이동 (null 체크) - if (profileData != null) { + if (currentUser != null && profileData != null) { Navigator.push( context, MaterialPageRoute( - builder: (context) => - ProfileEditScreen(profile: profileData), + builder: (context) => ProfileEditScreen( + user: currentUser, + detail: profileData, + ), ), ); } else { diff --git a/lib/features/user/screens/profile_edit_screen.dart b/lib/features/user/screens/profile_edit_screen.dart index 6ed8ffd..3e2aaf8 100644 --- a/lib/features/user/screens/profile_edit_screen.dart +++ b/lib/features/user/screens/profile_edit_screen.dart @@ -6,8 +6,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:image_picker/image_picker.dart'; import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; -import 'package:haenaem/features/user/models/user_model.dart'; -import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; + import 'package:haenaem/shared/models/tag_model.dart'; import 'package:haenaem/shared/widgets/app_tag_chip.dart'; import 'package:haenaem/shared/widgets/image_source_sheet.dart'; @@ -16,11 +15,20 @@ import 'package:haenaem/features/auth/signup/screens/profile_image_edit_screen.d import '../widgets/profile_image_menu.dart'; import '../data/user_repository.dart'; import '../provider/tag_provider.dart'; +// import 'package:haenaem/features/user/models/user_model.dart'; +import 'package:haenaem/shared/models/user_detail.dart'; +import 'package:haenaem/shared/models/user.dart'; +import 'package:haenaem/features/user/provider/user_provider.dart'; // 프로필 편집 화면 class ProfileEditScreen extends ConsumerStatefulWidget { - final UserProfileModel profile; - const ProfileEditScreen({super.key, required this.profile}); + final User user; // 닉네임, 프로필 이미지 + final UserDetail detail; // 한줄소개, 태그 + const ProfileEditScreen({ + super.key, + required this.user, + required this.detail, + }); @override ConsumerState createState() => _ProfileEditScreenState(); @@ -39,8 +47,8 @@ class _ProfileEditScreenState extends ConsumerState { @override void initState() { super.initState(); - _nicknameController = TextEditingController(text: widget.profile.nickname); - _introController = TextEditingController(text: widget.profile.introduction); + _nicknameController = TextEditingController(text: widget.user.nickname); + _introController = TextEditingController(text: widget.detail.introduction); _nicknameController.addListener(_validateNickname); _introController.addListener(() => setState(() {})); @@ -102,7 +110,8 @@ class _ProfileEditScreenState extends ConsumerState { _isImageDeleted = true; _showImageMenu = false; }); - ref.invalidate(myProfileProvider); + // API 재호출 없이 전역 상태만 업데이트 + ref.read(currentUserProvider.notifier).updateProfileImage(null); } catch (e) { debugPrint('삭제 실패: $e'); } @@ -127,18 +136,15 @@ class _ProfileEditScreenState extends ConsumerState { Future _handleSave() async { try { final userRepo = ref.read(userRepositoryProvider); - final tagNotifier = ref.read(tagProvider.notifier); // 로딩바 등을 보여줄 수 있는 로직 추가 가능 (예: 다이얼로그) // 1. 닉네임 변경 체크 및 실행 - if (_nicknameController.text != widget.profile.nickname) { + if (_nicknameController.text != widget.user.nickname) { await userRepo.updateNickname(_nicknameController.text); - } - - // 2. 💡 한 줄 소개 변경 체크 및 실행 - if (_introController.text != widget.profile.introduction) { - await userRepo.updateIntroduction(_introController.text); + ref + .read(currentUserProvider.notifier) + .updateNickname(_nicknameController.text); } // 3. 이미지 변경 체크 및 실행 @@ -146,15 +152,21 @@ class _ProfileEditScreenState extends ConsumerState { await userRepo.uploadProfileImage(_selectedImageFile!); } - final tagSuccess = await tagNotifier.updateInterestTags(); + // 2. UserDetail 정보 업데이트 (소개, 태그) + await userRepo.updateIntroduction(_introController.text); + await ref.read(tagProvider.notifier).updateInterestTags(); - if (!tagSuccess) { - throw Exception('태그 수정 중 오류가 발생했습니다.'); - } + // 로컬 전역 상태 업데이트 (UserDetail용) + ref + .read(myProfileProvider.notifier) + .updateLocalDetail( + introduction: _introController.text, + tags: ref.read(tagProvider).tags, + ); // 4. 모든 작업 성공 시 처리 if (mounted) { - ref.invalidate(myProfileProvider); // 마이페이지 정보 갱신 + // ref.invalidate(myProfileProvider); // 마이페이지 정보 갱신 Navigator.pop(context); ScaffoldMessenger.of( context, @@ -287,9 +299,9 @@ class _ProfileEditScreenState extends ConsumerState { _selectedImageFile!, fit: BoxFit.cover, ) // 2순위: 새로 고름 - : widget.profile.profileImageUrl.isNotEmpty + : (widget.user.profileUrl ?? '').isNotEmpty ? Image.network( - widget.profile.profileImageUrl, + widget.user.profileUrl!, fit: BoxFit.cover, ) // 3순위: 기존 이미지 : SvgPicture.asset( diff --git a/lib/shared/models/user_detail.dart b/lib/shared/models/user_detail.dart new file mode 100644 index 0000000..1134a73 --- /dev/null +++ b/lib/shared/models/user_detail.dart @@ -0,0 +1,16 @@ +// 최초 작성자: 김채영 + +// 한줄소개, 태그 모델 +class UserDetail { + final String introduction; + final List tags; + + UserDetail({required this.introduction, required this.tags}); + + factory UserDetail.fromJson(Map json) { + return UserDetail( + introduction: json['introduction'] ?? '', + tags: List.from(json['tags'] ?? []), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 7b1c9a1..6be68a5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -697,10 +697,10 @@ packages: dependency: transitive description: name: google_sign_in_ios - sha256: ac1e4c1205267cb7999d1d81333fccffdfda29e853f434bbaf71525498bb6950 + sha256: "234fc2830b55d1bbeb7e05662967691f5994143ff43dc70d3f139d1bbb3b8fb2" url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "6.2.5" google_sign_in_platform_interface: dependency: transitive description: @@ -809,10 +809,10 @@ packages: dependency: transitive description: name: image_picker_ios - sha256: b9c4a438a9ff4f60808c9cf0039b93a42bb6c2211ef6ebb647394b2b3fa84588 + sha256: "956c16a42c0c708f914021666ffcd8265dde36e673c9fa68c81f7d085d9774ad" url: "https://pub.dev" source: hosted - version: "0.8.13+6" + version: "0.8.13+3" image_picker_linux: dependency: transitive description: @@ -1009,10 +1009,10 @@ packages: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.16.0" mime: dependency: transitive description: @@ -1398,10 +1398,10 @@ packages: dependency: transitive description: name: test_api - sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.7" + version: "0.7.6" timing: dependency: transitive description: @@ -1478,10 +1478,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f + sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.1" url_launcher_windows: dependency: transitive description: @@ -1635,5 +1635,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.10.0 <4.0.0" - flutter: ">=3.38.0" + dart: ">=3.9.2 <4.0.0" + flutter: ">=3.35.0" From 6276da65b3d43378bf0f34abe42d9e5701877dab Mon Sep 17 00:00:00 2001 From: Seungvin Date: Wed, 1 Apr 2026 23:44:18 +0900 Subject: [PATCH 084/134] =?UTF-8?q?fix:=20=EB=AA=A8=EB=8D=B8=EC=A0=95?= =?UTF-8?q?=EB=B9=84=20-=20id=20=ED=83=80=EC=9E=85=20int=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/feed/models/comment.dart | 6 +++--- lib/features/feed/models/post.dart | 6 +++--- pubspec.lock | 20 ++++++++++---------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/features/feed/models/comment.dart b/lib/features/feed/models/comment.dart index 7d1eaf1..a66761b 100644 --- a/lib/features/feed/models/comment.dart +++ b/lib/features/feed/models/comment.dart @@ -4,7 +4,7 @@ import 'package:haenaem/shared/models/user.dart'; // 댓글 모델 클래스 // User에 정의된 필드(id, profileUrl, nickname)를 작성자 정보로 재사용 class Comment { - final String id; // 댓글 id + final int id; // 댓글 id final String content; // 댓글 내용 final DateTime date; // 초기 댓글 작성 날짜 final bool isEdited; // 댓글 수정 여부 @@ -20,7 +20,7 @@ class Comment { factory Comment.fromJson(Map json) { return Comment( - id: json['id'] as String, + id: json['id'] as int, content: json['content'] as String, date: DateTime.parse(json['date'] as String), isEdited: json['is_edited'] as bool, @@ -29,7 +29,7 @@ class Comment { } Comment copyWith({ - String? id, + int? id, String? content, DateTime? date, bool? isEdited, diff --git a/lib/features/feed/models/post.dart b/lib/features/feed/models/post.dart index e6c4055..f7a6979 100644 --- a/lib/features/feed/models/post.dart +++ b/lib/features/feed/models/post.dart @@ -4,7 +4,7 @@ import 'package:haenaem/shared/models/user.dart'; // 인증글 모델 클래스 // User에 정의된 필드(id, profileUrl, nickname)를 작성자 정보로 재사용 class Post { - final String id; // 인증글 id + final int id; // 인증글 id final String title; // 인증글 제목 final String content; // 인증글 내용 final String? pictureUrl; // 인증글 사진 주소 @@ -28,7 +28,7 @@ class Post { factory Post.fromJson(Map json) { return Post( - id: json['id'] as String, + id: json['id'] as int, title: json['title'] as String, content: json['content'] as String, pictureUrl: json['picture_url'] as String?, @@ -41,7 +41,7 @@ class Post { } Post copyWith({ - String? id, + int? id, String? title, String? content, String? pictureUrl, diff --git a/pubspec.lock b/pubspec.lock index 6be68a5..a9aacd6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -245,10 +245,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" checked_yaml: dependency: transitive description: @@ -993,26 +993,26 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.18" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.13.0" meta: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" mime: dependency: transitive description: @@ -1398,10 +1398,10 @@ packages: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" url: "https://pub.dev" source: hosted - version: "0.7.6" + version: "0.7.9" timing: dependency: transitive description: From 35827de769668db07639744b3b2476db98e37898 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 2 Apr 2026 00:01:52 +0900 Subject: [PATCH 085/134] =?UTF-8?q?feat:=20refactor=20=EB=B8=8C=EB=9E=9C?= =?UTF-8?q?=EC=B9=98=20=ED=92=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pubspec.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 6be68a5..a0a2f92 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1009,10 +1009,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" mime: dependency: transitive description: @@ -1398,10 +1398,10 @@ packages: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 url: "https://pub.dev" source: hosted - version: "0.7.6" + version: "0.7.7" timing: dependency: transitive description: From b826a112039153babb9317009eb5bc27c9f55af8 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Thu, 2 Apr 2026 01:14:03 +0900 Subject: [PATCH 086/134] =?UTF-8?q?fix:=20json=EC=97=90=20=EB=A7=9E?= =?UTF-8?q?=EA=B2=8C=20=EB=AA=A8=EB=8D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/feed/models/comment.dart | 32 ++++++++--- lib/features/feed/models/post.dart | 76 ++++++++++++++++++++++----- 2 files changed, 90 insertions(+), 18 deletions(-) diff --git a/lib/features/feed/models/comment.dart b/lib/features/feed/models/comment.dart index a66761b..93d9d21 100644 --- a/lib/features/feed/models/comment.dart +++ b/lib/features/feed/models/comment.dart @@ -6,9 +6,10 @@ import 'package:haenaem/shared/models/user.dart'; class Comment { final int id; // 댓글 id final String content; // 댓글 내용 - final DateTime date; // 초기 댓글 작성 날짜 + final DateTime date; // 댓글 작성(또는 수정) 날짜 final bool isEdited; // 댓글 수정 여부 final User writer; // 작성자 정보 (id, profileUrl, nickname) + final bool isMine; // 현재 로그인 유저의 댓글 여부 const Comment({ required this.id, @@ -16,15 +17,32 @@ class Comment { required this.date, required this.isEdited, required this.writer, + required this.isMine, }); factory Comment.fromJson(Map json) { + // 1. 날짜 파싱: 기존 모델의 로직을 참고하여 updatedAt 우선, 없으면 createdAt 사용 + DateTime parsedDate = DateTime.now(); + if (json['updatedAt'] != null) { + parsedDate = DateTime.parse(json['updatedAt'].toString()).toLocal(); + } else if (json['createdAt'] != null) { + parsedDate = DateTime.parse(json['createdAt'].toString()).toLocal(); + } + + // 2. 작성자 정보 조립: 서버의 평면적 데이터를 Nested User 객체로 매핑 + final writer = User( + id: json['userId'] ?? 0, + nickname: json['userNickname'] ?? '익명', // 기존 로직 참고하여 기본값 '익명' 부여 + profileUrl: json['userPicture'], + ); + return Comment( - id: json['id'] as int, - content: json['content'] as String, - date: DateTime.parse(json['date'] as String), - isEdited: json['is_edited'] as bool, - writer: User.fromJson(json['writer'] as Map), + id: json['commentId'] ?? 0, // id -> commentId + content: json['contents'] ?? '', // content -> contents + date: parsedDate, + isEdited: json['edited'] ?? false, // is_edited -> edited + writer: writer, + isMine: json['mine'] ?? false, // is_mine -> mine ); } @@ -34,6 +52,7 @@ class Comment { DateTime? date, bool? isEdited, User? writer, + bool? isMine, }) { return Comment( id: id ?? this.id, @@ -41,6 +60,7 @@ class Comment { date: date ?? this.date, isEdited: isEdited ?? this.isEdited, writer: writer ?? this.writer, + isMine: isMine ?? this.isMine, ); } } diff --git a/lib/features/feed/models/post.dart b/lib/features/feed/models/post.dart index f7a6979..c607ed3 100644 --- a/lib/features/feed/models/post.dart +++ b/lib/features/feed/models/post.dart @@ -1,4 +1,5 @@ import 'package:haenaem/shared/models/user.dart'; +import 'package:haenaem/features/challenge/models/image_model.dart'; // 최초 작성자: 강선욱 // 인증글 모델 클래스 @@ -7,36 +8,77 @@ class Post { final int id; // 인증글 id final String title; // 인증글 제목 final String content; // 인증글 내용 - final String? pictureUrl; // 인증글 사진 주소 + final List pictureUrl; // 인증글 사진 URL 리스트 final int likeCount; // 좋아요 수 final bool isLiked; // 현재 로그인 유저의 좋아요 여부 final int commentCount; // 댓글 수 final DateTime date; // 작성 날짜 final User writer; // 작성자 정보 (id, profileUrl, nickname) + final int challengeId; // 챌린지 id + final String challengeTitle; // 챌린지 제목 + final int totalSuccessDays; // 챌린지 총 성공 일수 + + final bool isAuthor; // 작성자 본인 여부 (수정/삭제 권한) + final bool isEdited; // 수정된 게시글 여부 + + // 편의 메서드: 사진이 있는지 여부와 첫 번째 사진 URL을 쉽게 접근할 수 있도록 합니다. + bool get hasImage => pictureUrl.isNotEmpty; + // 첫 번째 사진 URL을 반환하는 편의 메서드입니다. 사진이 없으면 null을 반환합니다. + String? get imageUrl => + pictureUrl.isNotEmpty ? pictureUrl.first.imageUrl : null; const Post({ required this.id, required this.title, required this.content, - this.pictureUrl, + required this.pictureUrl, required this.likeCount, required this.isLiked, required this.commentCount, required this.date, required this.writer, + required this.challengeId, + required this.challengeTitle, + required this.totalSuccessDays, + required this.isAuthor, + required this.isEdited, }); factory Post.fromJson(Map json) { + // 1. 날짜 파싱: updatedAt이 있으면 우선 사용하고, 없으면 createdAt 사용 + DateTime parsedDate = DateTime.now(); + if (json['updatedAt'] != null) { + parsedDate = DateTime.parse(json['updatedAt'].toString()).toLocal(); + } else if (json['createdAt'] != null) { + parsedDate = DateTime.parse(json['createdAt'].toString()).toLocal(); + } + + // 2. 작성자 정보 조립: 서버의 평면적 데이터를 Nested User 객체로 매핑 + final writer = User( + id: json['userId'] ?? 0, + nickname: json['userNickname'] ?? '익명', + profileUrl: json['userImageUrl'], + ); + return Post( - id: json['id'] as int, - title: json['title'] as String, - content: json['content'] as String, - pictureUrl: json['picture_url'] as String?, - likeCount: json['like_count'] as int, - isLiked: json['is_liked'] as bool, - commentCount: json['comment_count'] as int, - date: DateTime.parse(json['date'] as String), - writer: User.fromJson(json['writer'] as Map), + id: json['postId'] ?? 0, + challengeId: json['challengeId'] ?? 0, + challengeTitle: json['challengeTitle'] ?? '', + totalSuccessDays: json['totalSuccessDays'] ?? 0, + title: json['title'] ?? '', + content: json['content'] ?? '', + pictureUrl: + (json['images'] as List?) + ?.map((e) => PostImage.fromJson(e as Map)) + .toList() ?? + const [], + likeCount: json['likeNumber'] ?? 0, + isLiked: json['liked'] ?? false, + commentCount: json['commentNumber'] ?? 0, + date: parsedDate, + writer: writer, + isAuthor: json['author'] ?? false, + isEdited: json['edited'] ?? false, ); } @@ -44,12 +86,17 @@ class Post { int? id, String? title, String? content, - String? pictureUrl, + List? pictureUrl, int? likeCount, bool? isLiked, int? commentCount, DateTime? date, User? writer, + int? challengeId, + String? challengeTitle, + int? totalSuccessDays, + bool? isAuthor, + bool? isEdited, }) { return Post( id: id ?? this.id, @@ -61,6 +108,11 @@ class Post { commentCount: commentCount ?? this.commentCount, date: date ?? this.date, writer: writer ?? this.writer, + challengeId: challengeId ?? this.challengeId, + challengeTitle: challengeTitle ?? this.challengeTitle, + totalSuccessDays: totalSuccessDays ?? this.totalSuccessDays, + isAuthor: isAuthor ?? this.isAuthor, + isEdited: isEdited ?? this.isEdited, ); } } From 1800b6f6c04d29e33dfaa9e977576c9914a32d2e Mon Sep 17 00:00:00 2001 From: Seungvin Date: Thu, 2 Apr 2026 01:15:24 +0900 Subject: [PATCH 087/134] =?UTF-8?q?fix:=20=EC=83=88=20=ED=94=BC=EB=93=9C?= =?UTF-8?q?=20=EB=AA=A8=EB=8D=B8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/feed/data/feed_repository.dart | 7 ++++--- lib/features/feed/models/feed_model.dart | 7 ++++--- lib/features/feed/provider/feed_provider.dart | 20 +++++++++---------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/lib/features/feed/data/feed_repository.dart b/lib/features/feed/data/feed_repository.dart index 5552a96..e8bd585 100644 --- a/lib/features/feed/data/feed_repository.dart +++ b/lib/features/feed/data/feed_repository.dart @@ -1,5 +1,6 @@ import 'package:dio/dio.dart'; -import 'package:haenaem/features/challenge/models/challenge_model.dart'; +//import 'package:haenaem/features/challenge/models/challenge_model.dart'; +import 'package:haenaem/features/feed/models/post.dart'; class FeedRepository { final Dio _dio; @@ -18,10 +19,10 @@ class FeedRepository { if (response.statusCode == 200) { final List content = response.data['content'] ?? []; - final List posts = []; + final List posts = []; for (var item in content) { try { - posts.add(CertificationPostModel.fromJson(item)); + posts.add(Post.fromJson(item)); } catch (e) { print("⚠️ 특정 포스트 파싱 실패 (ID: ${item['postId']}): $e"); // 에러가 난 포스트는 건너뜁니다. diff --git a/lib/features/feed/models/feed_model.dart b/lib/features/feed/models/feed_model.dart index 6d96db7..c79906d 100644 --- a/lib/features/feed/models/feed_model.dart +++ b/lib/features/feed/models/feed_model.dart @@ -1,9 +1,10 @@ -import 'package:haenaem/features/challenge/models/challenge_model.dart'; +//import 'package:haenaem/features/challenge/models/challenge_model.dart'; +import 'package:haenaem/features/feed/models/post.dart'; // 피드 상태를 관리하는 클래스 // 로딩 상태, 에러 상태 관리 class FeedState { - final List posts; + final List posts; final bool isLoading; final String? errorMessage; final int currentPage; // 현재 페이지 번호 @@ -18,7 +19,7 @@ class FeedState { }); FeedState copyWith({ - List? posts, + List? posts, bool? isLoading, String? errorMessage, int? currentPage, diff --git a/lib/features/feed/provider/feed_provider.dart b/lib/features/feed/provider/feed_provider.dart index 014e6be..25eb7ba 100644 --- a/lib/features/feed/provider/feed_provider.dart +++ b/lib/features/feed/provider/feed_provider.dart @@ -117,8 +117,8 @@ class FeedNotifier extends StateNotifier { // 좋아요 상태 변경 메서드 Future toggleLike(int postId) async { // 1. 상태 변경 전, 현재 해당 포스트의 좋아요 여부를 확인합니다. - final post = state.posts.firstWhere((p) => p.postId == postId); - final wasLiked = post.liked; + final post = state.posts.firstWhere((p) => p.id == postId); + final wasLiked = post.isLiked; // 2. 로컬 UI 즉시 변경 (Optimistic Update) toggleLikeLocally(postId); @@ -136,11 +136,11 @@ class FeedNotifier extends StateNotifier { void toggleLikeLocally(int postId) { state = state.copyWith( posts: state.posts.map((post) { - if (post.postId == postId) { - final isLiked = post.liked; + if (post.id == postId) { + final isLiked = post.isLiked; return post.copyWith( - liked: !isLiked, - likeNumber: isLiked ? post.likeNumber - 1 : post.likeNumber + 1, + isLiked: !isLiked, + likeCount: isLiked ? post.likeCount - 1 : post.likeCount + 1, ); } return post; @@ -151,9 +151,9 @@ class FeedNotifier extends StateNotifier { void incrementCommentCountLocally(int postId) { state = state.copyWith( posts: state.posts.map((post) { - if (post.postId == postId) { + if (post.id == postId) { // 기존 post를 복사하면서 commentNumber만 1 증가시킴 - return post.copyWith(commentNumber: post.commentNumber + 1); + return post.copyWith(commentCount: post.commentCount + 1); } return post; }).toList(), @@ -163,10 +163,10 @@ class FeedNotifier extends StateNotifier { void decrementCommentCountLocally(int postId) { state = state.copyWith( posts: state.posts.map((post) { - if (post.postId == postId) { + if (post.id == postId) { return post.copyWith( // 💡 0보다 작아지지 않도록 처리하면서 -1 - commentNumber: post.commentNumber > 0 ? post.commentNumber - 1 : 0, + commentCount: post.commentCount > 0 ? post.commentCount - 1 : 0, ); } return post; From 1bbbb129d9b2cdedd6ecb9f8e5c84db38a52ffb9 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Thu, 2 Apr 2026 01:18:04 +0900 Subject: [PATCH 088/134] =?UTF-8?q?fix:=20=ED=94=BC=EB=93=9C=20=ED=8F=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B9=B4=EB=93=9C=20=ED=82=A4=EA=B0=92=20?= =?UTF-8?q?=EC=83=88=20=EB=AA=A8=EB=8D=B8=EB=A1=9C=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/feed/views/share_feed_view.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/features/feed/views/share_feed_view.dart b/lib/features/feed/views/share_feed_view.dart index baccab0..a3da5bb 100644 --- a/lib/features/feed/views/share_feed_view.dart +++ b/lib/features/feed/views/share_feed_view.dart @@ -108,7 +108,7 @@ class _ShareFeedViewState extends ConsumerState return FeedPostCard( key: ValueKey( - '${feedState.posts[index].postId}_${feedState.posts[index].liked}_${feedState.posts[index].likeNumber}_${feedState.posts[index].commentNumber}', + '${feedState.posts[index].id}_${feedState.posts[index].isLiked}_${feedState.posts[index].likeCount}_${feedState.posts[index].commentCount}', ), post: feedState.posts[index], provider: widget.provider, From 1bcd6a00fdf88da59e3eb900f41c597a173bee9d Mon Sep 17 00:00:00 2001 From: Seungvin Date: Thu, 2 Apr 2026 01:55:07 +0900 Subject: [PATCH 089/134] =?UTF-8?q?fix:=20=ED=94=BC=EB=93=9C=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EB=A0=88=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC,=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=EB=B0=94=EC=9D=B4=EB=8D=94=20=EC=B1=8C?= =?UTF-8?q?=EB=A6=B0=EC=A7=80=EC=97=90=EC=84=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/feed/data/feed_repository.dart | 169 +++++++++++++ .../feed/provider/comment_provider.dart | 104 ++++++++ .../feed/provider/comment_provider.g.dart | 224 ++++++++++++++++++ .../feed/provider/post_detail_provider.dart | 124 ++++++++++ .../feed/provider/post_detail_provider.g.dart | 216 +++++++++++++++++ 5 files changed, 837 insertions(+) create mode 100644 lib/features/feed/provider/comment_provider.dart create mode 100644 lib/features/feed/provider/comment_provider.g.dart create mode 100644 lib/features/feed/provider/post_detail_provider.dart create mode 100644 lib/features/feed/provider/post_detail_provider.g.dart diff --git a/lib/features/feed/data/feed_repository.dart b/lib/features/feed/data/feed_repository.dart index e8bd585..ecf10a3 100644 --- a/lib/features/feed/data/feed_repository.dart +++ b/lib/features/feed/data/feed_repository.dart @@ -1,6 +1,8 @@ import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; //import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/feed/models/post.dart'; +import 'package:haenaem/features/feed/models/comment.dart'; class FeedRepository { final Dio _dio; @@ -62,4 +64,171 @@ class FeedRepository { rethrow; } } + + // 인증글 상세 정보 가져오기 + Future getArticleDetail(int postId) async { + try { + debugPrint('🚀 [GET Request] /api/articles/$postId'); + final response = await _dio.get('/api/articles/$postId'); + + if (response.statusCode == 200) { + debugPrint('📥 상세조회 서버 응답 원본: ${response.data}'); + return Post.fromJson(response.data); + } else { + throw Exception('인증글 상세 조회 실패'); + } + } on DioException catch (e) { + debugPrint('❌ 상세 조회 에러: ${e.response?.data}'); + throw Exception('정보를 불러오지 못했습니다.'); + } + } + + // 인증글 생성 + Future createArticle({ + required int challengeId, + required String content, + required List tempImageIds, + }) async { + try { + final response = await _dio.post( + '/api/articles', + data: { + "content": content, + "challengeId": challengeId, + "tempImageIds": tempImageIds, + }, + ); + + if (response.statusCode == 201) { + return Post.fromJson(response.data); + } else { + throw Exception('인증글 생성 실패: ${response.statusCode}'); + } + } on DioException catch (e) { + debugPrint('❌ 인증글 생성 에러: ${e.response?.data}'); + throw Exception(e.response?.data['message'] ?? '게시글 업로드 실패'); + } + } + + // 인증글 수정 + Future updateArticle({ + required int postId, + required String content, + required List deleteImageIds, + required List tempImageIds, + }) async { + try { + final response = await _dio.patch( + '/api/articles/$postId', + data: { + "content": content, + "deleteImageIds": deleteImageIds, + "tempImageIds": tempImageIds, + }, + ); + if (response.statusCode == 200) { + debugPrint('✅ 인증글 수정 성공: ${response.data}'); + return Post.fromJson(response.data); + } else { + throw Exception('수정 실패: ${response.statusCode}'); + } + } on DioException catch (e) { + debugPrint('❌ 수정 에러 상세: ${e.response?.data}'); + throw Exception(e.response?.data?['message'] ?? '수정 중 오류 발생'); + } + } + + // 인증글 삭제 + Future deleteArticle(int postId) async { + try { + debugPrint('🚀 [DELETE Request] /api/articles/$postId'); + final response = await _dio.delete('/api/articles/$postId'); + + if (response.statusCode != 204 && response.statusCode != 200) { + throw Exception('삭제 실패 (Status: ${response.statusCode})'); + } + debugPrint('✅ 인증글 삭제 성공'); + } on DioException catch (e) { + debugPrint('❌ 인증글 삭제 에러: ${e.response?.data}'); + throw Exception(e.response?.data['message'] ?? '삭제 중 오류가 발생했습니다.'); + } + } + + // 댓글 목록 조회 + Future> getComments({required int postId, int page = 0}) async { + try { + final response = await _dio.get( + '/api/articles/$postId/comments', + queryParameters: {'page': page}, + ); + + if (response.statusCode == 200) { + final List content = response.data['content'] ?? []; + return content.map((json) => Comment.fromJson(json)).toList(); + } else { + throw Exception('댓글 목록 조회 실패'); + } + } on DioException catch (e) { + debugPrint('❌ 댓글 조회 에러: ${e.response?.data}'); + throw Exception('댓글을 불러오는 중 오류가 발생했습니다.'); + } + } + + // 댓글 생성 + Future createComment({ + required int postId, + required String contents, + }) async { + try { + final response = await _dio.post( + '/api/articles/$postId/comments', + data: {"contents": contents}, + ); + + if (response.statusCode != 201) { + throw Exception('댓글 생성 실패 (Status: ${response.statusCode})'); + } + } on DioException catch (e) { + debugPrint('❌ 댓글 생성 에러: ${e.response?.data}'); + throw Exception(e.response?.data['message'] ?? '댓글 작성 중 오류가 발생했습니다.'); + } + } + + // 댓글 수정 + Future updateComment({ + required int commentId, + required String contents, + }) async { + try { + debugPrint('🚀 [PATCH Request] /api/comments/$commentId'); + final response = await _dio.patch( + '/api/comments/$commentId', + data: {"contents": contents}, + ); + + if (response.statusCode != 204 && response.statusCode != 200) { + throw Exception('댓글 수정 실패 (Status: ${response.statusCode})'); + } + debugPrint('✅ 댓글 수정 성공'); + } on DioException catch (e) { + debugPrint('❌ 댓글 수정 에러: ${e.response?.data}'); + throw Exception(e.response?.data['message'] ?? '댓글 수정 중 오류가 발생했습니다.'); + } + } + + // 댓글 삭제 + Future deleteComment(int commentId) async { + try { + debugPrint('🚀 [DELETE Request] /api/comments/$commentId'); + final response = await _dio.delete('/api/comments/$commentId'); + + if (response.statusCode != 204 && response.statusCode != 200) { + throw Exception('댓글 삭제 실패 (Status: ${response.statusCode})'); + } + debugPrint('✅ 댓글 삭제 성공'); + } on DioException catch (e) { + debugPrint('❌ 댓글 삭제 에러: ${e.response?.data}'); + throw Exception(e.response?.data['message'] ?? '댓글 삭제 중 오류가 발생했습니다.'); + } + } } diff --git a/lib/features/feed/provider/comment_provider.dart b/lib/features/feed/provider/comment_provider.dart new file mode 100644 index 0000000..350e798 --- /dev/null +++ b/lib/features/feed/provider/comment_provider.dart @@ -0,0 +1,104 @@ +// 최초 작성자: 정승빈 (분리 및 리팩토링) +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:haenaem/features/feed/models/comment.dart'; +import 'package:haenaem/features/feed/provider/feed_provider.dart'; +// 💡 상세 정보 새로고침을 위해 post_detail_provider 임포트 필요 +import 'package:haenaem/features/feed/provider/post_detail_provider.dart'; + +part 'comment_provider.g.dart'; + +// 1. 댓글 목록 불러오기 로직 +@riverpod +Future> postComments( + // 💡 articleComments -> postComments, 타입 Comment로 변경 + PostCommentsRef ref, { + required int postId, + int page = 0, +}) async { + final repository = ref.watch(feedRepositoryProvider); + return repository.getComments(postId: postId, page: page); +} + +// 2. 댓글 생성 로직 +@riverpod +class CommentCreateNotifier extends _$CommentCreateNotifier { + @override + AsyncValue build() => const AsyncValue.data(null); + + Future addComment({ + required int postId, + required String contents, + }) async { + state = const AsyncValue.loading(); + + final result = await AsyncValue.guard( + () => ref + .read(feedRepositoryProvider) + .createComment(postId: postId, contents: contents), + ); + + if (!result.hasError) { + // 💡 댓글 목록 및 게시글 상세 정보 새로고침 + ref.invalidate(postCommentsProvider(postId: postId)); + ref.invalidate(postDetailProvider(postId: postId)); + } + + state = result; + return !result.hasError; + } +} + +// 3. 댓글 수정 로직 +@riverpod +class CommentUpdateNotifier extends _$CommentUpdateNotifier { + @override + AsyncValue build() => const AsyncValue.data(null); + + Future editComment({ + required int postId, + required int commentId, + required String contents, + }) async { + state = const AsyncValue.loading(); + + final result = await AsyncValue.guard( + () => ref + .read(feedRepositoryProvider) + .updateComment(commentId: commentId, contents: contents), + ); + + if (!result.hasError) { + ref.invalidate(postCommentsProvider(postId: postId)); + } + + state = result; + return !result.hasError; + } +} + +// 4. 댓글 삭제 로직 +@riverpod +class CommentDeleteNotifier extends _$CommentDeleteNotifier { + @override + AsyncValue build() => const AsyncValue.data(null); + + Future removeComment({ + required int postId, + required int commentId, + }) async { + state = const AsyncValue.loading(); + + final result = await AsyncValue.guard( + () => ref.read(feedRepositoryProvider).deleteComment(commentId), + ); + + if (!result.hasError) { + // 💡 댓글 목록 및 게시글 상세 정보 새로고침 + ref.invalidate(postCommentsProvider(postId: postId)); + ref.invalidate(postDetailProvider(postId: postId)); + } + + state = result; + return !result.hasError; + } +} diff --git a/lib/features/feed/provider/comment_provider.g.dart b/lib/features/feed/provider/comment_provider.g.dart new file mode 100644 index 0000000..1105e56 --- /dev/null +++ b/lib/features/feed/provider/comment_provider.g.dart @@ -0,0 +1,224 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'comment_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$postCommentsHash() => r'078468e7edde7672d4d1e91472df38af619eb8b7'; + +/// Copied from Dart SDK +class _SystemHash { + _SystemHash._(); + + static int combine(int hash, int value) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + value); + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); + return hash ^ (hash >> 6); + } + + static int finish(int hash) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); + // ignore: parameter_assignments + hash = hash ^ (hash >> 11); + return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); + } +} + +/// See also [postComments]. +@ProviderFor(postComments) +const postCommentsProvider = PostCommentsFamily(); + +/// See also [postComments]. +class PostCommentsFamily extends Family>> { + /// See also [postComments]. + const PostCommentsFamily(); + + /// See also [postComments]. + PostCommentsProvider call({required int postId, int page = 0}) { + return PostCommentsProvider(postId: postId, page: page); + } + + @override + PostCommentsProvider getProviderOverride( + covariant PostCommentsProvider provider, + ) { + return call(postId: provider.postId, page: provider.page); + } + + static const Iterable? _dependencies = null; + + @override + Iterable? get dependencies => _dependencies; + + static const Iterable? _allTransitiveDependencies = null; + + @override + Iterable? get allTransitiveDependencies => + _allTransitiveDependencies; + + @override + String? get name => r'postCommentsProvider'; +} + +/// See also [postComments]. +class PostCommentsProvider extends AutoDisposeFutureProvider> { + /// See also [postComments]. + PostCommentsProvider({required int postId, int page = 0}) + : this._internal( + (ref) => + postComments(ref as PostCommentsRef, postId: postId, page: page), + from: postCommentsProvider, + name: r'postCommentsProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$postCommentsHash, + dependencies: PostCommentsFamily._dependencies, + allTransitiveDependencies: + PostCommentsFamily._allTransitiveDependencies, + postId: postId, + page: page, + ); + + PostCommentsProvider._internal( + super._createNotifier, { + required super.name, + required super.dependencies, + required super.allTransitiveDependencies, + required super.debugGetCreateSourceHash, + required super.from, + required this.postId, + required this.page, + }) : super.internal(); + + final int postId; + final int page; + + @override + Override overrideWith( + FutureOr> Function(PostCommentsRef provider) create, + ) { + return ProviderOverride( + origin: this, + override: PostCommentsProvider._internal( + (ref) => create(ref as PostCommentsRef), + from: from, + name: null, + dependencies: null, + allTransitiveDependencies: null, + debugGetCreateSourceHash: null, + postId: postId, + page: page, + ), + ); + } + + @override + AutoDisposeFutureProviderElement> createElement() { + return _PostCommentsProviderElement(this); + } + + @override + bool operator ==(Object other) { + return other is PostCommentsProvider && + other.postId == postId && + other.page == page; + } + + @override + int get hashCode { + var hash = _SystemHash.combine(0, runtimeType.hashCode); + hash = _SystemHash.combine(hash, postId.hashCode); + hash = _SystemHash.combine(hash, page.hashCode); + + return _SystemHash.finish(hash); + } +} + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +mixin PostCommentsRef on AutoDisposeFutureProviderRef> { + /// The parameter `postId` of this provider. + int get postId; + + /// The parameter `page` of this provider. + int get page; +} + +class _PostCommentsProviderElement + extends AutoDisposeFutureProviderElement> + with PostCommentsRef { + _PostCommentsProviderElement(super.provider); + + @override + int get postId => (origin as PostCommentsProvider).postId; + @override + int get page => (origin as PostCommentsProvider).page; +} + +String _$commentCreateNotifierHash() => + r'c125a85e3dd166344703c77d2e7992c53fb9154a'; + +/// See also [CommentCreateNotifier]. +@ProviderFor(CommentCreateNotifier) +final commentCreateNotifierProvider = + AutoDisposeNotifierProvider< + CommentCreateNotifier, + AsyncValue + >.internal( + CommentCreateNotifier.new, + name: r'commentCreateNotifierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$commentCreateNotifierHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$CommentCreateNotifier = AutoDisposeNotifier>; +String _$commentUpdateNotifierHash() => + r'24745c04e7d1a4e433fd6df4ef4a55c70158f6cd'; + +/// See also [CommentUpdateNotifier]. +@ProviderFor(CommentUpdateNotifier) +final commentUpdateNotifierProvider = + AutoDisposeNotifierProvider< + CommentUpdateNotifier, + AsyncValue + >.internal( + CommentUpdateNotifier.new, + name: r'commentUpdateNotifierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$commentUpdateNotifierHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$CommentUpdateNotifier = AutoDisposeNotifier>; +String _$commentDeleteNotifierHash() => + r'25843072cf5f2a8d4461ca80c8746909cfe46261'; + +/// See also [CommentDeleteNotifier]. +@ProviderFor(CommentDeleteNotifier) +final commentDeleteNotifierProvider = + AutoDisposeNotifierProvider< + CommentDeleteNotifier, + AsyncValue + >.internal( + CommentDeleteNotifier.new, + name: r'commentDeleteNotifierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$commentDeleteNotifierHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$CommentDeleteNotifier = AutoDisposeNotifier>; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/feed/provider/post_detail_provider.dart b/lib/features/feed/provider/post_detail_provider.dart new file mode 100644 index 0000000..136e977 --- /dev/null +++ b/lib/features/feed/provider/post_detail_provider.dart @@ -0,0 +1,124 @@ +// 최초 작성자: 정승빈 (분리 및 리팩토링) +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:haenaem/features/feed/models/post.dart'; +// 💡 FeedRepository가 있는 경로를 임포트해주세요. (feed_provider.dart 내부에 있다면 해당 파일 임포트) +import 'package:haenaem/features/feed/provider/feed_provider.dart'; + +part 'post_detail_provider.g.dart'; + +// 1. 인증글 상세 정보 가져오기 로직 +@riverpod +Future postDetail( + // 💡 articleDetail -> postDetail로 변경, 타입 Post로 변경 + PostDetailRef ref, { + required int postId, +}) async { + final repository = ref.watch( + feedRepositoryProvider, + ); // 💡 challenge -> feed 레포지토리로 변경 + return repository.getArticleDetail(postId); +} + +// 2. 인증글 생성 로직 +@riverpod +class PostCreateNotifier extends _$PostCreateNotifier { + @override + AsyncValue build() => const AsyncValue.data(null); // 💡 타입 Post로 변경 + + Future submitArticle({ + required int challengeId, + required String content, + required List tempImageIds, + }) async { + state = const AsyncValue.loading(); + + final result = await AsyncValue.guard( + () => ref + .read(feedRepositoryProvider) + .createArticle( + challengeId: challengeId, + content: content, + tempImageIds: tempImageIds, + ), + ); + + state = result; + return !result.hasError; + } +} + +// 3. 인증글 수정 로직 +@riverpod +class PostUpdateNotifier extends _$PostUpdateNotifier { + @override + AsyncValue build() => const AsyncValue.data(null); // 💡 타입 Post로 변경 + + Future editArticle({ + required int postId, + required String content, + List deleteImageIds = const [], + List tempImageIds = const [], + }) async { + state = const AsyncValue.loading(); + + final result = await AsyncValue.guard( + () => ref + .read(feedRepositoryProvider) + .updateArticle( + postId: postId, + content: content, + deleteImageIds: deleteImageIds, + tempImageIds: tempImageIds, + ), + ); + + if (!result.hasError) { + // 💡 수정 완료 후 상세 페이지 무효화(새로고침) + ref.invalidate(postDetailProvider(postId: postId)); + //ref.invalidate(challengePostsProvider); // 필요하다면 챌린지 피드도 무효화하여 목록 갱신 + } + + state = result; + return !result.hasError; + } +} + +// 4. 인증글 삭제 로직 +@riverpod +class PostDeleteNotifier extends _$PostDeleteNotifier { + @override + AsyncValue build() => const AsyncValue.data(null); + + Future removeArticle(int postId) async { + state = const AsyncValue.loading(); + + final result = await AsyncValue.guard( + () => ref.read(feedRepositoryProvider).deleteArticle(postId), + ); + + state = result; + return !result.hasError; + } +} + +// 5. 좋아요 로직 +@riverpod +class PostLikeNotifier extends _$PostLikeNotifier { + @override + AsyncValue build() => const AsyncValue.data(null); + + Future toggleLike({ + required int postId, + required bool isCurrentlyLiked, + }) async { + final result = await AsyncValue.guard( + () => + ref.read(feedRepositoryProvider).toggleLike(postId, isCurrentlyLiked), + ); + + if (!result.hasError) { + // 💡 성공 시 해당 게시글 상세 데이터 무효화 -> 화면 자동 갱신 + ref.invalidate(postDetailProvider(postId: postId)); + } + } +} diff --git a/lib/features/feed/provider/post_detail_provider.g.dart b/lib/features/feed/provider/post_detail_provider.g.dart new file mode 100644 index 0000000..acf954c --- /dev/null +++ b/lib/features/feed/provider/post_detail_provider.g.dart @@ -0,0 +1,216 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'post_detail_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$postDetailHash() => r'4c7ecb10d1517df7f808b4645bd6cc6047aab5c6'; + +/// Copied from Dart SDK +class _SystemHash { + _SystemHash._(); + + static int combine(int hash, int value) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + value); + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); + return hash ^ (hash >> 6); + } + + static int finish(int hash) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); + // ignore: parameter_assignments + hash = hash ^ (hash >> 11); + return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); + } +} + +/// See also [postDetail]. +@ProviderFor(postDetail) +const postDetailProvider = PostDetailFamily(); + +/// See also [postDetail]. +class PostDetailFamily extends Family> { + /// See also [postDetail]. + const PostDetailFamily(); + + /// See also [postDetail]. + PostDetailProvider call({required int postId}) { + return PostDetailProvider(postId: postId); + } + + @override + PostDetailProvider getProviderOverride( + covariant PostDetailProvider provider, + ) { + return call(postId: provider.postId); + } + + static const Iterable? _dependencies = null; + + @override + Iterable? get dependencies => _dependencies; + + static const Iterable? _allTransitiveDependencies = null; + + @override + Iterable? get allTransitiveDependencies => + _allTransitiveDependencies; + + @override + String? get name => r'postDetailProvider'; +} + +/// See also [postDetail]. +class PostDetailProvider extends AutoDisposeFutureProvider { + /// See also [postDetail]. + PostDetailProvider({required int postId}) + : this._internal( + (ref) => postDetail(ref as PostDetailRef, postId: postId), + from: postDetailProvider, + name: r'postDetailProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$postDetailHash, + dependencies: PostDetailFamily._dependencies, + allTransitiveDependencies: PostDetailFamily._allTransitiveDependencies, + postId: postId, + ); + + PostDetailProvider._internal( + super._createNotifier, { + required super.name, + required super.dependencies, + required super.allTransitiveDependencies, + required super.debugGetCreateSourceHash, + required super.from, + required this.postId, + }) : super.internal(); + + final int postId; + + @override + Override overrideWith( + FutureOr Function(PostDetailRef provider) create, + ) { + return ProviderOverride( + origin: this, + override: PostDetailProvider._internal( + (ref) => create(ref as PostDetailRef), + from: from, + name: null, + dependencies: null, + allTransitiveDependencies: null, + debugGetCreateSourceHash: null, + postId: postId, + ), + ); + } + + @override + AutoDisposeFutureProviderElement createElement() { + return _PostDetailProviderElement(this); + } + + @override + bool operator ==(Object other) { + return other is PostDetailProvider && other.postId == postId; + } + + @override + int get hashCode { + var hash = _SystemHash.combine(0, runtimeType.hashCode); + hash = _SystemHash.combine(hash, postId.hashCode); + + return _SystemHash.finish(hash); + } +} + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +mixin PostDetailRef on AutoDisposeFutureProviderRef { + /// The parameter `postId` of this provider. + int get postId; +} + +class _PostDetailProviderElement extends AutoDisposeFutureProviderElement + with PostDetailRef { + _PostDetailProviderElement(super.provider); + + @override + int get postId => (origin as PostDetailProvider).postId; +} + +String _$postCreateNotifierHash() => + r'2d9392f118e628a9ab3f16ecd2d524fbf17e99bd'; + +/// See also [PostCreateNotifier]. +@ProviderFor(PostCreateNotifier) +final postCreateNotifierProvider = + AutoDisposeNotifierProvider>.internal( + PostCreateNotifier.new, + name: r'postCreateNotifierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$postCreateNotifierHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$PostCreateNotifier = AutoDisposeNotifier>; +String _$postUpdateNotifierHash() => + r'ffadccd22bb2faec7b7f4c8b11493fb4c8695351'; + +/// See also [PostUpdateNotifier]. +@ProviderFor(PostUpdateNotifier) +final postUpdateNotifierProvider = + AutoDisposeNotifierProvider>.internal( + PostUpdateNotifier.new, + name: r'postUpdateNotifierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$postUpdateNotifierHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$PostUpdateNotifier = AutoDisposeNotifier>; +String _$postDeleteNotifierHash() => + r'93485d48e410be62a04958383fa5104316a65079'; + +/// See also [PostDeleteNotifier]. +@ProviderFor(PostDeleteNotifier) +final postDeleteNotifierProvider = + AutoDisposeNotifierProvider>.internal( + PostDeleteNotifier.new, + name: r'postDeleteNotifierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$postDeleteNotifierHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$PostDeleteNotifier = AutoDisposeNotifier>; +String _$postLikeNotifierHash() => r'b90962918ddbd98fc1443e79ed66c99348906e93'; + +/// See also [PostLikeNotifier]. +@ProviderFor(PostLikeNotifier) +final postLikeNotifierProvider = + AutoDisposeNotifierProvider>.internal( + PostLikeNotifier.new, + name: r'postLikeNotifierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$postLikeNotifierHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$PostLikeNotifier = AutoDisposeNotifier>; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package From 37a49b31be617ba5444568497eee4a93b55c172b Mon Sep 17 00:00:00 2001 From: Seungvin Date: Thu, 2 Apr 2026 02:45:40 +0900 Subject: [PATCH 090/134] =?UTF-8?q?fix:=20=ED=94=BC=EB=93=9C=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=83=88=20=EB=AA=A8=EB=8D=B8,=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=EB=B0=94=EC=9D=B4=EB=8D=94=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=99=B8=EB=B6=80=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95/?= =?UTF-8?q?=20=ED=94=BC=EB=93=9C=ED=8C=9D=EC=97=85=EB=A9=94=EB=89=B4=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD,=20=EC=9C=84=EC=B9=98?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/data/challenge_repository.dart | 7 +-- .../challenge/detail/views/calendar_view.dart | 36 ++++++------ .../provider/challenge_provider.dart | 3 +- .../provider/challenge_provider.g.dart | 19 +++--- .../challenge_verification_screen.dart | 18 ++++-- .../challenge/widgets/comment_popup_menu.dart | 20 ++++--- .../feed/provider/post_detail_provider.g.dart | 2 +- .../feed/screens/post_detail_screen.dart | 43 ++++++++------ lib/features/feed/widgets/feed_post_card.dart | 58 ++++++++++--------- .../widgets/post_popup_menu.dart} | 22 ++++--- .../provider/user_profile_provider.g.dart | 2 +- 11 files changed, 124 insertions(+), 106 deletions(-) rename lib/features/{challenge/widgets/ChallengeFeedPopupMenu.dart => feed/widgets/post_popup_menu.dart} (90%) diff --git a/lib/features/challenge/data/challenge_repository.dart b/lib/features/challenge/data/challenge_repository.dart index 83a86c1..efd4f91 100644 --- a/lib/features/challenge/data/challenge_repository.dart +++ b/lib/features/challenge/data/challenge_repository.dart @@ -12,6 +12,7 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter/foundation.dart'; import 'package:haenaem/features/auth/services/auth_service.dart'; import 'package:haenaem/features/user/models/user_model.dart'; +import 'package:haenaem/features/feed/models/post.dart'; import 'package:haenaem/core/network/dio_provider.dart'; part 'challenge_repository.g.dart'; @@ -101,7 +102,7 @@ class ChallengeRepository { } //연도(year)와 월(month)을 파라미터로 받아 인증글 목록을 가져오는 함수 - Future> getChallengePosts({ + Future> getChallengePosts({ required int challengeId, required int year, required int month, @@ -119,9 +120,7 @@ class ChallengeRepository { if (response.statusCode == 200) { // Page 객체의 'content' 리스트를 추출 final List content = response.data['content'] ?? []; - return content - .map((json) => CertificationPostModel.fromJson(json)) - .toList(); + return content.map((json) => Post.fromJson(json)).toList(); } else { throw Exception('인증글 목록 조회 실패'); } diff --git a/lib/features/challenge/detail/views/calendar_view.dart b/lib/features/challenge/detail/views/calendar_view.dart index 7264945..d08586c 100644 --- a/lib/features/challenge/detail/views/calendar_view.dart +++ b/lib/features/challenge/detail/views/calendar_view.dart @@ -10,6 +10,7 @@ import 'package:intl/intl.dart'; import 'package:haenaem/features/feed/screens/post_detail_screen.dart'; import 'package:haenaem/features/challenge/models/challenge_model.dart'; +import 'package:haenaem/features/feed/models/post.dart'; class CalendarView extends ConsumerStatefulWidget { final int challengeId; @@ -242,7 +243,7 @@ class _CalendarViewState extends ConsumerState { Widget _buildCalendarGrid( DateTime date, List photos, - List allPosts, + List allPosts, ) { final int skipDays = DateTime(date.year, date.month, 1).weekday % 7; final int lastDayOfMonth = DateTime(date.year, date.month + 1, 0).day; @@ -271,9 +272,13 @@ class _CalendarViewState extends ConsumerState { ); bool isCertified = photoData != null && photoData.postId != -1; - final CertificationPostModel? fullPost = isCertified - ? allPosts.firstWhereOrNull((p) => p.postId == photoData.postId) ?? - allPosts.firstWhereOrNull((p) => p.postDate == targetDateStr) + final Post? fullPost = isCertified + ? allPosts.firstWhereOrNull((p) => p.id == photoData.postId) ?? + allPosts.firstWhereOrNull( + (p) => + DateFormat('yyyy-MM-dd').format(p.date) == + targetDateStr, + ) : null; return GestureDetector( @@ -281,10 +286,8 @@ class _CalendarViewState extends ConsumerState { ? () => Navigator.push( context, MaterialPageRoute( - builder: (_) => PostDetailScreen( - postId: fullPost.postId, - post: fullPost, - ), + builder: (_) => + PostDetailScreen(postId: fullPost.id, post: fullPost), ), ) : null, @@ -320,9 +323,7 @@ class _CalendarViewState extends ConsumerState { ); } - Widget _buildPostsHeader( - AsyncValue> postsAsync, - ) { + Widget _buildPostsHeader(AsyncValue> postsAsync) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -343,18 +344,15 @@ class _CalendarViewState extends ConsumerState { child: Text('이번 달 인증글이 없습니다.', style: TextStyle(color: AppColors.gray2)), ); - Widget _buildCertCard( - BuildContext context, { - required CertificationPostModel post, - }) { - final String formattedDate = (post.postDate.isNotEmpty) - ? DateFormat('M월 d일').format(DateTime.parse(post.postDate)) - : ""; + Widget _buildCertCard(BuildContext context, {required Post post}) { + // 날짜 포맷팅: "M월 d일" 형태로 변환 + final String formattedDate = DateFormat('M월 d일').format(post.date); + return GestureDetector( onTap: () => Navigator.push( context, MaterialPageRoute( - builder: (_) => PostDetailScreen(post: post, postId: post.postId), + builder: (_) => PostDetailScreen(post: post, postId: post.id), ), ), child: Container( diff --git a/lib/features/challenge/provider/challenge_provider.dart b/lib/features/challenge/provider/challenge_provider.dart index 6454217..dd384e6 100644 --- a/lib/features/challenge/provider/challenge_provider.dart +++ b/lib/features/challenge/provider/challenge_provider.dart @@ -6,6 +6,7 @@ import 'package:haenaem/features/user/data/user_repository.dart'; import '../models/challenge_model.dart'; import 'package:haenaem/features/user/models/user_model.dart'; import 'package:haenaem/shared/models/user.dart'; +import 'package:haenaem/features/feed/models/post.dart'; import 'dart:io'; part 'challenge_provider.g.dart'; @@ -138,7 +139,7 @@ Future challengeCalendarData( // 특정 챌린지 ID, 연도, 월에 따라 데이터를 캐싱 @riverpod -Future> challengePosts( +Future> challengePosts( ChallengePostsRef ref, { required int challengeId, required int year, diff --git a/lib/features/challenge/provider/challenge_provider.g.dart b/lib/features/challenge/provider/challenge_provider.g.dart index 9fd33a6..6fc7bc2 100644 --- a/lib/features/challenge/provider/challenge_provider.g.dart +++ b/lib/features/challenge/provider/challenge_provider.g.dart @@ -313,15 +313,14 @@ class _ChallengeCalendarDataProviderElement int get challengeId => (origin as ChallengeCalendarDataProvider).challengeId; } -String _$challengePostsHash() => r'08fedb7bb5a647c8fc3744997c2179902fb31fcd'; +String _$challengePostsHash() => r'ab79af0eb7249924a57b379a02a986c1a8e97bab'; /// See also [challengePosts]. @ProviderFor(challengePosts) const challengePostsProvider = ChallengePostsFamily(); /// See also [challengePosts]. -class ChallengePostsFamily - extends Family>> { +class ChallengePostsFamily extends Family>> { /// See also [challengePosts]. const ChallengePostsFamily(); @@ -365,8 +364,7 @@ class ChallengePostsFamily } /// See also [challengePosts]. -class ChallengePostsProvider - extends AutoDisposeFutureProvider> { +class ChallengePostsProvider extends AutoDisposeFutureProvider> { /// See also [challengePosts]. ChallengePostsProvider({ required int challengeId, @@ -410,8 +408,7 @@ class ChallengePostsProvider @override Override overrideWith( - FutureOr> Function(ChallengePostsRef provider) - create, + FutureOr> Function(ChallengePostsRef provider) create, ) { return ProviderOverride( origin: this, @@ -430,8 +427,7 @@ class ChallengePostsProvider } @override - AutoDisposeFutureProviderElement> - createElement() { + AutoDisposeFutureProviderElement> createElement() { return _ChallengePostsProviderElement(this); } @@ -456,8 +452,7 @@ class ChallengePostsProvider @Deprecated('Will be removed in 3.0. Use Ref instead') // ignore: unused_element -mixin ChallengePostsRef - on AutoDisposeFutureProviderRef> { +mixin ChallengePostsRef on AutoDisposeFutureProviderRef> { /// The parameter `challengeId` of this provider. int get challengeId; @@ -469,7 +464,7 @@ mixin ChallengePostsRef } class _ChallengePostsProviderElement - extends AutoDisposeFutureProviderElement> + extends AutoDisposeFutureProviderElement> with ChallengePostsRef { _ChallengePostsProviderElement(super.provider); diff --git a/lib/features/challenge/verification/screens/challenge_verification_screen.dart b/lib/features/challenge/verification/screens/challenge_verification_screen.dart index b5a9404..241323c 100644 --- a/lib/features/challenge/verification/screens/challenge_verification_screen.dart +++ b/lib/features/challenge/verification/screens/challenge_verification_screen.dart @@ -7,8 +7,12 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; + +// 캘린더 갱신 등 챌린지 로직 유지용 import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import 'package:haenaem/features/challenge/models/challenge_model.dart'; +// 새 인증글 생성/수정용? +import 'package:haenaem/features/feed/provider/post_detail_provider.dart'; +import 'package:haenaem/features/feed/models/post.dart'; import 'package:haenaem/features/challenge/models/image_model.dart'; import 'package:intl/intl.dart'; @@ -30,7 +34,7 @@ import 'package:haenaem/features/feed/models/feed_model.dart'; // 챌린지 인증하기 화면 class ChallengeVerificationScreen extends ConsumerStatefulWidget { final int challengeId; - final CertificationPostModel? existingPost; // 데이터가 있으면 수정 모드 + final Post? existingPost; // 데이터가 있으면 수정 모드 const ChallengeVerificationScreen({ super.key, @@ -55,7 +59,7 @@ class _ChallengeVerificationScreenState // 현재 "살아있는" 모든 사진의 총 합 (기존 사진 - 삭제할 것 + 새 사진) int get _currentTotalPhotoCount { - final int existingCount = widget.existingPost?.images.length ?? 0; + final int existingCount = widget.existingPost?.pictureUrl.length ?? 0; final int activeExisting = existingCount - _imageIdsToDelete.length; return activeExisting + _newImages.length; } @@ -71,7 +75,7 @@ class _ChallengeVerificationScreenState // 현재 화면에 보이는 총 사진 수 (기존 유지분 + 새로 추가분) int get _totalActivePhotoCount { - final int initialCount = widget.existingPost?.images.length ?? 0; + final int initialCount = widget.existingPost?.pictureUrl.length ?? 0; final int remainingExisting = initialCount - _imageIdsToDelete.length; return remainingExisting + _newImages.length; } @@ -116,7 +120,9 @@ class _ChallengeVerificationScreenState text: isEditMode ? widget.existingPost!.content : '', ); // 기존 이미지 데이터 초기화 - _existingImages = isEditMode ? List.from(widget.existingPost!.images) : []; + _existingImages = isEditMode + ? List.from(widget.existingPost!.pictureUrl) + : []; _scrollController.addListener(_onScroll); _contentController.addListener(() => setState(() {})); // 글자수 실시간 반영 @@ -610,7 +616,7 @@ class _ChallengeVerificationScreenState success = await ref .read(articleUpdateNotifierProvider.notifier) .editArticle( - postId: widget.existingPost!.postId, + postId: widget.existingPost!.id, content: content, deleteImageIds: _imageIdsToDelete, tempImageIds: _tempImageIds, // 💡 File 대신 ID 리스트 전달 diff --git a/lib/features/challenge/widgets/comment_popup_menu.dart b/lib/features/challenge/widgets/comment_popup_menu.dart index bcdc2da..1a81dfd 100644 --- a/lib/features/challenge/widgets/comment_popup_menu.dart +++ b/lib/features/challenge/widgets/comment_popup_menu.dart @@ -4,15 +4,17 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:haenaem/features/challenge/models/challenge_model.dart'; -import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; +//import 'package:haenaem/features/challenge/models/challenge_model.dart'; +//import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; +import 'package:haenaem/features/feed/models/comment.dart'; +import 'package:haenaem/features/feed/provider/comment_provider.dart'; import 'package:haenaem/features/challenge/widgets/DeleteConfirmDialog.dart'; import 'edit_article_dialog.dart'; // 내 댓글이면 삭제/수정 + 다른 사람 댓글이면 신고 다이얼로그 class CommentPopupMenu extends ConsumerWidget { final int postId; - final ChallengeComment comment; + final Comment comment; final dynamic feedProvider; const CommentPopupMenu({ @@ -38,7 +40,7 @@ class CommentPopupMenu extends ConsumerWidget { color: Colors.white, itemBuilder: (context) { // 내 댓글인 경우 : 수정/삭제 - if (comment.mine) { + if (comment.isMine) { return [ _buildPopupItem( '수정하기', @@ -107,17 +109,17 @@ class CommentPopupMenu extends ConsumerWidget { final String? newContents = await showDialog( context: context, builder: (context) => - EditArticleDialog(initialContent: comment.contents), + EditArticleDialog(initialContent: comment.content), ); // 수정을 완료하고 텍스트를 입력했을 경우 API 호출 if (newContents != null && newContents.trim().isNotEmpty) { //FocusManager.instance.primaryFocus?.unfocus(); // 키보드 닫기! final success = await ref - .read(articleCommentUpdateNotifierProvider.notifier) + .read(commentUpdateNotifierProvider.notifier) .editComment( postId: postId, - commentId: comment.commentId, + commentId: comment.id, contents: newContents, ); @@ -142,8 +144,8 @@ class CommentPopupMenu extends ConsumerWidget { if (confirmed == true) { // 댓글 삭제 API 호출 final success = await ref - .read(articleCommentDeleteNotifierProvider.notifier) - .removeComment(postId: postId, commentId: comment.commentId); + .read(commentDeleteNotifierProvider.notifier) + .removeComment(postId: postId, commentId: comment.id); if (success && context.mounted) { // 피드 화면 댓글 수 감소를 위해 필요한 코드 diff --git a/lib/features/feed/provider/post_detail_provider.g.dart b/lib/features/feed/provider/post_detail_provider.g.dart index acf954c..767d89f 100644 --- a/lib/features/feed/provider/post_detail_provider.g.dart +++ b/lib/features/feed/provider/post_detail_provider.g.dart @@ -196,7 +196,7 @@ final postDeleteNotifierProvider = ); typedef _$PostDeleteNotifier = AutoDisposeNotifier>; -String _$postLikeNotifierHash() => r'b90962918ddbd98fc1443e79ed66c99348906e93'; +String _$postLikeNotifierHash() => r'babbf64cb6d1c62edec7a8ee5635fa76b29bf63c'; /// See also [PostLikeNotifier]. @ProviderFor(PostLikeNotifier) diff --git a/lib/features/feed/screens/post_detail_screen.dart b/lib/features/feed/screens/post_detail_screen.dart index 0984824..31d0874 100644 --- a/lib/features/feed/screens/post_detail_screen.dart +++ b/lib/features/feed/screens/post_detail_screen.dart @@ -4,16 +4,21 @@ import 'package:intl/intl.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; +// 💡 기존 challenge_provider 대신 분리된 프로바이더들을 임포트합니다. +import 'package:haenaem/features/feed/provider/post_detail_provider.dart'; +import 'package:haenaem/features/feed/provider/comment_provider.dart'; +//import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:haenaem/features/challenge/models/challenge_model.dart'; +//import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/challenge/widgets/comment_popup_menu.dart'; import 'package:haenaem/features/feed/widgets/feed_post_card.dart'; // FeedPostCard 임포트 +import 'package:haenaem/features/feed/models/post.dart'; +import 'package:haenaem/features/feed/models/comment.dart'; class PostDetailScreen extends ConsumerStatefulWidget { final int postId; - final CertificationPostModel? post; + final Post? post; final dynamic feedProvider; const PostDetailScreen({ @@ -50,9 +55,9 @@ class _PostDetailScreenState extends ConsumerState { @override Widget build(BuildContext context) { // 상세 정보 및 댓글 데이터 구독 - final detailAsync = ref.watch(articleDetailProvider(postId: widget.postId)); + final detailAsync = ref.watch(postDetailProvider(postId: widget.postId)); final commentsAsync = ref.watch( - articleCommentsProvider(postId: widget.postId), + postCommentsProvider(postId: widget.postId), ); return Scaffold( @@ -184,7 +189,7 @@ class _PostDetailScreenState extends ConsumerState { // 💡 댓글 작성 API 호출 final contents = _commentController.text.trim(); final success = await ref - .read(articleCommentCreateNotifierProvider.notifier) + .read(commentCreateNotifierProvider.notifier) .addComment(postId: widget.postId, contents: contents); if (success && mounted) { @@ -224,7 +229,7 @@ class _PostDetailScreenState extends ConsumerState { Future _handleCommentSubmit() async { final contents = _commentController.text.trim(); final success = await ref - .read(articleCommentCreateNotifierProvider.notifier) + .read(commentCreateNotifierProvider.notifier) .addComment(postId: widget.postId, contents: contents); if (success && mounted) { @@ -238,12 +243,9 @@ class _PostDetailScreenState extends ConsumerState { } } - Widget _buildCommentItem(ChallengeComment comment) { - final DateTime? displayDate = comment.updatedAt ?? comment.createdAt; - String commentDate = ""; - if (displayDate != null) { - commentDate = DateFormat('yyyy.MM.dd HH:mm').format(displayDate); - } + Widget _buildCommentItem(Comment comment) { + //날짜 처리는 comment.date로 통합되었음 + String commentDate = DateFormat('yyyy.MM.dd HH:mm').format(comment.date); return Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), @@ -252,11 +254,15 @@ class _PostDetailScreenState extends ConsumerState { children: [ CircleAvatar( radius: 18, + // 타입 안정성을 위해 as ImageProvider 추가 backgroundImage: - (comment.userPicture != null && comment.userPicture!.isNotEmpty) - ? NetworkImage(comment.userPicture!) + (comment.writer.profileUrl != null && + comment.writer.profileUrl!.isNotEmpty) + ? NetworkImage(comment.writer.profileUrl!) as ImageProvider : null, - child: (comment.userPicture == null || comment.userPicture!.isEmpty) + child: + (comment.writer.profileUrl == null || + comment.writer.profileUrl!.isEmpty) ? SvgPicture.asset( 'assets/images/icons/default_profile_icon.svg', ) @@ -270,7 +276,8 @@ class _PostDetailScreenState extends ConsumerState { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text(comment.userNickname, style: AppTypography.b1), + Text(comment.writer.nickname, style: AppTypography.b1), + CommentPopupMenu( postId: widget.postId, comment: comment, @@ -279,7 +286,7 @@ class _PostDetailScreenState extends ConsumerState { ], ), const SizedBox(height: 2), - Text(comment.contents, style: AppTypography.b2), + Text(comment.content, style: AppTypography.b2), const SizedBox(height: 4), Text( commentDate, diff --git a/lib/features/feed/widgets/feed_post_card.dart b/lib/features/feed/widgets/feed_post_card.dart index 55bba0e..50a94ea 100644 --- a/lib/features/feed/widgets/feed_post_card.dart +++ b/lib/features/feed/widgets/feed_post_card.dart @@ -7,12 +7,13 @@ import 'package:haenaem/features/feed/screens/post_detail_screen.dart'; // 인 import 'package:intl/intl.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:haenaem/features/challenge/models/challenge_model.dart'; -import 'package:haenaem/features/challenge/widgets/ChallengeFeedPopupMenu.dart'; +//import 'package:haenaem/features/challenge/models/challenge_model.dart'; +import 'package:haenaem/features/feed/models/post.dart'; +import 'package:haenaem/features/feed/widgets/post_popup_menu.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; class FeedPostCard extends ConsumerWidget { - final CertificationPostModel post; + final Post post; final VoidCallback? onTap; final dynamic provider; // 어떤 Provider(친구/둘러보기)인지 받음 @@ -25,11 +26,15 @@ class FeedPostCard extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + /* final displayDate = post.updatedAt ?? post.createdAt; String formattedDate = displayDate != null ? DateFormat('yyyy년 MM월 dd일 HH:mm').format(displayDate) : ""; + */ + // 💡 날짜 처리: post.date 하나로 통합 + String formattedDate = DateFormat('yyyy년 MM월 dd일 HH:mm').format(post.date); return InkWell( onTap: @@ -40,7 +45,7 @@ class FeedPostCard extends ConsumerWidget { context, MaterialPageRoute( builder: (context) => PostDetailScreen( - postId: post.postId, + postId: post.id, post: post, feedProvider: provider, // 기존에 넘겨주던 프로바이더 ), @@ -58,12 +63,13 @@ class FeedPostCard extends ConsumerWidget { CircleAvatar( radius: 18, backgroundImage: - (post.userImageUrl != null && - post.userImageUrl!.isNotEmpty) - ? NetworkImage(post.userImageUrl!) as ImageProvider + (post.writer.profileUrl != null && + post.writer.profileUrl!.isNotEmpty) + ? NetworkImage(post.writer.profileUrl!) as ImageProvider : null, child: - (post.userImageUrl == null || post.userImageUrl!.isEmpty) + (post.writer.profileUrl == null || + post.writer.profileUrl!.isEmpty) ? SvgPicture.asset( 'assets/images/icons/default_profile_icon.svg', ) @@ -74,11 +80,11 @@ class FeedPostCard extends ConsumerWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(post.userName ?? '해냄', style: AppTypography.b1), + Text(post.writer.nickname, style: AppTypography.b1), ], ), ), - ChallengeFeedPopupMenu(post: post), + PostPopupMenu(post: post), ], ), ), @@ -89,7 +95,7 @@ class FeedPostCard extends ConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '${post.challengeTitle} ${post.totalSuccessDays}일차', + '${post.title} ${post.totalSuccessDays}일차', style: AppTypography.b3.copyWith(color: AppColors.black), ), const SizedBox(height: 4), // 간격 추가 @@ -106,7 +112,7 @@ class FeedPostCard extends ConsumerWidget { ), ), // 3. 이미지 - if (post.hasImage && post.images.isNotEmpty) + if (post.hasImage && post.pictureUrl.isNotEmpty) _PostImageSlider(post: post), // 4. 하단 아이콘 정보 Padding( @@ -117,29 +123,29 @@ class FeedPostCard extends ConsumerWidget { onTap: () async { // [로컬 업데이트] 서버 응답 기다리지 않고 즉시 UI 변경 if (provider != null) { - ref - .read(provider.notifier) - .toggleLikeLocally(post.postId); + ref.read(provider.notifier).toggleLikeLocally(post.id); } // [서버 통신] 백그라운드에서 조용히 처리 ref .read(articleLikeNotifierProvider.notifier) .toggleLike( - postId: post.postId, - isCurrentlyLiked: post.liked, + postId: post.id, + isCurrentlyLiked: post.isLiked, ); }, child: Row( children: [ SvgPicture.asset( - post.liked + post.isLiked ? 'assets/images/icons/like_filled_icon.svg' : 'assets/images/icons/like_icon.svg', width: 20, height: 20, colorFilter: ColorFilter.mode( - post.liked ? AppColors.notification : AppColors.gray2, + post.isLiked + ? AppColors.notification + : AppColors.gray2, BlendMode.srcIn, ), ), @@ -147,7 +153,7 @@ class FeedPostCard extends ConsumerWidget { Text( post.likeCount.toString(), style: AppTypography.b2.copyWith( - color: post.liked + color: post.isLiked ? AppColors.notification : AppColors.gray2, ), @@ -158,7 +164,7 @@ class FeedPostCard extends ConsumerWidget { const SizedBox(width: 16), _buildIconInfo( 'assets/images/icons/comment_icon.svg', - post.commentNumber.toString(), + post.commentCount.toString(), ), const Spacer(), Text( @@ -195,7 +201,7 @@ class FeedPostCard extends ConsumerWidget { // ✅ 이미지 슬라이더와 인디케이터 상태를 관리하기 위한 내부 위젯 class _PostImageSlider extends StatefulWidget { - final CertificationPostModel post; + final Post post; const _PostImageSlider({required this.post}); @@ -214,14 +220,14 @@ class _PostImageSliderState extends State<_PostImageSlider> { height: 375, // 기존 FeedPostCard 이미지 높이와 통일 width: double.infinity, child: PageView.builder( - itemCount: widget.post.images.length, + itemCount: widget.post.pictureUrl.length, onPageChanged: (index) { setState(() { _currentImagePage = index; }); }, itemBuilder: (context, index) { - final String path = widget.post.images[index].imageUrl; + final String path = widget.post.pictureUrl[index].imageUrl; // 💡 경로 처리: http로 시작하지 않으면 서버 주소 붙여주기 final String fullUrl = path.startsWith('http') ? path @@ -251,12 +257,12 @@ class _PostImageSliderState extends State<_PostImageSlider> { ), ), // 💡 이미지가 2장 이상일 때만 하단에 페이지 점(Indicator) 표시 - if (widget.post.images.length > 1) + if (widget.post.pictureUrl.length > 1) Padding( padding: const EdgeInsets.only(top: 10, bottom: 5), child: Row( mainAxisAlignment: MainAxisAlignment.center, - children: List.generate(widget.post.images.length, (index) { + children: List.generate(widget.post.pictureUrl.length, (index) { return Container( width: 6, height: 6, diff --git a/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart b/lib/features/feed/widgets/post_popup_menu.dart similarity index 90% rename from lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart rename to lib/features/feed/widgets/post_popup_menu.dart index e6a2c99..41f970a 100644 --- a/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart +++ b/lib/features/feed/widgets/post_popup_menu.dart @@ -6,15 +6,17 @@ import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/features/challenge/widgets/DeleteConfirmDialog.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:haenaem/features/challenge/models/challenge_model.dart'; +import 'package:haenaem/features/feed/models/post.dart'; +//import 'package:haenaem/features/challenge/models/challenge_model.dart'; +// 리스트 갱신용으로 유지 import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import 'edit_article_dialog.dart'; +//import '../../challenge/widgets/edit_article_dialog.dart'; import 'package:haenaem/features/challenge/verification/screens/challenge_verification_screen.dart'; // 인증글 다이얼로그 (내 인증글일 경우와 타인의 인증글일 경우) -class ChallengeFeedPopupMenu extends ConsumerWidget { - final CertificationPostModel post; // 인증글 데이터 - const ChallengeFeedPopupMenu({super.key, required this.post}); +class PostPopupMenu extends ConsumerWidget { + final Post post; // 인증글 데이터 + const PostPopupMenu({super.key, required this.post}); @override Widget build(BuildContext context, WidgetRef ref) { @@ -22,16 +24,18 @@ class ChallengeFeedPopupMenu extends ConsumerWidget { //final myProfileAsync = ref.watch(myProfileProvider); // 2. 내 닉네임과 게시글 작성자 닉네임을 비교하여 '내 글' 여부 판단 - final bool isMine = post.author; + final bool isMine = post.isAuthor; // 2. [날짜 체크] 오늘 날짜 문자열(yyyy-MM-dd) 생성 final String todayStr = DateFormat('yyyy-MM-dd').format(DateTime.now()); // 3. 게시글의 postDate와 오늘 날짜 비교 - final bool isToday = post.postDate.trim().startsWith(todayStr); + // 💡 날짜 타입이 DateTime으로 바뀌었으므로 String으로 포맷 변환 후 비교 + final String postDateStr = DateFormat('yyyy-MM-dd').format(post.date); + final bool isToday = postDateStr.startsWith(todayStr); // 💡 디버깅을 위해 로그를 한 번 찍어보세요. (문제 확인용) - debugPrint('🔍 비교 날짜 - 서버 데이터: "${post.postDate}", 오늘 날짜: "$todayStr"'); + debugPrint('🔍 비교 날짜 - 서버 데이터: "$postDateStr", 오늘 날짜: "$todayStr"'); debugPrint('🔍 판정 결과 - isMine: $isMine, isToday: $isToday'); return PopupMenuButton( @@ -182,7 +186,7 @@ class ChallengeFeedPopupMenu extends ConsumerWidget { // 💡 삭제 시도 final success = await ref .read(articleDeleteNotifierProvider.notifier) - .removeArticle(post.postId); + .removeArticle(post.id); if (success && context.mounted) { ScaffoldMessenger.of( diff --git a/lib/features/user/provider/user_profile_provider.g.dart b/lib/features/user/provider/user_profile_provider.g.dart index 9939d5d..ed7fd6b 100644 --- a/lib/features/user/provider/user_profile_provider.g.dart +++ b/lib/features/user/provider/user_profile_provider.g.dart @@ -6,7 +6,7 @@ part of 'user_profile_provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$userProfileHash() => r'63c409bf957bfbccdab141e1a960bb512bf8193e'; +String _$userProfileHash() => r'19eca05cb7e9cf8b28eba8eb8bbce5333c70101a'; /// See also [UserProfile]. @ProviderFor(UserProfile) From 99f98aaa13454ad574f644b12dae129fe3c12e8e Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 2 Apr 2026 12:12:06 +0900 Subject: [PATCH 091/134] =?UTF-8?q?feat:=20=EC=B9=B4=EB=A9=94=EB=9D=BC=20?= =?UTF-8?q?=EA=B6=8C=ED=95=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/src/main/AndroidManifest.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 752019b..525bfec 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -10,12 +10,15 @@ + + + - + android:enableOnBackInvokedCallback="true"> +ß Date: Thu, 2 Apr 2026 12:13:08 +0900 Subject: [PATCH 092/134] =?UTF-8?q?feat:=20=EC=A0=84=EC=97=AD=20=ED=97=A8?= =?UTF-8?q?=EB=93=A4=EB=9F=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/main.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/main.dart b/lib/main.dart index 8e18cbd..a553fcf 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -18,6 +18,12 @@ void main() async { // 플러터 엔진 초기화 확인 WidgetsFlutterBinding.ensureInitialized(); + // 전역 에러 핸들러 + FlutterError.onError = (FlutterErrorDetails details) { + debugPrint('🔴 Flutter 에러: ${details.exception}'); + debugPrint('🔴 스택: ${details.stack}'); + }; + // 저장소 인스턴스 생성 const storage = FlutterSecureStorage(); From 26e9fee39f3aa5aa96d8a9e2a8c201fbb6d4fcc5 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 2 Apr 2026 12:15:28 +0900 Subject: [PATCH 093/134] =?UTF-8?q?refactor:=20=EC=86=8C=EA=B0=9C=20?= =?UTF-8?q?=ED=83=AD=20=EC=B0=B8=EC=A1=B0=20=ED=8C=8C=EC=9D=BC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95,=20DetailContent=20=EB=AA=A8=EB=8D=B8=EC=97=90=20base?= =?UTF-8?q?=EB=8A=94=20=ED=95=84=EC=9A=94=20=EC=97=86=EC=96=B4=EC=84=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/views/information_view.dart | 4 ++-- lib/shared/models/challenge_detail.dart | 17 ++++++----------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/lib/features/challenge/detail/views/information_view.dart b/lib/features/challenge/detail/views/information_view.dart index 21e6366..175852d 100644 --- a/lib/features/challenge/detail/views/information_view.dart +++ b/lib/features/challenge/detail/views/information_view.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import 'package:haenaem/features/challenge/detail/widgets/challenge_detail_content.dart'; +import 'package:haenaem/shared/provider/challenge_detail_provider.dart'; +import 'package:haenaem/shared/widgets/challenge_detail_content.dart'; class InformationView extends ConsumerWidget { final int challengeId; diff --git a/lib/shared/models/challenge_detail.dart b/lib/shared/models/challenge_detail.dart index 56408a5..9ffd732 100644 --- a/lib/shared/models/challenge_detail.dart +++ b/lib/shared/models/challenge_detail.dart @@ -6,7 +6,6 @@ import 'package:haenaem/shared/models/user.dart'; // ChallengeBase에 정의된 필드(id, title, isLeader)를 재사용 // User 모델을 방장(host), 오늘 인증한 유저 리스트(todaySuccessUsers)에 재사용 class ChallengeDetail { - final ChallengeBase challengeBase; // 챌린지 기본 정보 (id, title, isLeader) final DateTime startDate; // 챌린지 시작 날짜 final DateTime endDate; // 챌린지 종료 날짜 final int weeklyFrequency; // 주간 최소 인증 빈도 @@ -18,7 +17,6 @@ class ChallengeDetail { final List todaySuccessUsers; // 오늘 인증 완료한 유저 리스트 const ChallengeDetail({ - required this.challengeBase, required this.startDate, required this.endDate, required this.weeklyFrequency, @@ -32,23 +30,21 @@ class ChallengeDetail { factory ChallengeDetail.fromJson(Map json) { return ChallengeDetail( - challengeBase: ChallengeBase.fromJson(json), - startDate: DateTime.parse(json['start_date'] as String), - endDate: DateTime.parse(json['end_date'] as String), - weeklyFrequency: json['weekly_frequency'] as int, - photoRequired: json['photo_required'] as bool, + startDate: DateTime.parse(json['startDate'] as String), + endDate: DateTime.parse(json['endDate'] as String), + weeklyFrequency: json['requiredWeeklyCount'] as int, + photoRequired: json['photoRequired'] as bool, tags: List.from(json['tags'] as List), description: json['description'] as String, leader: User.fromJson(json['host'] as Map), - participantCount: json['participant_count'] as int, - todaySuccessUsers: (json['today_success_users'] as List) + participantCount: json['participantCount'] as int, + todaySuccessUsers: (json['todaySuccessUsers'] as List) .map((e) => User.fromJson(e as Map)) .toList(), ); } ChallengeDetail copyWith({ - ChallengeBase? challengeBase, DateTime? startDate, DateTime? endDate, int? weeklyFrequency, @@ -60,7 +56,6 @@ class ChallengeDetail { List? todaySuccessUsers, }) { return ChallengeDetail( - challengeBase: challengeBase ?? this.challengeBase, startDate: startDate ?? this.startDate, endDate: endDate ?? this.endDate, weeklyFrequency: weeklyFrequency ?? this.weeklyFrequency, From 9e2b34352da1909c404595180f9bb06859ee9978 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 2 Apr 2026 12:21:43 +0900 Subject: [PATCH 094/134] =?UTF-8?q?feat:=20=EB=94=94=EB=B2=84=EA=B9=85=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/data/challenge_detail_repository.dart | 1 + lib/shared/widgets/challenge_detail_content.dart | 11 ----------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/lib/features/challenge/detail/data/challenge_detail_repository.dart b/lib/features/challenge/detail/data/challenge_detail_repository.dart index cdb7bd1..9d90b88 100644 --- a/lib/features/challenge/detail/data/challenge_detail_repository.dart +++ b/lib/features/challenge/detail/data/challenge_detail_repository.dart @@ -19,6 +19,7 @@ class ChallengeDetailRepository { final response = await _dio.get('/api/challenge/$challengeId'); if (response.statusCode == 200) { + debugPrint('📦 챌린지 상세 응답: ${response.data}'); return ChallengeDetail.fromJson(response.data as Map); } else { throw Exception('챌린지 상세 조회 실패'); diff --git a/lib/shared/widgets/challenge_detail_content.dart b/lib/shared/widgets/challenge_detail_content.dart index 3d22990..5d9fdd7 100644 --- a/lib/shared/widgets/challenge_detail_content.dart +++ b/lib/shared/widgets/challenge_detail_content.dart @@ -11,14 +11,12 @@ import 'package:haenaem/shared/widgets/tag_badge.dart'; class ChallengeDetailContent extends StatelessWidget { final ChallengeDetail challenge; - final String? title; final ScrollController scrollController; final bool showTitle; const ChallengeDetailContent({ super.key, required this.challenge, - required this.title, required this.scrollController, this.showTitle = true, }); @@ -73,15 +71,6 @@ class ChallengeDetailContent extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 챌린지 제목 - if (showTitle) ...[ - Text( - title ?? '챌린지 소개', - style: AppTypography.h3.copyWith(color: AppColors.black), - ), - const SizedBox(height: 24), - ], - _buildInfoSection('챌린지 시작일', formattedStart), _buildInfoSection('챌린지 마감일', '$formattedEnd $dDayString'), _buildInfoSection('인증 빈도', frequencyText), From 969c87dcbd06400d5ddff4b26857f33abfcceaa2 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 2 Apr 2026 12:30:09 +0900 Subject: [PATCH 095/134] =?UTF-8?q?refactor:=20API=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/shared/models/user.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/shared/models/user.dart b/lib/shared/models/user.dart index 2618915..649d9fb 100644 --- a/lib/shared/models/user.dart +++ b/lib/shared/models/user.dart @@ -15,7 +15,7 @@ class User { ? json['id'] : int.tryParse(json['id'].toString()) ?? 0, profileUrl: json['profileImageUrl'] as String?, - nickname: json['nickname'] as String, + nickname: (json['nickname'] ?? json['name']) as String, ); } From ca32b68d13151a9f5a07756a56e616bbf997c65e Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 2 Apr 2026 12:41:01 +0900 Subject: [PATCH 096/134] =?UTF-8?q?feat:=20=EB=8D=94=20=EC=9D=B4=EC=83=81?= =?UTF-8?q?=20=EC=95=88=20=EC=93=B8=20image=5Fmodel=20=EC=A3=BC=EC=84=9D?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/models/image_model.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/features/challenge/models/image_model.dart b/lib/features/challenge/models/image_model.dart index 780dd22..eaa279b 100644 --- a/lib/features/challenge/models/image_model.dart +++ b/lib/features/challenge/models/image_model.dart @@ -2,6 +2,7 @@ // 이미지 관련 정보 관리 클래스 // 인증글 사진 정보를 관리하는 클래스 +@Deprecated('shared/models/post.dart에 함께 정의. 이 모델은 사용 X') class PostImage { final int imageId; final String imageUrl; From c5f0a138659c62fe978602916ed6e4f15dcc5233 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 2 Apr 2026 12:50:17 +0900 Subject: [PATCH 097/134] =?UTF-8?q?feat:=20=EB=94=94=EB=B2=84=EA=B9=85=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge/verification/data/verification_repository.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/features/challenge/verification/data/verification_repository.dart b/lib/features/challenge/verification/data/verification_repository.dart index 2d8d6b0..07222a7 100644 --- a/lib/features/challenge/verification/data/verification_repository.dart +++ b/lib/features/challenge/verification/data/verification_repository.dart @@ -61,6 +61,8 @@ class VerificationRepository { ); if (response.statusCode == 201 || response.statusCode == 200) { + debugPrint('📦 서버 응답 데이터: ${response.data}'); + // [변경] CertificationPostModel -> Post return Post.fromJson(response.data); } else { From d80f393a34883afec3f4149c0f5c990557ce60d9 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 2 Apr 2026 12:55:01 +0900 Subject: [PATCH 098/134] =?UTF-8?q?refactor:=20API=20=ED=98=95=EC=8B=9D?= =?UTF-8?q?=EC=97=90=20=EB=A7=9E=EA=B2=8C=20post=20=EB=AA=A8=EB=8D=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95,=20=EA=B8=B0=EC=A1=B4=20image=20=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=20=EC=B0=B8=EC=A1=B0=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/shared/models/post.dart | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/shared/models/post.dart b/lib/shared/models/post.dart index dd60c58..14b180c 100644 --- a/lib/shared/models/post.dart +++ b/lib/shared/models/post.dart @@ -1,5 +1,4 @@ import 'package:haenaem/shared/models/user.dart'; -import 'package:haenaem/features/challenge/models/image_model.dart'; // 최초 작성자: 강선욱 // 인증글 모델 클래스 @@ -36,15 +35,19 @@ class Post { .toList(); return Post( - id: json['id'] as int, + id: json['postId'] as int, title: json['title'] as String, content: json['content'] as String, images: parsedImages, - likeCount: json['like_count'] as int, - isLiked: json['is_liked'] as bool, - commentCount: json['comment_count'] as int, - date: DateTime.parse(json['date'] as String), - writer: User.fromJson(json['writer'] as Map), + likeCount: json['likeNumber'] as int, + isLiked: json['liked'] as bool, + commentCount: json['commentNumber'] as int, + date: DateTime.parse(json['updatedAt'] as String), + writer: User( + id: json['userId'] as int, + nickname: json['userNickname'] as String? ?? '이름 없음', + profileUrl: json['userImageUrl'] as String?, + ), ); } From 46d819984568314130be0d0468d5a7b9cc498a33 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 2 Apr 2026 12:57:45 +0900 Subject: [PATCH 099/134] =?UTF-8?q?feat:=20=EC=9D=B8=EC=A6=9D=EA=B8=80=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1,=20=EC=88=98=EC=A0=95=EC=8B=9C=20provider=20?= =?UTF-8?q?=EC=BA=90=EC=8B=9C=20=EA=B0=B1=EC=8B=A0=20=EA=B3=B5=ED=86=B5=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../provider/verification_provider.dart | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/lib/features/challenge/verification/provider/verification_provider.dart b/lib/features/challenge/verification/provider/verification_provider.dart index 0e3aa27..ac111d8 100644 --- a/lib/features/challenge/verification/provider/verification_provider.dart +++ b/lib/features/challenge/verification/provider/verification_provider.dart @@ -1,12 +1,34 @@ import 'dart:io'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../data/verification_repository.dart'; import 'package:haenaem/shared/models/post.dart'; import 'package:haenaem/shared/provider/post_provider.dart'; import 'package:haenaem/shared/provider/home_provider.dart'; +import 'package:haenaem/features/challenge/detail/provider/stats_provider.dart'; part 'verification_provider.g.dart'; +// 인증글 생성, 수정 시 관련된 캐시를 한번에 갱신하는 함수 +void _refreshRelatedProviders(Ref ref, int challengeId) { + final now = DateTime.now(); + + // 1. 해당 챌린지의 월간 포스트 리스트 갱신 + ref.invalidate( + monthlyChallengePostsProvider( + challengeId: challengeId, + year: now.year, + month: now.month, + ), + ); + + // 2. 챌린지 상세 통계(총 인증 횟수, 연속 인증 횟수) 갱신 + ref.invalidate(challengeStatsProvider(challengeId)); + + // 3. 홈 화면(진행 중인 챌린지 현황 등) 갱신 + ref.invalidate(homeNotifierProvider); +} + // 인증 이미지 검증 @riverpod class ImageVerifyNotifier extends _$ImageVerifyNotifier { @@ -51,6 +73,10 @@ class ArticleCreateNotifier extends _$ArticleCreateNotifier { ), ); + if (!result.hasError && result.value != null) { + _refreshRelatedProviders(ref, challengeId); + } + state = result; return !result.hasError; } @@ -82,18 +108,8 @@ class ArticleUpdateNotifier extends _$ArticleUpdateNotifier { ), ); - if (!result.hasError) { - final now = DateTime.now(); - - // 수정 성공 시 관련 데이터 캐시 갱신 - ref.invalidate( - monthlyChallengePostsProvider( - challengeId: challengeId, - year: now.year, - month: now.month, - ), - ); - ref.invalidate(homeNotifierProvider); + if (!result.hasError && result.value != null) { + _refreshRelatedProviders(ref, challengeId); } state = result; From aac74cbad0bf41453acfcf2389ad8fa88b99a444 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 2 Apr 2026 13:09:21 +0900 Subject: [PATCH 100/134] =?UTF-8?q?refactor:=20=EC=B1=8C=EB=A6=B0=EC=A7=80?= =?UTF-8?q?=20=EC=9D=B8=EC=A6=9D=20=EC=B0=B8=EC=A1=B0=20=EC=88=98=EC=A0=95?= =?UTF-8?q?,=20=EB=82=B4=EB=B6=80=20=EB=A1=9C=EC=A7=81=20Provider=EB=A1=9C?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge_verification_screen.dart | 115 ++++++++---------- 1 file changed, 50 insertions(+), 65 deletions(-) diff --git a/lib/features/challenge/verification/screens/challenge_verification_screen.dart b/lib/features/challenge/verification/screens/challenge_verification_screen.dart index 90c3f6d..3fdadc0 100644 --- a/lib/features/challenge/verification/screens/challenge_verification_screen.dart +++ b/lib/features/challenge/verification/screens/challenge_verification_screen.dart @@ -9,13 +9,8 @@ import 'package:haenaem/core/theme/app_typography.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/shared/models/post.dart'; -import 'package:haenaem/shared/models/challenge_detail.dart'; import '../provider/verification_provider.dart'; import 'package:haenaem/shared/provider/challenge_detail_provider.dart'; -import 'package:haenaem/shared/provider/home_provider.dart'; -// import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -// import 'package:haenaem/features/challenge/models/challenge_model.dart'; -// import 'package:haenaem/features/challenge/models/image_model.dart'; import '../../../../shared/widgets/challenge_label.dart'; import '../../../../shared/widgets/challenge_input_box.dart'; @@ -30,7 +25,6 @@ import '../widgets/ai_fail_box.dart'; import 'package:haenaem/features/challenge/verification/widgets/reverification_guide_box.dart'; import '../widgets/verification_submit_button.dart'; import 'package:haenaem/features/challenge/widgets/verification_cancel_dialog.dart'; -import 'package:haenaem/features/feed/models/feed_model.dart'; // 챌린지 인증하기 화면 class ChallengeVerificationScreen extends ConsumerStatefulWidget { @@ -138,7 +132,20 @@ class _ChallengeVerificationScreenState } // 사진 추가 시트 띄우기 - void _showImageSourceSheet() { + void _showImageSourceSheet() async { + // ✅ 갤러리/카메라 접근 전 권한 먼저 요청 + final PermissionState ps = await PhotoManager.requestPermissionExtend(); + + if (!ps.hasAccess) { + if (mounted) { + ScaffoldMessenger.of( + context, + ).showSnackBar(const SnackBar(content: Text('사진 접근 권한이 필요합니다.'))); + PhotoManager.openSetting(); // 설정 화면으로 유도 + } + return; + } + showModalBottomSheet( context: context, isScrollControlled: true, @@ -605,67 +612,45 @@ class _ChallengeVerificationScreenState } Future _onSave() async { - final now = DateTime.now(); - bool success = false; final content = _contentController.text.trim(); + bool success = false; - try { - if (isEditMode) { - // ✨ editArticle의 파라미터명을 tempImageIds로 맞춤 - success = await ref - .read(articleUpdateNotifierProvider.notifier) - .editArticle( - postId: widget.existingPost!.id, - challengeId: widget.challengeId, - content: content, - deleteImageIds: _imageIdsToDelete, - tempImageIds: _tempImageIds, // 💡 File 대신 ID 리스트 전달 - ); - } else { - // ✨ submitArticle의 파라미터명을 tempImageIds로 맞춤 - success = await ref - .read(articleCreateNotifierProvider.notifier) - .submitArticle( - challengeId: widget.challengeId, - content: content, - tempImageIds: _tempImageIds, // 💡 File 대신 ID 리스트 전달 - ); - } - } catch (e) { - success = false; + if (isEditMode) { + success = await ref + .read(articleUpdateNotifierProvider.notifier) + .editArticle( + postId: widget.existingPost!.id, + challengeId: widget.challengeId, + content: content, + deleteImageIds: _imageIdsToDelete, + tempImageIds: _tempImageIds, + ); + } else { + success = await ref + .read(articleCreateNotifierProvider.notifier) + .submitArticle( + challengeId: widget.challengeId, + content: content, + tempImageIds: _tempImageIds, + ); } - // if (success && mounted) { - // // 💡 [에러 해결] 이 프로바이더만 이름 없이 숫자만 넣습니다 (Positional) - // ref.invalidate(challengeCalendarDataProvider(widget.challengeId)); - - // // 💡 아래 프로바이더들은 정의된 대로 이름을 명시합니다 (Named) - // ref.invalidate( - // challengeCalendarPhotosProvider( - // challengeId: widget.challengeId, - // year: now.year, - // month: now.month, - // ), - // ); - // ref.invalidate( - // challengePostsProvider( - // challengeId: widget.challengeId, - // year: now.year, - // month: now.month, - // ), - // ); - - // ref.invalidate(homeNotifierProvider); - - // ScaffoldMessenger.of( - // context, - // ).showSnackBar(SnackBar(content: Text(isEditMode ? '수정 완료!' : '인증 완료!'))); - - // Navigator.pop(context); - // } else if (mounted) { - // ScaffoldMessenger.of( - // context, - // ).showSnackBar(const SnackBar(content: Text('인증에 실패했습니다. 다시 시도해주세요.'))); - // } + if (!mounted) return; + + if (success) { + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text(isEditMode ? '수정 완료!' : '인증 완료!'))); + Navigator.pop(context); + } else { + // 에러 발생 시 처리 (예: 스낵바 노출) + final error = isEditMode + ? ref.read(articleUpdateNotifierProvider).error + : ref.read(articleCreateNotifierProvider).error; + + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('오류가 발생했습니다: $error'))); + } } } From 260db194b2d61da10eb2dbf6520361b5ecf6952a Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 2 Apr 2026 13:10:22 +0900 Subject: [PATCH 101/134] =?UTF-8?q?feat:=20=EA=B8=B0=ED=83=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .metadata | 15 +++++++++++++++ assets/images/profiles/user1.png | Bin 505341 -> 0 bytes assets/images/profiles/user2.png | Bin 505341 -> 0 bytes assets/images/profiles/user3.png | Bin 505341 -> 0 bytes 4 files changed, 15 insertions(+) delete mode 100644 assets/images/profiles/user1.png delete mode 100644 assets/images/profiles/user2.png delete mode 100644 assets/images/profiles/user3.png diff --git a/.metadata b/.metadata index defd946..2c6187b 100644 --- a/.metadata +++ b/.metadata @@ -18,6 +18,21 @@ migration: - platform: android create_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 base_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 + - platform: ios + create_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 + base_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 + - platform: linux + create_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 + base_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 + - platform: macos + create_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 + base_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 + - platform: web + create_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 + base_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 + - platform: windows + create_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 + base_revision: b45fa18946ecc2d9b4009952c636ba7e2ffbb787 # User provided section diff --git a/assets/images/profiles/user1.png b/assets/images/profiles/user1.png deleted file mode 100644 index d3e9c87d5d47f4251afcc4d1306c70a590f761ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 505341 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

?jwf#ojfKfke(v283 zNXy`^!Encw8H+S-(TrQANxQ}qm*lp?OCoX7E~E;>opak+%y)Xyu6Em1UYi<(o%<5p zy$+ez(c^J+dmLRJd#4+z-ED6}S6iFM+Tt~Xz`r-RP4%EjV;$kUSC8b;-S+6>eD~^7 z_^zw;=##NCOGe(UEAePcd{TLm>}Zq;ou*cx=18uhuj8V=GPkREXWj8l-9@|XwP*cw z?X1u|%`{HaEgo52@9isH*?Z5fUU~AJS8i&L4v6=4w-C68XeD4BT>Pv` zjw82JSn7GWXDG5EI>O-|3056O|H$bmho*R9XkHNz53Faw+Rvi{SUSX`qtuANkpopg za8xVAw3?V!i_0>aRAUZWz{DrGU&LPn9|K8|_hX3LlI0PDIK zZa4b337uXOO!w3U*&2`)>a9P82Kywi-9N*Y8<>a}&V*jVo(cmZp8& zkhQsS-`2|XHP<%0e`C{!P5Zaeg@@VGM_UeVzx?TIxo^BwwDPC7*1y%b`?L0g8@djI zbKeedSDs7*vcnCPgED9Mf;~WXCU3V;kR>6w?@}Jzczg4km)?8*^s1LHul=Ou@Cj{6 zeQ)>3fO0}hJuoXH68)tBhMm68vY&GatP9-NNc>}of2`piYxyTy_KB8xqNl;Le`{g? z7hJJ<|3*(gws2pXsC!)7RLc$5wQN=K{-$fkI@+#i#fCvk*QiVB=~sFN1DKE1~|1lR7~A;5ZvbD+~XjNm>vq8c7&#@zgb zPYa$MCCp4)=B91)L69R9bcO=6xC!(wA`RX1_b+&R zqeuYs0Zon+`dR?zk--r0F>o@5JOa$&)BwU|Kfx8yNT{{M3w`j+$nn}CXZP$7n8qgnvJ0d%R zI}*U1ay!%>tmoh^k0aiR5bt$@I^B*AfV;=m=C!tZEv+5|_eK!zoT+ykfbVr440o>% z^Bwv38n12{-(LuKk0uFsRA)z}b`dqa1KBa$%ZFuGOf`AkXEN)KZ)nTkVJOQT>nWY) z>gTwoS*|spZWw7P5ijRd?b&$d)3>f}`beI8;7&tXh>=e#JHfm^2Y0wfJMR;s$$=`` z!o$%~+})h~cODa%MG^k-^9v&I9h^IOXK>JTm}i!RZF@{7#dO+d;GRVMGXi&yRt{lB z$vyG%*wiD>j%zXm?(-l5cW}oHuF0?j?$SJiqZV0VmSUz9s_~X~-IePN`ww5+m{z(y zlRI<4*Da5*%$!;^C6~`CRUv9=SqH!!=S0$YFE�_!Pr^DeiHps~xvOz7X!{xPsS5 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

x{crh8*Uz~1PJ&JaQ9OttL7c~ zcbX|gH-<3W>E-~T`w`EuYyjffwg}sfjx0N7YlMv`kHQ%~Dr>2YCWyYi9-^bxJpfIk za08p-G8{47v7&5XH$pk^J?YbB4fb~e3>CVcw=pgg}R9+IywguT!NXW2b-G#fK zZt&A5kr?AY2=}?xc7S`&V~4sP-K#rT=VglWeM4Kr;M{uv?zw@s!Vrqxk%r}k0eN9i zQ5;s3)QaMmJUc2)E5)fnajcIY?38%8bba$__30DZ#zrS!lGIv0SWEvp`}(`-w=c!s zdMoweN2RYmDt-5M?wfO=U-~WElN}3ft*VCI?5FrHA0jL-YXLg}G54+WeY;dtQyqdv1h<;a(i$ls!8lJG%mRQBH>{VMI*vcnUbnZO)->5ZIID98o%xLKV%q;%G5YHQ;`ndU ziSLrp%kjv!$p{$pYx(5WT&1TtWs)}nt6#e8Z)-<4yQS;odNZTdCE_m2g{vJRU#G-B(6*r)$k@iu zxr`TAT(7M!ycJ*lAin(m`tp0v$);M9Jnyn10oiSyl z>MgAk(=8J&k{%Vd6Y`+)_A=kmWNFistKqJu>y4--LO!m6NYwtYae&f)~`L>eU41KC;L83$<{^9|kJ{r&4cHwvv)pBbxF` z)T)awb_DWW!7Mypw6DQ!0A2}X#}lU^9{ifqL5_6$ynhdm~=;s?Ib+A1HCidu}-zEQ*2@4bc5#D zpu-2SZ!jH5@EL&k;OHx%{JmsHi&u%;%uH6~1}B~pxDq@k7Fwf3G=YJSmyx(JxQQi5 z;Kxx#BRo~WfDpFlz;qX}UKBq3Op-gBn+lK}x0NUOUfC1Zw1_AD#=C;X0l)-0?_danD;J(Zd z=6Z*=herzo1DT$Vbg!&1)K(f+6oydRUQo8@2HOk6ottCbC2eO$EsG6`!hIrNJKx2l z>s#y9b!R48Df5cHoMHCu)y!wHSAQ9Q^}XEtZzkTol>G3W%&*?g{L{tQXQ{bYZA1PZ zhE`Z7tAD0-@BcWs>o1?(_cwc+9_c(28S&!j*QagVU;M zJlb_~U+3w={iIg4u-!UjS+OM|ORppYALXK7WH!FZM!rc$ze~ryO(!lVGbVn>SiW)E1SEWOoErcl};k_ey;SV^PB&YjoH6X=a%WvU{mE9|Mqw&HH>*xDXR9#zYI)EZ3?M zkF2JI{(St=+v6hyvC1tB|$#PV@6c)_E zueQ!{2U*hrrrpo5`)Kx6ifx$;o*k^Zbpb_H0C5nI-3CV(&ox<)8f|k;NDpb*JsL)j zn%u3W_5$2(1l(P8wTp(5cMntRVW9<0fb}KXB-S$30AydGn7m}8k31D1TLTnZkZK9g zrq-xNB8w+{BE#sXBN11OYg9o06jq34U#B^$3ek}eaEb8-z?Xr^YujLg$2W&rmI&J# z<=E~DPT5w}!vOhQ=Y0aQM_Kj=6Rf%;Oml{)cECCuH)u{QxCoRF@k|F!a;ohR z(&c@t(IS2fqG(o0&aC=x)92`t{ccgoO z>FuTAw)~*9FeEJwcL3Q-s=jS)e^Jww9Fd0l_<=6rteCBDZBm~(K33oAmUQHevv2!~ zpC(@ZEb-CGv4`<@QD z)Lznxvl>BGBP8H1Eb8T3M(Nh1te}=gd+GB$(j@7y^5l`8qx(D098+=Gw*HYN{rtMS zkX(B=8~LYf?Av_eN-A z38W{wh8aNidLyAJ+i4)X(Q?XQJ!Q1l0n^RX^_J-~W*E%WTRn}4>2pnv`4;C~vvZ*Z zk$thnwbVMZOmc&~6x4xWmG1DfT|usAgFhD*%twR^5z$=LFW)uJ1nyJfm84)TDe$F) zYl!k?xR+J&@_r0=B9vdv%hswTkF~ZP2Qo=`N&tyKVA#=OQ8=c=OE{)4zw+Lsh-eMA zg4;T#rCy>9UIWB~6blHfdW1O*xZj}J5%iJlSk)l@LAawvmBLv} z>I$sk6o=!$Xw*>v^$8%Fc~$Zmu>8oU=Oy!?n(xAJ$KQy{-r)z$Cb{lPlr&Ai-2q=p z3lQ1yY%rb)*g$)t+k*@n3S@o|?ksHE{~X*+$h_0_goU5<(fO_xAc?vJxHLx{2njh#-bphPvh02^NQ8v?29O>HD^zY~fa;lEVfGE(- z@ya=NCVA{k{a9nYl`W2{4R0*PKaRZo%fzdnB;NWc`Nli>58uju^k({(7h@l7`QBW& z70rE1oiq*mxSV;I!9K#4oe?YPJsR%d7^8cHBp)ToR3!0e3t!pD?Kw$rKSJ&}M(H`l z>N-J}9cmTrZEQP2GjjUU#-$H7&VC$w`QmamXPuFx%y_&bCUY_51ZTb9; ztKe5ITlxBqgKX9lb=037!Q3` zlpPghM!>3ba-%?YZcfbyW!3!j7(b&C8U%(_U7gvx3>P2N#EL7 z|7LFH{juRvmplwiuRAsgM};Uj+?O+IUv*jD^VmM{*gjmD{XFFTD&qep8u%s_{5rAz zO(uLf7rs`C+(@r~m)-cj6u+^Px^+Ht>q6?r_QrRK`H$yy=X%LAtb?k$N2PT?ngQHPzZ@@CxFx<~n;cm1OZXGmTKjmsL zgJ$Z@o<{S0t8K2uG2iN3Xq_g=K213HGTc|F&Q+@2N4NW#(?Rx3h~wGd&W8DO5n{7C zqSyJtgM3f$R{`#T_>|CBf%__AEFq1@4pyfV-Dw^ioaBWaA3i zv`U#;rJy4sJAykl?1qYGFWdGi+l$Q!VQ>E4(N1hPLuM!;x+; zi{N`1?rZ|?Tz87+Ndw>cvmmrORETSG%9FQ*vqqJU2=3zY?nu@C!x_T4SDOb^;ZDr= z&QupP5h$Oj&Ja{$B`5J%FoSD;s&l^^OvgII9-v#{7%UfAUz{&t4eWb8L>xEyKMZ;NG6@Q52OOMJ29@R1}9hizD6Jnt?4% ze_GiV>J_Xgm@_=;WOKvtsd_VuyFN7WlH2z|Xy=o}8=s~xeVYE@qtx4PX5R<6UrPV- zrH%Iz?sM)@|FFO)ZtUZol*#Hv?ai_wMwdY{Wb07b6~i`3Kgc0zn-+8JLhclsX<$&z z9Hv7cv1#%Y}O5$z>!@K@>5XUXDQYmp0cKCg0my2ApR?{h^b0z2-) z`MK?kG3M=`S2cDCcDFSCcyHs6pJP6@zioe=u7y1>>)9Aor3Twl%C_{dEHxs|3=1=( z!mLV^Rl$It9pNFVFxiC}(3mKz5$BLw7p2vLEKpu2&TEAEF+o8iEQ|>^`q_)J77OFl z=&6G}FFx0E4x9#qzphs`KwK5ER-fE zkFnSx4XKBUR>SKvw)YliKJ_nsEB*R-PzvwJ~98PW2n@}T%_z%9{+{-^kX8{3*DV{s!^&@ z&#@UO`YDRRLe|?!MtiH#(QLFg8EuV5d!y0Tptm)^(P(d|!X3$hux=u{iJ9C@=9xzG zOoPeOG(|-1_IWgk3bx%@fjf$2yrh{`D(Z^0MgutljOie;o%9CB6Xv?Zyjiqe5r3{q zc{C6%#6=aj3s+Mjq_lXo3U|OdHu9D5{Xd609^jn4_65}v$qL-d<{iTw+xBWG9}_I% zhK^CxA7){lGZ$pf`ho1MnHAdf3dONXb*xZO|9bH3%dO@mVg{ASUJ%ELVEul$Bfi(d zUBl=`u?(fxN*l&-$7IKFchR*T+Bk+g5xAG(zDzYOk&Rx0?+Ec^pmq)43B<2~sCUUu zz*#Y!$jI(Ws=`2T#iTEDB>(gx*@kAhl;2xq`2&SWI z8H9MMg?L+Z8m8S;A;N9Ror$I^13@8PBNAje3?hJ1xEAZq5cWZJgWi2jb(kn&l zVBT?eMg;VVRj-hJwld%AB7~<3Tyf3}uI+&_o-M$LkFmrx4W{)z zg%}pJLYRO%Dw25s?*6KnM$j6=u*T5)K`gD0Ik-&ib2Z4-&$o0va!B$IyN7lknI&;i zEHk1i4D=JROj~iNtElWGW>(va!(FA(zOAvL!f0=7Ko;y4%!?Todh29!^JoKUwNLqy zJMey}@L}Yok7JiU%f0(~{?m^#@4u0L_fqA> zX6l^0d&f5WSuFRP{JGDQrH?nV@u}s7Vdr$W(a~w}j(W1T*!jh+v$MsFIqqq*_MQ~i zKfM3wUq9LOljnH5kMtgI(bI$;X?LVg9v^B;jVO{M(xg(DQi5j}W=Fxi3$r5vBmlii zm{y6A)RK%wn$gOTG}4?-S{RoB?g9NtB{$s5aP#WN8}|1d+}*ZkclY6g+E%`+Z6Gwh zxao=I{g-l~53?H|X2PFl;$P;HUuRR_WRu_KGv8-Y*V2hA$=H=t>{=>*D-{RN4sict zGWJKncQSDUIF9+A&)(T8{jpg1eIkA>;QwmMc(J!T!C}m|)Y~X6E*5o8%w1It7H4el zE_ps(Tlx~Pj)1;?H4(XyjNFWdu17;KzM6_(PbaQtlGk&|TZP1}eEfDHdM6hH{Wc%H zQ;gl-PTV<{`rWz2?ak1Yu=`Wz=(#TXeCuB2sVC%(Pb;_w`nv0NYN}EH81qYveK9A6&0=AHl07?bRt({IaT%N7n)3;+mQn87^19yPFciI%?HBzrmRc zvCy_ke&(!?>0V(>d#O$|wLrG7kZj&oAiD)^7v79ZVyq9sy?PO;(GFyXV@>8x>9tUm z7TPd|yOT0j19#mbWgL@zkvzUc(F5O?DG2V%1m6+jNk)S2Wt0bi<{0!fWGCQm24S*e zxUZx9-ChfK#P z{}Apqe20Onvh;tBC|(3od&;XuD=j2(JL2+yXaz&mIL@K=#pUlR-x4Z(M?jCU;c)@i z;NQ)Z(2)gCB-6Nd6D3rYi2)e=AlwPz@)#3_du96ihv81h09s>eytMxL)^6)bp>lV9 z+fVn2e)P=Xt|K$e9B}SCBdX%y5K#@;Q5@fVe3X9o)BNWjWk0-_c^eqy@(^?Pi;AO7I=V2}B@GWK;=^qTr97?_CzYb~ zu!tz(7onY)fbtmYDoIK$NsUR^kMi7bW{% z5brzKb&@pB>6{((L~POg(rep+xAPlc%gN~FWbFG?{QGR`N+EYWmAsZr zTq8O--cH5u5ODu}D)Gm3@{fra>g<@y{H~b)<5uyHo4McTk~i1azOq{`DF<_W?h3WV z#UOhGY;SLS+^BoSV}IW}_Zj$fVEV?|WxzTxJsG`~h}?{Xt|el(l8M`Jw?LUbA%yt& zja1}%HgYSqaVr_Vm5JQW$8HzmcQzAuw&S-!#n6q7xnG%;TT;?Y!}9~j9+lQVpi(4v^X0q1mDfJ(`LsRR2B(X zpKY-qzPH@ni3zZ^&|HT563K}w+*_T9>}2-}AdhTarC2fCt9%bKoy2z1o+{s~h>xNC zWQ8#7z;|%mfMd*PJg7}+R;oZpgFgdzO!Km}mjK7_uZXX}y<8KC!~rf(Ap6`J!@WXtEd$w64ZD4rWXCPQKtT4zCQB{Kt8l-E>;&9F^GyyM%XFzo9U5|v znKB4)cTiP8b}YnqfIC&YNYVk;K?@|^0tpa5xkNTBk_;H`%P=4rs(klX6d))MLT!OT zR50wQw8l@i{5iM>$yN{oF@iFX+JXgS4^j+pteW&Fw(W#-$4sm>@0Ezg8DTpAf6Cqi zx~(hC^YrX=^~}!h>`c$;)4S6>z0*^vt6b&k3U+nbE=iVT1uKgIIWgxP0FnThGjb*} zk@E`x7?mSMMca}rTR8`cnUq|1SJ&SA9sokJ%d>ON|J-x&0D_OI^6&oNcfb36zC=t0 z=0TEVCnjrVpZt+j)Se89q^DE@5R+U^gS#P>pPniKpXvk>f$1(<@?(jO*@Rxfz2bgyoT{M(ct=e7Mvyol@ zPal>3cpY%=f_FYt@8_UZ0PgMM0+QdFCPt_o^&1#YjC~T(pu16 zm04Z7yQpk$VQp54m{Ho5TO}{AHPqDG8u^Z9zN?AvYUKMG>mq_Gq@^w*YzVhBqT(i0 z-0W{`u$Py~*u2(#l$KqY{fu0st^bM_yB9lhBQkNt7dsUkop7OExkVx9>nIlXS9A?` z+YZ_fesSRXAJ7BmsX zdOM2W#<3eXI)@>P7>vd&CWI{F*kTM{j^T^(=>ZcoCUNLvKhEwDxlhGT{Hco8ucr(}zj*s!$LcWK@4 z?5UGVsf2p+B8vIOswMPB30<(i#Kzz4}+G`^C4rC$VPVybdNf`igQ2LzIz9ifwDYBDrCzT$VA!F`I z=o3+LrZid4K;mOb!1n-z1-TGyq(dicFR|swRi7J06}Z33 zcMTa5Nh*$XFY~I1$CN({cffQ98>k;>nAPXt^a2gDdu+_Ep)9_9M`7P) zp7>o#-7j|3y!Bz#&o>C)`$)Bq9V)9E7l_9AO?X``R#Q150M5M*BEGqPq^$vIsqxlV z3>D`{S=llkZK%8m?drKO?7a~?bZhL`jgjduMyEd?y>vPH$p!S>xyUDHBIhO?2f|v! z*k#L*Im+dL8*ppwmC$Eu`FD)%qRaO}4Dh#znrrN^c#u8t1RY+JDY^e-16^B~N z2~|YIwP;&ops9Aaszg`J>1FL}+P%4D-*!`V>4_orm5}F3$agj5KNT4{hD;vxjRti- zZL4~qc2M1H@X3)$`_TioVG^5Oa1(s zP;)iXQi+Kwa8WrfEQ_|3z>}+@l9AT3czb!Ytqf}`N82kfi1q4dXARa-;cLz_S25(d zd)uR1#Q_657?Mu%{+IM<%Jdtlw~ z8Z&oGOY>drEt6W=$4>KY-|zzfbi_9U#-QtQ$o&Ms9oY6r2zd6HaBwahnu{RwKp|u{ zgv~~xvj|35`0(?f{|UGsEHnpJf>C^V6ki&}7e|oUcxYxUGCPSZ9>kVM0?)1LPdn;j zMf=tJ-w|y4aoNrvm*u?2uiVn!w5z{$&tTX7!QPC4zJ2|D`}+s>_XD^~_5-*}Q*c-B zm1*|MwEFwjX1O@4 zNjIw-xszk3+axu?jUg1eIQ5 z6t2n9fLls6-h=I7bM@rfKz^PS5nfN&^ORn_?F8Hb(}N5Z;Cqm%4lq^zWWp$X)`6P` zgFrrpd<3hOe8>N4{i zGP%9HTvb`Qm0xRbs&Y0}_*-fs;s!({K)~2mjkeVyt>8*6-XR$2ZH;z`LPEZ_IA5Hx zuV%}Kb=$XTO3RMwhdztoUtpuRV&kXrgD2w0k7LIWGpcUYi3>WqE2O4QFQz{^K z@W7*J@G-#pL44(K>_t5A+^)RbR*rE$9Nh7f+O6L&q5M;I!8&2>)^5S}9`VlJj@^CT zd;5C#_4O0ZorF6O5t&KAU6&y@WPwo%WXO`kzItSJU#h}PR0=Zz5#b1PhAahl2UQ8k zPU<`0{%ZW)gyh?Zgcci;Z%KnYOlrjQfqAz9vPTQ8K!ESDA}}%I#nyC=r}$1>fi3RH zE_VnlIRN~-6O0J4znVDQ^o_hs(zAoRN;b3BdpQ8>Iu`?IXqaxWQFRt7aPI0P+yU7E z-!(wiEH!|;DV^`%2KO~z51e}otx`y>5@l7jXV(qVS|l`)j4GB>#0pBQf&%<|tBT&L zp|uTV0h)IM!*0mzFlKaFvLMH;DP{Fqi7U430Xt<7h?oEuKQK%g9HtIBfU*Yx@m(-= zvfo7mj=rBb)Jkw4y8A&=;H8%de7bavxiI4exOiD2`JE*vPnM?O8zjyj0g>gvd`x+e zqlBILa=s5EuL|@DjLn zFxLjy>SWyleVC^O9{>|1*MR035O9U7CMi#Vo_rM05WA_s!oTv&k!In^{bW)yQhp|} zOH8bA;9n`JK@XG6f$2@A#6TqzQv1l4PGW!C!GPxv+?;+Fr`yJC)nwH7Y|9n=eoyr~ zTN>Wm(ftvbb^BWmwXnlytu#4Yeu)nI}al;0GptH+xJW3A%R)|Oa{AXHm#&MO|w zqId4e8f4_S_-!Z6fjg6D=g;4ryZHF-@h?6Z`}kt~;-!hp=f^%h7CAHGI2<;_3?j>5 zjk-O*UC0s(sMQUbB@LPRObL%Q`)~g9TW|kgKcW2My{fHy z6$KS;ezTX~;H)hlt}1fX76ls1k(R1ROH~-y`L;T|s}bpJ2zS&4+H1T`Rkrd%1&=D) zzq8`Q_j1>*FWS0A#4a`pdqav4Za5URoQk_X9`St<^WGcrKROVaI~ZDs`DS8)XCsl> zIP#pV>=;MpN3caeVJt9*hZaWBl`(8}6a&V2c_O|t7F~+?A1h^Nn;N3|JPRdLLCsLG zsoK)K;g*J|yzlhz(C2RZ?V$THY}pZQ(kD&`FwuAwpFgk>y3m690gGCITLy=iLG(Up@TBkyhMjrNHqN^QDt(&2So}Hoc zGQofBY7gK$4LtFKhgx-jWeBo|LL6g|YYy_PVW3=lIL{HucZTxqp@QK^@o=cvM#vg2 zHiwE~c6^{abrSTX(#sD-3M^zk z4B5asm}3T`muK+s^d7Fx&DOfuIv3mEWa<+glxRx0qd-#((-d$*ky$BHGf*~JY(SnK zWG5Z^(0-^C&;k9;SsLx#1p%($pAeW zod>{5l1r8hG%HCizg9LNUF3B#D?EAJ6!>msfTKu>$ekz39>ACKbOE@Nd?zPCqB=s5 zs|<70A?L%^{bI0GFYS} zHU_>W_Ch-JG^~FM+)4AEPI-8dXrJO@4>*~9@LhJVg9-jO6%1@IX?%Bo$uB>s`t4Tn zmTWbncqpe*PR;Ax%NWRDYdQJu%37>hjJJqF4Sb|Y5EBW}W`3}t&XQZCq;du_=yH0F zvsQRq=ej$3X5s9e<&PgfJNM|;vFo3Ve|mBB<4XswUYNXk9GOPUqt*dWZ>6-WL;~P0 z=C%u&bplFRQ+7ccGf!GrVXtX$)Yp3jwSGZWh+h@qS7U-oTu>fuu80AqLsi6Epuhx& ze6RM_6&MOA{n^`EcdqNp-sWv6pVsScc#&J)=!MX!Y2?xwJ?#Dj8RbgA%?& zCGy~g6O*n>Cn8@Q4O|T<4|EnuneVgL|LwbP|Hn5s{XcKgez8uppJ^zqa@96?YHMB9 z74F*dAh;P}J=#(i7E~jmI=q9AwKs;uwH`tFPzkS}y0>M=rs|FB0Nh(L>8k2lZ;y6t z$TvBBbliDq%=77p|9U)lHx_sp4?YU_-+VeUl$ z_gG|M6knN$e>om|0ZhGh=!?G2g| z+auiD-M*)*Goxo9vwtAFPm%g`v5*@LrQXmsmZUX+D zP?GO**g%yA%&c^nDt8i|9a5f*&k#o5$I$qh+5k)EXB+$+qn{14P`qrDmt*qhS^|02 zV4*EgYz>xJgTbB#W(-p$duH~{NF8YfHRVCtY~s$r^sO^_YtjFNgo%&Za9Yed;Kt(mp`l;%Ndi=5V~pti~Z;+!4yfJ#KRqQu?gGG>NbN_d}oE|eP-^D*6;hj ze^TQ-ZC zXqe0-#6WhG!I69KnEFe|d21tFh>+-}Oi-InS@f@;FvTww6O5DlKp~H^k)w(@x9H zfct@W_^!`!4-LS69Z|4sgaLdP2rb1T%TZ(%M_#Nc@&ZF%VCV{ttwylr5OCipfH*+; zGK#HW*b0g+Bghg7cR~R4ix|FyN0)(rkAUR|pg+72N0%m}FAm0DjD==B#xG>;N9yxk z``#D4|C9WUKgikhc17_fA%Aagd-h;wMt?_Uza(2K$sUwu^~(U+vj#Ppumv^&cVOE| z&ko}=B;0{*ht8cUGtuNwfbtX>%zOvdl_IlH<>qXu4Sx!LJ)aGSxR%3ia_cX3v2Uv~2Vjet9?RYn!bC_oVI zYHBNh`%o64{q4rg4s&J~p!qNacaJTr+XlxTdv>oqs}JBF2u$o*#LF!3nSR2#50G$o z)B0Y6yOY|Ng8Lfc0n1o}Ucfja5fJD#xW58=wkl=qlMx#Yu-h;wp8)qOKAnuiyax9q z(^I>+M0GP5Dp8S}u|&!Wz&9M>guRCH5RuK2UV|*mP1L9X@50B3w0e_dn27ju)Pz*& z0)Ge$uM=>8&7>!RJ^@ivNi# zC!@A;OTTNNQQ1>5D5=p%st39Xx`nLTW=g4;R@9eUs;j8?)bri-b$)&|(o~H#0kT&| z1ywOYd8`T0yebL|J0LrZeU}k%ufRlA5kaY|f}>*X?%cD!bN2>)E^WM{^@_#uFc`fQ zK79`T_+0GT+0i>wvAg5mD}Mbcm-3KPKIu~*j#{QqL~dLhe{?Q>_ki=fy*nu6v@_mg zz5ic-_wL{PX7^7w7H`Pzq?Z~hgu{&;PCex)umg+P5b-XGY31eBm)$ggd&w>4ahS4RTPOX8-`zo0Mj$%x(q1+cNy6TI}PrV zgoUR87cVu!K#jx%9lg}XP*`aSKzSe=Ks;UHV5po-jhn6Yuv9=^w%W(m_&6Fr@LoCk zVB%zxDUfdr6qx-m@M8AoTSx`-t)T)-sL(=$WeBn-$8cJunp9*afpx-?CqSQ{ApY7# z@>~+I>O^cE03B`s@L*z$k7FR=o zwo^!mcas_h%I+Bk#E0s0WcAy#$d`Qt+<|lNcToo1G}xB!JK*jiM#889&kh6=)qUj2 z9U{fsmzMOMCK!u{MJ3q^F9QHtf#hk4;LIzY9pI9rIT_Y}EiCi@2kt~bKk<}6-U<0K zxgU@S>j$~Y5LXrAslqt`^skg8dll~AA_DG;?}U55Ct=~i6>`gTjpJ)@=M0h};qK-R z64l-T-}^1pR@siqrgv#YKlzaQ_rIll|93U(GW5CpNVC*e->b{5@5?F>eMDDsN&@^= zRNND4YPVO`TPtczr4_22ya5`sYcEAg;rZ%Cm#qG!W0(GT>F(-3Y( zQ+KZ&`QqZ(C&$C5aqFmk(5-0J^i&T@8&s+$leAXSn$ymwmN!$1J2_>tlFFf~23Jj; zrw-Wm8my%TZ>q-ml`%o(h@d>)1ZZ9ffDWB|ODRyar3@FAW1nhX1i?)Au)I{c1<$4&Fe%V5qLk+SKoAl?FSM{x+Fc zEV1)D)g`r^w4C}KnH3v%RDYDw$|}&*34;TcaZBWg>-1so)B*S91D>nnfjc9iN3c#W zY(@PHw$zBsK&uYNSq!>$g6!CH9G{KH7DwYNVt#d&TH-IT|% zSCxf2TaU^H&e=^jL*A!YXbx_W2H@UlEV76OW=Xi?z`2K(@$hmqvJyj9UxRxT|B}!P zARO==OA3F1rYVdshw-HdA;5PGkUhErC?7`VQFJjHU5&?9adZ)n%#8vIkFSh|=K{lb z)ZNEx3!SVjUEAKS-0_pbj9*t2d?0Mx*(=VF^khlwhMza_nl zL5lCBD<{(#Qx2WHl5*>QZi4JSj^4*LBvT&sNzV=i$nIdi26yE*;4V!{_A1}kxNjyZ z6OaNwLj0`ajb>U|GqplQscFlu@23g|=|UN!RZhY^TL|G!7i#IP#;gvQEtB14%Iq{} zbOPsYBWa$Uggcz4)aRh|4`=tnIi(lOog~?*M8j1WYES8vTzH7EWF82S-X|sN^b*M} zfXFf;g$8CxzRGt+YEzVSO;S9Zrc z45&zHENHZRX3y-Q=|5h& z{imyszrOP1<&~M$tFto~p58fi7dZE6{M?9r!aCrTHK_(_C6WfYuGMU4wMpxw%`9PU zMqv{L*!D_wWsR}A-ceQUt*=I!Yj9yLCaA(1%j1pZBZAU+b4g5C5fhfjg=GZXOQH$B z1L#+T8wza26d7%6$L{q#`?gpLct`pMZaMuILPt(V&YXx`IF4LB8M}QPzjG*Z<51-K z;mGwvq0bM8zc`8CJ~MLv{KTVA4m`Oq`e4F&!PpTh&2HZNJNCvO@7VI@Hs*SI6SH1X zGhh~Lot;Cj4!xyWp{ws7ED{Q`i%YgKindUzcCp)Y>W9QCL>rhGJ~H7sKIywU8Mr#; zyFKE&6AuEiKP8*t;h~wezISjFbr#lV2W}mkjbYE@(fP6X(pY>2IO4GHsm1U`Z^wz+ z3M7YRWl{_UJV#Ugh_r9oY`o!eJV1i8fc`MACNPT<^EkSU2In!7>|sE5xNC|>UPO_X zfazEy$@kabj=jW^La`SS7^qoA@D~XFG9B(2Y;_!6L|pgu(zC*1A7yLDwl_;Q|2S{|FUs@YZ>s&MyCXx|ldb5d%B57fk|xto zq}pt$9>6_Y4qUvRDl^a&Lv$q+n9$@vCc4Z_mzhY>;AjLBhTO=MTbU{=Q)yu+!8pu@ z-R7Jet&^*B@$^2P)|aF6@pS$iT_8<>@4+0%_WqOZ@B`O#tq+3Nf{&joQ#hYmzWTGKQFd zyI4kPkyC|AhDghRdG145?WW9jOLn(4tJ{*%Y0c;a>~>H9%DaFZlx_#)I3a2;Fyr7Y zC^%1%eZWia_c9Wd-wC}EVMvEN!FLG>ccT0{u;j8tiX?HwDUI(6lI)}zkL1EQJNPOh zwhnlzOec8Cv!@WBQmXvqD;uiGm^*p;iSX<&bteGO%pv_dTxq~VL$Z>kaxJA2tP@=D zh2%ORBgz-c16(LSM+O8REZ7R-u|tuXkl8_i>|`k(vKmk7=&uv5g8jrMs)QiBjO074 zl24SBA={z6CLdSs1!U*RoUA^5hInvWm3Uol?b})9zuaB@Zl-uwfhJEFY*tV7+u~g& zQ(0SAW>L#d?jW<&S=WlTNrIx@p|W}zw|J0MFv!l6atj zKYRM88}nb?SX}tz+3Y8?_onV&8vk_Cd2m?bk?>2Vs`?EO`}e7c}! ze?beaL|Rm%ucoSu)7qi6ByQ|S3)$fw8g8z)EZ0=^$XZyt-@ zIuX5d9KU@6zkM=#_jK&u`SHgWC!U-@ZlT601>aPe#ozy%?Cn3@mi5lQn*C+Us(yEu zCD3bkw5U}T-Q7F^e}8G|R!-4oc0)$-K#^#;%@EaNhh0aGdd?p5P95@pKJL3b>bWuD z2XKFY2cF=8XLt~3CKjFriiT%Kkl7KK8#6x^T^Nfkj78_hV~b(No(^}w`e8D4 zD(MOpRjQ^)byS%?Tc*pF7^r~e3L{-`hCSRV}n`;8*-J7Eag4M)`Ttm{o`?=b1E)19ehy#=d@-2ZpOEAwG%C$xE z?O2f$EgVJ)?BPOtq-Yo^wgW|yyQ5?PJ*^(uD+w?p$5TxAa&!r%bM;Rw?{-pqlIkO4 zEJU!S*GZBc#@Qj+Nx1u%iJna)q+W|Td?R-oR&yk4^8&c1_)Z*gO1WlOJd%Wa>XZ}w zDk38uAT`aWCjuSm{yp_>%DKM^_axTI2Z&c)KRJge=cR4)CerZbM1*IMTr<)FKHy5C zA0Zj}A#W@tG8*GvE7*{LJIQx=0GQ}rOO(i$x)?GSL+WP9+-xaq+3{*ql(p8iT)8J# z=4A96GutIw>)O^8wYQm3?@J>43zIcNq0WqW1m8qCI)N^b%uv zlef8NxK1qNm332d2H8bJWp&O*(IJKD^YG}>=}-Q2`QE=?d-yNco_&3Ne)aSD*-xH4 zn0|QU_^q?C3%Dt6=rs4$4ffSLSbEYU0r5j z2e(R7$v4&4TWafFwY7dhEh?_Vh1HS9GNhq2DkzHyUWI#eaSHB4WTq_AROGGY8VmOi zQa88mdcP;*BY#89Cqt(5p~)%i^eOc0QRLF`=oeEH4^ECfIE-Bfa6cKpcQSUD)T!9L z>9I!_CZA1@Jv|(`6*Qb4sCVY%+L(OcoWpV_;s=(0 z5x^abEJlKJA^-ERZw6e%Li2#{7!0*91EJw1G`s>80&sts4tErRO7i_%;7%$MT?Mv1 z7+nm-0N^ zy*qzivHgdI8E;h<{=T_xM^8tVw4bJs(q(d*9PnL7lj*^jJ!qgxhiI}S#}j-v(iJ8~ znpjFR8iX561|adU<|T$pR<&4D|pfkdbTo=`>dZAiYI zBzUO61{BT*WVay&!&s3EEp!0NM~ExLyD&r(DKsMmLy>}^^h%Sd^QA=PfP_6yS#=Lv z3;3Rt*2B^gY3y23Zl)mx_hE*{PFLIMVAKuM^@&8FHMj$y%m0_)PB1+IcR+RscOkP< z#HfOBr`8QHTBJ-dfV+~>uAl+Fi{x~Xk|ovxszlE_W2XJ=*%CjVZ@84{C1$!B?VUs2&M{3UQ zR_turA_0h_P%9=ca z9!r(5hnC;6hu+J`chrl=236OQ$!AB-ub%zvk5}&h>H5<@elhdnvuBG}X6COxe|-MQ zjT5(yhfX;L+`Y8}?G>F;zRcQZ^U8ey?)^2&Ms|I5Mm3*W(pOM#sBJMfG?;2?-3|4D zraAz3R9G2lEJYj3V$EeE&BckZ3~@#@3HM^cxtHUja#UCxM54@6v_@08S-9lg=G z>GT2D#RHy82YsK8yFVNAUK#b>9SPkY2|tVm?&5(5vCy-T&?b}T#(G#Z)%aG$^y z$AEcH=DCMF4@{a*+gm0|a@`D?o=(*j6}Z~OhqUU;4*T7J?-`&u5Wsq(asWVTWHII3 zW5{w81>SrGLL8F)1xfZO`W23SiJ}neNMwZ+!S_`>`T~!x65FIi)+6D~fdI-w*kS_i z@#P3{1;8DUorF7v!lPAWT?FvkNku~oBgpb(d=OH69fMiFuHXH$ zvaGjC3f4FCclCB;4)jt62eT!z>_H{L_n{=&lN?u(GBZ^c)|vp>Nf|jR2UqXl=mFUQ z*4?}zAQ#u*;thFnjNTlJhiCTki~#X&j={sxleQX$PS0JHtqd7)zSQtq5C-~mjt-EWggZI$uyiEZopeo7IxrGg zR}mdh0kr|jH8!e_XfmZr?{*Dq%dCO^b-1S@>}0?_6`&^r?%;dC%JD`ktG1O<+e)qJ zBC0|v7-UsQD8O_LL#$zm^^7*M_P|<$J!&@*hgtLN$qmxpR6L!031csG7;1+B8A34Z z&PXUN_}-UX0A4$LnFe=4smP3X?c$mrPl6lp6kO>`&J&;~yLgi@^)n^kOe9aFlfwqz z0J0KdJ2%lqglOIb7L^{di6C61;By8MAY#Y^bXkZcPb)PnOQod~zbH}IlDr2XBEMxY zJ)s4R0NG?KTKHEm2UFG7*2=CirA}fcgNq{gr+_gTIS}MK6ud|TYJi28yV*c84-CjC z-CVhyAyMxYx2-R)dxul=4wJt=w-b<^B{UZGSZZXRCLP*kA06}rTaC&Bu`r{wVl%5X zt3*}QtSM<3;8r*9=Lz<5)TM$0TIan3r{|`wuAIO1FIS)b>E`^`H|Ae{G5?2~tE)Fw zpMCP|$)#r($38&}xS@SW-lWjC>)mo!SRe8#J<1kU6Hio0Ew0HfYtO4xRSV1lk+oT1 z=QsESRS^+{JFM%%FTw>yBTdDlO+_QZl6Wg@;};hekBUoyU`szyS+unxCN3T8D2s{< zZDpA<#^&z*>zcRzt}k<3GWPIf^x>J&8O-*nu6=}`r{!)JX05BvUSG}FRLk02%h^)T z-7YBD-6r6vWz7+X{3K?*I^w!9;=MWIzcu2&9rNFf1s{xro{U7EMZ+_A=y^2wJRW?W z^6WsPk$G|wi_F9k*aj~ee(JW}koBEvtd11r*tm2(mu9N3L?u0EY{nY__v46vhR}0> z@SNm+P9Mvm6P)j9Hv?n0|G-)he>+IU0YM|4!B z8?d{;4&=?VdUDO~93xl&z)Ilc=u;pDpoa-91q8u?Jtw+kfH`pbKH`Lt4}J_R24=Vo zo39PRuAc@VK>1W*GB2Px@kua}c`qI!$I;2skZ^Y~)lP=W$xs8DJ80@*stS&bgkeuP zbW#M?HAIOt2y_DCQj*kQlFEc3D6b-Arl`o`1ZJYV8rg%8d<(7pSTUDY$DGZ4mB^HZ8MN%WgF=+fCUJ?!dM~=T7NLCwuxlh4|M%@1ggRww>g=lL|iH zO*UUmezKp$dW!E!Nyt*YWKBnJlI$tC1F-s-iAXvz4g&w~V}s{_K0kYqbl<7q2^nfn z9(;ZMa1cBnL@q4}2Q7i&b%r7ZcX$Kvv4bQ#ggbF$RG!ot(-U7yJ{%Ailgmb89ZE#W z)57B5r7Lak;gw{^HNHcLlP7zd=Z}`oeX(@z=GWJr{_D-TKYTvB{Mqcw8_Qqb z`Eudf!o713r=sUPa({o_U}r^_vCA~(7(IoY9I?fFs{87hf=WtJ1FfpNuvSysY~~AX zO@d)TqgPNB7S$o*>Tpw8gb#a}jcRY_f-7uapca) z=>5|p4^NFfIX(VtYU26nvFB5x&!)#_E=(>RMeYZU=Vi@EB}10Ip>E4Ba(@3~>gJzw zxZA*O_lpXR;4O#z6d?PU`}UaoPRw&F>c1WJ-NF5LqyC4{;A1@W3=7Vn!5KX8JPI{K z@*R+U47%C{Fh3Aqnv5@E!6#P3XT9x*YRdctTuTAhTwdtvXgQ>jUUFLQguGAj@O(6~ zfQ9BTz|F`az2Sx9RhS7wz?~%f8r<sJ_Thf&ReR2-Qmnpad zk#LWo%P0z5Jb?Q$EL};!JrbVBk)R>PzcFIJXX>ABFAwMK7})f~ocI5Zvh^RB ztlyM1?PwpME2K=NoGF)POQjhSHC1V3>C7zM5KU#KYK_^Np)9qIuF){H8ioc)&(d4+ zEbcOQxGs$GvB|cP!(9_cx+V{Gj8BM0@VaoQ(i^V!;|&piuFcD{c(`T{&jeh&FV_l; zJoNIp7DtZWUu+GP*!+cNcb>tWqxa?-{6vdBvI#1Yzi135?71l~4z7^rZ^`R+I=G@prM{T6WoaKK z2%Zg3Dv{@vfa`}v3y4!oR+`SvFxcpNJKZo$H@wl#ZER;Zv@;sJ83Gwo2+7zVuGQ0_S&)jK$5@7 zBcREU5dbKxXhzz0A}JG^dLo>{B)$Kig}X03xSzs3vCO1J!xco6YbXy(;eyX42@#J4 zYhf!-68A(n2*TaX1m7U{5O8;~WKb|rBXhIlfb34T+{FP{hqAMzhRm*ktxf!YE-ZeN zQt}IG(+9;$y4YSObJeI!6;f@v%qy~u$UZ$kvP*hc)!mHB zE@p+Xrt^#)nVb6TkDonQI(L2P!tJlFJ^PpI^DjP|UA+2y^~Ta4?tZy^WA*O&M<=mq zm)s|7QYxAiE}1iKk0Hj8zC$Z46jfx^R8fmtIE{l90$sh()Yt;x?rh@wn`%PB+K8ws z+*}gj!(P>K0`4O%0PZCttcGVE>r4a7ovZ$zZw6zq#J=Dapmjm;@MYQAH)?FJF zj7)c1--Oja6+Su@oj!)0KODJw483{+zjGYBbppMA5`TCq{^<1Rv#GJ?r^cV38k;>c zIy*f+e|CKS^vKMl|F%qS(bMfH(NN|2EvN(<|0=SQ(^Ai~0`+Pj| z9PvN0=&y8&Cd&$(9GZ^DFxHd>y2OVp`p{YAQk2XKd2Cq=*=CDsYz#1pJSOe`~r;0(;4 zK?%4=S10i0@$ekxeBe}mGT1m;nx)wLyShz3$=Uu>F8g;?jr+Pgn6f^ex`!?4p?68S z1KNDKE>EUm52~2`I<{2Lmh0J?A&%a}8?xq^9mRHkr8iU)2-gOYx`>K4(7Q_{{Gg8i zepS=Dn$}JH-kq%~%77(DJH%EQxoQ(vW69Oo@`mhrMq8e7xWMcxwD`G(V2&XGSj^Of zSQ?b8$9M)DD91pwx-?+9LukGc2+13Y``Vhc+egf`*>_jOTEh%EI0~`lT2doF6 z2S9hwl|Urc$vG@4Kvmf(N+5`M!nUWAJsEoe6B!Y!fq62+3>DzJg(@Y3>2ORW&nSt4 zGej?03Iw`2TWh81fy@*wkd1DzGlqx}>WvPbpo1gmU6B-G)gb-94(-EKy=huH%r1Zo z!TisJWxiPq>ou}}2i(1hO;K4Q>4isbkjlvIO%n0RjZ-48CXMW`DM@w-@o*sbGZbV| zco=zS52mu<;fL4A{z{*altU-rE+@8yWkgjRxc%#8C&f~E!E+oT4^!=CC_Qv2*jJV) z1m8a@j=Vo@#(KGKm6+Qy`_tHS3Z6C)#uN@zOnG)^ZDg#^D8%2maeZp`*il& ziCYt%!`1<(rrj_+I2^M^5Bd&7t*EhQsGi+Wno(X$D{0SbR@4X$^{UG~E{=;zqOGOTHURgck+$Nou3}Wg z^VHFdg?qa*Hi~zw@6Fh5X%LMXhNmNk&&SSA;TKNfpHIcFPsi?`KyIGI?w^W2o{B%2 z8hw6dZ0_{f?8%Y2)1wP##+Rli7SB#Doxq=BwyV1C$=V!U#)gKizbR#IYwfEGTL(`C z4VOcvYv}OJxcB~u?_tdQDC&Czuud3unDQ8n%tj-?z%Jkjaf~Rm7!NOwqAMej#aMWD z1eqH}pU1*ay~DS)^7F#RkwTuGMbYLkO?4GvN$;s)({;b=QN%w(rm@2@G#`NhnK{^L z?>pg6PGChz6dpGvjwY>OQ6d79h^3HxCqgUu8o~dU;10-+z{djk8>4{l;5LY`Oca4x zl0;FO#VEcMgU=}Q6Uf4-|5-qPO)EOk$Qoj8Xx{cC?ngglbN{)jYFld?Rnf;$Nw^Y4 zj$F-?>39k)OR8ncEV+7nzR{L%7%mucl~}wLHgCDz#8nUO>lCc3DfvY%>-+n%|8D!9 zzuvUtKX2IeR~s|_W-If*?=AloPqeW{p3ybLmfH*Tjsk-{M{DJ3tX!>)qqTE&c8pjK6!xGfXEaD7=i2z*oDJF1K>^*4a!D`$Fi(+1(;aLIk7ux z0V5pc-KLd9St34g=Lo8s}69JjwESUJ{ z%<4{qdj}~etUJJXY!JQ~xM()`HxHD6I zR^`ckQ7Kt=I0bj&18Z<6$)1P>v6J^nY`6NLPgjtF2kMv_Qf`JCR;GqzR{;^XG)TZ5 zJ|d8-#cObf5g3Nd!IVRv&Q-W`6fOepknCK!jUzR)BzjuEY+qaJ=DO;)3-f=*D)}Y1 zV;A31p^tS0@eZG}-k>Xy>Z_E&PS+9r_(}7DQEAXzs}N^ZmwmwEyuGhrJ*}NtYZb_2 zQs)`x=#yig{_(RXfBgLE%d1bn{OtKxUo3oebNR~~%d6J`*;gK4n)&q5=i{Cu9#zoX zH#{u&;Fjn??}0Jrh*N6otL?7Ht|;DH+`uU7E);6&MTQ2Esh)2W)Vqa^p%wu5s!&UL zxVbn?w8)5yisHgTz;poj81U?(!qL`ZATYrZAB2l0Aj$FW}rt$M<@Xx2?*U!f9pG0n)#vV-JkEdc!&x}C0PmRu>8eKRw zwmdbld}?fN`oJ<^ecXM^B0V7}aj$Q;79u+;czbhD?w7p5WfcnCCI- zdxQoa!(>O8$^IOW9VU=K1G^kUR^pMBII=Q=tq>`L3vp~N;(z3@TpR2@0cZ}G&Y>Af z^IanTxLSJAZMz%xJV64`v*Y1;lI*~+BOzFU9d_*?N&%DlR=7i^lVkGGDGKw}36l=f z*jK{nN*GJT*^?PEFVN@2g{+bNTf#D=b6o_6HIxn;D_q(V`v6-b+}l&Op^^Ucyd8g^wehcazW<-LzVpAYC-s|ux9->9`~9!~ z;{A92a{Y$C`e^rmr{?^soWG@QfTq^uSPc2YrXrWA&}GbX8guQI+#zd@-kvk$Ei{LV ziIRM$j_m6{Dj1Y|lBqINlH-7Z?Uo8IGQ^n$sQ-tA%Zk^&dO=w(6k{!O^U zUBqu8`zvrKw@=fvWs-205gGB)0N^`I4n+_)NYs1}k#!cyAPh5U&tWiKnlRK!rK&J` z!7>1MQ(*#(kD-K>WMDlnSgetFGFVH6Bs)E&-3DACz{-)TZ3*F?_)M}OC1(xpZkEyw z%VI#e7~uaO(6f_D!X4bkpq~ZH*{7NJJ~v|kI(Hb2kvmulVA5SYrHdzba%3(pH0*Ys z+{%?17=!Z6u8wW|+TRryyu~g2Cmw%ejV@0SYmXe1j-nj_OQlv(IH;*q`#U{{^b;p- zhsTttrBTyPZ!Fu))S8By7T3icm6Q{`SP{nwK!<7t=Dlb{3{(gN=F!$- zTwF5RQ99XGI^JCz@61PpTz4&1o4dO=>%)%S8~QjLcU#vnYv=-c{9N?>S^V1B*tK)9 zyJxT)XRwD;*ki!=Gtrr;`0Sang)B7&oM9m;91P~EEaf%`({wzGX%*06bK8>;-NV}cCuJ*99tQ|S4U7t_Bgr< z;692kk6?=t{}Y4e<95+_Wr;6`Y2h)=Ri(l1wxb5s74Ptah;Jt3c}9{Q2o265(6a-+ z&y##lkv+xt1l&oKW2+?AiTVLB!7-KNh(=c-wQ)f9Fx<^J{u++FXK73~qX@Z`P4Ly~f{s%ltM<5X8VrNy>3x~yt@3;UhYoj;_l z`2{cpej^}pZv_W!wM z>wlxLepOz*rLB{qQs&tVC2muh*IMp#m-xJ8UQe;hU*rrGIUio3VTonrB4v zjDYn>o&kj&8Vp1MS77ksQIDuOyMhAd<(y%)SxDS(X zr<3uPv8ygV4R&{AenAw zf(cY2=H9_<>|r*&0(aJ{aHn=#lX)^E-<^a~0ryncJr!zq(7GM;9@km~1|YtV+>j)d z4);{d{S~qk5sB}Hd$M!IV1SiKpp5VUi{%~~xFRQ89T6v8Wy#)qDU(j7uCFO^T8c$h zjVCJ%0|%`RB;XDgiPulJ5)HV?j)3HTtS_0?xt3}PaZi>kh6O3T;NDm=4_oGD!}vIv z?m}d|04EOqE;*@0jtwi>tAsrW)*Daaz-pfh#@r<^yv|lQ*bwf(synz+Cr{?!%4{4N zAiI$*RZ)7ocM19HtBQY_!~Genc72tMF&GvGj;anFR!jy&K3$1QQXo^+TLOdl0n^c= zj+0SkOy8&%Gld14bJ^<{wHX!W7X2CjvBxKGE?#={^2)P6Tzj_i$^AckvGnE5)j!-^ z{rb+AU*G$eFYkQ)?8?Hq@ykJdRMM>J=PLl*5BLsG$Il-0P7e2*yDQu3SQUA@*rodm zTMMdWRc*#5kwwsKj9I5EC*YGUc+_|jqgdBFO)r0qa$fwMBl*4Y@d zYc9wA&&I;D@!)gZKNAhkVu9I6;CaaREaHDgkR9%P#*w8Fba@nC8H=t0jYd~Th%t_@ z;F0;D_pw29StuAS%o}FYhw{0@{MwkT|E$e;!{>Yy2I~a)P9k+Z>Dkw?4r4Om#s3N1 z@zq4}ujE;zB-tUgvDizLNRLUuJ(7U?+GmIb;C}*l1bq=f;D#z$mnMQOM~J$TD7FNX zCSxlh9G-px7CwR!QFx%xJRX`IMdo9Hr*6YliTGeCeQ4W1^S}SsS#SLO4HHiwmTI)f_omCtC{>W7t~Y(1GAVQ`q%XX{9ObX>hlv z;7(2GJKzqjI!kR~s?5OegKuW*%yc!7m8rEdG#0uV$O;7EuC~GKN!YCk$j$(_p-s%0 z+F_>72Cgu5VDd&guc4jO(8g%!X7bbFu4Q-Vl5ihlcUow$f$CZw3)ZzxH2Mj~4#y_AX%LQR&+ZGR2!X?&L^!xs?TWF_=usAR2FI$0P!&8nvy_v<2v zOd4%ffTa#5;11RUm^1E452nN9NLdQ*p5*;JzXBU z1n%O3rwW#2EeoEVCh=k|M^#6rjHf1L6E1;ERix}KR7m)4zv}R)eR|w+HlQ4n z^UclNPUZ*s+)cSXC0$W1dgIV%bLSsEKmTCv;)A7+?>|3xbM@N7iyJS#y!rAEcfbC_ zy+5wp`s&dqb5rq;J!(`g(gV4az_A}c9XlPj;rceExJXb%D=yg0s-c$llsBmA+l@^^ z3%|+U)Zl5W4|eb&+=b-;?uf7m6BR|p1u<~}q`4TvopA02q=1npdffr6myEU-#@cdY z9Y8sVkmanQsd>9P_id=zyrG*#cenK(vINhDk4>YOPDjp9g+D(Zy?!?O2$=UX0PZLO z_tE*O$(5rci<9{5^pP)*#22Fe2WHiUw#Hapk*~QLm3N=^m~O{|vm?Np2cDyWS&VSj zz?la9Gm*dyQHyaQ9$6egmPP^Gv1MRap<|7$j>ccaqbrfntlfHBI(V+WE|!<$;IPbj zyy2$*kF)mxYqMVe|Lf7VtW2Q0uIf?iILGaA9JjT0mzBK}62gYC_a>}B*eg2$vIh{L z(@|}!RlDq@+t%(up+oKe^Ld^mg|>Qr-~V;JujhIQVc6^P^}M-1_x-+82O8^s)~imK zdtjR*AUhC3_Dgo-C0{89k*7TdEyYYO%K$mhnv5^@%W*HS0oGC3oSs3X{|R>_egM^V zwBQaA@3@HwQ2x5fcFl}Tw1Phc%z)!aP=N_t2d*2P@W$-CX0l!~nl74+7fr^CMr84m z)pEgV{7t7Et(R_15u4U5t@_~g^!Hv$eD9@%rEh13eOMIvNlEy}rJuc#@yep;r)SgW zVOnG?7cyfWKA0%%S^2<{7`pSBQ-FAB|c5d^+Wgg7{C%bJsRi(iJk6qLHKO5UAC$`kq91NNY*dTN1Rk zc&#l~>xe}bWQ&yj!fuP8qlec5WZ<;uSj`CE!L?aUZ$zb}$ziw+a#c|3kwQv6xPfsu zRQO64sjd@Xo#ZL3PlbB}Dzq%qMyhM4G_=DWe|ZO0-brohpg?s}nz|^>UF4=NGThMA z6@?D6*59LU^aeapsB$F*2)5-wxEC-b`Lxs$YFZsVr;e6$7w(K=L`7}15+%7zfk;Uz z1yYd^rjtswz?+j{-;1wL28BBSx0+N2ojbZRVk+G4cF}nGZt$Yn6K{*4uovwkqUFs*Bnbduy&igYsCwic z7Jp!u3j%Iv!_hn$&#Y`6GXCmiIu#mi*cgN0SVw_5FhG#zXs!UYN=>cOP<*OJ1%trQ z-ba9bx>V1o(!mHYC>^~@L#qZ~rAMC%u;;y6NvTm%Yn8MbC8Ji!s8+ISRjitBc1;VV zykcce`Ui0_uXDLC(z*X)W_+H}72mZ{w&{Dt58t(Kbx8-hQx)|BSrNCcFhQlQ+vHI0 za4C0a>qcrbRJqZ0%rBCQL{(O~{d?PvlUq-n|LM&6pH5%db8hUHa~FO(F}5GTeQaWM z{Km1H<40~>_~r7!Z;!aO8x&Q#=8{frL*I~L!xq=J&F0Of=H7~l%_!=~$m&Xys4`P}izJrfbht$?C)S)T0&oYm-I338=J8wr?)id#VAT=O59SL7 z^ZCwPz9WzC1TO;U=W$&HTqodrA-M8;(^xJ1HC3b~G4H*azVZ`!Y`m?u`5S%z_m*v2 zt=qO)_Wt19x7~SsyYtjG$LXz(vs+!~w+>wXcIfIR=fxq*>2HU}26|6uT6b0ztjmb+ z%ZN2r=50_k?lx;qI{VJKjOT4If)VLsLAF<0k;*u_?Fhgf<@S6Hw~Brt@pm6Icz!A(j2=Juvvylw2~t$pWxw%vv_KB8oYVFLi)Rut~Qq+hpL z$9w`GqH-X~Ur7Gfy|A`TBKzdSQpk5`y{~)g?4B#M?GWG4;3FRYy7xfU3wOlDn;_N^ zxWh*UAUhmn?X_Pv1Ly9%*5|ka{CltEQlII9*>cHZ1=fDdW`nz*-2D@S&N1*Gs8gJ% zEZG__=vnn?@k@)?3ka*`<5tYWt$2J^#N(k+bMb44GnNq^SvK2$%>rB`(A>Z;dkh{Z8}aX3@@Vsi!BE?-H5=w5`0MamQyH*ABTDL z^{~iJ0oJ=gL6$>N8lg}pj*8OQL1}0u!2#V4N@E+T0d|E_nmZ{i9b|;>5bkn7_Ab~? zgNRh8BG+q3^~y+?3=Honay1zih+uO)rBOp^npVt_6tg8ojMNfZY7HZ!mYyY}=gH{+ z?!`^C(k6OY6SKUXUZ$p$sHvqu8VVqLv5H)%rW9$YMOs>^mI@$VqVckO>a=S4s8&tPl%koj0&q9nNK@r3S50f;pe8LW)cWEy&%npO*> zqSgQ+E2vdKN@|UYDpOJGfwWW^($`q6pjUR&DwIHUsfu1bRkdog83q`3YPEt^4alxx z*Xy|QZoaI8Q`N?;s*1|X_)N@ujS}(CRcoGHA$&(rFKo1z_kXYXd53=Y=FY7a=|Fp$ zs!AxU6g4$xTdj>-HX8O1seW!RvX{oT<*=psyqX@Fdt3j(y_-&)_~GKEeK*FB{5~=I z`}pD8V~20t9KCky=(X|DOJk!KF6=wKbN%)nxhkF_ERM~tl9V{REIWp_e{0{;*I;PK zs4b5z$e_lGms2xHyfS`bM|z$rHy@C_BT1}G75C;OTJsYu+0nM#7#m{S`}0Juyl7_* z&zTMQ4nG8lcjfU03IzT6Tt^PamB&S10g8ruP4mQ#+*o^Fye%hQlgw`skSoGI%=zNg zqVUhUQ^f0A8h026ce=j((f-4B%l7TIeLwV%Zgc&%b@2Q)_t^JCH+HO>_;L95*8WTD zdyn?D{7{qaNa3}MX$@(@?z&=kpK@2f@q|@>%4Yc0(R&7^yu)EKU+%B?-BlQwABFQ6?kNI&}(AZXjI zm!0;j4jUW}a=_8kadhs~VI8+xC+?BWb_2+6yWz0iv|C|895y~8GfHsy$aTZw4UIu_ zVH;lG1 zjp1Ui^_tl^?p}Y#F?ic-zv*<}+4S|DTKT@!5%L#aP9)AIP4`W^r&#fQ?cRCCeZ(t9P>_A#*&iq z2$`JK)+tbEW7Yatl_6H46L;z2y7dW4U2K;&rW0KCFf6aRZRDCR zx=hKED_M;yR->BJ)Jbb;B{j8@8r!0v+DT2_v{nV9wTsrQ@g8*|YVW4DcTw9qscl`< z)=ucwQ8l6JqBL~_0j85YXQ~QBzAhSdq)Z>tpo?hGMtY=+lIuy0K)T2VeS~~kF)yu{ zlLp{kN|)3!GwT@H^^E*R2C(fVEzGi3W_b&%qMdOU?f~V0?;2{cmR6#pgAXC@wbXK8 z&w)=@!&6hp>q)zoP?}dx)nC9JnBu!+|4X>vt)EPyJiNI(N?ParJD?7U&#gn@?ww9T z#!9Ka*`oVOGzjAFez!?No+Z@}fIF>vQdThX6hT9G0o-Yx$x=@@Izn~`cS^Mqkeybo zqJmcd`Wt}Y5i2rTs-#sa=z#2%D!ACXda}S%K?UDX1IZ5IUZY~xX*msAuDpX&)6TAL zW|Wt#OiO%^&wMc|>e(>%D~y7*dB#HPrsl7I(C_(Pw|isjcczN|_H=b^Ok+)4M|*+O zEdQpz>&L!^FJ+mA%7m_()UM8=-gVk-dpDgtvhBjz-Pf-kxOIK>_SnH2P>05E9T~fM zx5FB@vb?J*sjPsPo*F3xa4!=i z%HlIRGYb@%+3l%`9mz48j97C)ioGz&lFbL6eJb4f&MXdWk|_}P7eoWN4;DtdivZvG z2<5>m@T?VlcA!A)%on@z;d-XNG?7xwtRj7${ly#ED?Y3jFdfp$?K=Bz*Oz--Kkl$? z+hW@Jy>tH${b#-(I`_lK_|F^v_<7TfZG+<*`cCSbw$|j@lDMq`QcWDIDKDk3N%~c< zVz0CBq@(vYKz2lDQQ7;>+Yz!mVb<=Y0k{%xY{)eZ`R*KZ*e^`{Pt?hV)R`Y=X*88l$ zwqNeG0KQ*G23)~2W5U*d(>`!({g-#vZNAe#bjRwv-K9F8km7#-#bY5Lk%{Z_ph zumUQlDyNqcB&JZKJ5bUN7PMfRDy4X0Lef$zer7jf-AxiX(Hu5 ztOIFCav&|a5lDw1ep)d%qnMLX#7r+{q}Q>sWXzlfW?mDssD)YD$|?tHVOMl8%O}Gf zFx@BAx$9_fQKyDduA!7a5bpOO{sG-Gp2l$Rq`r4b$OGTWG{3h*4qIQ)Ggx0BfoEYf z(yLyBl)O<%ec>&WzW=?t=gD#3-wF?g`{alin0DaZh=c?QAd{s?FaSDhs-{R)zcp%R{7)i`aR#Ne_r4At+}$lEnQO;(^wVP)|_k6 zNJk8H8`}!)Wq|ByN{!UHUbB7I$kAilFa5TA;_|`UMWYQCo!?+2n7&Wme z?diG7ocykgwD#nKYcGK2&YUT5cNYnVON0RN zKm!Fx3r)TVd=~N@`1gYNfx;wPc3f|2bRB(F))#Ljef(Bl`0}o_rc?udVfV@fXAA#=%Yf_sz(>{o_dW8ezz)r!&Ts%`0#0WMojCAEoo z`jY(3oh|!~+S70i9vu9+gbtwk;En+Ongak4DXBZ`<7g&~9ZsL#0{BMR?TZsYTh2W~ zqhq{pm|8~np?ONt#(LM(d*SZoI}-dm4T>g*g%csv=Gt)oZFCaV+ zLk3uX0NI0CM52g5h(X{E$xg(HiP+c>TpScOJ{S`h92g%G7#|8006;IE6(|l31n-F> zV8nz#0Wp9T>Q4#vkDTitK0jdXqd{vIVb(qwwB~8-n&$~&FNcJ`F+1YDh2)Q)Vy<{j zK>AlK`#%!#M|qOZi}O}il!jMTlj`dkEv?+n4ncPZzq6gw*2->eVKuih8yl&zdQwdr zqq&9F*g}=J)0;Y(O&v6OJGB8=@^0`Uc+s1T)=KuMg;du@miba4k#Q$Eif=UuT$_{; z%|PnN79dqbvrp>CCQZ~`0q!H&HO*Q|iE#+|=e^sRk%A0bfw?z?;BIlIeCqk?-6%0+a_3&SdpTY^ znX2e9DT03Vkx=91J4*H{!=&d264>Gq+N(45DN^M-kM$w@FOp{-T$bs*FA)sD9oc>- z)zhY&5~IE98gjLoRHY_M)sWrQlYKqR|DxAush)r^cyl*f1}WB~g&l!wb#VmyWk$x*^!C^ecg^~*y1)Nc_0xCio!=;aTGzhSTs_>H zsjZBWSBP6=={>Clw)SF&EUQyV zXx^XCh1GU%Sq3nDs2E^ffI9d7Ji$ON44fIr2a0tUBn%ZMJCOi`b`hmC>XWSH9~Oi! zYmFBT%UbqX2ac`VF*>yUC+E+*hWG8>aAw!Wb3d-X{EhR1OLIV3yR9O_!VD{9tSw@M zmrBHnhRO|q>@fVx_^Zowy5IO4%>Oc<2kJLn0DMPu0TyS>7y50N-A>r-2q@pDJEdqp zP@K0x$k&mgT1XMial*dpvaPDl(H_kyqyCJo2U>myQipM(@mm(O0t3Up0Ha|bj17_< zNpOVq7OQz2UZ=v{$9Eg@X3xE^bLIhXpP0<(sc61_w=2f+0Goe5-|zn>z_X*a-Dn#F zh8_5Hd;cw)^R|89cYt;G`a4ed?^fqch2~6Q>Guqd@vV2u7Cat}4)=cW`8If~lgw6F^J>P%TLcf&@A6d5W;iZp0 zvgC;wpFcJ8^Jn~)JmWx$mb{;m z^I2xe^8D(sQaPonjUnp<{{yn?JK1%uq6=ly!&KDI#R*s0P6IE?Of{ zC#|uA+R#p}YmKS_>Lkn1d@(iRzM-NTwNXuaQj;#KMIF(miEIbbMYL|9wUbsWD>ltOJAmSP25biX1aO&CE z>Fs{`YujEq^+0thf+>^v{&#SnlpHV_?!M7hDTKTCN29<+&HG=&z3M^WzDKeLp}!gp z1$!Xe4K(jrG4hKc6SmblQni*;4G^z^O)>!GwMc7YjgE#iN&-=&zM7S8YJ8ZAS_eg| zQ!`|0W`l+;S8*DRbt^U@$ z?#KSGHfUV>s;-8N$|8PhN(4K3Ewz{v(~^{^&dpL~r*%u>6saPOMA(}ZW6h7V<%?}O zu)Q6UJx^fI<~noP0|i_l0C!k+_riU!kl&vV1q<#u(MXz@2niH}aCa9Z_2tq z^lJJS*~{Ng|NPxj(rSHX?hdv7#PGML)^8i#xc}hBgL~JV*fwxz(6C1-+ftcfO5-VG zs4@<@EJ4szl+o8zwNcalqg8*n-+bC_KR;+a>+Jp2)py3#_Z#BeVc8u9`5G^{U^n;W z;r{DDfbv?!5qa&7g6t6nxozpErPRpQlmr_R+k2!>ciLq5%?kT%V0#Q27XzbX%vWrd zt4RJAoaVn5?sgRJ6As%=56347n0hGS@!^Rjj0Ett%{ZK64!AyPYM#t}rhBsQo(%VU z$bJvpA1IUks<-Su4#@5t{KGNuht>JJ%l-TM&39bxJ8J#KYT3S+_`y#;um9)b6bz9% z-EYmzfVBZZ5dj!d5SEIE^>h|Md2omTPvBy4Y;YwI`NUv>Pw+zkcYGWW9v6!U+<*_` z3AjW8HUW=`$6*q1m_&R~5)lZKNW>)IgW_<3iMXJ6Tu>}7P=pKOPAQlnB2*EIC zW7tqZjM)K{*#V?^fl)y71ELoAg+JjJz9=C4sem<4`>%e^fAvd2t6s&g{ZDAr`*X=l z9;2^$E}H&Yvhcmkgpc#nzbGjVuc@XtHF4Toc^$3Xj&@Ev5KK^DwJSNDYF?*;-qKBP z25?tU8@plGqpUNkwgbit)cW$ppn!RgtXD_KbrEuHB=qc>s8%2?P(+JQ(8xzMqf(Mu zlwPr5ANyOr(^a_ZCFiq7T7xw~9TswICI;_cn>#gx4H*cN1J#qXdaPAj& z{kEfjo4QgVVI-11T(jb}kJ2bHwnp{7bz65hHV$>0)aA`JN%^^qn54Djl(4Akm{>)6 zvMx76krCgW0>~~hWQt6=F_yd-Yi=}Bih=Fz&Rm`~hvmp)_ZM>e3pvhwc&0i~0Qk;F z;f^?Z1n%JVTu63zzSvz5Hw2t}LE=D8yfag*ldv24D+^YCkow6RxywK5PDuD!r}=Z| zp*u&Q!GIQiPm^uDx&1^&&Xy>u{^i$-0tw9NGuBRfX!*m_*C6E=Di%+};+Z%C8vq@L=iu=? zJf06kAP9)W=-^->5V!$?uMlF1gm^%66zh0wJP-kw0N{?pC19~YNjOY0E+_?$3fyB7 zFyM83JPteqh;hVVF)>649w8w_ekf5eD>xb`6wf1KnD{^{5km zVn%8iBTdf9lCyJ~Sp}`E;x<-kJG-KtQ`ydycC#zA2-$sb?_pH{^|AomOH}~w%t{?Y zszEC6XzAJK-yf(+LriytMxQ^>x%=k((b3ZfRZGwbCT{{TOfo=$i~cMr+M(#>yR?Vy zgL}14lcVJSf583TOm=UaZx0>aCsl_e2Ezd*Jz1tB)dA^AG6Si;hXR+T!p2G(njFc*QYr2YS%VJVfBNz#*!?P)r`uI3?R+26|r7Km`ohs00 zi2AYt+=ZrWfhmiNoQ_5VpYF`zSaX^7JeIQ%cCWh%U|D9cP&iN^nBv@X`M|kD&z=w9 z9y^pDJDeXsoS)#%jUUL4wH1i8sg!!=vb<$)XMFl*dBobDEXmjHil2Hd15G`evbH)& zeI~b15S~q6o+*eb%M_`rbDi?aVO7gktA1a<@d%K!4`w~u3`ZP2#|O=45uF<}pNE1e zU{^-$*VYYA47tZ`2-z!&zeahU58k=LpdGSzyrVn z0|su`T{rLHy9dfsS#Ng2lhXU){#ON=DbER~=adzJ`z_bdpXkAreK47O2z~vVFHt}m?Q!wIT)WD zicbn9B!=SSLU1vmc=2pv;%s8VY+_s}RuqDb4#Dw5vHTDWFC>s1;?D>TpojX?X8Tj; z`BUc2jGQ|oY~IXpfcr;htbTmvszrXQp7vk)jQ{c%0$03F2zz%PX~|=Z)z1j1uO!C2 zmz}k=vLd3nfuZQ&=~cqMZoaCM)7{2wZ=<)g)0;aPjh%FP2d%z~R3T}?07FrA}@-&$d;H3`v7Q-b3;J8sPUqhE5TIUl06}mAy0{*?o+znVd=BOCy-72g1F2 zGTf2CfXQ&LLE7Z&d#Ny2Ku@mMk?M6(Q2MBb9w2f95^^AetFb*%V$GA`?pd}+k$T}? z<%7GL)zHPLYavUkSL9`VkidL_MtUZa`EPp0^2|<&dZh82Z#8?r*8H-md)H>=&)@3z zZ87ZMsN7|(|Ee|HR3vCgr&o#B7I2qm


?jwf#ojfKfke(v283 zNXy`^!Encw8H+S-(TrQANxQ}qm*lp?OCoX7E~E;>opak+%y)Xyu6Em1UYi<(o%<5p zy$+ez(c^J+dmLRJd#4+z-ED6}S6iFM+Tt~Xz`r-RP4%EjV;$kUSC8b;-S+6>eD~^7 z_^zw;=##NCOGe(UEAePcd{TLm>}Zq;ou*cx=18uhuj8V=GPkREXWj8l-9@|XwP*cw z?X1u|%`{HaEgo52@9isH*?Z5fUU~AJS8i&L4v6=4w-C68XeD4BT>Pv` zjw82JSn7GWXDG5EI>O-|3056O|H$bmho*R9XkHNz53Faw+Rvi{SUSX`qtuANkpopg za8xVAw3?V!i_0>aRAUZWz{DrGU&LPn9|K8|_hX3LlI0PDIK zZa4b337uXOO!w3U*&2`)>a9P82Kywi-9N*Y8<>a}&V*jVo(cmZp8& zkhQsS-`2|XHP<%0e`C{!P5Zaeg@@VGM_UeVzx?TIxo^BwwDPC7*1y%b`?L0g8@djI zbKeedSDs7*vcnCPgED9Mf;~WXCU3V;kR>6w?@}Jzczg4km)?8*^s1LHul=Ou@Cj{6 zeQ)>3fO0}hJuoXH68)tBhMm68vY&GatP9-NNc>}of2`piYxyTy_KB8xqNl;Le`{g? z7hJJ<|3*(gws2pXsC!)7RLc$5wQN=K{-$fkI@+#i#fCvk*QiVB=~sFN1DKE1~|1lR7~A;5ZvbD+~XjNm>vq8c7&#@zgb zPYa$MCCp4)=B91)L69R9bcO=6xC!(wA`RX1_b+&R zqeuYs0Zon+`dR?zk--r0F>o@5JOa$&)BwU|Kfx8yNT{{M3w`j+$nn}CXZP$7n8qgnvJ0d%R zI}*U1ay!%>tmoh^k0aiR5bt$@I^B*AfV;=m=C!tZEv+5|_eK!zoT+ykfbVr440o>% z^Bwv38n12{-(LuKk0uFsRA)z}b`dqa1KBa$%ZFuGOf`AkXEN)KZ)nTkVJOQT>nWY) z>gTwoS*|spZWw7P5ijRd?b&$d)3>f}`beI8;7&tXh>=e#JHfm^2Y0wfJMR;s$$=`` z!o$%~+})h~cODa%MG^k-^9v&I9h^IOXK>JTm}i!RZF@{7#dO+d;GRVMGXi&yRt{lB z$vyG%*wiD>j%zXm?(-l5cW}oHuF0?j?$SJiqZV0VmSUz9s_~X~-IePN`ww5+m{z(y zlRI<4*Da5*%$!;^C6~`CRUv9=SqH!!=S0$YFE�_!Pr^DeiHps~xvOz7X!{xPsS5 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

x{crh8*Uz~1PJ&JaQ9OttL7c~ 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


?jwf#ojfKfke(v283 zNXy`^!Encw8H+S-(TrQANxQ}qm*lp?OCoX7E~E;>opak+%y)Xyu6Em1UYi<(o%<5p zy$+ez(c^J+dmLRJd#4+z-ED6}S6iFM+Tt~Xz`r-RP4%EjV;$kUSC8b;-S+6>eD~^7 z_^zw;=##NCOGe(UEAePcd{TLm>}Zq;ou*cx=18uhuj8V=GPkREXWj8l-9@|XwP*cw z?X1u|%`{HaEgo52@9isH*?Z5fUU~AJS8i&L4v6=4w-C68XeD4BT>Pv` zjw82JSn7GWXDG5EI>O-|3056O|H$bmho*R9XkHNz53Faw+Rvi{SUSX`qtuANkpopg za8xVAw3?V!i_0>aRAUZWz{DrGU&LPn9|K8|_hX3LlI0PDIK zZa4b337uXOO!w3U*&2`)>a9P82Kywi-9N*Y8<>a}&V*jVo(cmZp8& zkhQsS-`2|XHP<%0e`C{!P5Zaeg@@VGM_UeVzx?TIxo^BwwDPC7*1y%b`?L0g8@djI zbKeedSDs7*vcnCPgED9Mf;~WXCU3V;kR>6w?@}Jzczg4km)?8*^s1LHul=Ou@Cj{6 zeQ)>3fO0}hJuoXH68)tBhMm68vY&GatP9-NNc>}of2`piYxyTy_KB8xqNl;Le`{g? z7hJJ<|3*(gws2pXsC!)7RLc$5wQN=K{-$fkI@+#i#fCvk*QiVB=~sFN1DKE1~|1lR7~A;5ZvbD+~XjNm>vq8c7&#@zgb zPYa$MCCp4)=B91)L69R9bcO=6xC!(wA`RX1_b+&R zqeuYs0Zon+`dR?zk--r0F>o@5JOa$&)BwU|Kfx8yNT{{M3w`j+$nn}CXZP$7n8qgnvJ0d%R zI}*U1ay!%>tmoh^k0aiR5bt$@I^B*AfV;=m=C!tZEv+5|_eK!zoT+ykfbVr440o>% z^Bwv38n12{-(LuKk0uFsRA)z}b`dqa1KBa$%ZFuGOf`AkXEN)KZ)nTkVJOQT>nWY) z>gTwoS*|spZWw7P5ijRd?b&$d)3>f}`beI8;7&tXh>=e#JHfm^2Y0wfJMR;s$$=`` z!o$%~+})h~cODa%MG^k-^9v&I9h^IOXK>JTm}i!RZF@{7#dO+d;GRVMGXi&yRt{lB z$vyG%*wiD>j%zXm?(-l5cW}oHuF0?j?$SJiqZV0VmSUz9s_~X~-IePN`ww5+m{z(y zlRI<4*Da5*%$!;^C6~`CRUv9=SqH!!=S0$YFE�_!Pr^DeiHps~xvOz7X!{xPsS5 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

x{crh8*Uz~1PJ&JaQ9OttL7c~ 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 JPDHLkV1l4{N~Zt- From 177b93b267e7c59bfbe0b98de89bb7c86c2a00f0 Mon Sep 17 00:00:00 2001 From: Chaeyeong_10 Date: Thu, 2 Apr 2026 23:51:21 +0900 Subject: [PATCH 102/134] =?UTF-8?q?refactor:=20=EC=B1=8C=EB=A6=B0=EC=A7=80?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../screens/challenge_create_screen.dart | 28 +- .../challenge_create_success_dialog.dart | 116 ----- .../challenge/data/challenge_repository.dart | 12 +- .../detail/screens/challenge_main_screen.dart | 28 +- .../challenge/models/challenge_model.dart | 78 +-- .../provider/challenge_provider.dart | 11 +- .../provider/challenge_provider.g.dart | 6 +- .../challenge_create_success_dialog.dart | 490 +----------------- .../provider/user_profile_provider.g.dart | 2 +- 9 files changed, 96 insertions(+), 675 deletions(-) delete mode 100644 lib/features/challenge/create/widgets/challenge_create_success_dialog.dart diff --git a/lib/features/challenge/create/screens/challenge_create_screen.dart b/lib/features/challenge/create/screens/challenge_create_screen.dart index e1e2de5..8e0162e 100644 --- a/lib/features/challenge/create/screens/challenge_create_screen.dart +++ b/lib/features/challenge/create/screens/challenge_create_screen.dart @@ -98,13 +98,10 @@ class _ChallengeCreateScreenState extends ConsumerState { super.dispose(); } - // 챌린지 생성 데이터 제출 준비 로직 - void _submitChallenge() async { - // 1. 데이터 가공 (Swagger 형식에 맞춤) + Map _buildRequestData() { final int duration = int.tryParse(_selectedDuration?.replaceAll('일', '') ?? '0') ?? 0; - // 인증 빈도 매핑 (예: "매일" -> 7, "주 3회" -> 3) int frequency = 7; if (_selectedFrequency != "매일") { frequency = @@ -114,50 +111,43 @@ class _ChallengeCreateScreenState extends ConsumerState { 7; } - // 서버 전송용 태그 데이터 가공 - final tagIds = _selectedTagModels.map((t) => t.id).toList(); - - final requestData = { + return { "title": _nameController.text.trim(), "startDate": _selectedDay != null ? "${_selectedDay!.year}-${_selectedDay!.month.toString().padLeft(2, '0')}-${_selectedDay!.day.toString().padLeft(2, '0')}" : "", "duration": duration, "frequency": frequency, - "tags": tagIds, + "tags": _selectedTagModels.map((t) => t.id).toList(), "description": _descriptionController.text.trim(), - "photoRequired": selectedType == 1, // 사진 필수 여부 (bool) + "photoRequired": selectedType == 1, "challengeVisibility": selectedVisibility == 1 ? "PRIVATE" : (selectedVisibility == 2 ? "PUBLIC" : "FRIENDS_ONLY"), "maxParticipantNumber": 50, }; + } + // 챌린지 생성 데이터 제출 준비 로직 + void _submitChallenge() async { + final requestData = _buildRequestData(); // ✅ 데이터 가공 분리 debugPrint('🚀 서버 전송 데이터: ${jsonEncode(requestData)}'); - // 2. API 호출 final notifier = ref.read(challengeCreateNotifierProvider.notifier); final response = await notifier.create(requestData); - // 3. 결과 처리 if (response != null && mounted) { - // 현황 페이지로 이동하며 데이터 전달 - debugPrint('✅ 5초 대기 후 이동 시도 - challengeId: ${response.id}'); - debugPrint('✅ 생성된 실제 ID: ${response.id}'); - - if (!mounted) return; ref.read(homeNotifierProvider.notifier).refresh(); ref.invalidate(myInProgressChallengesProvider); - await Navigator.pushReplacement( + Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => ChallengeMainScreen(challengeId: response.id), ), ); } else if (mounted) { - // 에러 발생 시 처리 (notifier 내부에서 에러가 관리되지만 간단히 추가 가능) ScaffoldMessenger.of( context, ).showSnackBar(const SnackBar(content: Text('챌린지 생성 중 오류가 발생했습니다.'))); diff --git a/lib/features/challenge/create/widgets/challenge_create_success_dialog.dart b/lib/features/challenge/create/widgets/challenge_create_success_dialog.dart deleted file mode 100644 index cdaa7c9..0000000 --- a/lib/features/challenge/create/widgets/challenge_create_success_dialog.dart +++ /dev/null @@ -1,116 +0,0 @@ -// 최초 작성자 : 김채영 -import 'package:flutter/material.dart'; -import 'package:haenaem/core/theme/app_colors.dart'; -import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:haenaem/features/challenge/invite/widgets/challenge_invite_content.dart'; - -// 챌린지 생성 성공했을 경우 띄우는 작은 화면 -class ChallengeCreateSuccessDialog extends StatelessWidget { - final int challengeId; // 친구 초대 API 호출용 - final String challengeLink; - - const ChallengeCreateSuccessDialog({ - super.key, - required this.challengeId, // 필수 - required this.challengeLink, - }); - - @override - Widget build(BuildContext context) { - return Dialog( - alignment: const Alignment(0, -0.3), - insetPadding: const EdgeInsets.symmetric(horizontal: 20), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), - child: Container( - width: double.infinity, - height: 700, - clipBehavior: Clip.antiAlias, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(16), - ), - child: Column( - children: [ - // 상단 그라데이션 헤더 - buildGradientHeader(), - - // 공통 초대 위젯 (여기서 검색, 리스트, 초대 로직 다 처리) - Expanded( - child: Padding( - padding: const EdgeInsets.fromLTRB(20, 20, 20, 0), - child: ChallengeInviteContent( - // 공통 위젯 사용! - challengeId: challengeId, - challengeUrl: challengeLink, - ), - ), - ), - // 하단 닫기 버튼 - buildLaterButton(context), - ], - ), - ), - ); - } - - // 상단 그라데이션 헤더 위젯 - Widget buildGradientHeader() { - return Container( - width: double.infinity, - padding: const EdgeInsets.symmetric(vertical: 24), - decoration: const BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [Color(0xFF009951), Color(0xFF00C94D)], - ), - ), - child: Column( - children: [ - SvgPicture.asset( - 'assets/images/icons/challenge_create_success_check.svg', - width: 44, - height: 44, - ), - const SizedBox(height: 12), - Text( - '챌린지 생성 완료!', - style: AppTypography.h2.copyWith(color: Colors.white), - ), - const SizedBox(height: 4), - Text( - '친구들을 초대해서 함께 도전해보세요', - style: AppTypography.b1.copyWith( - color: Colors.white.withAlpha(200), - ), - ), - ], - ), - ); - } - - // 나중에 초대하기 버튼 - Widget buildLaterButton(BuildContext context) { - return Container( - width: double.infinity, - padding: const EdgeInsets.all(16), - child: GestureDetector( - onTap: () => Navigator.pop(context), - child: Container( - width: double.infinity, - height: 44, - alignment: Alignment.center, - decoration: BoxDecoration( - border: Border.all(color: AppColors.gray2), - borderRadius: BorderRadius.circular(10), - ), - child: Text( - '나중에 초대하기', - style: AppTypography.b1.copyWith(color: AppColors.gray2), - ), - ), - ), - ); - } -} diff --git a/lib/features/challenge/data/challenge_repository.dart b/lib/features/challenge/data/challenge_repository.dart index 83a86c1..8b5ef1b 100644 --- a/lib/features/challenge/data/challenge_repository.dart +++ b/lib/features/challenge/data/challenge_repository.dart @@ -12,6 +12,7 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter/foundation.dart'; import 'package:haenaem/features/auth/services/auth_service.dart'; import 'package:haenaem/features/user/models/user_model.dart'; +import 'package:haenaem/shared/models/challenge_base.dart'; import 'package:haenaem/core/network/dio_provider.dart'; part 'challenge_repository.g.dart'; @@ -61,14 +62,17 @@ class ChallengeRepository { } // 챌린지 생성 post 요청 보내기 - Future createChallenge( - Map data, - ) async { + Future createChallenge(Map data) async { try { final response = await _dio.post('/api/challenges/create', data: data); debugPrint('📥 서버 생성 응답 원본: ${response.data}'); if (response.statusCode == 200 || response.statusCode == 201) { - return ChallengeCreateResponse.fromJson(response.data); + // ✅ 서버가 'id'로 주므로 'challengeId'로 변환 + final responseData = { + 'challengeId': response.data['id'], + 'title': response.data['title'] ?? '', + }; + return ChallengeBase.fromJson(responseData); } else { throw Exception('챌린지 생성 실패'); } diff --git a/lib/features/challenge/detail/screens/challenge_main_screen.dart b/lib/features/challenge/detail/screens/challenge_main_screen.dart index f0884fe..f069a80 100644 --- a/lib/features/challenge/detail/screens/challenge_main_screen.dart +++ b/lib/features/challenge/detail/screens/challenge_main_screen.dart @@ -6,11 +6,12 @@ import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/features/challenge/widgets/challenge_popup_menu.dart'; -import 'package:haenaem/features/challenge/models/challenge_model.dart'; -import 'package:haenaem/features/challenge/widgets/challenge_create_success_dialog.dart'; +//import 'package:haenaem/features/challenge/widgets/challenge_create_success_dialog_.dart'; import 'package:haenaem/shared/widgets/bottom_action_button.dart'; import 'package:haenaem/features/challenge/verification/screens/challenge_verification_screen.dart'; import 'package:haenaem/features/challenge/detail/screens/member_ranking_screen.dart'; +import 'package:haenaem/features/challenge/create/widgets/challenge_create_success_dialog.dart'; +import 'package:haenaem/shared/models/challenge_base.dart'; // 분리된 뷰 파일들 (아래 2번 단계에서 생성/수정할 파일들) import 'package:haenaem/features/challenge/detail/views/calendar_view.dart'; @@ -21,7 +22,7 @@ class ChallengeMainScreen extends ConsumerStatefulWidget { final int challengeId; final String? challengeTitle; final bool isJustCreated; - final ChallengeCreateResponse? createdData; + final ChallengeBase? createdData; const ChallengeMainScreen({ super.key, @@ -59,22 +60,13 @@ class _ChallengeDetailScreenState extends ConsumerState // 챌린지 생성 직후라면 생성 성공 다이얼로그 실행 if (widget.isJustCreated && widget.createdData != null) { - // 프레임이 그려진 직후에 다이얼로그를 띄우기 위해 postFrameCallback 사용 WidgetsBinding.instance.addPostFrameCallback((_) { showDialog( context: context, barrierColor: const Color(0x7F1A1D1B), builder: (context) => ChallengeCreateSuccessDialog( - // [수정 1] friends 파라미터 삭제 (이제 필요 없음) - // friends: widget.createdData!.friends, - - // [수정 2] challengeId 추가 (필수) - // 주의: createdData 객체 안에 있는 ID 변수명을 정확히 적어주세요. (예: .id 또는 .challengeId) - // challengeId: widget.createdData!.id, - - // // 기존 유지 - // challengeLink: widget.createdData!.challengeLink, - createdData: widget.createdData!, + challengeId: widget.createdData!.id, // ✅ ChallengeBase.id 사용 + //challengeLink: '', // ✅ ChallengeBase에 link 없으므로 빈 값 ), ); }); @@ -90,7 +82,7 @@ class _ChallengeDetailScreenState extends ConsumerState super.dispose(); } - void _scrollToTop(ScrollController controller) { + void scrollToTop(ScrollController controller) { if (controller.hasClients) { controller.animateTo( 0, @@ -176,11 +168,11 @@ class _ChallengeDetailScreenState extends ConsumerState ), ], ), - bottomNavigationBar: _buildBottomButton(), + bottomNavigationBar: buildBottomButton(), ); } - Widget _buildBottomButton() { + Widget buildBottomButton() { // 0: 소개, 1: 내 현황 -> '인증하기' // 2: 멤버 현황 -> '내 순위 확인하기' final bool isMemberTab = _tabController.index == 2; @@ -222,7 +214,7 @@ class _ChallengeDetailScreenState extends ConsumerState ); } - void _scrollToMyRank() { + void scrollToMyRank() { // MemberView에서 내 순위를 찾는 로직을 구현하거나 // scrollController를 통해 하단으로 이동시키는 로직 등을 수행합니다. _memberScrollController.animateTo( diff --git a/lib/features/challenge/models/challenge_model.dart b/lib/features/challenge/models/challenge_model.dart index 146e24f..c367c73 100644 --- a/lib/features/challenge/models/challenge_model.dart +++ b/lib/features/challenge/models/challenge_model.dart @@ -149,47 +149,47 @@ class ChallengeDetailModel { } // 챌린지 생성 데이터 관리 클래스 -@Deprecated('사용 X') -class ChallengeCreateResponse { - final int id; - final String challengeLink; - final List friends; - - ChallengeCreateResponse({ - required this.id, - required this.challengeLink, - required this.friends, - }); +// @Deprecated('사용 X') +// class ChallengeCreateResponse { +// final int id; +// final String challengeLink; +// final List friends; + +// ChallengeCreateResponse({ +// required this.id, +// required this.challengeLink, +// required this.friends, +// }); - factory ChallengeCreateResponse.fromJson(Map json) { - final String link = json['challengeLink'] ?? ''; - int finalId = 0; - - // 💡 서버가 'id'를 주면 그걸 쓰고, 없거나 null이면 링크에서 숫자를 추출합니다. - if (json['id'] != null && json['id'] != 0) { - finalId = json['id']; - } else if (link.isNotEmpty) { - // 링크 예시: http://localhost:3000/challenges/14 - try { - finalId = int.parse(Uri.parse(link).pathSegments.last); - print( - '🎯 링크에서 ID 추출 성공: $finalId', - ); // TODO: 링크에서 id 추출하지 않고 백엔드한테 받아야 함. - } catch (e) { - // Uri 파싱이 안 될 경우를 대비한 split 백업 로직 - finalId = int.tryParse(link.split('/').last) ?? 0; - } - } +// factory ChallengeCreateResponse.fromJson(Map json) { +// final String link = json['challengeLink'] ?? ''; +// int finalId = 0; + +// // 💡 서버가 'id'를 주면 그걸 쓰고, 없거나 null이면 링크에서 숫자를 추출합니다. +// if (json['id'] != null && json['id'] != 0) { +// finalId = json['id']; +// } else if (link.isNotEmpty) { +// // 링크 예시: http://localhost:3000/challenges/14 +// try { +// finalId = int.parse(Uri.parse(link).pathSegments.last); +// print( +// '🎯 링크에서 ID 추출 성공: $finalId', +// ); // TODO: 링크에서 id 추출하지 않고 백엔드한테 받아야 함. +// } catch (e) { +// // Uri 파싱이 안 될 경우를 대비한 split 백업 로직 +// finalId = int.tryParse(link.split('/').last) ?? 0; +// } +// } - return ChallengeCreateResponse( - id: finalId, - challengeLink: link, - friends: (json['friends'] as List? ?? []) - .map((f) => FriendModel.fromJson(f)) - .toList(), - ); - } -} +// return ChallengeCreateResponse( +// id: finalId, +// challengeLink: link, +// friends: (json['friends'] as List? ?? []) +// .map((f) => FriendModel.fromJson(f)) +// .toList(), +// ); +// } +// } // 챌린지 내 현황 탭 데이터 관리 클래스 @Deprecated('사용 X') diff --git a/lib/features/challenge/provider/challenge_provider.dart b/lib/features/challenge/provider/challenge_provider.dart index 6454217..89027b1 100644 --- a/lib/features/challenge/provider/challenge_provider.dart +++ b/lib/features/challenge/provider/challenge_provider.dart @@ -5,7 +5,7 @@ import '../data/challenge_repository.dart'; import 'package:haenaem/features/user/data/user_repository.dart'; import '../models/challenge_model.dart'; import 'package:haenaem/features/user/models/user_model.dart'; -import 'package:haenaem/shared/models/user.dart'; +import 'package:haenaem/shared/models/challenge_base.dart'; import 'dart:io'; part 'challenge_provider.g.dart'; @@ -110,18 +110,13 @@ Future> allTags(AllTagsRef ref) { @riverpod class ChallengeCreateNotifier extends _$ChallengeCreateNotifier { @override - AsyncValue build() => const AsyncValue.data(null); + AsyncValue build() => const AsyncValue.data(null); // ✅ ChallengeBase로 교체 - // Future를 반환하도록 수정 - Future create(Map data) async { + Future create(Map data) async { state = const AsyncValue.loading(); - - // AsyncValue.guard의 결과를 변수에 담습니다. state = await AsyncValue.guard( () => ref.read(challengeRepositoryProvider).createChallenge(data), ); - - // 💡 UI에서 결과를 기다릴 수 있게 value(성공 시 데이터)를 반환합니다. return state.valueOrNull; } } diff --git a/lib/features/challenge/provider/challenge_provider.g.dart b/lib/features/challenge/provider/challenge_provider.g.dart index 9fd33a6..8218bc4 100644 --- a/lib/features/challenge/provider/challenge_provider.g.dart +++ b/lib/features/challenge/provider/challenge_provider.g.dart @@ -1485,14 +1485,14 @@ final challengeLeaveNotifierProvider = typedef _$ChallengeLeaveNotifier = AutoDisposeNotifier>; String _$challengeCreateNotifierHash() => - r'cbc4cd944ef88513ff25539f16dbe448af4446e6'; + r'28b4eb6e6f9216f97eaa4ed5691eec105674bbea'; /// See also [ChallengeCreateNotifier]. @ProviderFor(ChallengeCreateNotifier) final challengeCreateNotifierProvider = AutoDisposeNotifierProvider< ChallengeCreateNotifier, - AsyncValue + AsyncValue >.internal( ChallengeCreateNotifier.new, name: r'challengeCreateNotifierProvider', @@ -1504,7 +1504,7 @@ final challengeCreateNotifierProvider = ); typedef _$ChallengeCreateNotifier = - AutoDisposeNotifier>; + AutoDisposeNotifier>; String _$articleCreateNotifierHash() => r'558fb00ff45dc4f321919d42368c1a94c415f602'; diff --git a/lib/features/challenge/widgets/challenge_create_success_dialog.dart b/lib/features/challenge/widgets/challenge_create_success_dialog.dart index e33de65..c91b8ed 100644 --- a/lib/features/challenge/widgets/challenge_create_success_dialog.dart +++ b/lib/features/challenge/widgets/challenge_create_success_dialog.dart @@ -1,464 +1,20 @@ -// // 최초 작성자 : 김채영 -// import 'package:flutter/material.dart'; -// import 'package:haenaem/core/theme/app_colors.dart'; -// import 'package:haenaem/core/theme/app_typography.dart'; -// import 'package:flutter_svg/flutter_svg.dart'; -// import 'package:flutter/services.dart'; // 클립보드 복사 -// import 'package:share_plus/share_plus.dart'; // 공유 -// import 'package:haenaem/features/challenge/model/challenge_model.dart'; // 💡 Response 및 Friend 모델 임포트 - -// // 챌린지 생성 성공했을 경우 띄우는 작은 화면 -// class ChallengeCreateSuccessDialog extends StatefulWidget { -// // 💡 response 모델 전체를 넘겨받습니다. -// final ChallengeCreateResponse createdData; - -// const ChallengeCreateSuccessDialog({super.key, required this.createdData}); - -// @override -// State createState() => -// _ChallengeCreateSuccessDialogState(); -// } - -// // 챌린지 생성 성공 화면의 로직 및 상태 관리 클래스 -// class _ChallengeCreateSuccessDialogState -// extends State { -// // 💡 초대한 친구들의 ID를 저장 (FriendModel의 id 타입에 맞춰 dynamic 또는 int/String 설정) -// final Set _invitedFriends = {}; - -// // 💡 모델의 친구 데이터를 기반으로 필터링 리스트 관리 -// List _filteredFriends = []; - -// // 검색창 제어를 위한 컨트롤러 -// final TextEditingController _searchController = TextEditingController(); - -// @override -// void initState() { -// super.initState(); -// // 💡 초기에는 모델에서 받은 실제 친구 목록을 보여주기 -// _filteredFriends = widget.createdData.friends; - -// // 검색창 입력 감지 리스너 추가 -// _searchController.addListener(onSearchChanged); -// } - -// @override -// void dispose() { -// _searchController.dispose(); -// super.dispose(); -// } - -// // 초대 버튼 누를 경우 뜨는 토스트 메시지 -// void _showToast(BuildContext context, String name) { -// OverlayEntry overlayEntry = OverlayEntry( -// builder: (context) => Positioned( -// bottom: 100, -// left: 20, -// right: 20, -// child: Material( -// color: Colors.transparent, -// child: Center( -// child: Container( -// padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), -// decoration: ShapeDecoration( -// color: const Color(0xff1B1D1B).withAlpha(200), -// shape: RoundedRectangleBorder( -// borderRadius: BorderRadius.circular(8), -// ), -// ), -// child: Text( -// '$name 님에게 챌린지 초대를 보냈습니다!', -// textAlign: TextAlign.center, -// style: AppTypography.b1.copyWith(color: Colors.white), -// ), -// ), -// ), -// ), -// ), -// ); - -// Overlay.of(context).insert(overlayEntry); - -// Future.delayed(const Duration(seconds: 2), () { -// overlayEntry.remove(); -// }); -// } - -// // 클립보드 복사 로직: 실제 응답받은 링크 사용 -// void copyToClipboard(BuildContext context) { -// Clipboard.setData( -// ClipboardData(text: widget.createdData.challengeLink), -// ).then((_) { -// ScaffoldMessenger.of(context).showSnackBar( -// SnackBar( -// content: const Text('링크가 클립보드에 복사되었습니다.'), -// behavior: SnackBarBehavior.floating, -// shape: RoundedRectangleBorder( -// borderRadius: BorderRadius.circular(10), -// ), -// duration: const Duration(seconds: 2), -// ), -// ); -// }); -// } - -// // 공유창 로직: 실제 응답받은 링크 사용 -// void shareChallenge(BuildContext context) async { -// final box = context.findRenderObject() as RenderBox?; - -// await Share.share( -// '[해냄] 새로운 챌린지에 초대받았어요!\n지금 바로 확인해보세요: ${widget.createdData.challengeLink}', -// subject: '해냄 챌린지 초대', -// sharePositionOrigin: box != null -// ? box.localToGlobal(Offset.zero) & box.size -// : null, -// ); -// } - -// // 검색 로직: 입력값이 바뀔 때마다 FriendModel 리스트를 필터링 -// void onSearchChanged() { -// String query = _searchController.text.toLowerCase(); -// setState(() { -// if (query.isEmpty) { -// _filteredFriends = widget.createdData.friends; -// } else { -// _filteredFriends = widget.createdData.friends -// .where((friend) => friend.nickname.toLowerCase().contains(query)) -// .toList(); -// } -// }); -// } - -// @override -// Widget build(BuildContext context) { -// return Dialog( -// alignment: const Alignment(0, -0.3), -// insetPadding: const EdgeInsets.symmetric(horizontal: 20), -// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), -// child: Container( -// width: double.infinity, -// height: 600, -// clipBehavior: Clip.antiAlias, -// decoration: BoxDecoration( -// color: Colors.white, -// borderRadius: BorderRadius.circular(16), -// ), -// child: Column( -// children: [ -// buildGradientHeader(), -// Expanded( -// child: SingleChildScrollView( -// padding: const EdgeInsets.all(20), -// child: Column( -// crossAxisAlignment: CrossAxisAlignment.start, -// children: [ -// buildLinkShareSection(), -// const SizedBox(height: 10), -// buildFriendSearchBar(), -// const SizedBox(height: 10), -// if (_filteredFriends.isEmpty) -// Center( -// child: Padding( -// padding: const EdgeInsets.symmetric(vertical: 20), -// child: Text( -// '검색 결과가 없습니다.', -// style: AppTypography.b2.copyWith( -// color: AppColors.gray3, -// ), -// ), -// ), -// ) -// else -// ..._filteredFriends.map( -// (friend) => buildInviteItem(friend), -// ), -// ], -// ), -// ), -// ), -// buildLaterButton(context), -// ], -// ), -// ), -// ); -// } - -// Widget buildGradientHeader() { -// return Container( -// width: double.infinity, -// padding: const EdgeInsets.symmetric(vertical: 24), -// decoration: const BoxDecoration( -// gradient: LinearGradient( -// begin: Alignment.topCenter, -// end: Alignment.bottomCenter, -// colors: [Color(0xFF009951), Color(0xFF00C94D)], -// ), -// ), -// child: Column( -// children: [ -// SvgPicture.asset( -// 'assets/images/icons/challenge_create_success_check.svg', -// width: 44, -// height: 44, -// ), -// const SizedBox(height: 12), -// Text( -// '챌린지 생성 완료!', -// style: AppTypography.h2.copyWith(color: Colors.white), -// ), -// const SizedBox(height: 4), -// Text( -// '친구들을 초대해서 함께 도전해보세요', -// style: AppTypography.b1.copyWith( -// color: Colors.white.withAlpha(200), -// ), -// ), -// ], -// ), -// ); -// } - -// Widget buildLinkShareSection() { -// return Column( -// crossAxisAlignment: CrossAxisAlignment.start, -// children: [ -// Text( -// '챌린지 링크 공유', -// style: AppTypography.b2.copyWith(color: AppColors.gray1), -// ), -// const SizedBox(height: 8), -// Container( -// width: double.infinity, -// padding: const EdgeInsets.all(10), -// decoration: ShapeDecoration( -// color: Colors.white, -// shape: RoundedRectangleBorder( -// side: const BorderSide(width: 1, color: AppColors.gray4), -// borderRadius: BorderRadius.circular(10), -// ), -// ), -// child: Text( -// // 💡 실제 응답받은 링크 텍스트 표시 -// widget.createdData.challengeLink, -// style: AppTypography.c1.copyWith(color: const Color(0xFF3E7E60)), -// maxLines: 1, -// overflow: TextOverflow.ellipsis, -// ), -// ), -// const SizedBox(height: 8), -// Row( -// children: [ -// Expanded( -// child: buildActionButton( -// label: '복사', -// color: AppColors.gray5, -// iconPath: 'assets/images/icons/link_copy.svg', -// onTap: (ctx) => copyToClipboard(ctx), -// ), -// ), -// const SizedBox(width: 10), -// Expanded( -// child: buildActionButton( -// label: '공유', -// color: AppColors.gray5, -// iconPath: 'assets/images/icons/link_share.svg', -// onTap: (ctx) => shareChallenge(ctx), -// ), -// ), -// ], -// ), -// ], -// ); -// } - -// Widget buildActionButton({ -// required String label, -// required Color color, -// required String iconPath, -// required Function(BuildContext) onTap, -// }) { -// return Builder( -// builder: (context) { -// return GestureDetector( -// onTap: () => onTap(context), -// child: Container( -// padding: const EdgeInsets.symmetric(horizontal: 44, vertical: 8), -// decoration: ShapeDecoration( -// color: AppColors.gray5, -// shape: RoundedRectangleBorder( -// borderRadius: BorderRadius.circular(10), -// ), -// ), -// child: Row( -// mainAxisSize: MainAxisSize.min, -// children: [ -// SvgPicture.asset( -// iconPath, -// width: 16, -// height: 16, -// colorFilter: const ColorFilter.mode( -// AppColors.gray2, -// BlendMode.srcIn, -// ), -// ), -// const SizedBox(width: 4), -// Text( -// label, -// textAlign: TextAlign.center, -// style: AppTypography.b2.copyWith(color: AppColors.gray2), -// ), -// ], -// ), -// ), -// ); -// }, -// ); -// } - -// Widget buildFriendSearchBar() { -// return Container( -// width: double.infinity, -// height: 37.98, -// padding: const EdgeInsets.symmetric(horizontal: 16), -// decoration: ShapeDecoration( -// shape: RoundedRectangleBorder( -// side: const BorderSide(width: 1, color: AppColors.gray3), -// borderRadius: BorderRadius.circular(9.50), -// ), -// ), -// child: Row( -// mainAxisAlignment: MainAxisAlignment.start, -// crossAxisAlignment: CrossAxisAlignment.center, -// children: [ -// SvgPicture.asset( -// 'assets/images/icons/friend_search.svg', -// width: 18.99, -// height: 18.99, -// ), -// const SizedBox(width: 8), -// Expanded( -// child: TextField( -// controller: _searchController, -// style: AppTypography.b2.copyWith(color: AppColors.black), -// decoration: InputDecoration( -// hintText: '친구 검색', -// hintStyle: AppTypography.b2.copyWith(color: AppColors.gray3), -// border: InputBorder.none, -// isDense: true, -// contentPadding: EdgeInsets.zero, -// ), -// ), -// ), -// ], -// ), -// ); -// } - -// // 💡 FriendModel 객체를 받아 스타일대로 렌더링 -// Widget buildInviteItem(FriendModel friend) { -// bool isInvited = _invitedFriends.contains(friend.id); - -// return Container( -// margin: const EdgeInsets.only(bottom: 0), -// padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 11), -// decoration: BoxDecoration(borderRadius: BorderRadius.circular(12)), -// child: Row( -// children: [ -// // 💡 프로필 이미지 연동 (null일 경우 기본 색상) -// CircleAvatar( -// radius: 20, -// backgroundColor: const Color(0xFFD9D9D9), -// backgroundImage: friend.profileImageUrl != null -// ? NetworkImage(friend.profileImageUrl!) -// : null, -// ), -// const SizedBox(width: 10), -// Text( -// friend.nickname, -// style: AppTypography.b2.copyWith(color: AppColors.black), -// ), -// const Spacer(), -// GestureDetector( -// onTap: isInvited -// ? null -// : () { -// setState(() { -// _invitedFriends.add(friend.id); -// }); -// _showToast(context, friend.nickname); -// }, -// child: isInvited ? buildInvitedButton() : buildActiveInviteButton(), -// ), -// ], -// ), -// ); -// } - -// Widget buildInvitedButton() { -// return Container( -// width: 54.08, -// height: 33.99, -// decoration: ShapeDecoration( -// color: AppColors.disable, -// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), -// ), -// child: Center( -// child: Text( -// '초대함', -// textAlign: TextAlign.center, -// style: AppTypography.c1.copyWith(color: AppColors.gray2), -// ), -// ), -// ); -// } - -// Widget buildActiveInviteButton() { -// return Container( -// width: 54.08, -// height: 33.99, -// alignment: Alignment.center, -// decoration: BoxDecoration( -// color: AppColors.primaryAble, -// borderRadius: BorderRadius.circular(8), -// ), -// child: Text('초대', style: AppTypography.c1.copyWith(color: Colors.white)), -// ); -// } - -// Widget buildLaterButton(BuildContext context) { -// return Container( -// width: double.infinity, -// padding: const EdgeInsets.all(16), -// child: GestureDetector( -// onTap: () => Navigator.pop(context), -// child: Container( -// width: double.infinity, -// height: 44, -// alignment: Alignment.center, -// decoration: BoxDecoration( -// border: Border.all(color: AppColors.gray2), -// borderRadius: BorderRadius.circular(10), -// ), -// child: Text( -// '나중에 초대하기', -// style: AppTypography.b1.copyWith(color: AppColors.gray2), -// ), -// ), -// ), -// ); -// } -// } - +// 최초 작성자 : 김채영 import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:haenaem/features/challenge/models/challenge_model.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/features/challenge/invite/widgets/challenge_invite_content.dart'; +// 챌린지 생성 성공했을 경우 띄우는 작은 화면 class ChallengeCreateSuccessDialog extends StatelessWidget { - final ChallengeCreateResponse createdData; + final int challengeId; // 친구 초대 API 호출용 + final String challengeLink; - const ChallengeCreateSuccessDialog({super.key, required this.createdData}); + const ChallengeCreateSuccessDialog({ + super.key, + required this.challengeId, // 필수 + this.challengeLink = '', + }); @override Widget build(BuildContext context) { @@ -468,7 +24,7 @@ class ChallengeCreateSuccessDialog extends StatelessWidget { shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), child: Container( width: double.infinity, - height: 600, // 전체 높이 유지 + height: 700, clipBehavior: Clip.antiAlias, decoration: BoxDecoration( color: Colors.white, @@ -476,30 +32,30 @@ class ChallengeCreateSuccessDialog extends StatelessWidget { ), child: Column( children: [ - // 1. 상단 그라데이션 헤더 (김채영님 스타일 유지) - _buildGradientHeader(), + // 상단 그라데이션 헤더 + buildGradientHeader(), - // 2. 본문 (정승빈님의 InviteContent 위젯 사용) + // 공통 초대 위젯 (여기서 검색, 리스트, 초대 로직 다 처리) Expanded( child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.fromLTRB(20, 20, 20, 0), child: ChallengeInviteContent( - challengeId: createdData.id, - challengeUrl: createdData.challengeLink, + // 공통 위젯 사용! + challengeId: challengeId, + challengeUrl: challengeLink, ), ), ), - - // 3. 하단 닫기 버튼 (김채영님 스타일 유지) - _buildLaterButton(context), + // 하단 닫기 버튼 + buildLaterButton(context), ], ), ), ); } - // 상단 그라데이션 헤더 - Widget _buildGradientHeader() { + // 상단 그라데이션 헤더 위젯 + Widget buildGradientHeader() { return Container( width: double.infinity, padding: const EdgeInsets.symmetric(vertical: 24), @@ -535,7 +91,7 @@ class ChallengeCreateSuccessDialog extends StatelessWidget { } // 나중에 초대하기 버튼 - Widget _buildLaterButton(BuildContext context) { + Widget buildLaterButton(BuildContext context) { return Container( width: double.infinity, padding: const EdgeInsets.all(16), diff --git a/lib/features/user/provider/user_profile_provider.g.dart b/lib/features/user/provider/user_profile_provider.g.dart index 9939d5d..ed7fd6b 100644 --- a/lib/features/user/provider/user_profile_provider.g.dart +++ b/lib/features/user/provider/user_profile_provider.g.dart @@ -6,7 +6,7 @@ part of 'user_profile_provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$userProfileHash() => r'63c409bf957bfbccdab141e1a960bb512bf8193e'; +String _$userProfileHash() => r'19eca05cb7e9cf8b28eba8eb8bbce5333c70101a'; /// See also [UserProfile]. @ProviderFor(UserProfile) From 4fd54a668089f62a2115bddb6fd25df6a3f9d59d Mon Sep 17 00:00:00 2001 From: Seungvin Date: Mon, 6 Apr 2026 15:01:00 +0900 Subject: [PATCH 103/134] =?UTF-8?q?refactor:=20=EB=8C=93=EA=B8=80,=20?= =?UTF-8?q?=EB=8C=93=EA=B8=80=EC=9E=91=EC=84=B1=EB=9E=80=20=EC=9C=84?= =?UTF-8?q?=EC=A0=AF=20=EB=B6=84=EB=A6=AC=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feed/screens/post_detail_screen.dart | 221 ++---------------- .../feed/widgets/comment_input_field.dart | 128 ++++++++++ lib/features/feed/widgets/comment_item.dart | 80 +++++++ 3 files changed, 225 insertions(+), 204 deletions(-) create mode 100644 lib/features/feed/widgets/comment_input_field.dart create mode 100644 lib/features/feed/widgets/comment_item.dart diff --git a/lib/features/feed/screens/post_detail_screen.dart b/lib/features/feed/screens/post_detail_screen.dart index 31d0874..6b647d1 100644 --- a/lib/features/feed/screens/post_detail_screen.dart +++ b/lib/features/feed/screens/post_detail_screen.dart @@ -1,22 +1,20 @@ // 최초 작성자 : 강선욱 import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; +//import 'package:intl/intl.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; // 💡 기존 challenge_provider 대신 분리된 프로바이더들을 임포트합니다. import 'package:haenaem/features/feed/provider/post_detail_provider.dart'; import 'package:haenaem/features/feed/provider/comment_provider.dart'; -//import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -//import 'package:haenaem/features/challenge/models/challenge_model.dart'; -import 'package:haenaem/features/challenge/widgets/comment_popup_menu.dart'; +import 'package:haenaem/features/feed/widgets/comment_item.dart'; import 'package:haenaem/features/feed/widgets/feed_post_card.dart'; // FeedPostCard 임포트 +import 'package:haenaem/features/feed/widgets/comment_input_field.dart'; import 'package:haenaem/features/feed/models/post.dart'; -import 'package:haenaem/features/feed/models/comment.dart'; -class PostDetailScreen extends ConsumerStatefulWidget { +class PostDetailScreen extends ConsumerWidget { final int postId; final Post? post; final dynamic feedProvider; @@ -29,36 +27,10 @@ class PostDetailScreen extends ConsumerStatefulWidget { }); @override - ConsumerState createState() => _PostDetailScreenState(); -} - -class _PostDetailScreenState extends ConsumerState { - final TextEditingController _commentController = TextEditingController(); - bool _isButtonActive = false; - - @override - void initState() { - super.initState(); - _commentController.addListener(() { - setState(() { - _isButtonActive = _commentController.text.trim().isNotEmpty; - }); - }); - } - - @override - void dispose() { - _commentController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - // 상세 정보 및 댓글 데이터 구독 - final detailAsync = ref.watch(postDetailProvider(postId: widget.postId)); - final commentsAsync = ref.watch( - postCommentsProvider(postId: widget.postId), - ); + Widget build(BuildContext context, WidgetRef ref) { + // 상세 정보 및 댓글 구독 + final detailAsync = ref.watch(postDetailProvider(postId: postId)); + final commentsAsync = ref.watch(postCommentsProvider(postId: postId)); return Scaffold( backgroundColor: Colors.white, @@ -95,7 +67,7 @@ class _PostDetailScreenState extends ConsumerState { // --- 리팩토링 포인트: FeedPostCard 재사용 --- FeedPostCard( post: latestPost, - provider: widget.feedProvider, + provider: feedProvider, onTap: () {}, // 상세 페이지 내에서는 클릭 시 아무 동작 안 함 ), @@ -118,7 +90,12 @@ class _PostDetailScreenState extends ConsumerState { physics: const NeverScrollableScrollPhysics(), itemCount: comments.length, itemBuilder: (context, index) => - _buildCommentItem(comments[index]), + // 💡 분리한 위젯을 여기서 간편하게 호출합니다. + CommentItem( + comment: comments[index], + postId: postId, + feedProvider: feedProvider, + ), ); }, ), @@ -127,8 +104,8 @@ class _PostDetailScreenState extends ConsumerState { ), ), ), - // 키보드에 가려지지 않도록 처리된 댓글 입력창 - _buildCommentInputField(), + // 💡 분리된 입력창 위젯 호출! + CommentInputField(postId: postId, feedProvider: feedProvider), ], ); }, @@ -136,170 +113,6 @@ class _PostDetailScreenState extends ConsumerState { ); } - // 댓글 입력창 (기존 로직 유지) - Widget _buildCommentInputField() { - final double systemBottomPadding = - MediaQuery.of(context).viewInsets.bottom > 0 - ? 10 - : MediaQuery.of(context).padding.bottom + 10; - - return Container( - padding: EdgeInsets.only( - left: 16, - right: 16, - top: 10, - bottom: systemBottomPadding, - ), - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.05), - offset: const Offset(0, -2), - blurRadius: 4, - ), - ], - border: Border(top: BorderSide(color: Colors.grey.shade200)), - ), - child: Row( - children: [ - Expanded( - child: TextField( - controller: _commentController, - decoration: InputDecoration( - hintText: '댓글을 입력하세요...', - hintStyle: AppTypography.b2.copyWith(color: AppColors.gray3), - filled: true, - fillColor: AppColors.gray5, // 연한 회색 배경 - contentPadding: const EdgeInsets.symmetric( - horizontal: 20, - vertical: 10, - ), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(20), - borderSide: BorderSide.none, - ), - ), - ), - ), - const SizedBox(width: 10), - GestureDetector( - onTap: _isButtonActive - ? () async { - // 💡 댓글 작성 API 호출 - final contents = _commentController.text.trim(); - final success = await ref - .read(commentCreateNotifierProvider.notifier) - .addComment(postId: widget.postId, contents: contents); - - if (success && mounted) { - // 피드 화면에서 댓글 수 업데이트를 위해 필요한 코드 - if (widget.feedProvider != null) { - // 목록의 댓글 수를 로컬에서 +1 시켜서 UI를 즉시 갱신 - ref - .read(widget.feedProvider.notifier) - .incrementCommentCountLocally(widget.postId); - } - - // 성공 시 입력창 초기화 및 키보드 내리기 - _commentController.clear(); - FocusScope.of(context).unfocus(); - - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('댓글이 작성되었습니다.')), - ); - } - } - : null, - child: CircleAvatar( - radius: 22, - backgroundColor: _isButtonActive - ? AppColors.primaryAble - : AppColors.disable, - child: SvgPicture.asset( - 'assets/images/icons/comment_upload_icon.svg', - ), - ), - ), - ], - ), - ); - } - - Future _handleCommentSubmit() async { - final contents = _commentController.text.trim(); - final success = await ref - .read(commentCreateNotifierProvider.notifier) - .addComment(postId: widget.postId, contents: contents); - - if (success && mounted) { - if (widget.feedProvider != null) { - ref - .read(widget.feedProvider.notifier) - .incrementCommentCountLocally(widget.postId); - } - _commentController.clear(); - FocusScope.of(context).unfocus(); - } - } - - Widget _buildCommentItem(Comment comment) { - //날짜 처리는 comment.date로 통합되었음 - String commentDate = DateFormat('yyyy.MM.dd HH:mm').format(comment.date); - - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - CircleAvatar( - radius: 18, - // 타입 안정성을 위해 as ImageProvider 추가 - backgroundImage: - (comment.writer.profileUrl != null && - comment.writer.profileUrl!.isNotEmpty) - ? NetworkImage(comment.writer.profileUrl!) as ImageProvider - : null, - child: - (comment.writer.profileUrl == null || - comment.writer.profileUrl!.isEmpty) - ? SvgPicture.asset( - 'assets/images/icons/default_profile_icon.svg', - ) - : null, - ), - const SizedBox(width: 12), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(comment.writer.nickname, style: AppTypography.b1), - - CommentPopupMenu( - postId: widget.postId, - comment: comment, - feedProvider: widget.feedProvider, - ), - ], - ), - const SizedBox(height: 2), - Text(comment.content, style: AppTypography.b2), - const SizedBox(height: 4), - Text( - commentDate, - style: AppTypography.c1.copyWith(color: AppColors.gray2), - ), - ], - ), - ), - ], - ), - ); - } - Widget _buildEmptyComments() { return const Padding( padding: EdgeInsets.symmetric(vertical: 60), diff --git a/lib/features/feed/widgets/comment_input_field.dart b/lib/features/feed/widgets/comment_input_field.dart new file mode 100644 index 0000000..b2b23c0 --- /dev/null +++ b/lib/features/feed/widgets/comment_input_field.dart @@ -0,0 +1,128 @@ +// 최초 작성자 : 정승빈 (분리 및 리팩토링) +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; +import 'package:haenaem/features/feed/provider/comment_provider.dart'; + +class CommentInputField extends ConsumerStatefulWidget { + final int postId; + final dynamic feedProvider; + + const CommentInputField({super.key, required this.postId, this.feedProvider}); + + @override + ConsumerState createState() => _CommentInputFieldState(); +} + +class _CommentInputFieldState extends ConsumerState { + final TextEditingController _commentController = TextEditingController(); + bool _isButtonActive = false; + + @override + void initState() { + super.initState(); + _commentController.addListener(() { + setState(() { + _isButtonActive = _commentController.text.trim().isNotEmpty; + }); + }); + } + + @override + void dispose() { + _commentController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + // 키보드가 올라왔을 때 하단 여백 자동 조절 + final double systemBottomPadding = + MediaQuery.of(context).viewInsets.bottom > 0 + ? 10 + : MediaQuery.of(context).padding.bottom + 10; + + return Container( + padding: EdgeInsets.only( + left: 16, + right: 16, + top: 10, + bottom: systemBottomPadding, + ), + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + offset: const Offset(0, -2), + blurRadius: 4, + ), + ], + border: Border(top: BorderSide(color: Colors.grey.shade200)), + ), + child: Row( + children: [ + Expanded( + child: TextField( + controller: _commentController, + decoration: InputDecoration( + hintText: '댓글을 입력하세요...', + hintStyle: AppTypography.b2.copyWith(color: AppColors.gray3), + filled: true, + fillColor: AppColors.gray5, + contentPadding: const EdgeInsets.symmetric( + horizontal: 20, + vertical: 10, + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(20), + borderSide: BorderSide.none, + ), + ), + ), + ), + const SizedBox(width: 10), + GestureDetector( + onTap: _isButtonActive + ? () async { + final contents = _commentController.text.trim(); + // 💡 API 호출 + final success = await ref + .read(commentCreateNotifierProvider.notifier) + .addComment(postId: widget.postId, contents: contents); + + if (success && mounted) { + // 리스트 업데이트 + if (widget.feedProvider != null) { + // 피드 화면에서 댓글 수 업데이트를 위해 필요한 코드 + ref + .read(widget.feedProvider.notifier) + .incrementCommentCountLocally(widget.postId); + } + // 입력창 초기화 + _commentController.clear(); + FocusScope.of(context).unfocus(); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('댓글이 작성되었습니다.')), + ); + } + } + : null, + child: CircleAvatar( + radius: 22, + backgroundColor: _isButtonActive + ? AppColors.primaryAble + : AppColors.disable, + child: SvgPicture.asset( + 'assets/images/icons/comment_upload_icon.svg', + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/features/feed/widgets/comment_item.dart b/lib/features/feed/widgets/comment_item.dart new file mode 100644 index 0000000..8f34e7b --- /dev/null +++ b/lib/features/feed/widgets/comment_item.dart @@ -0,0 +1,80 @@ +// 최초 작성자 : 정승빈 (분리 및 리팩토링) +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; +import 'package:haenaem/features/challenge/widgets/comment_popup_menu.dart'; +import 'package:haenaem/features/feed/models/comment.dart'; + +class CommentItem extends StatelessWidget { + final Comment comment; + final int postId; + final dynamic feedProvider; + + const CommentItem({ + super.key, + required this.comment, + required this.postId, + this.feedProvider, + }); + + @override + Widget build(BuildContext context) { + String commentDate = DateFormat('yyyy.MM.dd HH:mm').format(comment.date); + + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 프로필 이미지 + CircleAvatar( + radius: 18, + // 타입 안정성을 위해 as ImageProvider 추가 + backgroundImage: + (comment.writer.profileUrl != null && + comment.writer.profileUrl!.isNotEmpty) + ? NetworkImage(comment.writer.profileUrl!) as ImageProvider + : null, + child: + (comment.writer.profileUrl == null || + comment.writer.profileUrl!.isEmpty) + ? SvgPicture.asset( + 'assets/images/icons/default_profile_icon.svg', + ) + : null, + ), + const SizedBox(width: 12), + // 댓글 내용 및 팝업 메뉴 + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(comment.writer.nickname, style: AppTypography.b1), + CommentPopupMenu( + postId: postId, + comment: comment, + feedProvider: feedProvider, + ), + ], + ), + const SizedBox(height: 2), + Text(comment.content, style: AppTypography.b2), + const SizedBox(height: 4), + Text( + commentDate, + style: AppTypography.c1.copyWith(color: AppColors.gray2), + ), + ], + ), + ), + ], + ), + ); + } +} From eead793935fb90ac06ff875004adceae05f4280b Mon Sep 17 00:00:00 2001 From: Chaeyeong_10 Date: Mon, 6 Apr 2026 16:08:19 +0900 Subject: [PATCH 104/134] =?UTF-8?q?refactor:=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20&=20=EB=82=98=EC=9D=98=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/signup/screens/auth_gate.dart | 6 +- .../challenge/data/challenge_repository.dart | 13 +- .../detail/screens/challenge_main_screen.dart | 2 +- .../challenge/models/challenge_model.dart | 127 ++++++------- .../provider/challenge_provider.dart | 27 ++- .../provider/challenge_provider.g.dart | 47 +++-- .../challenge_verification_screen.dart | 27 ++- lib/features/home/data/home_repository.dart | 39 +++- lib/features/home/provider/home_provider.dart | 23 +++ lib/features/home/widgets/challenge_card.dart | 3 +- lib/features/user/data/user_repository.dart | 18 +- .../user/models/my_page_challenge_card.dart | 27 ++- lib/features/user/provider/tag_provider.dart | 2 +- .../user/provider/user_profile_provider.dart | 22 ++- .../provider/user_profile_provider.g.dart | 2 +- lib/features/user/provider/user_provider.dart | 24 ++- .../user/provider/user_provider.g.dart | 2 +- .../challenge/challenge_list_screen.dart | 27 +-- .../user/screens/my_page_main_screen.dart | 19 +- .../screens/profile/profile_edit_screen.dart | 24 +-- .../user/views/my_challenge_section_view.dart | 13 +- .../user/widgets/my_challenge_card.dart | 172 ++++++++---------- lib/shared/models/home_challenge_card.dart | 14 +- lib/shared/models/user_detail.dart | 19 +- 24 files changed, 389 insertions(+), 310 deletions(-) diff --git a/lib/features/auth/signup/screens/auth_gate.dart b/lib/features/auth/signup/screens/auth_gate.dart index e0fc9fb..ac9f213 100644 --- a/lib/features/auth/signup/screens/auth_gate.dart +++ b/lib/features/auth/signup/screens/auth_gate.dart @@ -6,7 +6,7 @@ import 'package:haenaem/features/main/screens/main_screen.dart'; import 'package:haenaem/features/auth/login/login_screen.dart'; import 'signup_main_screen.dart'; import 'package:haenaem/features/user/data/user_repository.dart'; -import 'package:haenaem/shared/models/user.dart'; +import 'package:haenaem/shared/models/user_detail.dart'; import 'package:haenaem/features/user/provider/user_provider.dart'; import 'package:haenaem/features/notification/services/fcm_service.dart'; @@ -29,7 +29,7 @@ class AuthGate extends ConsumerWidget { // 1. 토큰이 있는 경우 if (snapshot.hasData && snapshot.data != null) { // 💡 핵심: 서버에 내 프로필을 물어봐서 가입이 끝났는지 확인합니다. - return FutureBuilder( + return FutureBuilder( future: ref.read(userRepositoryProvider).getMyProfile(), builder: (context, profileSnapshot) { if (profileSnapshot.connectionState == ConnectionState.waiting) { @@ -50,7 +50,7 @@ class AuthGate extends ConsumerWidget { // 성공적으로 정보를 가져왔다면 전역 Provider에 저장 // 프레임 렌더링 후에 상태를 업데이트하도록 처리 WidgetsBinding.instance.addPostFrameCallback((_) { - ref.read(currentUserProvider.notifier).setUser(user); + ref.read(currentUserProvider.notifier).setUser(user.user); // FCM 초기화 등 추가 작업 ref.read(fcmServiceProvider).initialize(); }); diff --git a/lib/features/challenge/data/challenge_repository.dart b/lib/features/challenge/data/challenge_repository.dart index 8b5ef1b..cb09fb2 100644 --- a/lib/features/challenge/data/challenge_repository.dart +++ b/lib/features/challenge/data/challenge_repository.dart @@ -13,6 +13,7 @@ import 'package:flutter/foundation.dart'; import 'package:haenaem/features/auth/services/auth_service.dart'; import 'package:haenaem/features/user/models/user_model.dart'; import 'package:haenaem/shared/models/challenge_base.dart'; +import 'package:haenaem/features/user/models/my_page_challenge_card.dart'; import 'package:haenaem/core/network/dio_provider.dart'; part 'challenge_repository.g.dart'; @@ -432,7 +433,7 @@ class ChallengeRepository { } // 내 페이지 - 나의 챌린지 - 진행 중인 챌린지 - Future> getInProgressChallenges({ + Future> getInProgressChallenges({ required bool onlyTwo, }) async { try { @@ -442,7 +443,7 @@ class ChallengeRepository { ); if (response.statusCode == 200) { return (response.data as List) - .map((e) => ChallengeInProgressModel.fromJson(e)) + .map((e) => MyPageChallengeCard.fromJson(e)) .toList(); } throw Exception('챌린지 로드 실패'); @@ -452,7 +453,7 @@ class ChallengeRepository { } // 내 페이지 - 나의 챌린지 - 완료한 챌린지 - Future> getSuccessChallenges({ + Future> getSuccessChallenges({ required bool onlyTwo, }) async { try { @@ -462,7 +463,7 @@ class ChallengeRepository { ); if (response.statusCode == 200) { return (response.data as List) - .map((e) => ChallengeInProgressModel.fromJson(e)) + .map((e) => MyPageChallengeCard.fromJson(e)) .toList(); } throw Exception('완료된 챌린지 로드 실패'); @@ -472,7 +473,7 @@ class ChallengeRepository { } // 내페이지 - 나의 챌린지 - 실패한 챌린지 - Future> getFailedChallenges({ + Future> getFailedChallenges({ required bool onlyTwo, }) async { try { @@ -482,7 +483,7 @@ class ChallengeRepository { ); if (response.statusCode == 200) { return (response.data as List) - .map((e) => ChallengeInProgressModel.fromJson(e)) + .map((e) => MyPageChallengeCard.fromJson(e)) .toList(); } throw Exception('실패한 챌린지 로드 실패'); diff --git a/lib/features/challenge/detail/screens/challenge_main_screen.dart b/lib/features/challenge/detail/screens/challenge_main_screen.dart index f069a80..d2aa082 100644 --- a/lib/features/challenge/detail/screens/challenge_main_screen.dart +++ b/lib/features/challenge/detail/screens/challenge_main_screen.dart @@ -10,7 +10,7 @@ import 'package:haenaem/features/challenge/widgets/challenge_popup_menu.dart'; import 'package:haenaem/shared/widgets/bottom_action_button.dart'; import 'package:haenaem/features/challenge/verification/screens/challenge_verification_screen.dart'; import 'package:haenaem/features/challenge/detail/screens/member_ranking_screen.dart'; -import 'package:haenaem/features/challenge/create/widgets/challenge_create_success_dialog.dart'; +import 'package:haenaem/features/challenge/widgets/challenge_create_success_dialog.dart'; import 'package:haenaem/shared/models/challenge_base.dart'; // 분리된 뷰 파일들 (아래 2번 단계에서 생성/수정할 파일들) diff --git a/lib/features/challenge/models/challenge_model.dart b/lib/features/challenge/models/challenge_model.dart index c367c73..734abb4 100644 --- a/lib/features/challenge/models/challenge_model.dart +++ b/lib/features/challenge/models/challenge_model.dart @@ -434,76 +434,77 @@ class CertificationPostModel { } // 마이페이지 탭 구분을 위한 전용 이름 -enum MyPageTab { inProgress, success, fail } +// enum MyPageTab { inProgress, success, fail } // 내 페이지 - 나의 챌린지 - 진행중인 챌린지 -@Deprecated( - 'user/models/my_page_challenge_card.dart내에 MyPageChallengeCard 모델 대신 사용', -) -class ChallengeInProgressModel { - final int challengeId; - final String title; - final int requiredWeeklyCount; // 필수는 유지하되 - final int todaySuccessCount; - final int participantNumber; - final int duringDate; - final String endDate; - final double achievementRate; - final String status; - - ChallengeInProgressModel({ - required this.challengeId, - required this.title, - required this.requiredWeeklyCount, - required this.todaySuccessCount, - required this.participantNumber, - required this.duringDate, - required this.endDate, - required this.achievementRate, - required this.status, - }); +// // 리팩토링 완료 +// @Deprecated( +// 'user/models/my_page_challenge_card.dart내에 MyPageChallengeCard 모델 대신 사용', +// ) +// class ChallengeInProgressModel { +// final int challengeId; +// final String title; +// final int requiredWeeklyCount; // 필수는 유지하되 +// final int todaySuccessCount; +// final int participantNumber; +// final int duringDate; +// final String endDate; +// final double achievementRate; +// final String status; + +// ChallengeInProgressModel({ +// required this.challengeId, +// required this.title, +// required this.requiredWeeklyCount, +// required this.todaySuccessCount, +// required this.participantNumber, +// required this.duringDate, +// required this.endDate, +// required this.achievementRate, +// required this.status, +// }); - factory ChallengeInProgressModel.fromJson(Map json) { - double rate = (json['achievementRate'] ?? 0).toDouble(); +// factory ChallengeInProgressModel.fromJson(Map json) { +// double rate = (json['achievementRate'] ?? 0).toDouble(); - // 💡 방어 로직: 0%일 때 직접 계산하는 로직에서도 null 체크 강화 - final int today = json['todaySuccessCount'] ?? 0; - final int weekly = json['requiredWeeklyCount'] ?? 0; +// // 💡 방어 로직: 0%일 때 직접 계산하는 로직에서도 null 체크 강화 +// final int today = json['todaySuccessCount'] ?? 0; +// final int weekly = json['requiredWeeklyCount'] ?? 0; - if (rate == 0 && weekly > 0) { - rate = today / weekly; - } else if (rate > 1.0) { - rate = rate / 100.0; - } +// if (rate == 0 && weekly > 0) { +// rate = today / weekly; +// } else if (rate > 1.0) { +// rate = rate / 100.0; +// } - return ChallengeInProgressModel( - challengeId: json['challengeId'] ?? 0, - title: json['title'] ?? '', - requiredWeeklyCount: json['requiredWeeklyCount'] ?? 0, - todaySuccessCount: json['todaySuccessCount'] ?? 0, - participantNumber: json['participantNumber'] ?? 0, - duringDate: json['duringDate'] ?? 0, - endDate: json['endDate'] ?? '', - achievementRate: rate, - status: json['status'] ?? 'IN_PROGRESS', - ); - } +// return ChallengeInProgressModel( +// challengeId: json['challengeId'] ?? 0, +// title: json['title'] ?? '', +// requiredWeeklyCount: json['requiredWeeklyCount'] ?? 0, +// todaySuccessCount: json['todaySuccessCount'] ?? 0, +// participantNumber: json['participantNumber'] ?? 0, +// duringDate: json['duringDate'] ?? 0, +// endDate: json['endDate'] ?? '', +// achievementRate: rate, +// status: json['status'] ?? 'IN_PROGRESS', +// ); +// } - // 기존 UI 위젯 수정을 최소화하기 위한 Getter - String get dateInfo => "완료일까지 D-${_calculateDDay()}"; - String get countInfo => "$todaySuccessCount/$participantNumber명"; - double get progress => achievementRate; - - int _calculateDDay() { - try { - final end = DateTime.parse(endDate); - final dDay = end.difference(DateTime.now()).inDays; - return dDay < 0 ? 0 : dDay; - } catch (_) { - return 0; - } - } -} +// // 기존 UI 위젯 수정을 최소화하기 위한 Getter +// String get dateInfo => "완료일까지 D-${_calculateDDay()}"; +// String get countInfo => "$todaySuccessCount/$participantNumber명"; +// double get progress => achievementRate; + +// int _calculateDDay() { +// try { +// final end = DateTime.parse(endDate); +// final dDay = end.difference(DateTime.now()).inDays; +// return dDay < 0 ? 0 : dDay; +// } catch (_) { +// return 0; +// } +// } +// } // 챌린지 검색 // TODO: 챌린지 아이디 부분 수정 diff --git a/lib/features/challenge/provider/challenge_provider.dart b/lib/features/challenge/provider/challenge_provider.dart index 89027b1..beaaa1b 100644 --- a/lib/features/challenge/provider/challenge_provider.dart +++ b/lib/features/challenge/provider/challenge_provider.dart @@ -5,7 +5,11 @@ import '../data/challenge_repository.dart'; import 'package:haenaem/features/user/data/user_repository.dart'; import '../models/challenge_model.dart'; import 'package:haenaem/features/user/models/user_model.dart'; +import 'package:haenaem/features/user/models/my_page_challenge_card.dart' + hide ChallengeStatus; import 'package:haenaem/shared/models/challenge_base.dart'; +import 'package:haenaem/features/home/provider/home_provider.dart'; + import 'dart:io'; part 'challenge_provider.g.dart'; @@ -452,42 +456,37 @@ class ChallengeDeleteNotifier extends _$ChallengeDeleteNotifier { } } -// 내페이지 사용자 프로필 정보 -// ♥️user_provider의 myprofile로 대체♥️ -// @riverpod -// Future myProfile(MyProfileRef ref) async { -// final repository = ref.watch(userRepositoryProvider); -// return repository.getMyProfile(); -// } - -// 내 페이지 - 나의 챌린지 - 진행중인 챌린지 +// 1. 내 페이지 - 나의 챌린지 - 진행중인 챌린지 @riverpod -Future> myInProgressChallenges( +Future> myInProgressChallenges( MyInProgressChallengesRef ref, { bool onlyTwo = false, }) { + // ✅ 리턴 타입을 List로 변경 return ref .watch(challengeRepositoryProvider) .getInProgressChallenges(onlyTwo: onlyTwo); } -// 내 페이지 - 나의 챌린지 - 완료한 챌린지 +// 2. 내 페이지 - 나의 챌린지 - 완료한 챌린지 @riverpod -Future> mySuccessChallenges( +Future> mySuccessChallenges( MySuccessChallengesRef ref, { bool onlyTwo = false, }) { + // ✅ 리턴 타입을 List로 변경 return ref .watch(challengeRepositoryProvider) .getSuccessChallenges(onlyTwo: onlyTwo); } -// 내 페이지 - 나의 챌린지 - 실패한 챌린지 +// 3. 내 페이지 - 나의 챌린지 - 실패한 챌린지 @riverpod -Future> myFailedChallenges( +Future> myFailedChallenges( MyFailedChallengesRef ref, { bool onlyTwo = false, }) { + // ✅ 리턴 타입을 List로 변경 return ref .watch(challengeRepositoryProvider) .getFailedChallenges(onlyTwo: onlyTwo); diff --git a/lib/features/challenge/provider/challenge_provider.g.dart b/lib/features/challenge/provider/challenge_provider.g.dart index 8218bc4..0a61baf 100644 --- a/lib/features/challenge/provider/challenge_provider.g.dart +++ b/lib/features/challenge/provider/challenge_provider.g.dart @@ -914,7 +914,7 @@ class _ArticleCommentsProviderElement } String _$myInProgressChallengesHash() => - r'4f53f796e087c3f28343d446396e079ac6ab81dc'; + r'566737730a407176974c16e5c3f17eb9edeb1526'; /// See also [myInProgressChallenges]. @ProviderFor(myInProgressChallenges) @@ -922,7 +922,7 @@ const myInProgressChallengesProvider = MyInProgressChallengesFamily(); /// See also [myInProgressChallenges]. class MyInProgressChallengesFamily - extends Family>> { + extends Family>> { /// See also [myInProgressChallenges]. const MyInProgressChallengesFamily(); @@ -955,7 +955,7 @@ class MyInProgressChallengesFamily /// See also [myInProgressChallenges]. class MyInProgressChallengesProvider - extends AutoDisposeFutureProvider> { + extends AutoDisposeFutureProvider> { /// See also [myInProgressChallenges]. MyInProgressChallengesProvider({bool onlyTwo = false}) : this._internal( @@ -988,7 +988,7 @@ class MyInProgressChallengesProvider @override Override overrideWith( - FutureOr> Function( + FutureOr> Function( MyInProgressChallengesRef provider, ) create, @@ -1008,8 +1008,7 @@ class MyInProgressChallengesProvider } @override - AutoDisposeFutureProviderElement> - createElement() { + AutoDisposeFutureProviderElement> createElement() { return _MyInProgressChallengesProviderElement(this); } @@ -1030,13 +1029,13 @@ class MyInProgressChallengesProvider @Deprecated('Will be removed in 3.0. Use Ref instead') // ignore: unused_element mixin MyInProgressChallengesRef - on AutoDisposeFutureProviderRef> { + on AutoDisposeFutureProviderRef> { /// The parameter `onlyTwo` of this provider. bool get onlyTwo; } class _MyInProgressChallengesProviderElement - extends AutoDisposeFutureProviderElement> + extends AutoDisposeFutureProviderElement> with MyInProgressChallengesRef { _MyInProgressChallengesProviderElement(super.provider); @@ -1045,7 +1044,7 @@ class _MyInProgressChallengesProviderElement } String _$mySuccessChallengesHash() => - r'95d005eec80994a28c20765d27b9a28ab78d01cf'; + r'0a13385a3d9c28538e51e5cacef629199fba64b6'; /// See also [mySuccessChallenges]. @ProviderFor(mySuccessChallenges) @@ -1053,7 +1052,7 @@ const mySuccessChallengesProvider = MySuccessChallengesFamily(); /// See also [mySuccessChallenges]. class MySuccessChallengesFamily - extends Family>> { + extends Family>> { /// See also [mySuccessChallenges]. const MySuccessChallengesFamily(); @@ -1086,7 +1085,7 @@ class MySuccessChallengesFamily /// See also [mySuccessChallenges]. class MySuccessChallengesProvider - extends AutoDisposeFutureProvider> { + extends AutoDisposeFutureProvider> { /// See also [mySuccessChallenges]. MySuccessChallengesProvider({bool onlyTwo = false}) : this._internal( @@ -1119,7 +1118,7 @@ class MySuccessChallengesProvider @override Override overrideWith( - FutureOr> Function( + FutureOr> Function( MySuccessChallengesRef provider, ) create, @@ -1139,8 +1138,7 @@ class MySuccessChallengesProvider } @override - AutoDisposeFutureProviderElement> - createElement() { + AutoDisposeFutureProviderElement> createElement() { return _MySuccessChallengesProviderElement(this); } @@ -1161,13 +1159,13 @@ class MySuccessChallengesProvider @Deprecated('Will be removed in 3.0. Use Ref instead') // ignore: unused_element mixin MySuccessChallengesRef - on AutoDisposeFutureProviderRef> { + on AutoDisposeFutureProviderRef> { /// The parameter `onlyTwo` of this provider. bool get onlyTwo; } class _MySuccessChallengesProviderElement - extends AutoDisposeFutureProviderElement> + extends AutoDisposeFutureProviderElement> with MySuccessChallengesRef { _MySuccessChallengesProviderElement(super.provider); @@ -1176,7 +1174,7 @@ class _MySuccessChallengesProviderElement } String _$myFailedChallengesHash() => - r'332d3fb3a12b34ae0912d92300578649335a35e8'; + r'284d1ed842f2abd2a862672dc15d6434094118e1'; /// See also [myFailedChallenges]. @ProviderFor(myFailedChallenges) @@ -1184,7 +1182,7 @@ const myFailedChallengesProvider = MyFailedChallengesFamily(); /// See also [myFailedChallenges]. class MyFailedChallengesFamily - extends Family>> { + extends Family>> { /// See also [myFailedChallenges]. const MyFailedChallengesFamily(); @@ -1217,7 +1215,7 @@ class MyFailedChallengesFamily /// See also [myFailedChallenges]. class MyFailedChallengesProvider - extends AutoDisposeFutureProvider> { + extends AutoDisposeFutureProvider> { /// See also [myFailedChallenges]. MyFailedChallengesProvider({bool onlyTwo = false}) : this._internal( @@ -1248,9 +1246,7 @@ class MyFailedChallengesProvider @override Override overrideWith( - FutureOr> Function( - MyFailedChallengesRef provider, - ) + FutureOr> Function(MyFailedChallengesRef provider) create, ) { return ProviderOverride( @@ -1268,8 +1264,7 @@ class MyFailedChallengesProvider } @override - AutoDisposeFutureProviderElement> - createElement() { + AutoDisposeFutureProviderElement> createElement() { return _MyFailedChallengesProviderElement(this); } @@ -1290,13 +1285,13 @@ class MyFailedChallengesProvider @Deprecated('Will be removed in 3.0. Use Ref instead') // ignore: unused_element mixin MyFailedChallengesRef - on AutoDisposeFutureProviderRef> { + on AutoDisposeFutureProviderRef> { /// The parameter `onlyTwo` of this provider. bool get onlyTwo; } class _MyFailedChallengesProviderElement - extends AutoDisposeFutureProviderElement> + extends AutoDisposeFutureProviderElement> with MyFailedChallengesRef { _MyFailedChallengesProviderElement(super.provider); diff --git a/lib/features/challenge/verification/screens/challenge_verification_screen.dart b/lib/features/challenge/verification/screens/challenge_verification_screen.dart index b5a9404..f1eb030 100644 --- a/lib/features/challenge/verification/screens/challenge_verification_screen.dart +++ b/lib/features/challenge/verification/screens/challenge_verification_screen.dart @@ -26,6 +26,8 @@ import 'package:haenaem/features/challenge/verification/widgets/reverification_g import '../widgets/verification_submit_button.dart'; import 'package:haenaem/features/challenge/widgets/verification_cancel_dialog.dart'; import 'package:haenaem/features/feed/models/feed_model.dart'; +import 'package:haenaem/features/home/provider/home_provider.dart'; +import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; // 챌린지 인증하기 화면 class ChallengeVerificationScreen extends ConsumerStatefulWidget { @@ -649,14 +651,33 @@ class _ChallengeVerificationScreenState ), ); - ref.invalidate(challengeHomeNotifierProvider); + // ♥️ 임시 코드 여기서부터 + // ✅ 서버 재조회 없이 로컬 상태 즉시 반영 + if (!isEditMode) { + ref + .read(homeNotifierProvider.notifier) + .markChallengeAsDone(widget.challengeId); + } + ref.invalidate(myInProgressChallengesProvider); + if (!mounted) return; ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text(isEditMode ? '수정 완료!' : '인증 완료!'))); - Navigator.pop(context); - } else if (mounted) { + } + // ♥️여기까지 + // 복원할 코드 + // // ✅ await로 fetch 완료 후 pop + // await ref.read(homeNotifierProvider.notifier).refresh(); + // ref.invalidate(myInProgressChallengesProvider); + // if (!mounted) return; + // ScaffoldMessenger.of( + // context, + // ).showSnackBar(SnackBar(content: Text(isEditMode ? '수정 완료!' : '인증 완료!'))); + // Navigator.pop(context); + //} + else if (mounted) { ScaffoldMessenger.of( context, ).showSnackBar(const SnackBar(content: Text('인증에 실패했습니다. 다시 시도해주세요.'))); diff --git a/lib/features/home/data/home_repository.dart b/lib/features/home/data/home_repository.dart index 4e390f1..40dbd64 100644 --- a/lib/features/home/data/home_repository.dart +++ b/lib/features/home/data/home_repository.dart @@ -11,6 +11,27 @@ class HomeRepository { HomeRepository(this._dio); + // Future getHomeData(String date) async { + // try { + // final response = await _dio.get( + // '/api/mainHome', + // queryParameters: {'date': date}, + // ); + + // if (response.statusCode == 200) { + // debugPrint('📥 [HomeRepository] 서버 응답 원본: ${response.data}'); + + // // HomeResponse.fromJson 안에서 myChallenges, notificationNumber 분리 + // return HomeResponse.fromJson(response.data); + // } else { + // throw Exception( + // '홈 데이터를 불러오는데 실패했습니다. (Status: ${response.statusCode})', + // ); + // } + // } on DioException catch (e) { + // throw Exception('서버 연결 실패: ${e.response?.statusMessage}'); + // } + // } Future getHomeData(String date) async { try { final response = await _dio.get( @@ -19,14 +40,20 @@ class HomeRepository { ); if (response.statusCode == 200) { - debugPrint('📥 [HomeRepository] 서버 응답 원본: ${response.data}'); + final data = response.data; + + // ✅ 인증 후 각 챌린지의 doIt, currentStreak 값 확인 + debugPrint('📥 [HomeRepository] 원본 응답: $data'); + final challenges = data['myChallenges'] as List? ?? []; + for (final c in challenges) { + debugPrint( + '🔥 challengeId=${c['challengeId']} | doIt=${c['doIt']} | currentStreak=${c['currentStreak']} | warning=${c['warning']}', + ); + } - // HomeResponse.fromJson 안에서 myChallenges, notificationNumber 분리 - return HomeResponse.fromJson(response.data); + return HomeResponse.fromJson(data); } else { - throw Exception( - '홈 데이터를 불러오는데 실패했습니다. (Status: ${response.statusCode})', - ); + throw Exception('홈 데이터 로드 실패 (Status: ${response.statusCode})'); } } on DioException catch (e) { throw Exception('서버 연결 실패: ${e.response?.statusMessage}'); diff --git a/lib/features/home/provider/home_provider.dart b/lib/features/home/provider/home_provider.dart index ccae42d..17fb8b5 100644 --- a/lib/features/home/provider/home_provider.dart +++ b/lib/features/home/provider/home_provider.dart @@ -22,6 +22,29 @@ class HomeNotifier extends _$HomeNotifier { ); } + // ♥️ 삭제할 거임 여기부터 + //✅ 인증 완료 시 서버 재조회 없이 로컬 상태만 즉시 갱신 + void markChallengeAsDone(int challengeId) { + final current = state.valueOrNull; + if (current == null) return; + + final updatedChallenges = current.myChallenges.map((c) { + if (c.challengeBase.id == challengeId) { + return c.copyWith(isDone: true); + } + return c; + }).toList(); + + state = AsyncValue.data( + HomeResponse( + myChallenges: updatedChallenges, + notificationNumber: current.notificationNumber, + ), + ); + } + + // ♥️ 여기까지 + String _getFormattedDate(DateTime dateTime) { return "${dateTime.year}-${dateTime.month.toString().padLeft(2, '0')}-${dateTime.day.toString().padLeft(2, '0')}"; } diff --git a/lib/features/home/widgets/challenge_card.dart b/lib/features/home/widgets/challenge_card.dart index 21fa447..85eb347 100644 --- a/lib/features/home/widgets/challenge_card.dart +++ b/lib/features/home/widgets/challenge_card.dart @@ -6,6 +6,7 @@ import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/shared/models/home_challenge_card.dart'; import 'package:haenaem/features/challenge/detail/screens/challenge_main_screen.dart'; +// 홈탭의 챌린지 카드 class ChallengeCard extends StatelessWidget { final HomeChallengeCard challenge; @@ -79,7 +80,7 @@ class ChallengeCard extends StatelessWidget { final frequencyText = challenge.weeklyFrequency == 7 ? '매일' : '주 ${challenge.weeklyFrequency}회'; - final dDayText = challenge.dDay == 0 ? '오늘 종료' : 'D-${challenge.dDay}'; + final dDayText = challenge.dDay == 0 ? '오늘 종료' : '완료까지 D-${challenge.dDay}'; return Text( '$frequencyText, $dDayText', style: AppTypography.b2.copyWith(fontSize: 14), diff --git a/lib/features/user/data/user_repository.dart b/lib/features/user/data/user_repository.dart index 16516e9..d97a82e 100644 --- a/lib/features/user/data/user_repository.dart +++ b/lib/features/user/data/user_repository.dart @@ -16,25 +16,11 @@ class UserRepository { UserRepository(this._dio); // 내 프로필 정보 조회 - Future getMyProfile() async { + Future getMyProfile() async { try { final response = await _dio.get('/api/users/me/profile'); if (response.statusCode == 200) { - return User.fromJson(response.data); - } else { - throw Exception('프로필 정보를 불러오지 못했습니다.'); - } - } on DioException catch (e) { - throw Exception('네트워크 에러: ${e.message}'); - } - } - - // 마이페이지용 상세 프로필 조회 - Future getMyProfileDetail() async { - try { - final response = await _dio.get('/api/users/me/profile'); - if (response.statusCode == 200) { - return UserDetail.fromJson(response.data); // ✅ UserDetail로 파싱 + return UserDetail.fromJson(response.data); } else { throw Exception('프로필 정보를 불러오지 못했습니다.'); } diff --git a/lib/features/user/models/my_page_challenge_card.dart b/lib/features/user/models/my_page_challenge_card.dart index 36a41ea..2f17c6c 100644 --- a/lib/features/user/models/my_page_challenge_card.dart +++ b/lib/features/user/models/my_page_challenge_card.dart @@ -29,17 +29,32 @@ class MyPageChallengeCard { factory MyPageChallengeCard.fromJson(Map json) { return MyPageChallengeCard( + // 홈탭 모델의 팩토리 메서드를 그대로 호출 challengeInfo: HomeChallengeCard.fromJson(json), - rate: (json['rate'] as num).toDouble(), - status: ChallengeStatus.values.byName(json['status'] as String), - failedDate: json['failed_date'] != null - ? DateTime.parse(json['failed_date'] as String) + + // 마이페이지 전용 필드들만 추가로 매핑 + rate: (json['achievementRate'] as num? ?? 0).toDouble(), + status: _mapStatus(json['status'] as String? ?? ''), + failedDate: json['endDate'] != null + ? DateTime.tryParse(json['endDate']) : null, - maxStreakCount: json['max_streak_count'] as int, - isParticipated: json['is_participated'] as bool, + maxStreakCount: json['currentStreak'] as int? ?? 0, // max를 현재 스트리크로 우선 매핑 + isParticipated: true, ); } + // 상태 값(SUCCESS, FAIL 등)을 Enum으로 안전하게 변환하는 헬퍼 + static ChallengeStatus _mapStatus(String raw) { + switch (raw.toUpperCase()) { + case 'SUCCESS': + return ChallengeStatus.success; + case 'FAIL': + return ChallengeStatus.fail; + default: + return ChallengeStatus.inProgress; + } + } + MyPageChallengeCard copyWith({ HomeChallengeCard? challengeInfo, double? rate, diff --git a/lib/features/user/provider/tag_provider.dart b/lib/features/user/provider/tag_provider.dart index 69cf135..2dd4e64 100644 --- a/lib/features/user/provider/tag_provider.dart +++ b/lib/features/user/provider/tag_provider.dart @@ -29,7 +29,7 @@ class TagNotifier extends Notifier { // 전체 태그와 내 프로필 동시 로드 final results = await Future.wait([ repository.getAllTags(), - repository.getMyProfileDetail(), + repository.getMyProfile(), ]); _allServerTags = results[0] as List; diff --git a/lib/features/user/provider/user_profile_provider.dart b/lib/features/user/provider/user_profile_provider.dart index 015add1..e734431 100644 --- a/lib/features/user/provider/user_profile_provider.dart +++ b/lib/features/user/provider/user_profile_provider.dart @@ -24,7 +24,10 @@ class UserProfile extends _$UserProfile { ref .read(currentUserProvider.notifier) .updateProfileImage(null); // 전역 상태 업데이트 - ref.invalidate(myProfileProvider); // 마이페이지 프로필 상태 갱신 + ref + .read(myProfileProvider.notifier) + .updateLocalDetail(profileUrl: null); // 로컬 업데이트 + state = const AsyncValue.data(null); } catch (e, stack) { state = AsyncValue.error(e, stack); @@ -59,14 +62,16 @@ class UserProfile extends _$UserProfile { } // 3) 프로필 이미지 변경 + String? finalProfileUrl; if (newImageFile != null) { await userRepo.uploadProfileImage(newImageFile); // 업로드 후 새 URL 가져와서 전역 상태 업데이트 - final updatedUser = await userRepo.getMyProfile(); + final updatedUserDetail = await userRepo.getMyProfile(); + finalProfileUrl = updatedUserDetail.user.profileUrl; ref .read(currentUserProvider.notifier) - .updateProfileImage(updatedUser.profileUrl); + .updateProfileImage(updatedUserDetail.user.profileUrl); } // 4) 태그 업데이트 @@ -75,8 +80,15 @@ class UserProfile extends _$UserProfile { throw Exception('태그 수정 중 오류가 발생했습니다.'); } - // 5) 성공 시 마이페이지 갱신 - ref.invalidate(myProfileProvider); + // 내페이지 전역 상태 로컬 업데이트 + ref + .read(myProfileProvider.notifier) + .updateLocalDetail( + nickname: newNickname, + introduction: newIntro, + tags: ref.read(tagProvider).tags, + profileUrl: finalProfileUrl, // 이미지가 바뀌었다면 새 URL, 아니면 기존 유지 + ); state = const AsyncValue.data(null); } catch (e, stack) { state = AsyncValue.error(e, stack); diff --git a/lib/features/user/provider/user_profile_provider.g.dart b/lib/features/user/provider/user_profile_provider.g.dart index ed7fd6b..d8e3b6a 100644 --- a/lib/features/user/provider/user_profile_provider.g.dart +++ b/lib/features/user/provider/user_profile_provider.g.dart @@ -6,7 +6,7 @@ part of 'user_profile_provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$userProfileHash() => r'19eca05cb7e9cf8b28eba8eb8bbce5333c70101a'; +String _$userProfileHash() => r'8d8ac63bfedecf90ac1d25e08d8d740cb55398de'; /// See also [UserProfile]. @ProviderFor(UserProfile) diff --git a/lib/features/user/provider/user_provider.dart b/lib/features/user/provider/user_provider.dart index 7ba09f9..ab9f69f 100644 --- a/lib/features/user/provider/user_provider.dart +++ b/lib/features/user/provider/user_provider.dart @@ -40,14 +40,32 @@ class MyProfile extends _$MyProfile { @override FutureOr build() async { final userRepo = ref.read(userRepositoryProvider); - return userRepo.getMyProfileDetail(); // ✅ 새 메서드 호출 + final detail = await userRepo.getMyProfile(); + + // ✨ [1. 초기 로드 시 자동 업데이트] + // 프로필 상세를 가져오자마자 기본 정보(User)를 전역 상태에 꽂아줍니다. + ref.read(currentUserProvider.notifier).setUser(detail.user); + + return detail; } // API 호출 없이 로컬 상세 정보만 업데이트 - void updateLocalDetail({String? introduction, List? tags}) { + void updateLocalDetail({ + String? introduction, + List? tags, + String? nickname, + String? profileUrl, + }) { state.whenData((current) { + // 새로운 유저 객체 생성 + final updatedUser = current.user.copyWith( + nickname: nickname ?? current.user.nickname, + profileUrl: profileUrl ?? current.user.profileUrl, + ); + // 2. 업데이트된 User를 포함하여 UserDetail 전체 상태를 갱신합니다. state = AsyncData( - UserDetail( + current.copyWith( + user: updatedUser, introduction: introduction ?? current.introduction, tags: tags ?? current.tags, ), diff --git a/lib/features/user/provider/user_provider.g.dart b/lib/features/user/provider/user_provider.g.dart index 6fb448f..63acd16 100644 --- a/lib/features/user/provider/user_provider.g.dart +++ b/lib/features/user/provider/user_provider.g.dart @@ -21,7 +21,7 @@ final currentUserProvider = NotifierProvider.internal( ); typedef _$CurrentUser = Notifier; -String _$myProfileHash() => r'4b209ac932e27d9c0deca6af80d9b5115cf82b65'; +String _$myProfileHash() => r'a2ae41d2429d95cb9cbdecd38b5825067b6b9ebc'; /// See also [MyProfile]. @ProviderFor(MyProfile) diff --git a/lib/features/user/screens/challenge/challenge_list_screen.dart b/lib/features/user/screens/challenge/challenge_list_screen.dart index 675350c..5daf2a9 100644 --- a/lib/features/user/screens/challenge/challenge_list_screen.dart +++ b/lib/features/user/screens/challenge/challenge_list_screen.dart @@ -4,9 +4,10 @@ import 'package:flutter_svg/flutter_svg.dart'; import '../../../../../core/theme/app_colors.dart'; import '../../../../../core/theme/app_typography.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:haenaem/features/challenge/models/challenge_model.dart'; +// import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import '../../widgets/my_challenge_card.dart'; // 💡 공통 카드 위젯 추가 +import 'package:haenaem/features/user/models/my_page_challenge_card.dart'; // 클래스의 용도: 챌린지 목록을 진행중, 완료, 실패 탭으로 구분하여 보여주는 화면 class ChallengeListScreen extends ConsumerWidget { @@ -54,20 +55,19 @@ class ChallengeListScreen extends ConsumerWidget { child: TabBarView( children: [ inProgressAsync.when( - data: (list) => - _buildFilteredListView(list, "IN_PROGRESS"), + data: (list) => _buildFilteredListView(list), loading: () => const Center(child: CircularProgressIndicator()), error: (err, __) => Center(child: Text('로드 실패: $err')), ), successAsync.when( - data: (list) => _buildFilteredListView(list, "SUCCESS"), + data: (list) => _buildFilteredListView(list), loading: () => const Center(child: CircularProgressIndicator()), error: (err, __) => Center(child: Text('로드 실패: $err')), ), failedAsync.when( - data: (list) => _buildFilteredListView(list, "FAIL"), + data: (list) => _buildFilteredListView(list), loading: () => const Center(child: CircularProgressIndicator()), error: (err, __) => Center(child: Text('로드 실패: $err')), @@ -101,25 +101,16 @@ class ChallengeListScreen extends ConsumerWidget { ); } - Widget _buildFilteredListView( - List list, - String tabStatus, - ) { - final filtered = list.where((item) { - final serverStatus = item.status.toUpperCase(); - return serverStatus == tabStatus || - (tabStatus == "FAIL" && serverStatus == "FAILED"); - }).toList(); - - if (filtered.isEmpty) { + Widget _buildFilteredListView(List list) { + if (list.isEmpty) { return const Center(child: Text('해당하는 챌린지가 없습니다.')); } return ListView.separated( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), - itemCount: filtered.length, + itemCount: list.length, separatorBuilder: (_, __) => const SizedBox(height: 12), - itemBuilder: (context, index) => MyChallengeCard(item: filtered[index]), + itemBuilder: (context, index) => MyChallengeCard(item: list[index]), ); } } diff --git a/lib/features/user/screens/my_page_main_screen.dart b/lib/features/user/screens/my_page_main_screen.dart index 7b59a62..9055da4 100644 --- a/lib/features/user/screens/my_page_main_screen.dart +++ b/lib/features/user/screens/my_page_main_screen.dart @@ -8,7 +8,6 @@ import '../../../../core/theme/app_typography.dart'; import 'package:haenaem/features/notification/services/fcm_service.dart'; import 'package:haenaem/features/user/provider/user_provider.dart'; -import 'package:haenaem/shared/models/user.dart'; import 'package:haenaem/shared/models/user_detail.dart'; import 'profile/profile_edit_screen.dart'; @@ -26,12 +25,14 @@ class MyPageMainScreen extends ConsumerStatefulWidget { class _MyPageMainScreenState extends ConsumerState { @override Widget build(BuildContext context) { + // myProfileProvider가 로딩중일 때 + // 전역 관리하는 currentUserProvider가 닉네임/이미지라도 먼저 가져옴 final currentUser = ref.watch(currentUserProvider); final profileAsync = ref.watch(myProfileProvider); return Scaffold( backgroundColor: Colors.white, - appBar: _buildAppBar(currentUser), + appBar: _buildAppBar(profileAsync.value), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 20.0), @@ -55,8 +56,8 @@ class _MyPageMainScreenState extends ConsumerState { ), data: (UserDetail detail) => ProfileHeaderView( // ✅ UserDetail 사용 - nickname: currentUser.nickname, // ✅ currentUserProvider 우선 - profileImageUrl: currentUser.profileUrl ?? '', + nickname: detail.user.nickname, + profileImageUrl: detail.user.profileUrl ?? '', introduction: detail.introduction, tags: detail.tags, ), @@ -82,7 +83,7 @@ class _MyPageMainScreenState extends ConsumerState { ); } - PreferredSizeWidget _buildAppBar(User? currentUser) { + PreferredSizeWidget _buildAppBar(UserDetail? detail) { return AppBar( backgroundColor: Colors.white, elevation: 0, @@ -98,14 +99,14 @@ class _MyPageMainScreenState extends ConsumerState { InkWell( onTap: () { // 1. 현재 로드된 프로필 데이터를 가져옵니다. - final profileData = ref.read(myProfileProvider).value; - if (currentUser != null && profileData != null) { + //final profileData = ref.read(myProfileProvider).value; + if (detail != null) { Navigator.push( context, MaterialPageRoute( builder: (context) => ProfileEditScreen( - user: currentUser, - detail: profileData, + //user: currentUser, + detail: detail, ), ), ); diff --git a/lib/features/user/screens/profile/profile_edit_screen.dart b/lib/features/user/screens/profile/profile_edit_screen.dart index e88a48d..7c966e4 100644 --- a/lib/features/user/screens/profile/profile_edit_screen.dart +++ b/lib/features/user/screens/profile/profile_edit_screen.dart @@ -7,16 +7,12 @@ import 'package:image_picker/image_picker.dart'; import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; import 'package:haenaem/shared/models/tag_model.dart'; -import '../../../../../core/theme/app_colors.dart'; -import '../../../../../core/theme/app_typography.dart'; -import 'package:haenaem/features/user/models/user_model.dart'; + import 'package:haenaem/shared/widgets/app_tag_chip.dart'; import 'package:haenaem/shared/widgets/image_source_sheet.dart'; import '../../../../../shared/widgets/bottom_action_button.dart'; import 'package:haenaem/features/auth/signup/screens/profile_image_edit_screen.dart'; -// import 'package:haenaem/features/user/models/user_model.dart'; import 'package:haenaem/shared/models/user_detail.dart'; -import 'package:haenaem/shared/models/user.dart'; import 'package:haenaem/features/user/provider/user_provider.dart'; import '../../widgets/profile_image_menu.dart'; @@ -25,13 +21,8 @@ import '../../provider/user_profile_provider.dart'; // 프로필 편집 화면 class ProfileEditScreen extends ConsumerStatefulWidget { - final User user; // 닉네임, 프로필 이미지 - final UserDetail detail; // 한줄소개, 태그 - const ProfileEditScreen({ - super.key, - required this.user, - required this.detail, - }); + final UserDetail detail; + const ProfileEditScreen({super.key, required this.detail}); @override ConsumerState createState() => _ProfileEditScreenState(); @@ -50,7 +41,9 @@ class _ProfileEditScreenState extends ConsumerState { @override void initState() { super.initState(); - _nicknameController = TextEditingController(text: widget.user.nickname); + _nicknameController = TextEditingController( + text: widget.detail.user.nickname, + ); _introController = TextEditingController(text: widget.detail.introduction); _nicknameController.addListener(_validateNickname); @@ -140,7 +133,7 @@ class _ProfileEditScreenState extends ConsumerState { .read(userProfileProvider.notifier) .updateProfile( currentNickname: - widget.user.nickname, // ✅ widget.profile → widget.user + widget.detail.user.nickname, // ✅ widget.profile → widget.user newNickname: _nicknameController.text, currentIntro: widget.detail.introduction, // ✅ widget.profile → widget.detail @@ -283,10 +276,11 @@ class _ProfileEditScreenState extends ConsumerState { _selectedImageFile!, fit: BoxFit.cover, ) // 2순위: 새로 고름 - : (widget.user.profileUrl ?? '') + : (widget.detail.user.profileUrl ?? '') .isNotEmpty // ✅ widget.profile → widget.user ? Image.network( widget + .detail .user .profileUrl!, // ✅ widget.profile → widget.user fit: BoxFit.cover, diff --git a/lib/features/user/views/my_challenge_section_view.dart b/lib/features/user/views/my_challenge_section_view.dart index 094e3b9..c271bca 100644 --- a/lib/features/user/views/my_challenge_section_view.dart +++ b/lib/features/user/views/my_challenge_section_view.dart @@ -4,11 +4,13 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/theme/app_colors.dart'; import '../../../core/theme/app_typography.dart'; -import '../../challenge/models/challenge_model.dart'; +//import '../../challenge/models/challenge_model.dart'; import '../../challenge/provider/challenge_provider.dart'; import '../screens/challenge/challenge_list_screen.dart'; import '../widgets/my_challenge_card.dart'; // 💡 공통 카드 위젯 추가 (위치가 widgets 내부일 경우 경로 주의) +import 'package:haenaem/features/user/models/my_page_challenge_card.dart'; +// 내페이지 나의 챌린지 영역 class MyChallengeSectionView extends ConsumerStatefulWidget { const MyChallengeSectionView({super.key}); @@ -17,6 +19,8 @@ class MyChallengeSectionView extends ConsumerStatefulWidget { _MyChallengeSectionViewState(); } +enum MyPageTab { inProgress, success, fail } + class _MyChallengeSectionViewState extends ConsumerState { // 섹션 내부에서 탭 상태 관리 @@ -189,9 +193,10 @@ class _MyChallengeSectionViewState return Column( children: list.asMap().entries.map((entry) { final isLast = entry.key == (list.length - 1); + final challenge = entry.value; return Column( children: [ - MyChallengeCard(item: entry.value), + MyChallengeCard(item: challenge), if (!isLast) const Divider(height: 1, color: AppColors.gray5), ], ); @@ -201,9 +206,11 @@ class _MyChallengeSectionViewState ); } - AsyncValue> _getChallengesProvider() { + AsyncValue> _getChallengesProvider() { switch (selectedTab) { case MyPageTab.inProgress: + // 💡 주의: 프로바이더 자체의 정의(challenge_provider.dart)도 + // MyPageChallengeCard를 반환하도록 수정되어 있어야 합니다. return ref.watch(myInProgressChallengesProvider(onlyTwo: true)); case MyPageTab.success: return ref.watch(mySuccessChallengesProvider(onlyTwo: true)); diff --git a/lib/features/user/widgets/my_challenge_card.dart b/lib/features/user/widgets/my_challenge_card.dart index e5bf813..8e58e3d 100644 --- a/lib/features/user/widgets/my_challenge_card.dart +++ b/lib/features/user/widgets/my_challenge_card.dart @@ -3,66 +3,47 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import '../../../../core/theme/app_colors.dart'; import '../../../../core/theme/app_typography.dart'; -import '../../challenge/models/challenge_model.dart'; +//import '../../challenge/models/challenge_model.dart'; +import '../models/my_page_challenge_card.dart'; +// 내페이지 나의 챌린지의 챌린지 리스트에 속하는 챌린지 카드 위젯 +// mypage challenge card 모델을 데이터로 받아서 화면에 그린다 class MyChallengeCard extends StatelessWidget { - final ChallengeInProgressModel item; + final MyPageChallengeCard item; const MyChallengeCard({super.key, required this.item}); @override Widget build(BuildContext context) { - final serverStatus = item.status.toUpperCase(); + // 상태별 테마 설정 + Color themeColor; + String statusText; + bool showBorder = item.status != ChallengeStatus.inProgress; - if (serverStatus == "FAIL" || serverStatus == "FAILED") { - return _buildCard( - statusText: '실패', - themeColor: AppColors.notification, - dateLabel: '실패일', - duringLabel: '최대', - showBorder: true, - ); + switch (item.status) { + case ChallengeStatus.success: + themeColor = AppColors.primaryAble; + statusText = '완료'; + break; + case ChallengeStatus.fail: + themeColor = AppColors.notification; + statusText = '실패'; + break; + case ChallengeStatus.inProgress: + default: + themeColor = AppColors.blue; + statusText = '진행중'; + break; } - - if (serverStatus == "SUCCESS") { - return _buildCard( - statusText: '완료', - themeColor: AppColors.primaryAble, - dateLabel: '완료일', - duringLabel: '총', - showBorder: true, - ); - } - - // 기본: 진행중 - return _buildCard( - statusText: '진행중', - themeColor: AppColors.blue, - dateLabel: '', - duringLabel: '', - showBorder: false, - ); - } - - // 통합된 카드 빌더 (상태에 따라 컬러와 텍스트만 바뀜) - Widget _buildCard({ - required String statusText, - required Color themeColor, - required String dateLabel, - required String duringLabel, - required bool showBorder, - }) { - final bool isInProgress = statusText == '진행중'; - return Container( width: double.infinity, padding: const EdgeInsets.all(16), - decoration: BoxDecoration( + decoration: ShapeDecoration( color: Colors.white, - borderRadius: BorderRadius.circular(12), - border: showBorder - ? Border.all(color: AppColors.gray5, width: 0.69) - : null, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: const BorderSide(width: 0.69, color: AppColors.gray5), + ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -74,13 +55,13 @@ class MyChallengeCard extends StatelessWidget { Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, + spacing: 2, children: [ Row( - mainAxisAlignment: MainAxisAlignment.start, children: [ Flexible( child: Text( - item.title, + item.challengeInfo.challengeBase.title, style: AppTypography.b3.copyWith( color: AppColors.black, ), @@ -92,52 +73,66 @@ class MyChallengeCard extends StatelessWidget { _buildStatusBadge(statusText, themeColor), ], ), - const SizedBox(height: 3), - // 날짜 정보 + // ✅ 날짜 형식 수정 Text( - isInProgress - ? item.dateInfo - : '$dateLabel ${item.endDate.replaceAll('-', '/')}', + item.status == ChallengeStatus.inProgress + ? '주 ${item.challengeInfo.weeklyFrequency}회, 완료까지 D-${item.challengeInfo.dDay}' + : '$statusText일 ${item.failedDate?.toString().substring(0, 10).replaceAll('-', '/') ?? ''}', style: AppTypography.b2.copyWith(color: AppColors.gray2), ), - if (!isInProgress) const SizedBox(height: 2), - // 불 아이콘 및 기간 정보 (완료/실패 시에만 아래로 내려감, 진행중은 _buildInfoRow에서 처리) - if (!isInProgress) - Row( - children: [ - SvgPicture.asset( - 'assets/images/icons/small_fire_icon.svg', - width: 16, - ), - const SizedBox(width: 2), - Text( - '$duringLabel ${item.duringDate}일', - style: AppTypography.b2.copyWith( - color: AppColors.black, - ), - ), - ], - ), + // ✅ 스트리크/멤버 정보를 Column 안으로 이동 + _buildDetailInfoRow(themeColor), ], ), ), - _buildProgressText(item.progress, themeColor), + _buildProgressText(item.rate, themeColor), ], ), const SizedBox(height: 8), - if (isInProgress) _buildInProgressInfoRow(item), - if (isInProgress) const SizedBox(height: 8), - _buildGaugeBar(item.progress, themeColor), + _buildGaugeBar(item.rate, themeColor), ], ), ); } + // --- 하단 상세 정보 (스트리크 + 멤버 참여도) --- + Widget _buildDetailInfoRow(Color themeColor) { + final info = item.challengeInfo; + return Row( + children: [ + // ✅ ChallengeCard와 동일한 조건 적용 + if (info.streakCount > 0 && info.isDone) + Padding( + padding: const EdgeInsets.only(right: 4), + child: SvgPicture.asset( + 'assets/images/icons/small_fire_icon.svg', + width: 14, + ), + ), + Text( + '${info.streakCount}일째', // ✅ currentStreak 매핑 + style: AppTypography.b2.copyWith(color: AppColors.black), + ), + const SizedBox(width: 12), + SvgPicture.asset( + 'assets/images/icons/mini_success_icon.svg', + width: 16, + ), + const SizedBox(width: 4), + // 예: 3/5명 인증 완료 + Text( + '${info.successParticipantCount}/${info.participantCount}명', + style: AppTypography.b2.copyWith(color: AppColors.black), + ), + ], + ); + } + Widget _buildStatusBadge(String text, Color color) { return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: ShapeDecoration( - color: color.withOpacity(0.1), + color: color.withValues(alpha: 0.1), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), ), child: Text(text, style: AppTypography.c1.copyWith(color: color)), @@ -157,29 +152,6 @@ class MyChallengeCard extends StatelessWidget { ); } - Widget _buildInProgressInfoRow(ChallengeInProgressModel item) { - return Row( - children: [ - SvgPicture.asset('assets/images/icons/small_fire_icon.svg', width: 16), - const SizedBox(width: 4), - Text( - '${item.duringDate}일째', - style: AppTypography.b2.copyWith(color: AppColors.black), - ), - const SizedBox(width: 12), - SvgPicture.asset( - 'assets/images/icons/mini_success_icon.svg', - width: 16, - ), - const SizedBox(width: 4), - Text( - item.countInfo, - style: AppTypography.b2.copyWith(color: AppColors.black), - ), - ], - ); - } - Widget _buildGaugeBar(double progress, Color color) { return ClipRRect( borderRadius: BorderRadius.circular(23), diff --git a/lib/shared/models/home_challenge_card.dart b/lib/shared/models/home_challenge_card.dart index 35415e2..e2e1862 100644 --- a/lib/shared/models/home_challenge_card.dart +++ b/lib/shared/models/home_challenge_card.dart @@ -27,13 +27,13 @@ class HomeChallengeCard { factory HomeChallengeCard.fromJson(Map json) { return HomeChallengeCard( challengeBase: ChallengeBase.fromJson(json), - streakCount: json['currentStreak'] as int, - participantCount: json['participantNumber'] as int, - successParticipantCount: json['todaySuccessCount'] as int, - warning: json['warning'] as bool, - isDone: json['doIt'] as bool, - dDay: json['dueToDate'] as int, - weeklyFrequency: json['requiredWeeklyCount'] as int, + streakCount: json['currentStreak'] as int? ?? 0, + participantCount: json['participantNumber'] as int? ?? 0, + successParticipantCount: json['todaySuccessCount'] as int? ?? 0, + warning: json['warning'] as bool? ?? false, + isDone: json['doIt'] as bool? ?? false, + dDay: json['dueToDate'] as int? ?? 0, + weeklyFrequency: json['requiredWeeklyCount'] as int? ?? 0, ); } diff --git a/lib/shared/models/user_detail.dart b/lib/shared/models/user_detail.dart index 1134a73..58ae92c 100644 --- a/lib/shared/models/user_detail.dart +++ b/lib/shared/models/user_detail.dart @@ -1,16 +1,31 @@ // 최초 작성자: 김채영 +import 'user.dart'; -// 한줄소개, 태그 모델 +// 한줄소개, 태그 모델 + 기본 유저 정보 class UserDetail { + final User user; final String introduction; final List tags; - UserDetail({required this.introduction, required this.tags}); + UserDetail({ + required this.user, + required this.introduction, + required this.tags, + }); factory UserDetail.fromJson(Map json) { return UserDetail( + user: User.fromJson(json), introduction: json['introduction'] ?? '', tags: List.from(json['tags'] ?? []), ); } + // 로컬 업데이트를 위한 copyWith + UserDetail copyWith({User? user, String? introduction, List? tags}) { + return UserDetail( + user: user ?? this.user, + introduction: introduction ?? this.introduction, + tags: tags ?? this.tags, + ); + } } From 712496baecc7abfac58783a80478d55ddd106319 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Tue, 7 Apr 2026 02:08:29 +0900 Subject: [PATCH 105/134] =?UTF-8?q?chore:=20=ED=94=BC=EB=93=9C=20=EB=94=94?= =?UTF-8?q?=EC=9E=90=EC=9D=B8=20=ED=8C=A8=EB=94=A9=20=EA=B0=84=EA=B2=A9=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/feed/widgets/feed_post_card.dart | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/features/feed/widgets/feed_post_card.dart b/lib/features/feed/widgets/feed_post_card.dart index 50a94ea..52efaf0 100644 --- a/lib/features/feed/widgets/feed_post_card.dart +++ b/lib/features/feed/widgets/feed_post_card.dart @@ -57,11 +57,11 @@ class FeedPostCard extends ConsumerWidget { children: [ // 1. 헤더 Padding( - padding: const EdgeInsets.fromLTRB(15, 12, 5, 10), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Row( children: [ CircleAvatar( - radius: 18, + radius: 20, // 반지름 backgroundImage: (post.writer.profileUrl != null && post.writer.profileUrl!.isNotEmpty) @@ -90,7 +90,10 @@ class FeedPostCard extends ConsumerWidget { ), // 2. 텍스트 본문 Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), + padding: const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ From 576cecfeda3d6800c571e13ba7c729b4fcbc0b38 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 28 Apr 2026 22:11:03 +0900 Subject: [PATCH 106/134] =?UTF-8?q?feat:=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20provider,=20repository=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/challenge_create_repository.dart | 77 +++++++++++++++++++ .../data/challenge_create_repository.g.dart | 30 ++++++++ .../create/provider/create_provider.dart | 28 +++++++ .../create/provider/create_provider.g.dart | 31 ++++++++ 4 files changed, 166 insertions(+) create mode 100644 lib/features/challenge/create/data/challenge_create_repository.dart create mode 100644 lib/features/challenge/create/data/challenge_create_repository.g.dart create mode 100644 lib/features/challenge/create/provider/create_provider.dart create mode 100644 lib/features/challenge/create/provider/create_provider.g.dart diff --git a/lib/features/challenge/create/data/challenge_create_repository.dart b/lib/features/challenge/create/data/challenge_create_repository.dart new file mode 100644 index 0000000..e9ccb2f --- /dev/null +++ b/lib/features/challenge/create/data/challenge_create_repository.dart @@ -0,0 +1,77 @@ +// 최초 작성자 : 강선욱 +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:haenaem/core/network/dio_provider.dart'; +import 'package:haenaem/shared/models/challenge_base.dart'; +import 'dart:io'; +import 'package:http_parser/http_parser.dart'; + +part 'challenge_create_repository.g.dart'; + +class ChallengeCreateRepository { + final Dio _dio; + + ChallengeCreateRepository(this._dio); + + // 1. 챌린지 생성 POST 요청 + Future createChallenge(Map data) async { + try { + final response = await _dio.post('/api/challenges/create', data: data); + debugPrint('📥 서버 생성 응답 원본: ${response.data}'); + + if (response.statusCode == 200 || response.statusCode == 201) { + // ✅ 서버 응답의 'id'를 모델의 'challengeId'로 매핑 + final responseData = { + 'challengeId': response.data['id'], + 'title': response.data['title'] ?? '', + }; + return ChallengeBase.fromJson(responseData); + } else { + throw Exception('챌린지 생성 실패'); + } + } on DioException catch (e) { + debugPrint('❌ 서버 상세 에러: ${e.response?.data}'); + throw Exception( + '서버 에러: ${e.response?.statusCode} - ${e.response?.data['message'] ?? '잘못된 요청'}', + ); + } + } + + // 2. 인증 사진 검증 (생성 과정에서 AI 검증 등이 필요한 경우 사용) + Future verifyImage(File imageFile, int challengeId) async { + try { + final formData = FormData.fromMap({ + "image": await MultipartFile.fromFile( + imageFile.path, + filename: imageFile.path.split('/').last, + contentType: MediaType('image', 'jpeg'), + ), + }); + + final response = await _dio.post( + '/api/image/verify', + data: formData, + queryParameters: {'challengeId': challengeId}, + ); + + if (response.statusCode == 200 || response.statusCode == 204) { + debugPrint('✅ 이미지 검증 및 임시 업로드 성공: ${response.data}'); + return response.data['tempImageId']; + } + return null; + } on DioException catch (e) { + debugPrint('❌ 이미지 검증 에러: ${e.response?.data}'); + return null; + } + } +} + +// Provider 설정 +@riverpod +ChallengeCreateRepository challengeCreateRepository( + ChallengeCreateRepositoryRef ref, +) { + final dio = ref.watch(dioProvider); + return ChallengeCreateRepository(dio); +} diff --git a/lib/features/challenge/create/data/challenge_create_repository.g.dart b/lib/features/challenge/create/data/challenge_create_repository.g.dart new file mode 100644 index 0000000..1d61c93 --- /dev/null +++ b/lib/features/challenge/create/data/challenge_create_repository.g.dart @@ -0,0 +1,30 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'challenge_create_repository.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$challengeCreateRepositoryHash() => + r'1d25f3888829a9d120dde7fbe087998c8601fcad'; + +/// See also [challengeCreateRepository]. +@ProviderFor(challengeCreateRepository) +final challengeCreateRepositoryProvider = + AutoDisposeProvider.internal( + challengeCreateRepository, + name: r'challengeCreateRepositoryProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$challengeCreateRepositoryHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +typedef ChallengeCreateRepositoryRef = + AutoDisposeProviderRef; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/challenge/create/provider/create_provider.dart b/lib/features/challenge/create/provider/create_provider.dart new file mode 100644 index 0000000..c41352a --- /dev/null +++ b/lib/features/challenge/create/provider/create_provider.dart @@ -0,0 +1,28 @@ +// 최초 작성자 : 강선욱 +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:haenaem/shared/models/challenge_base.dart'; +import '../data/challenge_create_repository.dart'; +import 'package:haenaem/shared/models/tag_model.dart'; + +part 'create_provider.g.dart'; // 파일명에 맞춰 변경 + +// 생성 상태(로딩/성공/에러)를 관리하는 Notifier +@riverpod +class ChallengeCreateNotifier extends _$ChallengeCreateNotifier { + @override + AsyncValue build() => const AsyncValue.data(null); + + Future create(Map data) async { + state = const AsyncValue.loading(); + + // 비동기 실행 결과 가드 + final result = await AsyncValue.guard( + () => ref.read(challengeCreateRepositoryProvider).createChallenge(data), + ); + + state = result; + + // 성공 시 ChallengeBase 객체를 반환하거나, 에러 시 null 반환 + return result.valueOrNull; + } +} diff --git a/lib/features/challenge/create/provider/create_provider.g.dart b/lib/features/challenge/create/provider/create_provider.g.dart new file mode 100644 index 0000000..a100c20 --- /dev/null +++ b/lib/features/challenge/create/provider/create_provider.g.dart @@ -0,0 +1,31 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'create_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$challengeCreateNotifierHash() => + r'b003af1426fa23673811d44e5f7ec81ed7075068'; + +/// See also [ChallengeCreateNotifier]. +@ProviderFor(ChallengeCreateNotifier) +final challengeCreateNotifierProvider = + AutoDisposeNotifierProvider< + ChallengeCreateNotifier, + AsyncValue + >.internal( + ChallengeCreateNotifier.new, + name: r'challengeCreateNotifierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$challengeCreateNotifierHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$ChallengeCreateNotifier = + AutoDisposeNotifier>; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package From 65a3d7fbefb142e0148057b7012ee9060f371d75 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 28 Apr 2026 22:19:56 +0900 Subject: [PATCH 107/134] =?UTF-8?q?feat:=20tag=20model=20=EA=B8=B0?= =?UTF-8?q?=EC=A1=B4=20=EB=AA=A8=EB=8D=B8=EA=B3=BC=20=EB=B3=91=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/shared/models/tag_model.dart | 23 +++++ lib/shared/provider/tag_provider.dart | 127 ++++++++++++++++++++++++ lib/shared/provider/tag_provider.g.dart | 28 ++++++ 3 files changed, 178 insertions(+) create mode 100644 lib/shared/provider/tag_provider.dart create mode 100644 lib/shared/provider/tag_provider.g.dart diff --git a/lib/shared/models/tag_model.dart b/lib/shared/models/tag_model.dart index 7bbacf6..777dad5 100644 --- a/lib/shared/models/tag_model.dart +++ b/lib/shared/models/tag_model.dart @@ -1,4 +1,27 @@ // 최초 작성자 : 김채영 + +class ChallengeTagModel { + final int id; + final String tag; + final String tagCategory; + + int get tagId => id; + + ChallengeTagModel({ + required this.id, + required this.tag, + required this.tagCategory, + }); + + factory ChallengeTagModel.fromJson(Map json) { + return ChallengeTagModel( + id: json['tagId'] ?? 0, + tag: json['tag'] ?? '', + tagCategory: json['tagCategory'] ?? 'AGE', + ); + } +} + // 서버의 영문 카테고리를 앱 내 한글 명칭으로 변환 class TagMapper { // 카테고리 배치 순서 diff --git a/lib/shared/provider/tag_provider.dart b/lib/shared/provider/tag_provider.dart new file mode 100644 index 0000000..9199d7e --- /dev/null +++ b/lib/shared/provider/tag_provider.dart @@ -0,0 +1,127 @@ +// 최초 작성자 : 김채영 +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:haenaem/shared/models/tag_model.dart'; +// import '../../challenge/models/challenge_model.dart'; +import 'package:haenaem/shared/models/user_detail.dart'; +import 'package:haenaem/features/user/data/user_repository.dart'; +import 'package:flutter/foundation.dart'; +import '../../features/auth/signup/models/signup_state.dart'; + +part 'tag_provider.g.dart'; + +// 서버 태그 목록 불러오기 (생성 화면에서 사용하므로 함께 이동하는 것이 좋습니다) +@riverpod +Future> allTags(AllTagsRef ref) { + return ref.watch(userRepositoryProvider).getAllTags(); +} + +final tagProvider = NotifierProvider(() { + return TagNotifier(); +}); + +class TagNotifier extends Notifier { + List _allServerTags = []; + List _initialTagNames = []; // 수정 전 초기 상태 저장용 + + @override + SignupState build() { + return SignupState(); + } + + // 1. 초기 데이터 로드 (전체 태그 + 내 프로필 태그) + Future initialize() async { + state = state.copyWith(isLoading: true); + try { + final repository = ref.read(userRepositoryProvider); + + // 전체 태그와 내 프로필 동시 로드 + final results = await Future.wait([ + repository.getAllTags(), + repository.getMyProfile(), + ]); + + _allServerTags = results[0] as List; + final profile = results[1] as UserDetail; // 프로필 모델 가정 + + _initialTagNames = List.from(profile.tags); + + // 카테고리 분류 (채영님이 만든 로직 그대로) + final Map> grouped = {}; + for (var tagModel in _allServerTags) { + final category = tagModel.tagCategory; + if (!grouped.containsKey(category)) grouped[category] = []; + grouped[category]!.add(tagModel.tag); + } + + state = state.copyWith( + categorizedTags: grouped, + tags: _initialTagNames, // 현재 선택된 상태를 내 태그로 초기화 + isLoading: false, + ); + } catch (e) { + debugPrint("🚨 로드 실패: $e"); + state = state.copyWith(isLoading: false); + } + } + + // 태그 토글 로직 (채영님 코드와 동일) + void toggleTag(String tag) { + final currentTags = List.from(state.tags); + if (currentTags.contains(tag)) { + currentTags.remove(tag); + } else if (currentTags.length < 6) { + currentTags.add(tag); + } + state = state.copyWith(tags: currentTags); + } + + // 태그 서버 전송 + Future updateInterestTags() async { + state = state.copyWith(isLoading: true); + try { + final repository = ref.read(userRepositoryProvider); + + // (1) 추가된 태그 이름 추출 + final addedTagNames = state.tags + .where((name) => !_initialTagNames.contains(name)) + .toList(); + // (2) 삭제된 태그 이름 추출 + final deletedTagNames = _initialTagNames + .where((name) => !state.tags.contains(name)) + .toList(); + + // (3) 이름을 ID로 변환 + final List addedIds = addedTagNames + .map( + (name) => _allServerTags.firstWhere((t) => t.tag == name).tagId, + ) + .toList(); + + final List deletedIds = deletedTagNames + .map( + (name) => _allServerTags.firstWhere((t) => t.tag == name).tagId, + ) + .toList(); + + // (4) API 호출 + if (addedIds.isNotEmpty) { + await repository.addUserTags(addedIds); // POST /api/users/me/tags + } + if (deletedIds.isNotEmpty) { + await repository.deleteUserTags( + deletedIds, + ); // DELETE /api/users/me/tags + } + + // 성공 시 초기 상태 업데이트 + _initialTagNames = List.from(state.tags); + return true; + } catch (e) { + debugPrint("🚨 수정 실패: $e"); + return false; + } finally { + state = state.copyWith(isLoading: false); + } + } +} diff --git a/lib/shared/provider/tag_provider.g.dart b/lib/shared/provider/tag_provider.g.dart new file mode 100644 index 0000000..2977fc4 --- /dev/null +++ b/lib/shared/provider/tag_provider.g.dart @@ -0,0 +1,28 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'tag_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$allTagsHash() => r'509a8857edbc465e553a55ab145a6a56fd3ac1f8'; + +/// See also [allTags]. +@ProviderFor(allTags) +final allTagsProvider = + AutoDisposeFutureProvider>.internal( + allTags, + name: r'allTagsProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$allTagsHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +typedef AllTagsRef = AutoDisposeFutureProviderRef>; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package From 72964da99583d7ed8bdccb1e4309e952f12e5704 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 28 Apr 2026 22:26:06 +0900 Subject: [PATCH 108/134] =?UTF-8?q?fix:=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20?= =?UTF-8?q?=EC=86=8C=EA=B0=9C=20=EB=82=A0=EC=A7=9C=20=EA=B3=84=EC=82=B0=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/shared/widgets/challenge_detail_content.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/shared/widgets/challenge_detail_content.dart b/lib/shared/widgets/challenge_detail_content.dart index 5d9fdd7..30d39bc 100644 --- a/lib/shared/widgets/challenge_detail_content.dart +++ b/lib/shared/widgets/challenge_detail_content.dart @@ -38,7 +38,7 @@ class ChallengeDetailContent extends StatelessWidget { ); final DateTime today = DateTime.now(); final DateTime currentDay = DateTime(today.year, today.month, today.day); - final int difference = targetDay.difference(currentDay).inDays; + final int difference = targetDay.difference(currentDay).inDays + 1; if (difference == 0) { dDayString = "(D-Day)"; From 1aedb2ed110d902667dcf14c7ab9fdf0f83f0767 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 28 Apr 2026 22:28:25 +0900 Subject: [PATCH 109/134] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=20?= =?UTF-8?q?=EC=95=88=20=ED=95=98=EB=8A=94=20=EC=9E=84=ED=8F=AC=ED=8A=B8=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../widgets/challenge_tag_bottom_sheet.dart | 7 +++--- .../challenge/data/challenge_repository.dart | 25 +++++++++++-------- .../feed/screens/challenge_search_screen.dart | 3 ++- .../challenge_invite_detail_screen.dart | 10 +++++--- .../user/views/my_challenge_section_view.dart | 13 +++++++--- 5 files changed, 37 insertions(+), 21 deletions(-) diff --git a/lib/features/challenge/create/widgets/challenge_tag_bottom_sheet.dart b/lib/features/challenge/create/widgets/challenge_tag_bottom_sheet.dart index bf17ae0..2d41674 100644 --- a/lib/features/challenge/create/widgets/challenge_tag_bottom_sheet.dart +++ b/lib/features/challenge/create/widgets/challenge_tag_bottom_sheet.dart @@ -3,13 +3,14 @@ import 'package:flutter/material.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import 'package:haenaem/features/challenge/models/challenge_model.dart'; +// import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; +import 'package:haenaem/shared/models/tag_model.dart'; +import 'package:haenaem/shared/provider/tag_provider.dart'; +// import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/features/challenge/create/widgets/plus_button.dart'; import 'package:haenaem/shared/widgets/custom_bottom_sheet.dart'; import 'package:haenaem/shared/widgets/app_tag_chip.dart'; -import 'package:haenaem/shared/models/tag_model.dart'; // 서버에서 태그 목록을 불러와 카테고리별로 표시하고 선택을 관리하는 바텀시트 class ChallengeTagBottomSheet extends ConsumerStatefulWidget { diff --git a/lib/features/challenge/data/challenge_repository.dart b/lib/features/challenge/data/challenge_repository.dart index 83a86c1..cb09fb2 100644 --- a/lib/features/challenge/data/challenge_repository.dart +++ b/lib/features/challenge/data/challenge_repository.dart @@ -12,6 +12,8 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter/foundation.dart'; import 'package:haenaem/features/auth/services/auth_service.dart'; import 'package:haenaem/features/user/models/user_model.dart'; +import 'package:haenaem/shared/models/challenge_base.dart'; +import 'package:haenaem/features/user/models/my_page_challenge_card.dart'; import 'package:haenaem/core/network/dio_provider.dart'; part 'challenge_repository.g.dart'; @@ -61,14 +63,17 @@ class ChallengeRepository { } // 챌린지 생성 post 요청 보내기 - Future createChallenge( - Map data, - ) async { + Future createChallenge(Map data) async { try { final response = await _dio.post('/api/challenges/create', data: data); debugPrint('📥 서버 생성 응답 원본: ${response.data}'); if (response.statusCode == 200 || response.statusCode == 201) { - return ChallengeCreateResponse.fromJson(response.data); + // ✅ 서버가 'id'로 주므로 'challengeId'로 변환 + final responseData = { + 'challengeId': response.data['id'], + 'title': response.data['title'] ?? '', + }; + return ChallengeBase.fromJson(responseData); } else { throw Exception('챌린지 생성 실패'); } @@ -428,7 +433,7 @@ class ChallengeRepository { } // 내 페이지 - 나의 챌린지 - 진행 중인 챌린지 - Future> getInProgressChallenges({ + Future> getInProgressChallenges({ required bool onlyTwo, }) async { try { @@ -438,7 +443,7 @@ class ChallengeRepository { ); if (response.statusCode == 200) { return (response.data as List) - .map((e) => ChallengeInProgressModel.fromJson(e)) + .map((e) => MyPageChallengeCard.fromJson(e)) .toList(); } throw Exception('챌린지 로드 실패'); @@ -448,7 +453,7 @@ class ChallengeRepository { } // 내 페이지 - 나의 챌린지 - 완료한 챌린지 - Future> getSuccessChallenges({ + Future> getSuccessChallenges({ required bool onlyTwo, }) async { try { @@ -458,7 +463,7 @@ class ChallengeRepository { ); if (response.statusCode == 200) { return (response.data as List) - .map((e) => ChallengeInProgressModel.fromJson(e)) + .map((e) => MyPageChallengeCard.fromJson(e)) .toList(); } throw Exception('완료된 챌린지 로드 실패'); @@ -468,7 +473,7 @@ class ChallengeRepository { } // 내페이지 - 나의 챌린지 - 실패한 챌린지 - Future> getFailedChallenges({ + Future> getFailedChallenges({ required bool onlyTwo, }) async { try { @@ -478,7 +483,7 @@ class ChallengeRepository { ); if (response.statusCode == 200) { return (response.data as List) - .map((e) => ChallengeInProgressModel.fromJson(e)) + .map((e) => MyPageChallengeCard.fromJson(e)) .toList(); } throw Exception('실패한 챌린지 로드 실패'); diff --git a/lib/features/feed/screens/challenge_search_screen.dart b/lib/features/feed/screens/challenge_search_screen.dart index aa88ae7..0628900 100644 --- a/lib/features/feed/screens/challenge_search_screen.dart +++ b/lib/features/feed/screens/challenge_search_screen.dart @@ -7,7 +7,7 @@ import 'package:haenaem/features/feed/screens/challenge_detail_screen.dart'; // import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/features/challenge/models/challenge_model.dart'; -import 'package:haenaem/features/user/models/user_model.dart'; +// import 'package:haenaem/features/user/models/user_model.dart'; import 'package:haenaem/shared/models/user.dart'; import 'package:haenaem/features/user/provider/user_provider.dart'; @@ -296,6 +296,7 @@ class ChallengeCard extends StatelessWidget { MaterialPageRoute( builder: (context) => ChallengeDetailScreen( challengeId: challenge.challengeId, + challengeTitle: challenge.title, ), ), ); diff --git a/lib/features/notification/screens/challenge_invite_detail_screen.dart b/lib/features/notification/screens/challenge_invite_detail_screen.dart index 4234353..acdbe1f 100644 --- a/lib/features/notification/screens/challenge_invite_detail_screen.dart +++ b/lib/features/notification/screens/challenge_invite_detail_screen.dart @@ -3,23 +3,25 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; - import '../../../core/theme/app_colors.dart'; import '../../../core/theme/app_typography.dart'; -import '../../challenge/provider/challenge_provider.dart'; -import '../../challenge/detail/widgets/challenge_detail_content.dart'; +// import '../../challenge/provider/challenge_provider.dart'; +import 'package:haenaem/shared/widgets/challenge_detail_content.dart'; +import 'package:haenaem/shared/provider/challenge_detail_provider.dart'; import '../../../shared/widgets/bottom_action_button.dart'; import '../provider/notification_provider.dart'; import 'package:haenaem/features/feed/widgets/enter_confirm_dialog.dart'; class ChallengeInviteDetailScreen extends ConsumerWidget { final int challengeId; + final String challengeTitle; final String inviterName; final String? inviterProfileImageUrl; const ChallengeInviteDetailScreen({ super.key, required this.challengeId, + required this.challengeTitle, required this.inviterName, this.inviterProfileImageUrl, }); @@ -129,7 +131,7 @@ class ChallengeInviteDetailScreen extends ConsumerWidget { context: context, builder: (context) => EnterConfirmDialog( challengeId: challengeId, - challengeTitle: challenge?.title ?? '챌린지', // 제목 전달 + challengeTitle: challengeTitle, ), ); } diff --git a/lib/features/user/views/my_challenge_section_view.dart b/lib/features/user/views/my_challenge_section_view.dart index 094e3b9..c271bca 100644 --- a/lib/features/user/views/my_challenge_section_view.dart +++ b/lib/features/user/views/my_challenge_section_view.dart @@ -4,11 +4,13 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/theme/app_colors.dart'; import '../../../core/theme/app_typography.dart'; -import '../../challenge/models/challenge_model.dart'; +//import '../../challenge/models/challenge_model.dart'; import '../../challenge/provider/challenge_provider.dart'; import '../screens/challenge/challenge_list_screen.dart'; import '../widgets/my_challenge_card.dart'; // 💡 공통 카드 위젯 추가 (위치가 widgets 내부일 경우 경로 주의) +import 'package:haenaem/features/user/models/my_page_challenge_card.dart'; +// 내페이지 나의 챌린지 영역 class MyChallengeSectionView extends ConsumerStatefulWidget { const MyChallengeSectionView({super.key}); @@ -17,6 +19,8 @@ class MyChallengeSectionView extends ConsumerStatefulWidget { _MyChallengeSectionViewState(); } +enum MyPageTab { inProgress, success, fail } + class _MyChallengeSectionViewState extends ConsumerState { // 섹션 내부에서 탭 상태 관리 @@ -189,9 +193,10 @@ class _MyChallengeSectionViewState return Column( children: list.asMap().entries.map((entry) { final isLast = entry.key == (list.length - 1); + final challenge = entry.value; return Column( children: [ - MyChallengeCard(item: entry.value), + MyChallengeCard(item: challenge), if (!isLast) const Divider(height: 1, color: AppColors.gray5), ], ); @@ -201,9 +206,11 @@ class _MyChallengeSectionViewState ); } - AsyncValue> _getChallengesProvider() { + AsyncValue> _getChallengesProvider() { switch (selectedTab) { case MyPageTab.inProgress: + // 💡 주의: 프로바이더 자체의 정의(challenge_provider.dart)도 + // MyPageChallengeCard를 반환하도록 수정되어 있어야 합니다. return ref.watch(myInProgressChallengesProvider(onlyTwo: true)); case MyPageTab.success: return ref.watch(mySuccessChallengesProvider(onlyTwo: true)); From b3cab05928e80f145bbff0113fa86c4370eb5a82 Mon Sep 17 00:00:00 2001 From: Chaeyeong_10 Date: Tue, 5 May 2026 19:04:13 +0900 Subject: [PATCH 110/134] =?UTF-8?q?refactor:=20baseurl=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/src/main/AndroidManifest.xml | 1 + assets/images/icons/gray_line_graph_icon.svg | 4 + assets/images/icons/green_line_graph_icon.svg | 4 + ios/Runner/Info.plist | 5 + lib/core/network/dio_provider.dart | 29 ++- lib/features/auth/services/auth_service.dart | 4 +- .../auth/signup/services/user_service.dart | 4 +- .../provider/challenge_provider.dart | 23 ++ lib/features/feed/provider/feed_provider.dart | 10 +- lib/features/home/data/home_repository.dart | 7 + lib/features/main/screens/main_screen.dart | 3 +- .../data/notification_repository.dart | 2 +- .../social/data/social_repository.dart | 2 +- .../provider/line_graph_provider.dart | 5 + .../statistics/screens/statistics_screen.dart | 60 +++++ .../statistics/widgets/haenaem_grass.dart | 124 +++++++++++ .../widgets/line_graph/line_graph.dart | 163 ++++++++++++++ .../line_graph/monthly_line_graph.dart | 209 ++++++++++++++++++ .../widgets/line_graph/weekly_line_graph.dart | 99 +++++++++ .../statistics/widgets/pie_graph.dart | 202 +++++++++++++++++ .../statistics/widgets/statistics_card.dart | 62 ++++++ .../user/widgets/my_challenge_card.dart | 2 +- 22 files changed, 1004 insertions(+), 20 deletions(-) create mode 100644 assets/images/icons/gray_line_graph_icon.svg create mode 100644 assets/images/icons/green_line_graph_icon.svg create mode 100644 lib/features/statistics/provider/line_graph_provider.dart create mode 100644 lib/features/statistics/screens/statistics_screen.dart create mode 100644 lib/features/statistics/widgets/haenaem_grass.dart create mode 100644 lib/features/statistics/widgets/line_graph/line_graph.dart create mode 100644 lib/features/statistics/widgets/line_graph/monthly_line_graph.dart create mode 100644 lib/features/statistics/widgets/line_graph/weekly_line_graph.dart create mode 100644 lib/features/statistics/widgets/pie_graph.dart create mode 100644 lib/features/statistics/widgets/statistics_card.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 9dd7016..57ce224 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -14,6 +14,7 @@ android:label="해냄" android:name="${applicationName}" android:icon="@mipmap/ic_launcher" + android:usesCleartextTraffic="true" android:enableOnBackInvokedCallback="false"> + + + diff --git a/assets/images/icons/green_line_graph_icon.svg b/assets/images/icons/green_line_graph_icon.svg new file mode 100644 index 0000000..e1005d5 --- /dev/null +++ b/assets/images/icons/green_line_graph_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index cb2ac8d..e9b2236 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -30,6 +30,11 @@ + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + NSCameraUsageDescription 프로필 사진 촬영을 위해 카메라 권한이 필요합니다. NSPhotoLibraryUsageDescription diff --git a/lib/core/network/dio_provider.dart b/lib/core/network/dio_provider.dart index b66c4ad..1af129f 100644 --- a/lib/core/network/dio_provider.dart +++ b/lib/core/network/dio_provider.dart @@ -13,9 +13,8 @@ part 'dio_provider.g.dart'; Dio dio(DioRef ref) { final dio = Dio( BaseOptions( - baseUrl: 'https://hanaem.onrender.com/', - connectTimeout: const Duration(seconds: 45), - receiveTimeout: const Duration(seconds: 45), + baseUrl: 'http://158.247.216.11:8080', + connectTimeout: const Duration(seconds: 5), ), ); @@ -24,6 +23,8 @@ Dio dio(DioRef ref) { onRequest: (options, handler) async { const storage = FlutterSecureStorage(); final String? token = await storage.read(key: 'accessToken'); + // 💡 [디버깅 로그] 저장소에서 꺼낸 생생한 토큰 상태를 확인합니다. + debugPrint('🕵️‍♂️ [Interceptor] Storage Read (accessToken): $token'); if (token != null) { options.headers['Authorization'] = 'Bearer $token'; } @@ -31,11 +32,23 @@ Dio dio(DioRef ref) { }, onError: (DioException e, handler) async { if (e.response?.statusCode == 401) { - final newToken = await AuthService.refreshTokens(); - if (newToken != null) { - e.requestOptions.headers['Authorization'] = 'Bearer $newToken'; - final response = await dio.fetch(e.requestOptions); - return handler.resolve(response); + const storage = FlutterSecureStorage(); + final refreshToken = await storage.read(key: 'refreshToken'); + if (refreshToken != null) { + try { + // 🎯 토큰 갱신 전용 가벼운 Dio 생성 (인터셉터 없음) + final refreshDio = Dio( + BaseOptions(baseUrl: e.requestOptions.baseUrl), + ); + + final response = await refreshDio.post( + '/api/token', + data: {"refreshToken": refreshToken}, + ); + } catch (err) { + // 재발급 실패 시 로그아웃 처리 + debugPrint("재발급 실패!"); + } } } return handler.next(e); diff --git a/lib/features/auth/services/auth_service.dart b/lib/features/auth/services/auth_service.dart index 4c89e9c..30ca97c 100644 --- a/lib/features/auth/services/auth_service.dart +++ b/lib/features/auth/services/auth_service.dart @@ -5,6 +5,7 @@ import 'dart:math'; import 'package:crypto/crypto.dart'; import 'package:flutter_appauth/flutter_appauth.dart'; import 'package:dio/dio.dart'; +import '../../../core/network/dio_provider.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; // 토큰 저장을 위해 필요 import 'package:haenaem/features/auth/signup/screens/signup_main_screen.dart'; import 'package:haenaem/features/main/screens/main_screen.dart'; @@ -39,8 +40,9 @@ class AuthService { // static const String kakaoRedirectUri = // 'https://ungenially-undebatable-sindy.ngrok-free.dev/oauth/kakao/callback'; + // ♥️ 기존 서버 static final Dio _dio = Dio( - BaseOptions(baseUrl: 'https://hanaem.onrender.com'), + BaseOptions(baseUrl: 'http://158.247.216.11:8080'), ); // ♥️ 로컬 서버로 테스트 diff --git a/lib/features/auth/signup/services/user_service.dart b/lib/features/auth/signup/services/user_service.dart index 5e56b87..6b3fa1e 100644 --- a/lib/features/auth/signup/services/user_service.dart +++ b/lib/features/auth/signup/services/user_service.dart @@ -6,7 +6,7 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart'; // 유저 정보와 관련된 API 통신을 담당하는 서비스 클래스 class UserService { - final Dio _dio = Dio(BaseOptions(baseUrl: 'https://hanaem.onrender.com')); + final Dio _dio = Dio(BaseOptions(baseUrl: 'http://158.247.216.11:8080')); // final Dio _dio = Dio( // BaseOptions( // // 1. 서버 주소를 팀원이 준 ngrok 주소로 변경 @@ -16,7 +16,7 @@ class UserService { // // 2. ngrok 경고창 우회를 위한 헤더 필수 추가 // headers: {'ngrok-skip-browser-warning': 'true'}, // ), - //); + // ); final _storage = const FlutterSecureStorage(); // 로컬 기기에 저장된 토큰을 읽기 위한 보안 저장소 diff --git a/lib/features/challenge/provider/challenge_provider.dart b/lib/features/challenge/provider/challenge_provider.dart index beaaa1b..cc8641d 100644 --- a/lib/features/challenge/provider/challenge_provider.dart +++ b/lib/features/challenge/provider/challenge_provider.dart @@ -4,6 +4,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../data/challenge_repository.dart'; import 'package:haenaem/features/user/data/user_repository.dart'; import '../models/challenge_model.dart'; +import 'package:flutter/foundation.dart'; // ✅ debugPrint를 쓰기 위해 필요합니다! import 'package:haenaem/features/user/models/user_model.dart'; import 'package:haenaem/features/user/models/my_page_challenge_card.dart' hide ChallengeStatus; @@ -190,6 +191,28 @@ class ArticleCreateNotifier extends _$ArticleCreateNotifier { ), ); + // ♥️ 로그 찍어보기 여기부터 + if (!result.hasError) { + debugPrint('🚀 인증 성공! 홈 데이터 새로고침 및 검증 시작...'); + + // 1. 홈 데이터 새로고침 + await ref.read(homeNotifierProvider.notifier).refresh(); + + // 2. 새로고침된 최신 데이터 가져와서 확인 + final latestHomeData = ref.read(homeNotifierProvider).value; + if (latestHomeData != null) { + for (var c in latestHomeData.myChallenges) { + debugPrint( + 'challengeId=${c.challengeBase.id} | ' // ✅ challenge → c + 'doIt=${c.isDone} | ' // ✅ challenge → c + 'currentStreak=${c.streakCount} | ' // ✅ challenge → c + 'warning=${c.warning}', // ✅ challenge → c + ); + } + } + } + // ♥️ 여기까지 + state = result; return !result.hasError; } diff --git a/lib/features/feed/provider/feed_provider.dart b/lib/features/feed/provider/feed_provider.dart index 014e6be..3b0596d 100644 --- a/lib/features/feed/provider/feed_provider.dart +++ b/lib/features/feed/provider/feed_provider.dart @@ -9,11 +9,11 @@ final feedRepositoryProvider = Provider((ref) { final dio = Dio( BaseOptions( // Render.com 서버 주소를 베이스로 넣어두면 편리합니다 - baseUrl: 'https://hanaem.onrender.com', - //baseUrl: 'https://ungenially-undebatable-sindy.ngrok-free.dev', - connectTimeout: const Duration(seconds: 45), - receiveTimeout: const Duration(seconds: 45), - //headers: {'ngrok-skip-browser-warning': 'true'}, + baseUrl: 'http://158.247.216.11:8080', + // baseUrl: 'https://ungenially-undebatable-sindy.ngrok-free.dev', + // connectTimeout: const Duration(seconds: 45), + // receiveTimeout: const Duration(seconds: 45), + // headers: {'ngrok-skip-browser-warning': 'true'}, ), ); diff --git a/lib/features/home/data/home_repository.dart b/lib/features/home/data/home_repository.dart index 40dbd64..2e89da1 100644 --- a/lib/features/home/data/home_repository.dart +++ b/lib/features/home/data/home_repository.dart @@ -33,6 +33,13 @@ class HomeRepository { // } // } Future getHomeData(String date) async { + // 💡 [디버깅용] 호출 직전 헤더 상태를 확인합니다. + debugPrint( + '🚀 [Auth Check] Header: ${_dio.options.headers['Authorization']}', + ); + debugPrint( + '🚀 [ngrok Check] Header: ${_dio.options.headers['ngrok-skip-browser-warning']}', + ); try { final response = await _dio.get( '/api/mainHome', diff --git a/lib/features/main/screens/main_screen.dart b/lib/features/main/screens/main_screen.dart index 014e7fe..2a5d334 100644 --- a/lib/features/main/screens/main_screen.dart +++ b/lib/features/main/screens/main_screen.dart @@ -5,6 +5,7 @@ import 'package:haenaem/features/social/screens/social_main_screen.dart'; import '../widgets/bottom_nav_bar.dart'; import 'package:haenaem/features/user/screens/my_page_main_screen.dart'; import 'package:haenaem/features/feed/screens/feed_screen.dart'; +import 'package:haenaem/features/statistics/screens/statistics_screen.dart'; // 내비게이션 바를 넣은 화면 class MainScreen extends StatefulWidget { @@ -20,7 +21,7 @@ class _MainScreenState extends State { // 하단 바를 통해 전환될 화면 리스트 final List _pages = [ const HomeScreen(), - const Center(child: Text("통계 화면")), + const StatisticsScreen(), const FeedScreen(), const SocialMainScreen(), const MyPageMainScreen(), diff --git a/lib/features/notification/data/notification_repository.dart b/lib/features/notification/data/notification_repository.dart index 196b131..9b2cb95 100644 --- a/lib/features/notification/data/notification_repository.dart +++ b/lib/features/notification/data/notification_repository.dart @@ -14,7 +14,7 @@ final secureStorageProvider = Provider((ref) { final notiDioProvider = Provider((ref) { final dio = Dio( BaseOptions( - baseUrl: 'https://hanaem.onrender.com', // 확인된 백엔드 주소 + baseUrl: 'http://158.247.216.11:8080', // 확인된 백엔드 주소 connectTimeout: const Duration(seconds: 5), receiveTimeout: const Duration(seconds: 3), ), diff --git a/lib/features/social/data/social_repository.dart b/lib/features/social/data/social_repository.dart index 1d08366..dfbbd97 100644 --- a/lib/features/social/data/social_repository.dart +++ b/lib/features/social/data/social_repository.dart @@ -15,7 +15,7 @@ import '../../auth/services/auth_service.dart'; final dioProvider = Provider((ref) { final dio = Dio( BaseOptions( - baseUrl: 'https://hanaem.onrender.com', // 서버 주소 + baseUrl: 'http://158.247.216.11:8080', // 서버 주소 //baseUrl: 'https://ungenially-undebatable-sindy.ngrok-free.dev', connectTimeout: const Duration(seconds: 5), //headers: {'ngrok-skip-browser-warning': 'true'}, diff --git a/lib/features/statistics/provider/line_graph_provider.dart b/lib/features/statistics/provider/line_graph_provider.dart new file mode 100644 index 0000000..d834c0a --- /dev/null +++ b/lib/features/statistics/provider/line_graph_provider.dart @@ -0,0 +1,5 @@ +// 최초 작성자: 김채영 +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +// true면 월간, false면 주간 +final graphTypeProvider = StateProvider((ref) => true); diff --git a/lib/features/statistics/screens/statistics_screen.dart b/lib/features/statistics/screens/statistics_screen.dart new file mode 100644 index 0000000..a129faf --- /dev/null +++ b/lib/features/statistics/screens/statistics_screen.dart @@ -0,0 +1,60 @@ +// 최초 작성자: 김채영 +import 'package:flutter/material.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; +import '../widgets/haenaem_grass.dart'; +import '../widgets/pie_graph.dart'; +import '../widgets/line_graph/line_graph.dart'; + +class StatisticsScreen extends StatelessWidget { + const StatisticsScreen({super.key}); + + @override + Widget build(BuildContext context) { + // 임시 데이터 (나중에 API 응답값으로 대체) + final List mockActivity = List.generate(365, (index) => (index % 5)); + + return Scaffold( + backgroundColor: AppColors.gray5, + appBar: AppBar( + backgroundColor: Colors.white, + elevation: 0, + scrolledUnderElevation: 0, + title: Text( + '통계', + style: AppTypography.h3.copyWith(color: AppColors.black), + ), + centerTitle: true, + ), + body: SingleChildScrollView( + child: Column( + children: [ + const SizedBox(height: 10), + // 잔디 위젯 배치 + HaenaemGrass( + successDays: 00, + currentStreak: 00, + activity: mockActivity, + ), + + const SizedBox(height: 20), + const PieGraph( + totalCount: 48, + tagCounts: [ + TagCount(tag: '자격증', count: 24, color: Color(0xFF8979FF)), + TagCount(tag: '다이어트', count: 15, color: Color(0xFFFF928A)), + TagCount(tag: '독서', count: 8, color: Color(0xff3cc3df)), + TagCount(tag: 'tag', count: 00, color: AppColors.gray4), + TagCount(tag: 'tag', count: 00, color: Color(0xFFFFD166)), + TagCount(tag: 'tag', count: 00, color: AppColors.primaryAble), + ], + ), + const SizedBox(height: 20), + const LineGraph(), + const SizedBox(height: 20), + ], + ), + ), + ); + } +} diff --git a/lib/features/statistics/widgets/haenaem_grass.dart b/lib/features/statistics/widgets/haenaem_grass.dart new file mode 100644 index 0000000..111c5c8 --- /dev/null +++ b/lib/features/statistics/widgets/haenaem_grass.dart @@ -0,0 +1,124 @@ +// 최초 작성자: 김채영 +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; +import 'statistics_card.dart'; + +class HaenaemGrass extends StatelessWidget { + final int successDays; + final int currentStreak; + final List activity; // 1년치 활동 데이터 (약 365개) + + const HaenaemGrass({ + super.key, + required this.successDays, + required this.currentStreak, + required this.activity, + }); + + @override + Widget build(BuildContext context) { + // 2026년 월별 일수 배열 (평년 기준) + // 나중에 연별로 알아서 바뀌게끔 로직 수정 + final List daysInMonths = [ + 31, + 28, + 31, + 30, + 31, + 30, + 31, + 31, + 30, + 31, + 30, + 31, + ]; + + return StatisticsCard( + title: "해냄 잔디", + // ✅ headerAction을 사용하여 상단 우측에 인증 횟수 배치 + headerAction: Row( + mainAxisSize: MainAxisSize.min, + children: [ + _buildSummaryItem( + 'assets/images/icons/mini_success_icon.svg', + '$successDays일', + AppColors.primaryAble, + ), + const SizedBox(width: 10), + _buildSummaryItem( + 'assets/images/icons/small_fire_icon.svg', + '$currentStreak일', + AppColors.fire, + ), + ], + ), + child: Padding( + // StatisticsCard 내부 패딩(20) + 12.5 = 카드 끝에서 총 32.5 여백 + padding: const EdgeInsets.symmetric(horizontal: 12.5), + child: Column( + mainAxisSize: MainAxisSize.min, + spacing: 6, // 잔디 한 줄(월)끼리의 간격 + children: List.generate(12, (monthIndex) { + int dayCount = daysInMonths[monthIndex]; + + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 2, // 잔디 한 칸끼리의 간격 + children: List.generate(dayCount, (dayIndex) { + return _buildGrassNode(); // 모든 잔디 gray5 색상 + }), + ); + }), + ), + ), + ); + } + + Widget _buildSummaryItem(String iconPath, String text, Color textColor) { + return Row( + children: [ + SvgPicture.asset( + iconPath, + width: 20, + height: 20, + colorFilter: ColorFilter.mode(textColor, BlendMode.srcIn), + ), + const SizedBox(width: 4), + Text(text, style: AppTypography.b2.copyWith(color: textColor)), + ], + ); + } + + // 잔디 한 알 + Widget _buildGrassNode() { + // Color nodeColor; + // switch (level) { + // case 1: + // nodeColor = AppColors.primaryAble.withValues(alpha: 0.25); + // break; + // case 2: + // nodeColor = AppColors.primaryAble.withValues(alpha: 0.5); + // break; + // case 3: + // nodeColor = AppColors.primaryAble.withValues(alpha: 0.75); + // break; + // case 4: + // nodeColor = AppColors.primaryAble; + // break; + // default: + // nodeColor = AppColors.gray5; + // } + + return Container( + width: 6, + height: 6, + decoration: BoxDecoration( + color: AppColors.gray5, + borderRadius: BorderRadius.circular(1), + ), + ); + } +} diff --git a/lib/features/statistics/widgets/line_graph/line_graph.dart b/lib/features/statistics/widgets/line_graph/line_graph.dart new file mode 100644 index 0000000..b1699dd --- /dev/null +++ b/lib/features/statistics/widgets/line_graph/line_graph.dart @@ -0,0 +1,163 @@ +// 최초 작성자: 김채영 +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../../provider/line_graph_provider.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import '../statistics_card.dart'; +import 'monthly_line_graph.dart'; +import 'weekly_line_graph.dart'; + +// 나의 해냄 추이 꺾은선 그래프 +class LineGraph extends ConsumerWidget { + final bool isMonthly; // 현재 월간/주간 선택 상태 + final VoidCallback? onToggle; // 탭 전환 시 호출될 콜백 (상태 관리용) + + const LineGraph({ + super.key, + this.isMonthly = true, // 기본값 월간 + this.onToggle, + }); + + @override + Widget build(BuildContext context, WidgetRef ref) { + // 현재 상태를 감시하여 상태가 바뀔 때마다 위젯이 다시 그려짐 + final isMonthly = ref.watch(graphTypeProvider); + return StatisticsCard( + title: "나의 해냄 추이", + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Column( + children: [ + // 월간/주간 토글 버튼 영역 + _buildToggleButtons(ref, isMonthly), // ref와 isMonthly 전달 + const SizedBox(height: 20), // 버튼과 그래프 사이 간격 + // 범례 영역 (이번 달/주, 저번 달/주) + _buildLegend(isMonthly), + + // ✅ 그래프 전환 로직 적용 + AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + child: SizedBox( + key: ValueKey(isMonthly), + height: 184, + width: double.infinity, + child: const MonthlyLineGraph( + data: WeeklyGraphData( + thisMonth: [28, 15, 20, 25], + lastMonth: [10, 22, 17, 12], + ), + ), + // : const WeeklyLineGraph( + // // ✅ 주간 그래프 추가 + // data: DailyGraphData( + // thisWeek: [3, 5, 2, 8, 4, 6, 7], + // lastWeek: [2, 4, 3, 5, 3, 5, 4], + // ), + // ), + ), + ), + ], + ), + ], + ), + ); + } + + // 범례 빌더: 상태에 따라 텍스트 변경 + Widget _buildLegend(bool isMonthly) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 8, // 두 범례 사이의 간격 + children: [ + _buildLegendItem( + iconPath: 'assets/images/icons/green_line_graph_icon.svg', + label: isMonthly ? '이번 달' : '이번 주', + ), + _buildLegendItem( + iconPath: 'assets/images/icons/gray_line_graph_icon.svg', + label: isMonthly ? '저번 달' : '저번 주', + ), + ], + ); + } + + // 범례 개별 아이템 + Widget _buildLegendItem({required String iconPath, required String label}) { + return Row( + mainAxisSize: MainAxisSize.min, + spacing: 4, // 아이콘과 텍스트 사이 간격 + children: [ + SvgPicture.asset(iconPath, width: 16, height: 16), + Text( + label, + style: AppTypography.b2.copyWith( + color: AppColors.gray1, + ), // 디자인의 apptypography가 프리텐다드가 아니라서 임시로 지정 + ), + ], + ); + } + + // 월간/주간 선택 버튼 + Widget _buildToggleButtons(WidgetRef ref, bool isMonthly) { + return Container( + width: double.infinity, + height: 35.99, + decoration: ShapeDecoration( + color: AppColors.gray5, // 기본 배경 + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(100)), + ), + child: Row( + children: [ + _buildTab( + ref: ref, + label: '월간', + isSelected: isMonthly, + onTap: () => ref.read(graphTypeProvider.notifier).state = true, + ), + _buildTab( + ref: ref, + label: '주간', + isSelected: !isMonthly, + onTap: () => ref.read(graphTypeProvider.notifier).state = false, + ), + ], + ), + ); + } + + // 개별 탭 버튼 구현 + Widget _buildTab({ + required WidgetRef ref, + required String label, + required bool isSelected, + required VoidCallback onTap, + }) { + return Expanded( + child: GestureDetector( + onTap: onTap, // 탭 클릭 시 동작 + behavior: HitTestBehavior.opaque, // 빈 공간 클릭도 인식 + child: Container( + height: double.infinity, + alignment: Alignment.center, + decoration: ShapeDecoration( + // 선택 시 배경색 적용, 미선택 시 투명 + color: isSelected ? AppColors.primaryAble : Colors.transparent, + shape: const StadiumBorder(), + ), + child: Text( + label, + textAlign: TextAlign.center, + style: AppTypography.b2.copyWith( + // 선택 시 흰색, 미선택 시 검은색 + color: isSelected ? Colors.white : AppColors.black, + ), + ), + ), + ), + ); + } +} diff --git a/lib/features/statistics/widgets/line_graph/monthly_line_graph.dart b/lib/features/statistics/widgets/line_graph/monthly_line_graph.dart new file mode 100644 index 0000000..1b0aa5c --- /dev/null +++ b/lib/features/statistics/widgets/line_graph/monthly_line_graph.dart @@ -0,0 +1,209 @@ +// 최초 작성자: 김채영 +import 'package:flutter/material.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; + +// 4주간 챌린지 성공 추이 모델 +class WeeklyGraphData { + final List thisMonth; // 이번달 4주 데이터 + final List lastMonth; // 지난달 4주 데이터 + + const WeeklyGraphData({required this.thisMonth, required this.lastMonth}); + + factory WeeklyGraphData.fromJson(Map json) { + return WeeklyGraphData( + thisMonth: List.from(json['thisMonth'] ?? [0, 0, 0, 0]), + lastMonth: List.from(json['lastMonth'] ?? [0, 0, 0, 0]), + ); + } +} + +// 4주 라인 그래프 위젯 +class MonthlyLineGraph extends StatelessWidget { + final WeeklyGraphData data; + + const MonthlyLineGraph({super.key, required this.data}); + + @override + Widget build(BuildContext context) { + // Y축 최댓값 계산 (10 단위로 올림) + final allValues = [...data.thisMonth, ...data.lastMonth]; + final maxValue = allValues.isEmpty + ? 30 + : ((allValues.reduce((a, b) => a > b ? a : b) / 10).ceil() * 10).clamp( + 10, + 999, + ); + + final yLabels = [maxValue, (maxValue * 2 ~/ 3), (maxValue * 1 ~/ 3), 0]; + + const xLabels = ['전전전주', '전전주', '전주', '이번주']; + + return SizedBox( + width: double.infinity, + height: 164, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 그래프 영역 + Expanded( + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // Y축 레이블 + Padding( + padding: const EdgeInsets.symmetric(horizontal: 4), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: yLabels + .map( + (label) => Text( + '$label', + style: const TextStyle( + color: Color(0xFF444444), + fontSize: 12, + fontFamily: 'Inter', + fontWeight: FontWeight.w400, + ), + ), + ) + .toList(), + ), + ), + + // 그래프 본체 + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 6), + child: CustomPaint( + painter: _LineGraphPainter( + thisMonth: data.thisMonth, + lastMonth: data.lastMonth, + maxValue: maxValue.toDouble(), + ), + ), + ), + ), + ], + ), + ), + + // X축 레이블 + Padding( + padding: const EdgeInsets.only(left: 24, bottom: 8), + child: Row( + children: xLabels + .map( + (label) => Expanded( + child: Text( + label, + textAlign: TextAlign.center, + style: const TextStyle( + color: Color(0xFF444444), + fontSize: 12, + fontFamily: 'Inter', + fontWeight: FontWeight.w400, + ), + ), + ), + ) + .toList(), + ), + ), + ], + ), + ); + } +} + +class _LineGraphPainter extends CustomPainter { + final List thisMonth; + final List lastMonth; + final double maxValue; + + const _LineGraphPainter({ + required this.thisMonth, + required this.lastMonth, + required this.maxValue, + }); + + @override + void paint(Canvas canvas, Size size) { + _drawGrid(canvas, size); + if (lastMonth.length >= 4) + _drawLine(canvas, size, lastMonth, const Color(0xFFD9D9D9)); + if (thisMonth.length >= 4) + _drawLine(canvas, size, thisMonth, AppColors.primaryAble); + if (lastMonth.length >= 4) + _drawDots(canvas, size, lastMonth, const Color(0xFFD9D9D9)); + if (thisMonth.length >= 4) + _drawDots(canvas, size, thisMonth, AppColors.primaryAble); + } + + // 격자선 그리기 + void _drawGrid(Canvas canvas, Size size) { + final paint = Paint() + ..color = const Color(0xFFD9D9D9) + ..strokeWidth = 1; + + // 가로 격자선 4개 + for (int i = 0; i < 4; i++) { + final y = size.height * i / 3; + canvas.drawLine(Offset(0, y), Offset(size.width, y), paint); + } + + // 세로 격자선 5개 + for (int i = 0; i < 5; i++) { + final x = size.width * i / 4; + canvas.drawLine(Offset(x, 0), Offset(x, size.height), paint); + } + } + + // 라인 그리기 + void _drawLine(Canvas canvas, Size size, List values, Color color) { + final paint = Paint() + ..color = color + ..strokeWidth = 1.5 + ..style = PaintingStyle.stroke + ..strokeCap = StrokeCap.round + ..strokeJoin = StrokeJoin.round; + + final path = Path(); + for (int i = 0; i < 4; i++) { + final x = size.width * i / 3; + final y = size.height - (values[i] / maxValue) * size.height; + if (i == 0) { + path.moveTo(x, y); + } else { + path.lineTo(x, y); + } + } + canvas.drawPath(path, paint); + } + + // 데이터 포인트 점 그리기 + void _drawDots(Canvas canvas, Size size, List values, Color color) { + final outerPaint = Paint() + ..color = Colors.white + ..style = PaintingStyle.fill; + final borderPaint = Paint() + ..color = color + ..style = PaintingStyle.stroke + ..strokeWidth = 2; + + for (int i = 0; i < 4; i++) { + final x = size.width * i / 3; + final y = size.height - (values[i] / maxValue) * size.height; + canvas.drawCircle(Offset(x, y), 4, outerPaint); + canvas.drawCircle(Offset(x, y), 4, borderPaint); + } + } + + @override + bool shouldRepaint(covariant _LineGraphPainter oldDelegate) => + oldDelegate.thisMonth != thisMonth || + oldDelegate.lastMonth != lastMonth || + oldDelegate.maxValue != maxValue; +} diff --git a/lib/features/statistics/widgets/line_graph/weekly_line_graph.dart b/lib/features/statistics/widgets/line_graph/weekly_line_graph.dart new file mode 100644 index 0000000..f350c67 --- /dev/null +++ b/lib/features/statistics/widgets/line_graph/weekly_line_graph.dart @@ -0,0 +1,99 @@ +// // 최초 작성자: 김채영 +// import 'package:flutter/material.dart'; +// import 'package:haenaem/core/theme/app_colors.dart'; +// import 'package:haenaem/core/theme/app_typography.dart'; + +// // 주간 데이터 모델 +// class DailyGraphData { +// final List thisWeek; +// final List lastWeek; +// const DailyGraphData({required this.thisWeek, required this.lastWeek}); +// } + +// // 주간 라인 그래프 (7일 기준) +// class WeeklyLineGraph extends StatelessWidget { +// final DailyGraphData data; +// const WeeklyLineGraph({super.key, required this.data}); + +// @override +// Widget build(BuildContext context) { +// final allValues = [...data.thisWeek, ...data.lastWeek]; +// final maxValue = allValues.isEmpty +// ? 10 +// : ((allValues.reduce((a, b) => a > b ? a : b) / 5).ceil() * 5) +// .toDouble(); + +// final yLabels = [ +// maxValue.toInt(), +// (maxValue * 2 ~/ 3), +// (maxValue * 1 ~/ 3), +// 0, +// ]; +// const xLabels = ['월', '화', '수', '목', '금', '토', '일']; + +// return Column( +// children: [ +// Expanded( +// child: Row( +// children: [ +// _buildYAxis(yLabels), +// Expanded( +// child: CustomPaint( +// painter: _LineGraphPainter( +// thisPeriod: data.thisWeek, +// lastPeriod: data.lastWeek, +// maxValue: maxValue, +// pointCount: 7, // ✅ 점 7개 +// ), +// ), +// ), +// ], +// ), +// ), +// _buildXAxis(xLabels), +// ], +// ); +// } + +// // Y축 레이블 빌더 (스타일 유지) +// Widget _buildYAxis(List labels) { +// return Padding( +// padding: const EdgeInsets.only(right: 8), +// child: Column( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// crossAxisAlignment: CrossAxisAlignment.end, +// children: labels +// .map( +// (l) => Text( +// '$l', +// style: const TextStyle(color: Color(0xFF444444), fontSize: 12), +// ), +// ) +// .toList(), +// ), +// ); +// } + +// // X축 레이블 빌더 (스타일 유지) +// Widget _buildXAxis(List labels) { +// return Padding( +// padding: const EdgeInsets.only(left: 24, top: 8), +// child: Row( +// children: labels +// .map( +// (l) => Expanded( +// child: Text( +// l, +// textAlign: TextAlign.center, +// style: const TextStyle( +// color: Color(0xFF444444), +// fontSize: 12, +// ), +// ), +// ), +// ) +// .toList(), +// ), +// ); +// } +// } diff --git a/lib/features/statistics/widgets/pie_graph.dart b/lib/features/statistics/widgets/pie_graph.dart new file mode 100644 index 0000000..6861d1a --- /dev/null +++ b/lib/features/statistics/widgets/pie_graph.dart @@ -0,0 +1,202 @@ +// 최초 작성자: 김채영 +import 'dart:math'; +import 'package:flutter/material.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; +import 'statistics_card.dart'; + +// 태그별 해냄 횟수 데이터 모델 +class TagCount { + final String tag; + final int count; + final Color color; + + const TagCount({required this.tag, required this.count, required this.color}); +} + +// 나의 해냄 분포 원형 그래프 +class PieGraph extends StatelessWidget { + final List tagCounts; // 태그별 데이터 + final int totalCount; // 총 해냄 횟수 + + // 그래프 색상 팔레트 + static const List defaultColors = [ + Color(0xFF8979FF), + Color(0xFFFF928A), + Color(0xFF3BC3DE), + Color(0xFFFFD166), + Color(0xFF06D6A0), + Color(0xFFEF476F), + ]; + + const PieGraph({ + super.key, + required this.tagCounts, + required this.totalCount, + }); + @override + Widget build(BuildContext context) { + if (tagCounts.isEmpty) return const SizedBox.shrink(); + + // 상위 3개 + 나머지 + final top3 = tagCounts.take(3).toList(); + final rest = tagCounts.skip(3).toList(); + + return StatisticsCard( + title: '나의 해냄 분포', + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 12, + children: [ + // 2. 차트 + 태그 영역 + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 10, + children: [ + // 파이 차트 + 총 해냄 텍스트 + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 10, + children: [ + // 원형 파이 차트 영역 + Padding( + padding: const EdgeInsets.symmetric(horizontal: 60), + child: AspectRatio( + aspectRatio: 1, // 정사각형 유지 (원형 그래프용) + child: CustomPaint( + painter: _PieChartPainter(tagCounts: tagCounts), + ), + ), + ), + + // 총 N번 해냄! + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.end, + spacing: 2, + children: [ + Text( + '총', + style: AppTypography.b3.copyWith( + color: AppColors.black, + ), + ), + Text( + '$totalCount번', + style: AppTypography.h3.copyWith( + color: AppColors.primaryAble, + ), + ), + Text( + '해냄!', + style: AppTypography.b3.copyWith( + color: AppColors.black, + ), + ), + ], + ), + + // 상위 3개 태그 (큰 폰트) + if (top3.isNotEmpty) + Padding( + padding: const EdgeInsets.symmetric(horizontal: 60), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: top3 + .map((tag) => _buildTopTagItem(tag)) + .toList(), + ), + ), + + // 나머지 태그 (작은 폰트) + if (rest.isNotEmpty) + Padding( + padding: const EdgeInsets.symmetric(horizontal: 50), + child: Column( + spacing: 1, + children: rest + .map((tag) => _buildRestTagRow(tag)) + .toList(), + ), + ), + ], + ), + ], + ), + ], + ), + ); + } + + // 상위 3개 태그 아이템 + Widget _buildTopTagItem(TagCount tag) { + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 2, + children: [ + Text(tag.tag, style: AppTypography.b1.copyWith(color: AppColors.gray2)), + Text( + '${tag.count}번', + style: AppTypography.h3.copyWith(color: tag.color), + ), + ], + ); + } + + // 나머지 태그 행 + Widget _buildRestTagRow(TagCount tag) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(tag.tag, style: AppTypography.b2.copyWith(color: AppColors.gray2)), + Text( + '${tag.count}번', + style: AppTypography.b2.copyWith(color: AppColors.gray2), + ), + ], + ); + } +} + +// 파이 차트 CustomPainter +class _PieChartPainter extends CustomPainter { + final List tagCounts; + + const _PieChartPainter({required this.tagCounts}); + + @override + void paint(Canvas canvas, Size size) { + if (tagCounts.isEmpty) return; + + final total = tagCounts.fold(0, (sum, t) => sum + t.count); + if (total == 0) return; + + final center = Offset(size.width / 2, size.height / 2); + final radius = 85.33; + final rect = Rect.fromCircle(center: center, radius: radius); + + double startAngle = -pi / 2; + final paint = Paint()..style = PaintingStyle.fill; + + for (final tag in tagCounts) { + final sweepAngle = (tag.count / total) * (2 * pi); // 원 + paint.color = tag.color; + canvas.drawArc(rect, startAngle, sweepAngle, true, paint); + startAngle += sweepAngle; + } + + // 중앙 흰색 원 (도넛 효과) + final innerPaint = Paint() + ..color = Colors.white + ..style = PaintingStyle.fill; + canvas.drawCircle(center, radius * 0.50, innerPaint); + } + + @override + bool shouldRepaint(covariant _PieChartPainter oldDelegate) => + oldDelegate.tagCounts != tagCounts; +} diff --git a/lib/features/statistics/widgets/statistics_card.dart b/lib/features/statistics/widgets/statistics_card.dart new file mode 100644 index 0000000..aaed8f6 --- /dev/null +++ b/lib/features/statistics/widgets/statistics_card.dart @@ -0,0 +1,62 @@ +// 최초 작성자: 김채영 +import 'package:flutter/material.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; + +// 통계 화면 위젯들의 공통 흰색 카드 +class StatisticsCard extends StatelessWidget { + final String title; + final Widget child; + final Widget? headerAction; // 오른쪽 상단에 들어갈 인증 횟수 등 + + const StatisticsCard({ + super.key, + required this.title, + required this.child, + this.headerAction, + }); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), // 화면 양끝과 20 차이 + child: Container( + padding: const EdgeInsets.all(20), // 카드 내부 기본 패딩 (상단 20 포함) + decoration: ShapeDecoration( + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + shadows: const [ + BoxShadow( + color: Color(0x3F000000), + blurRadius: 16, + offset: Offset(0, 4), + spreadRadius: 0, + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 헤더 영역 (제목 + 선택적 액션) + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + title, + style: AppTypography.h3.copyWith(color: AppColors.black), + ), + if (headerAction != null) headerAction!, + ], + ), + const SizedBox(height: 20), // 헤더와 콘텐츠 사이 20 차이 + child, + ], + ), + ), + ); + } +} diff --git a/lib/features/user/widgets/my_challenge_card.dart b/lib/features/user/widgets/my_challenge_card.dart index 8e58e3d..26ab288 100644 --- a/lib/features/user/widgets/my_challenge_card.dart +++ b/lib/features/user/widgets/my_challenge_card.dart @@ -144,7 +144,7 @@ class MyChallengeCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( - '${(progress * 100).toInt()}%', + '${progress.toInt()}%', style: AppTypography.h2.copyWith(color: color), ), Text('달성률', style: AppTypography.c1.copyWith(color: AppColors.gray2)), From c2fcc04c07a7acf61169678f694f25c274ea6282 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Wed, 6 May 2026 04:20:13 +0900 Subject: [PATCH 111/134] =?UTF-8?q?feat:=20=EC=8B=A0=EA=B3=A0=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20ui=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../widgets/ChallengeFeedPopupMenu.dart | 13 +- .../challenge/widgets/comment_popup_menu.dart | 70 +++++------ .../home/provider/home_provider.g.dart | 2 +- .../report/screens/report_screen.dart | 112 ++++++++++++++++++ .../report/screens/report_success_screen.dart | 72 +++++++++++ .../report/widgets/report_reason_tile.dart | 109 +++++++++++++++++ pubspec.lock | 20 ++-- 7 files changed, 351 insertions(+), 47 deletions(-) create mode 100644 lib/features/report/screens/report_screen.dart create mode 100644 lib/features/report/screens/report_success_screen.dart create mode 100644 lib/features/report/widgets/report_reason_tile.dart diff --git a/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart b/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart index e6a2c99..0e0ba1e 100644 --- a/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart +++ b/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart @@ -10,6 +10,7 @@ import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'edit_article_dialog.dart'; import 'package:haenaem/features/challenge/verification/screens/challenge_verification_screen.dart'; +import 'package:haenaem/features/report/screens/report_screen.dart'; // 인증글 다이얼로그 (내 인증글일 경우와 타인의 인증글일 경우) class ChallengeFeedPopupMenu extends ConsumerWidget { @@ -219,10 +220,16 @@ class ChallengeFeedPopupMenu extends ConsumerWidget { debugPrint('🚀 [Action] 챌린지 보기 클릭'); // TODO: Navigator.push(...) 혹은 현재 탭 전환 로직 추가 break; - case 'complain': - ScaffoldMessenger.of( + // case 'complain': + // ScaffoldMessenger.of( + // context, + // ).showSnackBar(const SnackBar(content: Text("신고가 접수되었습니다."))); + // break; + case 'report': + Navigator.push( context, - ).showSnackBar(const SnackBar(content: Text("신고가 접수되었습니다."))); + MaterialPageRoute(builder: (context) => const ReportScreen()), + ); break; } } diff --git a/lib/features/challenge/widgets/comment_popup_menu.dart b/lib/features/challenge/widgets/comment_popup_menu.dart index bcdc2da..a37e163 100644 --- a/lib/features/challenge/widgets/comment_popup_menu.dart +++ b/lib/features/challenge/widgets/comment_popup_menu.dart @@ -8,6 +8,7 @@ import 'package:haenaem/features/challenge/models/challenge_model.dart'; import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/features/challenge/widgets/DeleteConfirmDialog.dart'; import 'edit_article_dialog.dart'; +import 'package:haenaem/features/report/screens/report_screen.dart'; // 내 댓글이면 삭제/수정 + 다른 사람 댓글이면 신고 다이얼로그 class CommentPopupMenu extends ConsumerWidget { @@ -60,7 +61,7 @@ class CommentPopupMenu extends ConsumerWidget { _buildPopupItem( '신고하기', 'assets/images/icons/complaint.svg', - 'complain', + 'report', isDanger: true, ), ]; @@ -161,40 +162,43 @@ class CommentPopupMenu extends ConsumerWidget { } } break; - case 'complain': - _showComplainDialog(context); + case 'report': + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const ReportScreen()), + ); break; } } - // TODO: 나중에 따로 뺄까여 - // 신고 확인 다이얼로그 - void _showComplainDialog(BuildContext context) { - showDialog( - context: context, - builder: (context) => AlertDialog( - title: const Text('신고하기'), - content: const Text('이 댓글을 신고하시겠습니까?'), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context), - child: const Text('취소', style: TextStyle(color: AppColors.gray2)), - ), - TextButton( - onPressed: () { - // TODO: 신고 API 연결 (현재는 스낵바만 표시) - Navigator.pop(context); - ScaffoldMessenger.of( - context, - ).showSnackBar(const SnackBar(content: Text('신고가 접수되었습니다.'))); - }, - child: const Text( - '신고', - style: TextStyle(color: AppColors.notification), - ), - ), - ], - ), - ); - } + // // TODO: 나중에 따로 뺄까여 + // // 신고 확인 다이얼로그 + // void _showComplainDialog(BuildContext context) { + // showDialog( + // context: context, + // builder: (context) => AlertDialog( + // title: const Text('신고하기'), + // content: const Text('이 댓글을 신고하시겠습니까?'), + // actions: [ + // TextButton( + // onPressed: () => Navigator.pop(context), + // child: const Text('취소', style: TextStyle(color: AppColors.gray2)), + // ), + // TextButton( + // onPressed: () { + // // TODO: 신고 API 연결 (현재는 스낵바만 표시) + // Navigator.pop(context); + // ScaffoldMessenger.of( + // context, + // ).showSnackBar(const SnackBar(content: Text('신고가 접수되었습니다.'))); + // }, + // child: const Text( + // '신고', + // style: TextStyle(color: AppColors.notification), + // ), + // ), + // ], + // ), + // ); + // } } diff --git a/lib/features/home/provider/home_provider.g.dart b/lib/features/home/provider/home_provider.g.dart index b2a7cfd..bcade9d 100644 --- a/lib/features/home/provider/home_provider.g.dart +++ b/lib/features/home/provider/home_provider.g.dart @@ -6,7 +6,7 @@ part of 'home_provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$homeNotifierHash() => r'79469b283e0bb3cd1f61eccb03f0923297609835'; +String _$homeNotifierHash() => r'8b37dfa057e9f5064aa299312acc9b381811c7a1'; /// See also [HomeNotifier]. @ProviderFor(HomeNotifier) diff --git a/lib/features/report/screens/report_screen.dart b/lib/features/report/screens/report_screen.dart new file mode 100644 index 0000000..68cdb78 --- /dev/null +++ b/lib/features/report/screens/report_screen.dart @@ -0,0 +1,112 @@ +// 최초 작성자: 정승빈 + +import 'package:flutter/material.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; +import 'package:haenaem/shared/widgets/bottom_action_button.dart'; +import '../widgets/report_reason_tile.dart'; +import 'report_success_screen.dart'; + +class ReportScreen extends StatefulWidget { + const ReportScreen({super.key}); + + @override + State createState() => _ReportScreenState(); +} + +class _ReportScreenState extends State { + int? _selectedReasonIndex; + final TextEditingController _otherReasonController = TextEditingController(); + + final List> _reasons = [ + {'title': '영리목적/홍보성', 'desc': '상업적 광고, 도배성 게시글, 링크 유도 등'}, + {'title': '욕설/비하 발언', 'desc': '특정 개인이나 집단에 대한 혐오, 비하, 욕설 포함'}, + {'title': '부적절한 콘텐츠', 'desc': '음란물, 폭력적 내용, 불법 정보 포함'}, + {'title': '개인정보 노출', 'desc': '타인의 연락처, 주소 등 민감한 정보 공유'}, + {'title': '명의 도용/사칭', 'desc': '타인을 사칭하거나 저작권을 침해하는 이미지 사용'}, + {'title': '기타 (직접 입력)', 'desc': '위 항목에 해당하지 않는 구체적인 사유'}, + ]; + + @override + void dispose() { + _otherReasonController.dispose(); + super.dispose(); + } + + void _submitReport() { + if (_selectedReasonIndex == null) return; + + // TODO: 서버로 신고 내용 전송하는 로직 (API 연동 시 여기에 작성) + // _selectedReasonIndex == 5 인 경우 _otherReasonController.text를 함께 전송 + + // 현재 신고 화면을 종료(pop)하고 신고 완료 화면으로 대체(pushReplacement)합니다. + // 이렇게 하면 신고 완료 화면에서 '확인'을 눌렀을 때 원래 있던 피드나 댓글 창으로 깔끔하게 돌아갑니다. + Navigator.of(context).pushReplacement( + MaterialPageRoute(builder: (context) => const ReportSuccessScreen()), + ); + } + + @override + Widget build(BuildContext context) { + // 항목이 하나라도 선택되었는지 여부로 하단 버튼 활성화 상태 결정 + final bool isButtonActive = _selectedReasonIndex != null; + + return Scaffold( + appBar: AppBar( + leading: IconButton( + icon: const Icon(Icons.arrow_back, color: AppColors.black), + onPressed: () => Navigator.of(context).pop(), + ), + title: const Text('신고하기', style: AppTypography.h3), + ), + body: Column( + children: [ + // 상단 안내 문구 + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20), + child: Text( + '더 깨끗한 \'해냄\'을 위해 부적절한 콘텐츠를 알려주세요.\n신고하신 내용은 운영 정책에 따라 검토 후 조치됩니다.', + textAlign: TextAlign.center, + style: AppTypography.b2.copyWith(color: AppColors.gray2), + ), + ), + + // 신고 사유 리스트 + Expanded( + child: ListView.separated( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), + itemCount: _reasons.length, + separatorBuilder: (context, index) => const SizedBox(height: 12), + itemBuilder: (context, index) { + final isSelected = _selectedReasonIndex == index; + final isOtherOption = index == _reasons.length - 1; + + return ReportReasonTile( + title: _reasons[index]['title']!, + subtitle: _reasons[index]['desc']!, + isSelected: isSelected, + isOtherOption: isOtherOption, + textController: _otherReasonController, + onTap: () { + setState(() { + _selectedReasonIndex = index; + }); + }, + ); + }, + ), + ), + ], + ), + + // 하단 고정 버튼 + bottomNavigationBar: BottomActionButton( + text: '신고하기', + backgroundColor: isButtonActive + ? AppColors.primaryAble + : AppColors.disable, + onPressed: isButtonActive ? _submitReport : () {}, + ), + ); + } +} diff --git a/lib/features/report/screens/report_success_screen.dart b/lib/features/report/screens/report_success_screen.dart new file mode 100644 index 0000000..2778e33 --- /dev/null +++ b/lib/features/report/screens/report_success_screen.dart @@ -0,0 +1,72 @@ +// 최초 작성자: 정승빈 + +import 'package:flutter/material.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; +import 'package:haenaem/shared/widgets/bottom_action_button.dart'; + +class ReportSuccessScreen extends StatelessWidget { + const ReportSuccessScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SafeArea( + child: Column( + children: [ + Expanded( + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // 초록색 체크 원형 아이콘 + Container( + width: 84, + height: 84, + decoration: const BoxDecoration( + color: AppColors.primaryAble, + shape: BoxShape.circle, + ), + child: const Icon( + Icons.check_rounded, + color: Colors.white, + size: 48, + ), + ), + const SizedBox(height: 24), + + // 완료 안내 제목 + const Text( + '신고가 접수되었습니다.', + textAlign: TextAlign.center, + style: AppTypography.h1, // 24px, Bold + ), + const SizedBox(height: 12), + + // 완료 안내 부가 설명 + Text( + '검토 결과에 따라 적절한 조치가 취해질 예정이며,\n깨끗한 \'해냄\'을 위해 항상 노력하겠습니다.', + textAlign: TextAlign.center, + style: AppTypography.b3.copyWith( + color: AppColors.gray1, + ), // 16px, SemiBold + ), + ], + ), + ), + ), + ], + ), + ), + // 하단 '확인' 버튼 + bottomNavigationBar: BottomActionButton( + text: '확인', + onPressed: () { + // '확인' 버튼을 누르면 이 화면을 닫고 피드(또는 댓글) 화면으로 돌아갑니다. + Navigator.of(context).pop(); + }, + ), + ); + } +} diff --git a/lib/features/report/widgets/report_reason_tile.dart b/lib/features/report/widgets/report_reason_tile.dart new file mode 100644 index 0000000..2a7e062 --- /dev/null +++ b/lib/features/report/widgets/report_reason_tile.dart @@ -0,0 +1,109 @@ +// 최초 작성자: 정승빈 + +import 'package:flutter/material.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; + +class ReportReasonTile extends StatelessWidget { + final String title; + final String subtitle; + final bool isSelected; + final bool isOtherOption; + final VoidCallback onTap; + final TextEditingController textController; + + const ReportReasonTile({ + super.key, + required this.title, + required this.subtitle, + required this.isSelected, + required this.isOtherOption, + required this.onTap, + required this.textController, + }); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + // color: isSelected ? AppColors.selected : AppColors.gray5, + color: AppColors.gray5, + borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: AppTypography.b3.copyWith( + color: AppColors.gray1, + ), + ), + const SizedBox(height: 4), + Text( + subtitle, + style: AppTypography.b2.copyWith( + color: AppColors.gray3, + ), + ), + ], + ), + ), + const SizedBox(width: 16), + // 커스텀 라디오 버튼 아이콘 처리 + Icon( + isSelected + ? Icons.radio_button_checked + : Icons.radio_button_unchecked, + color: isSelected ? AppColors.primaryAble : AppColors.gray4, + size: 24, + ), + ], + ), + + // '기타 (직접 입력)' 항목이 선택되었을 때만 노출되는 텍스트 입력창 + if (isOtherOption && isSelected) ...[ + const SizedBox(height: 16), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 8, + ), + decoration: BoxDecoration( + // color: Colors.white, + borderRadius: BorderRadius.circular(10), + border: Border.all(color: AppColors.gray4), + ), + child: TextField( + controller: textController, + maxLines: 3, + style: AppTypography.b2.copyWith(color: AppColors.black), + decoration: InputDecoration( + hintText: '예: 챌린지 주제와 상관없는 사진을 반복적으로 올립니다.', + hintStyle: AppTypography.b2.copyWith( + color: AppColors.gray3, + ), + border: InputBorder.none, + isDense: true, + contentPadding: EdgeInsets.zero, + ), + ), + ), + ], + ], + ), + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 6be68a5..a9aacd6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -245,10 +245,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" checked_yaml: dependency: transitive description: @@ -993,26 +993,26 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.18" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.13.0" meta: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" mime: dependency: transitive description: @@ -1398,10 +1398,10 @@ packages: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" url: "https://pub.dev" source: hosted - version: "0.7.6" + version: "0.7.9" timing: dependency: transitive description: From 91d4fcd8fc383254a53a96936c4e2580da442f13 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Thu, 7 May 2026 14:57:02 +0900 Subject: [PATCH 112/134] =?UTF-8?q?fix:=20api=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/data/challenge_repository.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/features/challenge/data/challenge_repository.dart b/lib/features/challenge/data/challenge_repository.dart index cb09fb2..39b72af 100644 --- a/lib/features/challenge/data/challenge_repository.dart +++ b/lib/features/challenge/data/challenge_repository.dart @@ -51,7 +51,7 @@ class ChallengeRepository { // 챌린지 상세정보 조회 수정 Future getChallengeDetail(int challengeId) async { try { - final response = await _dio.get('api/challenge/$challengeId'); + final response = await _dio.get('/api/challenge/$challengeId'); print("서버 응답 데이터: ${response.data}"); // 데이터 확인 완료! // 상세 API는 content 없이 바로 객체가 오므로 response.data를 그대로 사용합니다. From d1107bdce273d5a5fb2ea582be965103de7b5c1d Mon Sep 17 00:00:00 2001 From: Seungvin Date: Thu, 7 May 2026 15:11:10 +0900 Subject: [PATCH 113/134] =?UTF-8?q?feat:=20=EB=8C=93=EA=B8=80,=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=EA=B8=80=20=EC=8B=A0=EA=B3=A0=20api=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../widgets/ChallengeFeedPopupMenu.dart | 8 +- .../challenge/widgets/comment_popup_menu.dart | 8 +- .../report/data/report_repository.dart | 57 ++++++++++++++ .../report/provider/report_provider.dart | 58 +++++++++++++++ .../report/provider/report_provider.g.dart | 26 +++++++ .../report/screens/report_screen.dart | 74 ++++++++++++++----- 6 files changed, 211 insertions(+), 20 deletions(-) create mode 100644 lib/features/report/data/report_repository.dart create mode 100644 lib/features/report/provider/report_provider.dart create mode 100644 lib/features/report/provider/report_provider.g.dart diff --git a/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart b/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart index 0e0ba1e..758740c 100644 --- a/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart +++ b/lib/features/challenge/widgets/ChallengeFeedPopupMenu.dart @@ -11,6 +11,7 @@ import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'edit_article_dialog.dart'; import 'package:haenaem/features/challenge/verification/screens/challenge_verification_screen.dart'; import 'package:haenaem/features/report/screens/report_screen.dart'; +import 'package:haenaem/features/report/provider/report_provider.dart'; // 인증글 다이얼로그 (내 인증글일 경우와 타인의 인증글일 경우) class ChallengeFeedPopupMenu extends ConsumerWidget { @@ -228,7 +229,12 @@ class ChallengeFeedPopupMenu extends ConsumerWidget { case 'report': Navigator.push( context, - MaterialPageRoute(builder: (context) => const ReportScreen()), + MaterialPageRoute( + builder: (context) => ReportScreen( + targetType: ReportTargetType.article, // 인증글 타입 + targetId: post.postId, // 인증글 ID + ), + ), ); break; } diff --git a/lib/features/challenge/widgets/comment_popup_menu.dart b/lib/features/challenge/widgets/comment_popup_menu.dart index a37e163..e687c69 100644 --- a/lib/features/challenge/widgets/comment_popup_menu.dart +++ b/lib/features/challenge/widgets/comment_popup_menu.dart @@ -9,6 +9,7 @@ import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; import 'package:haenaem/features/challenge/widgets/DeleteConfirmDialog.dart'; import 'edit_article_dialog.dart'; import 'package:haenaem/features/report/screens/report_screen.dart'; +import 'package:haenaem/features/report/provider/report_provider.dart'; // 내 댓글이면 삭제/수정 + 다른 사람 댓글이면 신고 다이얼로그 class CommentPopupMenu extends ConsumerWidget { @@ -165,7 +166,12 @@ class CommentPopupMenu extends ConsumerWidget { case 'report': Navigator.push( context, - MaterialPageRoute(builder: (context) => const ReportScreen()), + MaterialPageRoute( + builder: (context) => ReportScreen( + targetType: ReportTargetType.comment, // 댓글 타입 + targetId: comment.commentId, // 댓글 ID + ), + ), ); break; } diff --git a/lib/features/report/data/report_repository.dart b/lib/features/report/data/report_repository.dart new file mode 100644 index 0000000..a08603e --- /dev/null +++ b/lib/features/report/data/report_repository.dart @@ -0,0 +1,57 @@ +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:haenaem/core/network/dio_provider.dart'; + +// Repository Provider +final reportRepositoryProvider = Provider((ref) { + return ReportRepository(ref.watch(dioProvider)); +}); + +class ReportRepository { + final Dio _dio; + + ReportRepository(this._dio); + + // 인증글 신고 API + Future reportArticle({ + required int articleId, + required String reportReason, + required String detailReason, + }) async { + try { + await _dio.post( + '/api/articles/$articleId/report', + data: {'reportReason': reportReason, 'detailReason': detailReason}, + ); + } on DioException catch (e) { + debugPrint('---------- [인증글 신고 실패] ----------'); + debugPrint('대상 ID: $articleId'); + debugPrint('상태 코드: ${e.response?.statusCode}'); + debugPrint('에러 데이터: ${e.response?.data}'); + debugPrint('------------------------------------'); + rethrow; + } + } + + // 댓글 신고 API + Future reportComment({ + required int commentId, + required String reportReason, + required String detailReason, + }) async { + try { + await _dio.post( + '/api/comments/$commentId/report', + data: {'reportReason': reportReason, 'detailReason': detailReason}, + ); + } on DioException catch (e) { + debugPrint('---------- [댓글 신고 실패] ----------'); + debugPrint('대상 ID: $commentId'); + debugPrint('상태 코드: ${e.response?.statusCode}'); + debugPrint('에러 데이터: ${e.response?.data}'); + debugPrint('------------------------------------'); + rethrow; + } + } +} diff --git a/lib/features/report/provider/report_provider.dart b/lib/features/report/provider/report_provider.dart new file mode 100644 index 0000000..cd30a46 --- /dev/null +++ b/lib/features/report/provider/report_provider.dart @@ -0,0 +1,58 @@ +import 'package:flutter/foundation.dart'; +import 'package:dio/dio.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import '../data/report_repository.dart'; + +part 'report_provider.g.dart'; + +enum ReportTargetType { article, comment } + +@riverpod +class ReportController extends _$ReportController { + @override + FutureOr build() {} + + Future submitReport({ + required ReportTargetType targetType, + required int targetId, + required String reportReason, + required String detailReason, + }) async { + state = const AsyncValue.loading(); + + try { + if (targetType == ReportTargetType.article) { + await ref + .read(reportRepositoryProvider) + .reportArticle( + articleId: targetId, + reportReason: reportReason, + detailReason: detailReason, + ); + } else { + await ref + .read(reportRepositoryProvider) + .reportComment( + commentId: targetId, + reportReason: reportReason, + detailReason: detailReason, + ); + } + + state = const AsyncValue.data(null); + return true; + } catch (e, stack) { + if (e is DioException) { + debugPrint('---------- [신고 컨트롤러 오류] ----------'); + debugPrint('타입: $targetType, ID: $targetId'); + debugPrint('서버 응답: ${e.response?.data}'); + debugPrint('---------------------------------------'); + } else { + debugPrint('신고 처리 중 알 수 없는 에러: $e'); + } + + state = AsyncValue.error(e, stack); + return false; + } + } +} diff --git a/lib/features/report/provider/report_provider.g.dart b/lib/features/report/provider/report_provider.g.dart new file mode 100644 index 0000000..e2b3171 --- /dev/null +++ b/lib/features/report/provider/report_provider.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'report_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$reportControllerHash() => r'ce81a7ac083ec6c7d626d50e5adb28d495f1b992'; + +/// See also [ReportController]. +@ProviderFor(ReportController) +final reportControllerProvider = + AutoDisposeAsyncNotifierProvider.internal( + ReportController.new, + name: r'reportControllerProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$reportControllerHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$ReportController = AutoDisposeAsyncNotifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/report/screens/report_screen.dart b/lib/features/report/screens/report_screen.dart index 68cdb78..c76d9e4 100644 --- a/lib/features/report/screens/report_screen.dart +++ b/lib/features/report/screens/report_screen.dart @@ -6,25 +6,46 @@ import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/shared/widgets/bottom_action_button.dart'; import '../widgets/report_reason_tile.dart'; import 'report_success_screen.dart'; +import 'package:haenaem/features/report/provider/report_provider.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; -class ReportScreen extends StatefulWidget { - const ReportScreen({super.key}); +class ReportScreen extends ConsumerStatefulWidget { + final ReportTargetType targetType; + final int targetId; + const ReportScreen({ + super.key, + required this.targetType, + required this.targetId, + }); @override - State createState() => _ReportScreenState(); + ConsumerState createState() => _ReportScreenState(); } -class _ReportScreenState extends State { +class _ReportScreenState extends ConsumerState { int? _selectedReasonIndex; final TextEditingController _otherReasonController = TextEditingController(); + // 백엔드 API 명세에 맞게 keys 값을 꼭 수정해주세요! final List> _reasons = [ - {'title': '영리목적/홍보성', 'desc': '상업적 광고, 도배성 게시글, 링크 유도 등'}, - {'title': '욕설/비하 발언', 'desc': '특정 개인이나 집단에 대한 혐오, 비하, 욕설 포함'}, - {'title': '부적절한 콘텐츠', 'desc': '음란물, 폭력적 내용, 불법 정보 포함'}, - {'title': '개인정보 노출', 'desc': '타인의 연락처, 주소 등 민감한 정보 공유'}, - {'title': '명의 도용/사칭', 'desc': '타인을 사칭하거나 저작권을 침해하는 이미지 사용'}, - {'title': '기타 (직접 입력)', 'desc': '위 항목에 해당하지 않는 구체적인 사유'}, + {'key': 'SPAM', 'title': '영리목적/홍보성', 'desc': '상업적 광고, 도배성 게시글, 링크 유도 등'}, + { + 'key': 'ABUSE', + 'title': '욕설/비하 발언', + 'desc': '특정 개인이나 집단에 대한 혐오, 비하, 욕설 포함', + }, + { + 'key': 'INAPPROPRIATE', + 'title': '부적절한 콘텐츠', + 'desc': '음란물, 폭력적 내용, 불법 정보 포함', + }, + {'key': 'PRIVACY', 'title': '개인정보 노출', 'desc': '타인의 연락처, 주소 등 민감한 정보 공유'}, + { + 'key': 'IMPERSONATION', + 'title': '명의 도용/사칭', + 'desc': '타인을 사칭하거나 저작권을 침해하는 이미지 사용', + }, + {'key': 'OTHER', 'title': '기타 (직접 입력)', 'desc': '위 항목에 해당하지 않는 구체적인 사유'}, ]; @override @@ -33,17 +54,34 @@ class _ReportScreenState extends State { super.dispose(); } - void _submitReport() { + Future _submitReport() async { if (_selectedReasonIndex == null) return; + FocusManager.instance.primaryFocus?.unfocus(); - // TODO: 서버로 신고 내용 전송하는 로직 (API 연동 시 여기에 작성) - // _selectedReasonIndex == 5 인 경우 _otherReasonController.text를 함께 전송 + final selectedKey = _reasons[_selectedReasonIndex!]['key']!; + final detailReason = _selectedReasonIndex == 5 + ? _otherReasonController.text + : ''; - // 현재 신고 화면을 종료(pop)하고 신고 완료 화면으로 대체(pushReplacement)합니다. - // 이렇게 하면 신고 완료 화면에서 '확인'을 눌렀을 때 원래 있던 피드나 댓글 창으로 깔끔하게 돌아갑니다. - Navigator.of(context).pushReplacement( - MaterialPageRoute(builder: (context) => const ReportSuccessScreen()), - ); + // 바뀐 부분: 모델 객체 생성 없이 파라미터로 바로 전달 + final success = await ref + .read(reportControllerProvider.notifier) + .submitReport( + targetType: widget.targetType, + targetId: widget.targetId, + reportReason: selectedKey, + detailReason: detailReason, + ); + + if (success && mounted) { + Navigator.of(context).pushReplacement( + MaterialPageRoute(builder: (context) => const ReportSuccessScreen()), + ); + } else if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('신고 접수에 실패했습니다. 다시 시도해주세요.')), + ); + } } @override From f2446f5a5c969024039b1d3fc5bd13247849b8eb Mon Sep 17 00:00:00 2001 From: Seungvin Date: Thu, 7 May 2026 15:14:23 +0900 Subject: [PATCH 114/134] =?UTF-8?q?docs:=20=EC=A3=BC=EC=84=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/report/data/report_repository.dart | 2 ++ lib/features/report/provider/report_provider.dart | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lib/features/report/data/report_repository.dart b/lib/features/report/data/report_repository.dart index a08603e..7819eb5 100644 --- a/lib/features/report/data/report_repository.dart +++ b/lib/features/report/data/report_repository.dart @@ -1,3 +1,5 @@ +// 최초 작성자: 정승빈 + import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; diff --git a/lib/features/report/provider/report_provider.dart b/lib/features/report/provider/report_provider.dart index cd30a46..282c4be 100644 --- a/lib/features/report/provider/report_provider.dart +++ b/lib/features/report/provider/report_provider.dart @@ -1,3 +1,5 @@ +// 최초 작성자: 정승빈 + import 'package:flutter/foundation.dart'; import 'package:dio/dio.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; From 1d29964c6f44d2257b9885c50e7ead9462b2b6be Mon Sep 17 00:00:00 2001 From: Seungvin Date: Thu, 7 May 2026 23:17:50 +0900 Subject: [PATCH 115/134] =?UTF-8?q?fix:=20ReportController=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=20=EC=B2=98=EB=A6=AC=20=EB=B0=8F=20ReportScreen=20?= =?UTF-8?q?=EB=82=B4=20=EA=B8=B0=ED=83=80=20=EC=82=AC=EC=9C=A0=20=ED=82=A4?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/report/provider/report_provider.dart | 8 ++++---- lib/features/report/screens/report_screen.dart | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/features/report/provider/report_provider.dart b/lib/features/report/provider/report_provider.dart index 282c4be..3eff236 100644 --- a/lib/features/report/provider/report_provider.dart +++ b/lib/features/report/provider/report_provider.dart @@ -20,7 +20,7 @@ class ReportController extends _$ReportController { required String reportReason, required String detailReason, }) async { - state = const AsyncValue.loading(); + // state = const AsyncValue.loading(); try { if (targetType == ReportTargetType.article) { @@ -41,9 +41,9 @@ class ReportController extends _$ReportController { ); } - state = const AsyncValue.data(null); + // state = const AsyncValue.data(null); return true; - } catch (e, stack) { + } catch (e) { if (e is DioException) { debugPrint('---------- [신고 컨트롤러 오류] ----------'); debugPrint('타입: $targetType, ID: $targetId'); @@ -53,7 +53,7 @@ class ReportController extends _$ReportController { debugPrint('신고 처리 중 알 수 없는 에러: $e'); } - state = AsyncValue.error(e, stack); + // state = AsyncValue.error(e, stack); return false; } } diff --git a/lib/features/report/screens/report_screen.dart b/lib/features/report/screens/report_screen.dart index c76d9e4..c7153f1 100644 --- a/lib/features/report/screens/report_screen.dart +++ b/lib/features/report/screens/report_screen.dart @@ -45,7 +45,7 @@ class _ReportScreenState extends ConsumerState { 'title': '명의 도용/사칭', 'desc': '타인을 사칭하거나 저작권을 침해하는 이미지 사용', }, - {'key': 'OTHER', 'title': '기타 (직접 입력)', 'desc': '위 항목에 해당하지 않는 구체적인 사유'}, + {'key': 'ECT', 'title': '기타 (직접 입력)', 'desc': '위 항목에 해당하지 않는 구체적인 사유'}, ]; @override From 04c05750cb4e04cb897b9fe626fe54703e2c0e06 Mon Sep 17 00:00:00 2001 From: Chaeyeong_10 Date: Thu, 7 May 2026 23:42:23 +0900 Subject: [PATCH 116/134] =?UTF-8?q?feat:=20=ED=86=B5=EA=B3=84=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=203=EA=B0=9C=20=EC=9C=84=EC=A0=AF=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/core/network/dio_provider.dart | 29 +- lib/core/network/dio_provider.g.dart | 2 +- lib/features/auth/services/auth_service.dart | 4 - .../challenge/data/challenge_repository.dart | 2 +- .../provider/challenge_provider.g.dart | 2 +- .../home/provider/home_provider.g.dart | 2 +- .../statistics/data/activity_repository.dart | 58 ++++ .../data/activity_repository.g.dart | 27 ++ .../data/distribution_repository.dart | 128 ++++++++ .../data/distribution_repository.g.dart | 30 ++ .../data/monthly_weekly_repository.dart | 63 ++++ .../data/monthly_weekly_repository.g.dart | 30 ++ .../statistics/screens/statistics_screen.dart | 132 ++++++-- .../statistics/widgets/haenaem_grass.dart | 102 +++--- .../widgets/line_graph/line_chart_grid.dart | 290 ++++++++++++++++++ .../widgets/line_graph/line_graph.dart | 64 ++-- .../line_graph/monthly_line_graph.dart | 209 ++----------- .../widgets/line_graph/weekly_line_graph.dart | 143 +++------ .../statistics/widgets/pie_graph.dart | 171 +++++------ 19 files changed, 997 insertions(+), 491 deletions(-) create mode 100644 lib/features/statistics/data/activity_repository.dart create mode 100644 lib/features/statistics/data/activity_repository.g.dart create mode 100644 lib/features/statistics/data/distribution_repository.dart create mode 100644 lib/features/statistics/data/distribution_repository.g.dart create mode 100644 lib/features/statistics/data/monthly_weekly_repository.dart create mode 100644 lib/features/statistics/data/monthly_weekly_repository.g.dart create mode 100644 lib/features/statistics/widgets/line_graph/line_chart_grid.dart diff --git a/lib/core/network/dio_provider.dart b/lib/core/network/dio_provider.dart index 1af129f..975987f 100644 --- a/lib/core/network/dio_provider.dart +++ b/lib/core/network/dio_provider.dart @@ -31,24 +31,47 @@ Dio dio(DioRef ref) { return handler.next(options); }, onError: (DioException e, handler) async { + // 1. 401 에러(토큰 만료) 발생 시 if (e.response?.statusCode == 401) { + debugPrint( + '⚠️ [401 Detected] 토큰 만료됨. 재발급 시도 중... (Path: ${e.requestOptions.path})', + ); + const storage = FlutterSecureStorage(); final refreshToken = await storage.read(key: 'refreshToken'); + if (refreshToken != null) { try { - // 🎯 토큰 갱신 전용 가벼운 Dio 생성 (인터셉터 없음) final refreshDio = Dio( BaseOptions(baseUrl: e.requestOptions.baseUrl), ); + debugPrint('🔄 [Refresh] 리프레시 토큰으로 전송 중: $refreshToken'); + final response = await refreshDio.post( '/api/token', data: {"refreshToken": refreshToken}, ); + + // 성공 시 로그 (여기에 새 토큰 저장 로직이 추가되어야 합니다) + debugPrint('✅ [Refresh Success] 새로운 토큰 발급 완료: ${response.data}'); + + // TODO: 여기서 발급받은 새 토큰을 storage에 저장하고 + // 원래 실패했던 요청(e.requestOptions)을 다시 시도(dio.fetch)하는 로직이 필요합니다. } catch (err) { - // 재발급 실패 시 로그아웃 처리 - debugPrint("재발급 실패!"); + // 2. 재발급 과정에서 발생한 상세 에러 로그 + if (err is DioException) { + debugPrint( + '❌ [Refresh Failed] 상태 코드: ${err.response?.statusCode}', + ); + debugPrint('❌ [Refresh Failed] 서버 메시지: ${err.response?.data}'); + debugPrint('❌ [Refresh Failed] 에러 타입: ${err.type}'); + } else { + debugPrint('❌ [Refresh Failed] 알 수 없는 에러: $err'); + } } + } else { + debugPrint('🚫 [Refresh Aborted] 저장된 리프레시 토큰이 없습니다.'); } } return handler.next(e); diff --git a/lib/core/network/dio_provider.g.dart b/lib/core/network/dio_provider.g.dart index 92d4137..6c0585e 100644 --- a/lib/core/network/dio_provider.g.dart +++ b/lib/core/network/dio_provider.g.dart @@ -6,7 +6,7 @@ part of 'dio_provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$dioHash() => r'db900e733514ad57f7f6f488298446b8ed14a932'; +String _$dioHash() => r'6d2d983d038fab8e6b21ded10b369255f9e341f3'; /// See also [dio]. @ProviderFor(dio) diff --git a/lib/features/auth/services/auth_service.dart b/lib/features/auth/services/auth_service.dart index 30ca97c..a8d2b8a 100644 --- a/lib/features/auth/services/auth_service.dart +++ b/lib/features/auth/services/auth_service.dart @@ -36,10 +36,6 @@ class AuthService { //static const String kakaoRedirectUri = //'kakao9fdd13c0777c415d8fa4055b5b26a6c5://oauth'; - // ♥️ 로컬 서버로 테스트 - // static const String kakaoRedirectUri = - // 'https://ungenially-undebatable-sindy.ngrok-free.dev/oauth/kakao/callback'; - // ♥️ 기존 서버 static final Dio _dio = Dio( BaseOptions(baseUrl: 'http://158.247.216.11:8080'), diff --git a/lib/features/challenge/data/challenge_repository.dart b/lib/features/challenge/data/challenge_repository.dart index cb09fb2..39b72af 100644 --- a/lib/features/challenge/data/challenge_repository.dart +++ b/lib/features/challenge/data/challenge_repository.dart @@ -51,7 +51,7 @@ class ChallengeRepository { // 챌린지 상세정보 조회 수정 Future getChallengeDetail(int challengeId) async { try { - final response = await _dio.get('api/challenge/$challengeId'); + final response = await _dio.get('/api/challenge/$challengeId'); print("서버 응답 데이터: ${response.data}"); // 데이터 확인 완료! // 상세 API는 content 없이 바로 객체가 오므로 response.data를 그대로 사용합니다. diff --git a/lib/features/challenge/provider/challenge_provider.g.dart b/lib/features/challenge/provider/challenge_provider.g.dart index 0a61baf..a357b1a 100644 --- a/lib/features/challenge/provider/challenge_provider.g.dart +++ b/lib/features/challenge/provider/challenge_provider.g.dart @@ -1501,7 +1501,7 @@ final challengeCreateNotifierProvider = typedef _$ChallengeCreateNotifier = AutoDisposeNotifier>; String _$articleCreateNotifierHash() => - r'558fb00ff45dc4f321919d42368c1a94c415f602'; + r'f3e3030ff3ca5e030ff6e1797cf60cfa819b8bec'; /// See also [ArticleCreateNotifier]. @ProviderFor(ArticleCreateNotifier) diff --git a/lib/features/home/provider/home_provider.g.dart b/lib/features/home/provider/home_provider.g.dart index b2a7cfd..bcade9d 100644 --- a/lib/features/home/provider/home_provider.g.dart +++ b/lib/features/home/provider/home_provider.g.dart @@ -6,7 +6,7 @@ part of 'home_provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$homeNotifierHash() => r'79469b283e0bb3cd1f61eccb03f0923297609835'; +String _$homeNotifierHash() => r'8b37dfa057e9f5064aa299312acc9b381811c7a1'; /// See also [HomeNotifier]. @ProviderFor(HomeNotifier) diff --git a/lib/features/statistics/data/activity_repository.dart b/lib/features/statistics/data/activity_repository.dart new file mode 100644 index 0000000..1cccadf --- /dev/null +++ b/lib/features/statistics/data/activity_repository.dart @@ -0,0 +1,58 @@ +// 최초 작성자: 김채영 +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:haenaem/core/network/dio_provider.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +part 'activity_repository.g.dart'; + +// 해냄 잔디 레포지토리 +class ActivityData { + final int successDays; + final int currentStreak; + final List activity; + + ActivityData({ + required this.successDays, + required this.currentStreak, + required this.activity, + }); + + factory ActivityData.fromJson(Map json) { + return ActivityData( + successDays: json['successDays'], + currentStreak: json['currentStreak'], + activity: List.from(json['activity']), + ); + } +} + +@riverpod +class ActivityRepository extends _$ActivityRepository { + @override + Future build() async { + final dio = ref.watch(dioProvider); + return _fetchActivity(dio); + } + + Future _fetchActivity(Dio dio) async { + final year = DateTime.now().year; + final response = await dio.get( + '/api/users/activity', + queryParameters: {'year': year}, + ); + // ✅ API 응답 원본 확인 + debugPrint('🌐 [ActivityRepository] status: ${response.statusCode}'); + debugPrint('🌐 [ActivityRepository] raw data: ${response.data}'); + + return ActivityData.fromJson(response.data); + } + + Future refresh() async { + state = const AsyncLoading(); + state = await AsyncValue.guard(() async { + final dio = ref.read(dioProvider); + return _fetchActivity(dio); + }); + } +} diff --git a/lib/features/statistics/data/activity_repository.g.dart b/lib/features/statistics/data/activity_repository.g.dart new file mode 100644 index 0000000..4041ef3 --- /dev/null +++ b/lib/features/statistics/data/activity_repository.g.dart @@ -0,0 +1,27 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'activity_repository.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$activityRepositoryHash() => + r'deac898ee453d5c15e95786c15a00557263bffc9'; + +/// See also [ActivityRepository]. +@ProviderFor(ActivityRepository) +final activityRepositoryProvider = + AutoDisposeAsyncNotifierProvider.internal( + ActivityRepository.new, + name: r'activityRepositoryProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$activityRepositoryHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$ActivityRepository = AutoDisposeAsyncNotifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/statistics/data/distribution_repository.dart b/lib/features/statistics/data/distribution_repository.dart new file mode 100644 index 0000000..c3cecea --- /dev/null +++ b/lib/features/statistics/data/distribution_repository.dart @@ -0,0 +1,128 @@ +// 최초 작성자: 김채영 +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:haenaem/core/network/dio_provider.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/features/statistics/widgets/pie_graph.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +part 'distribution_repository.g.dart'; + +// 나의 해냄 분포 데이터 매핑 +class DistributionData { + final int totalCount; + final List top3; // 1~3위: 각각 색상 + final List rest; // 4위~: 각각 따로 (이름, 횟수 표시용) + final int restCount; // 4위~ 합산 (파이 차트용) + + DistributionData({ + required this.totalCount, + required this.top3, + required this.rest, + required this.restCount, + }); +} + +@riverpod +class DistributionRepository extends _$DistributionRepository { + @override + Future build() async { + final dio = ref.watch(dioProvider); + return _fetchDistribution(dio); + } + + Future refresh() async { + state = const AsyncLoading(); + state = await AsyncValue.guard(() async { + final dio = ref.read(dioProvider); + return _fetchDistribution(dio); + }); + } + + Future _fetchDistribution(Dio dio) async { + final response = await dio.get('/api/users/graph/tag'); + + debugPrint('🥧 [Distribution] ── 1. API 원본 응답 ──────────────────'); + debugPrint('🥧 [Distribution] status: ${response.statusCode}'); + debugPrint('🥧 [Distribution] raw data: ${response.data}'); + + final List raw = response.data; + + debugPrint('🥧 [Distribution] ── 2. 정렬 전 ──────────────────────'); + for (int i = 0; i < raw.length; i++) { + debugPrint( + '🥧 [Distribution] [$i] ${raw[i]['tagName']} : ${raw[i]['count']}번', + ); + } + + raw.sort((a, b) => (b['count'] as int).compareTo(a['count'] as int)); + + debugPrint('🥧 [Distribution] ── 3. 정렬 후 ──────────────────────'); + for (int i = 0; i < raw.length; i++) { + debugPrint( + '🥧 [Distribution] [$i] ${raw[i]['tagName']} : ${raw[i]['count']}번', + ); + } + + const top3Colors = [ + Color(0xFF8979FF), // 1위 보라 + Color(0xFFFF928A), // 2위 핑크 + Color(0xFF3CC3DF), // 3위 파랑 + ]; + + // 1~3위: 각각 색상 유지 + final top3 = raw.take(3).toList().asMap().entries.map((entry) { + return TagCount( + tag: entry.value['tagName'], + count: entry.value['count'], + color: top3Colors[entry.key], + ); + }).toList(); + + // 4위~: 이름/횟수 각각 유지 (UI 표시용), 색상은 gray4 + final restList = raw.skip(3).toList(); + final rest = restList + .take(3) + .map( + (item) => TagCount( + tag: item['tagName'], + count: item['count'], + color: AppColors.gray4, + ), + ) + .toList(); + + // 4위~ 합산 (파이 차트에서 gray4 하나로 표시용) + final restCount = restList.fold( + 0, + (sum, item) => sum + (item['count'] as int), + ); + + final totalCount = raw.fold( + 0, + (sum, item) => sum + (item['count'] as int), + ); + + debugPrint('🥧 [Distribution] ── 4. 위젯 전달 데이터 ───────────────'); + debugPrint('🥧 [Distribution] totalCount: $totalCount'); + for (int i = 0; i < top3.length; i++) { + final medal = ['🥇', '🥈', '🥉'][i]; + debugPrint( + '🥧 [Distribution] $medal ${i + 1}위 | ${top3[i].tag} : ${top3[i].count}번', + ); + } + for (int i = 0; i < rest.length; i++) { + debugPrint( + '🥧 [Distribution] 🔘 ${i + 4}위 | ${rest[i].tag} : ${rest[i].count}번', + ); + } + debugPrint('🥧 [Distribution] 🔘 기타 합산: $restCount번 (파이 차트용)'); + + return DistributionData( + totalCount: totalCount, + top3: top3, + rest: rest, + restCount: restCount, + ); + } +} diff --git a/lib/features/statistics/data/distribution_repository.g.dart b/lib/features/statistics/data/distribution_repository.g.dart new file mode 100644 index 0000000..f831d67 --- /dev/null +++ b/lib/features/statistics/data/distribution_repository.g.dart @@ -0,0 +1,30 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'distribution_repository.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$distributionRepositoryHash() => + r'dc3366618b82dc5934300051f6b59ba877a536f7'; + +/// See also [DistributionRepository]. +@ProviderFor(DistributionRepository) +final distributionRepositoryProvider = + AutoDisposeAsyncNotifierProvider< + DistributionRepository, + DistributionData + >.internal( + DistributionRepository.new, + name: r'distributionRepositoryProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$distributionRepositoryHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$DistributionRepository = AutoDisposeAsyncNotifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/statistics/data/monthly_weekly_repository.dart b/lib/features/statistics/data/monthly_weekly_repository.dart new file mode 100644 index 0000000..006ead1 --- /dev/null +++ b/lib/features/statistics/data/monthly_weekly_repository.dart @@ -0,0 +1,63 @@ +// 최초 작성자: 김채영 +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:haenaem/core/network/dio_provider.dart'; +import 'package:haenaem/features/statistics/widgets/line_graph/monthly_line_graph.dart'; +import 'package:haenaem/features/statistics/widgets/line_graph/weekly_line_graph.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +part 'monthly_weekly_repository.g.dart'; + +// 나의 해냄 추이 레포지토리 +class MonthlyWeeklyData { + final WeeklyGraphData monthly; + final DailyGraphData weekly; + + MonthlyWeeklyData({required this.monthly, required this.weekly}); +} + +@riverpod +class MonthlyWeeklyRepository extends _$MonthlyWeeklyRepository { + // ✅ _$TrendRepository → _$MonthlyWeeklyRepository + @override + Future build() async { + final dio = ref.watch(dioProvider); + return _fetch(dio); + } + + Future _fetch(Dio dio) async { + final responses = await Future.wait([ + dio.get('/api/users/graph/4weeks'), + dio.get('/api/users/graph/weekly'), // ✅ daily → weekly + ]); + + debugPrint('📈 [MonthlyWeekly] ── 월간 API 응답 ──────────────────────'); + debugPrint('📈 [MonthlyWeekly] status: ${responses[0].statusCode}'); + debugPrint('📈 [MonthlyWeekly] raw data: ${responses[0].data}'); + + debugPrint('📈 [MonthlyWeekly] ── 주간 API 응답 ──────────────────────'); + debugPrint('📈 [MonthlyWeekly] status: ${responses[1].statusCode}'); + debugPrint('📈 [MonthlyWeekly] raw data: ${responses[1].data}'); + + final monthly = WeeklyGraphData.fromJson(responses[0].data); + final weekly = DailyGraphData.fromJson(responses[1].data); + + debugPrint('📈 [MonthlyWeekly] ── 월간 파싱 결과 ─────────────────────'); + debugPrint('📈 [MonthlyWeekly] thisMonth: ${monthly.thisMonth}'); + debugPrint('📈 [MonthlyWeekly] lastMonth: ${monthly.lastMonth}'); + + debugPrint('📈 [MonthlyWeekly] ── 주간 파싱 결과 ─────────────────────'); + debugPrint('📈 [MonthlyWeekly] thisWeek: ${weekly.thisWeek}'); + debugPrint('📈 [MonthlyWeekly] lastWeek: ${weekly.lastWeek}'); + + return MonthlyWeeklyData(monthly: monthly, weekly: weekly); + } + + Future refresh() async { + state = const AsyncLoading(); + state = await AsyncValue.guard(() async { + final dio = ref.read(dioProvider); + return _fetch(dio); + }); + } +} diff --git a/lib/features/statistics/data/monthly_weekly_repository.g.dart b/lib/features/statistics/data/monthly_weekly_repository.g.dart new file mode 100644 index 0000000..66a5f18 --- /dev/null +++ b/lib/features/statistics/data/monthly_weekly_repository.g.dart @@ -0,0 +1,30 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'monthly_weekly_repository.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$monthlyWeeklyRepositoryHash() => + r'a1b957980c63fa664de422f1081d12f2ffda867f'; + +/// See also [MonthlyWeeklyRepository]. +@ProviderFor(MonthlyWeeklyRepository) +final monthlyWeeklyRepositoryProvider = + AutoDisposeAsyncNotifierProvider< + MonthlyWeeklyRepository, + MonthlyWeeklyData + >.internal( + MonthlyWeeklyRepository.new, + name: r'monthlyWeeklyRepositoryProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$monthlyWeeklyRepositoryHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +typedef _$MonthlyWeeklyRepository = AutoDisposeAsyncNotifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/statistics/screens/statistics_screen.dart b/lib/features/statistics/screens/statistics_screen.dart index a129faf..7120e7f 100644 --- a/lib/features/statistics/screens/statistics_screen.dart +++ b/lib/features/statistics/screens/statistics_screen.dart @@ -1,18 +1,24 @@ // 최초 작성자: 김채영 import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; +import '../data/activity_repository.dart'; +import '../data/distribution_repository.dart'; +import '../data/monthly_weekly_repository.dart'; import '../widgets/haenaem_grass.dart'; import '../widgets/pie_graph.dart'; import '../widgets/line_graph/line_graph.dart'; -class StatisticsScreen extends StatelessWidget { +// 통계화면 프레임 (안에다 위젯을 넣는 구조) +class StatisticsScreen extends ConsumerWidget { const StatisticsScreen({super.key}); @override - Widget build(BuildContext context) { - // 임시 데이터 (나중에 API 응답값으로 대체) - final List mockActivity = List.generate(365, (index) => (index % 5)); + Widget build(BuildContext context, WidgetRef ref) { + final activityAsync = ref.watch(activityRepositoryProvider); + final distributionAsync = ref.watch(distributionRepositoryProvider); + final monthlyWeeklyAsync = ref.watch(monthlyWeeklyRepositoryProvider); return Scaffold( backgroundColor: AppColors.gray5, @@ -30,27 +36,111 @@ class StatisticsScreen extends StatelessWidget { child: Column( children: [ const SizedBox(height: 10), - // 잔디 위젯 배치 - HaenaemGrass( - successDays: 00, - currentStreak: 00, - activity: mockActivity, + // 해냄 잔디 + activityAsync.when( + loading: () => const SizedBox( + height: 200, + child: Center(child: CircularProgressIndicator()), + ), + error: (e, _) => SizedBox( + height: 200, + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + '데이터를 불러오지 못했어요', + style: AppTypography.b2.copyWith( + color: AppColors.gray4, + ), + ), + const SizedBox(height: 8), + TextButton( + onPressed: () => ref + .read(activityRepositoryProvider.notifier) + .refresh(), + child: const Text('다시 시도'), + ), + ], + ), + ), + ), + data: (data) => HaenaemGrass( + successDays: data.successDays, + currentStreak: data.currentStreak, + activity: data.activity, + ), ), - const SizedBox(height: 20), - const PieGraph( - totalCount: 48, - tagCounts: [ - TagCount(tag: '자격증', count: 24, color: Color(0xFF8979FF)), - TagCount(tag: '다이어트', count: 15, color: Color(0xFFFF928A)), - TagCount(tag: '독서', count: 8, color: Color(0xff3cc3df)), - TagCount(tag: 'tag', count: 00, color: AppColors.gray4), - TagCount(tag: 'tag', count: 00, color: Color(0xFFFFD166)), - TagCount(tag: 'tag', count: 00, color: AppColors.primaryAble), - ], + // 나의 해냄 분포 + distributionAsync.when( + loading: () => const SizedBox( + height: 200, + child: Center(child: CircularProgressIndicator()), + ), + error: (e, _) => SizedBox( + height: 200, + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + '데이터를 불러오지 못했어요', + style: AppTypography.b2.copyWith( + color: AppColors.gray4, + ), + ), + const SizedBox(height: 8), + TextButton( + onPressed: () => ref + .read(distributionRepositoryProvider.notifier) + .refresh(), + child: const Text('다시 시도'), + ), + ], + ), + ), + ), + data: (data) => PieGraph( + top3: data.top3, + rest: data.rest, + restCount: data.restCount, + totalCount: data.totalCount, + ), ), const SizedBox(height: 20), - const LineGraph(), + // 나의 해냄 추이 + monthlyWeeklyAsync.when( + loading: () => const SizedBox( + height: 200, + child: Center(child: CircularProgressIndicator()), + ), + error: (e, _) => SizedBox( + height: 200, + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + '데이터를 불러오지 못했어요', + style: AppTypography.b2.copyWith( + color: AppColors.gray4, + ), + ), + const SizedBox(height: 8), + TextButton( + onPressed: () => ref + .read(monthlyWeeklyRepositoryProvider.notifier) + .refresh(), + child: const Text('다시 시도'), + ), + ], + ), + ), + ), + data: (data) => + LineGraph(monthlyData: data.monthly, weeklyData: data.weekly), + ), const SizedBox(height: 20), ], ), diff --git a/lib/features/statistics/widgets/haenaem_grass.dart b/lib/features/statistics/widgets/haenaem_grass.dart index 111c5c8..2bf27dc 100644 --- a/lib/features/statistics/widgets/haenaem_grass.dart +++ b/lib/features/statistics/widgets/haenaem_grass.dart @@ -5,10 +5,11 @@ import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'statistics_card.dart'; +// 해냄 잔디 위젯 class HaenaemGrass extends StatelessWidget { final int successDays; final int currentStreak; - final List activity; // 1년치 활동 데이터 (약 365개) + final List activity; const HaenaemGrass({ super.key, @@ -17,28 +18,32 @@ class HaenaemGrass extends StatelessWidget { required this.activity, }); + int _getLevel(int count) { + if (count <= 0) return 0; + if (count == 1) return 1; + if (count == 2) return 2; + if (count == 3) return 3; + return 4; + } + @override Widget build(BuildContext context) { - // 2026년 월별 일수 배열 (평년 기준) - // 나중에 연별로 알아서 바뀌게끔 로직 수정 - final List daysInMonths = [ - 31, - 28, - 31, - 30, - 31, - 30, - 31, - 31, - 30, - 31, - 30, - 31, - ]; + debugPrint('🌿 [HaenaemGrass] successDays: $successDays'); + debugPrint('🔥 [HaenaemGrass] currentStreak: $currentStreak'); + debugPrint('📊 [HaenaemGrass] activity length: ${activity.length}'); + debugPrint( + '📊 [HaenaemGrass] activity (first 10): ${activity.take(10).toList()}', + ); + + final int year = DateTime.now().year; + final List daysInMonths = List.generate(12, (monthIndex) { + // 다음 달 1일에서 하루를 빼면 이번 달 마지막 날 = 해당 월의 일수 + return DateTime(year, monthIndex + 2, 0).day; + }); + debugPrint('📅 [HaenaemGrass] year: $year, daysInMonths: $daysInMonths'); return StatisticsCard( title: "해냄 잔디", - // ✅ headerAction을 사용하여 상단 우측에 인증 횟수 배치 headerAction: Row( mainAxisSize: MainAxisSize.min, children: [ @@ -56,19 +61,29 @@ class HaenaemGrass extends StatelessWidget { ], ), child: Padding( - // StatisticsCard 내부 패딩(20) + 12.5 = 카드 끝에서 총 32.5 여백 padding: const EdgeInsets.symmetric(horizontal: 12.5), child: Column( mainAxisSize: MainAxisSize.min, - spacing: 6, // 잔디 한 줄(월)끼리의 간격 + spacing: 6, + // ✅ 월 루프 (12개) children: List.generate(12, (monthIndex) { int dayCount = daysInMonths[monthIndex]; + // ✅ startIndex: 이 월 이전까지의 누적 일수 + int startIndex = daysInMonths + .sublist(0, monthIndex) + .fold(0, (sum, d) => sum + d); + + // ✅ 일 루프 (각 월의 일수만큼) return Row( mainAxisAlignment: MainAxisAlignment.center, - spacing: 2, // 잔디 한 칸끼리의 간격 + spacing: 2, children: List.generate(dayCount, (dayIndex) { - return _buildGrassNode(); // 모든 잔디 gray5 색상 + int activityIndex = startIndex + dayIndex; + int count = activityIndex < activity.length + ? activity[activityIndex] + : 0; + return _buildGrassNode(_getLevel(count)); }), ); }), @@ -92,31 +107,30 @@ class HaenaemGrass extends StatelessWidget { ); } - // 잔디 한 알 - Widget _buildGrassNode() { - // Color nodeColor; - // switch (level) { - // case 1: - // nodeColor = AppColors.primaryAble.withValues(alpha: 0.25); - // break; - // case 2: - // nodeColor = AppColors.primaryAble.withValues(alpha: 0.5); - // break; - // case 3: - // nodeColor = AppColors.primaryAble.withValues(alpha: 0.75); - // break; - // case 4: - // nodeColor = AppColors.primaryAble; - // break; - // default: - // nodeColor = AppColors.gray5; - // } + Widget _buildGrassNode(int level) { + Color nodeColor; + switch (level) { + case 1: + nodeColor = AppColors.primaryAble.withValues(alpha: 0.30); + break; + case 2: + nodeColor = AppColors.primaryAble.withValues(alpha: 0.55); + break; + case 3: + nodeColor = AppColors.primaryAble.withValues(alpha: 0.80); + break; + case 4: + nodeColor = AppColors.primaryAble; + break; + default: + nodeColor = AppColors.gray5; + } return Container( - width: 6, - height: 6, + width: 7, + height: 7, decoration: BoxDecoration( - color: AppColors.gray5, + color: nodeColor, borderRadius: BorderRadius.circular(1), ), ); diff --git a/lib/features/statistics/widgets/line_graph/line_chart_grid.dart b/lib/features/statistics/widgets/line_graph/line_chart_grid.dart new file mode 100644 index 0000000..4b56fa8 --- /dev/null +++ b/lib/features/statistics/widgets/line_graph/line_chart_grid.dart @@ -0,0 +1,290 @@ +// 최초 작성자: 김채영 +import 'package:flutter/material.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'package:haenaem/core/theme/app_typography.dart'; + +// ─────────────────────────────────────────────── +// 공통 라인 차트 위젯 +// ─────────────────────────────────────────────── + +/// 월간/주간 공통 꺾은선 그래프 위젯 +/// +/// - [columnCount] : 데이터 포인트 수 (월간: 4, 주간: 7) +/// - [rowCount] : 가로 구간 수 (월간: 3, 주간: 5) → 가로선은 rowCount+1개 +/// - [xLabels] : X축 레이블 목록 (columnCount와 길이 일치) +/// - [yMax] : Y축 최댓값 (데이터 기반으로 계산된 값) +/// - [thisData] : 이번 달/주 데이터 +/// - [lastData] : 저번 달/주 데이터 +/// - [labelColor] : 축 레이블 색상 (기본: AppColors.gray1) +class LineChartGrid extends StatelessWidget { + final int columnCount; + final int rowCount; + final List xLabels; + final double yMax; + final List thisData; + final List lastData; + final Color? labelColor; + + const LineChartGrid({ + super.key, + required this.columnCount, + this.rowCount = 3, + required this.xLabels, + required this.yMax, + required this.thisData, + required this.lastData, + this.labelColor, + }) : assert( + xLabels.length == columnCount, + 'xLabels 길이는 columnCount와 같아야 합니다.', + ); + + @override + Widget build(BuildContext context) { + final axisColor = labelColor ?? AppColors.gray1; + + // Y축 레이블: yMax에서 0까지 rowCount+1개 균등 분할 + final yLabels = List.generate( + rowCount + 1, + (i) => (yMax * (rowCount - i) / rowCount).round(), + ); + + return SizedBox( + width: double.infinity, + height: 164, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // ── 그래프 본체 (Y축 레이블 + 캔버스) ── + Expanded( + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // Y축 레이블 + Padding( + padding: const EdgeInsets.symmetric(horizontal: 4), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: yLabels + .map( + (label) => Text( + '$label', + style: AppTypography.c1.copyWith(color: axisColor), + ), + ) + .toList(), + ), + ), + + // 그래프 캔버스 + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 6), + child: CustomPaint( + painter: _LineChartPainter( + columnCount: columnCount, + rowCount: rowCount, + yMax: yMax, + thisData: thisData, + lastData: lastData, + ), + ), + ), + ), + ], + ), + ), + + // ── X축 레이블 ── + // 그래프 본체와 동일한 Row 구조 사용: + // [Y축 더미 공간] + [캔버스 영역을 columnCount로 균등 분할] + // → Y축 너비를 하드코딩 없이 정확히 맞춤 + Padding( + padding: const EdgeInsets.only(bottom: 8), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Y축 레이블과 동일한 패딩/텍스트 스타일로 더미 공간 확보 + IntrinsicWidth( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 4), + child: Text( + '${yMax.toInt()}', + style: AppTypography.c1.copyWith( + color: Colors.transparent, + ), + ), + ), + ), + + // 캔버스 영역: columnCount 구간으로 균등 분할 + // 각 Expanded가 세로 점선 사이 한 구간에 대응 + Expanded( + child: Row( + children: List.generate( + columnCount, + (i) => Expanded( + child: Text( + xLabels[i], + textAlign: TextAlign.center, + style: AppTypography.c1.copyWith(color: axisColor), + ), + ), + ), + ), + ), + ], + ), + ), + ], + ), + ); + } +} + +// ─────────────────────────────────────────────── +// CustomPainter +// ─────────────────────────────────────────────── + +class _LineChartPainter extends CustomPainter { + final int columnCount; + final int rowCount; + final double yMax; + final List thisData; + final List lastData; + + const _LineChartPainter({ + required this.columnCount, + required this.rowCount, + required this.yMax, + required this.thisData, + required this.lastData, + }); + + @override + void paint(Canvas canvas, Size size) { + _drawGrid(canvas, size); + if (lastData.length >= columnCount) { + _drawLine(canvas, size, lastData, AppColors.gray4); + _drawDots(canvas, size, lastData, AppColors.gray4); + } + if (thisData.length >= columnCount) { + _drawLine(canvas, size, thisData, AppColors.primaryAble); + _drawDots(canvas, size, thisData, AppColors.primaryAble); + } + } + + /// 격자선 + /// - 가로: rowCount+1개, 맨 아래만 실선 나머지는 점선 + /// - 세로: columnCount+1개 점선 (양끝 포함) + void _drawGrid(Canvas canvas, Size size) { + final solidPaint = Paint() + ..color = AppColors.gray4 + ..strokeWidth = 1; + + final dashedPaint = Paint() + ..color = AppColors.gray4 + ..strokeWidth = 1; + + // 가로선: rowCount+1개 (i=0: top, i=rowCount: bottom) + for (int i = 0; i <= rowCount; i++) { + final y = size.height * i / rowCount; + if (i == rowCount) { + // 맨 아래만 실선 + canvas.drawLine(Offset(0, y), Offset(size.width, y), solidPaint); + } else { + // 나머지 점선 + _drawDashedHorizontalLine(canvas, y, 0, size.width, dashedPaint); + } + } + + // 세로 점선: columnCount+1개 (양끝 포함) + for (int i = 0; i <= columnCount; i++) { + final x = size.width * i / columnCount; + _drawDashedVerticalLine(canvas, x, 0, size.height, dashedPaint); + } + } + + // 점선 가로선 헬퍼 + void _drawDashedHorizontalLine( + Canvas canvas, + double y, + double startX, + double endX, + Paint paint, + ) { + const dashWidth = 4.0; + const dashGap = 3.0; + double currentX = startX; + while (currentX < endX) { + final nextX = (currentX + dashWidth).clamp(0.0, endX); + canvas.drawLine(Offset(currentX, y), Offset(nextX, y), paint); + currentX += dashWidth + dashGap; + } + } + + // 점선 세로선 헬퍼 + void _drawDashedVerticalLine( + Canvas canvas, + double x, + double startY, + double endY, + Paint paint, + ) { + const dashHeight = 4.0; + const dashGap = 3.0; + double currentY = startY; + while (currentY < endY) { + final nextY = (currentY + dashHeight).clamp(0.0, endY); + canvas.drawLine(Offset(x, currentY), Offset(x, nextY), paint); + currentY += dashHeight + dashGap; + } + } + + /// 꺾은선 그리기 + /// x 위치: 각 구간 중앙 → (2i + 1) / (2 * columnCount) + void _drawLine(Canvas canvas, Size size, List values, Color color) { + final paint = Paint() + ..color = color + ..strokeWidth = 1.5 + ..style = PaintingStyle.stroke + ..strokeCap = StrokeCap.round + ..strokeJoin = StrokeJoin.round; + + final path = Path(); + for (int i = 0; i < columnCount; i++) { + final x = size.width * (2 * i + 1) / (2 * columnCount); + final y = size.height - (values[i] / yMax) * size.height; + i == 0 ? path.moveTo(x, y) : path.lineTo(x, y); + } + canvas.drawPath(path, paint); + } + + /// 데이터 포인트 점 그리기 (흰색 채우기 + 컬러 테두리) + void _drawDots(Canvas canvas, Size size, List values, Color color) { + final fillPaint = Paint() + ..color = Colors.white + ..style = PaintingStyle.fill; + final borderPaint = Paint() + ..color = color + ..style = PaintingStyle.stroke + ..strokeWidth = 2; + + for (int i = 0; i < columnCount; i++) { + final x = size.width * (2 * i + 1) / (2 * columnCount); + final y = size.height - (values[i] / yMax) * size.height; + canvas.drawCircle(Offset(x, y), 4, fillPaint); + canvas.drawCircle(Offset(x, y), 4, borderPaint); + } + } + + @override + bool shouldRepaint(covariant _LineChartPainter old) => + old.columnCount != columnCount || + old.rowCount != rowCount || + old.yMax != yMax || + old.thisData != thisData || + old.lastData != lastData; +} diff --git a/lib/features/statistics/widgets/line_graph/line_graph.dart b/lib/features/statistics/widgets/line_graph/line_graph.dart index b1699dd..aa03195 100644 --- a/lib/features/statistics/widgets/line_graph/line_graph.dart +++ b/lib/features/statistics/widgets/line_graph/line_graph.dart @@ -9,21 +9,21 @@ import '../statistics_card.dart'; import 'monthly_line_graph.dart'; import 'weekly_line_graph.dart'; -// 나의 해냄 추이 꺾은선 그래프 +// 나의 해냄 추이 위젯 틀 class LineGraph extends ConsumerWidget { - final bool isMonthly; // 현재 월간/주간 선택 상태 - final VoidCallback? onToggle; // 탭 전환 시 호출될 콜백 (상태 관리용) + final WeeklyGraphData monthlyData; + final DailyGraphData weeklyData; const LineGraph({ super.key, - this.isMonthly = true, // 기본값 월간 - this.onToggle, + required this.monthlyData, + required this.weeklyData, }); @override Widget build(BuildContext context, WidgetRef ref) { - // 현재 상태를 감시하여 상태가 바뀔 때마다 위젯이 다시 그려짐 final isMonthly = ref.watch(graphTypeProvider); + return StatisticsCard( title: "나의 해냄 추이", child: Column( @@ -31,32 +31,17 @@ class LineGraph extends ConsumerWidget { children: [ Column( children: [ - // 월간/주간 토글 버튼 영역 - _buildToggleButtons(ref, isMonthly), // ref와 isMonthly 전달 - const SizedBox(height: 20), // 버튼과 그래프 사이 간격 - // 범례 영역 (이번 달/주, 저번 달/주) + _buildToggleButtons(ref, isMonthly), + const SizedBox(height: 20), _buildLegend(isMonthly), - - // ✅ 그래프 전환 로직 적용 + const SizedBox(height: 12), AnimatedSwitcher( duration: const Duration(milliseconds: 300), - child: SizedBox( + child: KeyedSubtree( key: ValueKey(isMonthly), - height: 184, - width: double.infinity, - child: const MonthlyLineGraph( - data: WeeklyGraphData( - thisMonth: [28, 15, 20, 25], - lastMonth: [10, 22, 17, 12], - ), - ), - // : const WeeklyLineGraph( - // // ✅ 주간 그래프 추가 - // data: DailyGraphData( - // thisWeek: [3, 5, 2, 8, 4, 6, 7], - // lastWeek: [2, 4, 3, 5, 3, 5, 4], - // ), - // ), + child: isMonthly + ? MonthlyLineGraph(data: monthlyData) + : WeeklyLineGraph(data: weeklyData), ), ), ], @@ -66,11 +51,10 @@ class LineGraph extends ConsumerWidget { ); } - // 범례 빌더: 상태에 따라 텍스트 변경 Widget _buildLegend(bool isMonthly) { return Row( mainAxisAlignment: MainAxisAlignment.center, - spacing: 8, // 두 범례 사이의 간격 + spacing: 8, children: [ _buildLegendItem( iconPath: 'assets/images/icons/green_line_graph_icon.svg', @@ -84,30 +68,23 @@ class LineGraph extends ConsumerWidget { ); } - // 범례 개별 아이템 Widget _buildLegendItem({required String iconPath, required String label}) { return Row( mainAxisSize: MainAxisSize.min, - spacing: 4, // 아이콘과 텍스트 사이 간격 + spacing: 4, children: [ SvgPicture.asset(iconPath, width: 16, height: 16), - Text( - label, - style: AppTypography.b2.copyWith( - color: AppColors.gray1, - ), // 디자인의 apptypography가 프리텐다드가 아니라서 임시로 지정 - ), + Text(label, style: AppTypography.c1.copyWith(color: AppColors.gray1)), ], ); } - // 월간/주간 선택 버튼 Widget _buildToggleButtons(WidgetRef ref, bool isMonthly) { return Container( width: double.infinity, height: 35.99, decoration: ShapeDecoration( - color: AppColors.gray5, // 기본 배경 + color: AppColors.gray5, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(100)), ), child: Row( @@ -129,7 +106,6 @@ class LineGraph extends ConsumerWidget { ); } - // 개별 탭 버튼 구현 Widget _buildTab({ required WidgetRef ref, required String label, @@ -138,13 +114,12 @@ class LineGraph extends ConsumerWidget { }) { return Expanded( child: GestureDetector( - onTap: onTap, // 탭 클릭 시 동작 - behavior: HitTestBehavior.opaque, // 빈 공간 클릭도 인식 + onTap: onTap, + behavior: HitTestBehavior.opaque, child: Container( height: double.infinity, alignment: Alignment.center, decoration: ShapeDecoration( - // 선택 시 배경색 적용, 미선택 시 투명 color: isSelected ? AppColors.primaryAble : Colors.transparent, shape: const StadiumBorder(), ), @@ -152,7 +127,6 @@ class LineGraph extends ConsumerWidget { label, textAlign: TextAlign.center, style: AppTypography.b2.copyWith( - // 선택 시 흰색, 미선택 시 검은색 color: isSelected ? Colors.white : AppColors.black, ), ), diff --git a/lib/features/statistics/widgets/line_graph/monthly_line_graph.dart b/lib/features/statistics/widgets/line_graph/monthly_line_graph.dart index 1b0aa5c..e2b10bb 100644 --- a/lib/features/statistics/widgets/line_graph/monthly_line_graph.dart +++ b/lib/features/statistics/widgets/line_graph/monthly_line_graph.dart @@ -1,12 +1,17 @@ // 최초 작성자: 김채영 import 'package:flutter/material.dart'; -import 'package:haenaem/core/theme/app_colors.dart'; -import 'package:haenaem/core/theme/app_typography.dart'; +import 'line_chart_grid.dart'; -// 4주간 챌린지 성공 추이 모델 +// ─────────────────────────────────────────────── +// 데이터 모델 +// ─────────────────────────────────────────────── + +/// 월간 그래프 데이터 모델 +/// - [thisMonth] : 이번 달 4주 데이터 (전전전주 → 이번주) +/// - [lastMonth] : 저번 달 4주 데이터 (전전전주 → 이번주) class WeeklyGraphData { - final List thisMonth; // 이번달 4주 데이터 - final List lastMonth; // 지난달 4주 데이터 + final List thisMonth; + final List lastMonth; const WeeklyGraphData({required this.thisMonth, required this.lastMonth}); @@ -18,192 +23,32 @@ class WeeklyGraphData { } } -// 4주 라인 그래프 위젯 +// ─────────────────────────────────────────────── +// 월간 꺾은선 그래프 위젯 +// ─────────────────────────────────────────────── + +/// 이번 달 vs 저번 달 4주 인증 추이를 꺾은선 그래프로 표시 class MonthlyLineGraph extends StatelessWidget { final WeeklyGraphData data; const MonthlyLineGraph({super.key, required this.data}); + static const _xLabels = ['첫째 주', '둘째 주', '셋째 주', '넷째 주']; + @override Widget build(BuildContext context) { - // Y축 최댓값 계산 (10 단위로 올림) final allValues = [...data.thisMonth, ...data.lastMonth]; - final maxValue = allValues.isEmpty + final rawMax = allValues.isEmpty ? 30 - : ((allValues.reduce((a, b) => a > b ? a : b) / 10).ceil() * 10).clamp( - 10, - 999, - ); - - final yLabels = [maxValue, (maxValue * 2 ~/ 3), (maxValue * 1 ~/ 3), 0]; - - const xLabels = ['전전전주', '전전주', '전주', '이번주']; - - return SizedBox( - width: double.infinity, - height: 164, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // 그래프 영역 - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - // Y축 레이블 - Padding( - padding: const EdgeInsets.symmetric(horizontal: 4), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.end, - children: yLabels - .map( - (label) => Text( - '$label', - style: const TextStyle( - color: Color(0xFF444444), - fontSize: 12, - fontFamily: 'Inter', - fontWeight: FontWeight.w400, - ), - ), - ) - .toList(), - ), - ), - - // 그래프 본체 - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 6), - child: CustomPaint( - painter: _LineGraphPainter( - thisMonth: data.thisMonth, - lastMonth: data.lastMonth, - maxValue: maxValue.toDouble(), - ), - ), - ), - ), - ], - ), - ), - - // X축 레이블 - Padding( - padding: const EdgeInsets.only(left: 24, bottom: 8), - child: Row( - children: xLabels - .map( - (label) => Expanded( - child: Text( - label, - textAlign: TextAlign.center, - style: const TextStyle( - color: Color(0xFF444444), - fontSize: 12, - fontFamily: 'Inter', - fontWeight: FontWeight.w400, - ), - ), - ), - ) - .toList(), - ), - ), - ], - ), + : allValues.reduce((a, b) => a > b ? a : b); + final yMax = ((rawMax / 10).ceil() * 10).clamp(10, 999).toDouble(); + + return LineChartGrid( + columnCount: 4, + xLabels: _xLabels, + yMax: yMax, + thisData: data.thisMonth, + lastData: data.lastMonth, ); } } - -class _LineGraphPainter extends CustomPainter { - final List thisMonth; - final List lastMonth; - final double maxValue; - - const _LineGraphPainter({ - required this.thisMonth, - required this.lastMonth, - required this.maxValue, - }); - - @override - void paint(Canvas canvas, Size size) { - _drawGrid(canvas, size); - if (lastMonth.length >= 4) - _drawLine(canvas, size, lastMonth, const Color(0xFFD9D9D9)); - if (thisMonth.length >= 4) - _drawLine(canvas, size, thisMonth, AppColors.primaryAble); - if (lastMonth.length >= 4) - _drawDots(canvas, size, lastMonth, const Color(0xFFD9D9D9)); - if (thisMonth.length >= 4) - _drawDots(canvas, size, thisMonth, AppColors.primaryAble); - } - - // 격자선 그리기 - void _drawGrid(Canvas canvas, Size size) { - final paint = Paint() - ..color = const Color(0xFFD9D9D9) - ..strokeWidth = 1; - - // 가로 격자선 4개 - for (int i = 0; i < 4; i++) { - final y = size.height * i / 3; - canvas.drawLine(Offset(0, y), Offset(size.width, y), paint); - } - - // 세로 격자선 5개 - for (int i = 0; i < 5; i++) { - final x = size.width * i / 4; - canvas.drawLine(Offset(x, 0), Offset(x, size.height), paint); - } - } - - // 라인 그리기 - void _drawLine(Canvas canvas, Size size, List values, Color color) { - final paint = Paint() - ..color = color - ..strokeWidth = 1.5 - ..style = PaintingStyle.stroke - ..strokeCap = StrokeCap.round - ..strokeJoin = StrokeJoin.round; - - final path = Path(); - for (int i = 0; i < 4; i++) { - final x = size.width * i / 3; - final y = size.height - (values[i] / maxValue) * size.height; - if (i == 0) { - path.moveTo(x, y); - } else { - path.lineTo(x, y); - } - } - canvas.drawPath(path, paint); - } - - // 데이터 포인트 점 그리기 - void _drawDots(Canvas canvas, Size size, List values, Color color) { - final outerPaint = Paint() - ..color = Colors.white - ..style = PaintingStyle.fill; - final borderPaint = Paint() - ..color = color - ..style = PaintingStyle.stroke - ..strokeWidth = 2; - - for (int i = 0; i < 4; i++) { - final x = size.width * i / 3; - final y = size.height - (values[i] / maxValue) * size.height; - canvas.drawCircle(Offset(x, y), 4, outerPaint); - canvas.drawCircle(Offset(x, y), 4, borderPaint); - } - } - - @override - bool shouldRepaint(covariant _LineGraphPainter oldDelegate) => - oldDelegate.thisMonth != thisMonth || - oldDelegate.lastMonth != lastMonth || - oldDelegate.maxValue != maxValue; -} diff --git a/lib/features/statistics/widgets/line_graph/weekly_line_graph.dart b/lib/features/statistics/widgets/line_graph/weekly_line_graph.dart index f350c67..8927567 100644 --- a/lib/features/statistics/widgets/line_graph/weekly_line_graph.dart +++ b/lib/features/statistics/widgets/line_graph/weekly_line_graph.dart @@ -1,99 +1,58 @@ -// // 최초 작성자: 김채영 -// import 'package:flutter/material.dart'; -// import 'package:haenaem/core/theme/app_colors.dart'; -// import 'package:haenaem/core/theme/app_typography.dart'; +// 최초 작성자: 김채영 +import 'package:flutter/material.dart'; +import 'package:haenaem/core/theme/app_colors.dart'; +import 'line_chart_grid.dart'; -// // 주간 데이터 모델 -// class DailyGraphData { -// final List thisWeek; -// final List lastWeek; -// const DailyGraphData({required this.thisWeek, required this.lastWeek}); -// } +// ─────────────────────────────────────────────── +// 데이터 모델 +// ─────────────────────────────────────────────── -// // 주간 라인 그래프 (7일 기준) -// class WeeklyLineGraph extends StatelessWidget { -// final DailyGraphData data; -// const WeeklyLineGraph({super.key, required this.data}); +/// 주간 그래프 데이터 모델 +/// - [thisWeek] : 이번 주 요일별 데이터 (월~일, 7개) +/// - [lastWeek] : 저번 주 요일별 데이터 (월~일, 7개) +class DailyGraphData { + final List thisWeek; + final List lastWeek; -// @override -// Widget build(BuildContext context) { -// final allValues = [...data.thisWeek, ...data.lastWeek]; -// final maxValue = allValues.isEmpty -// ? 10 -// : ((allValues.reduce((a, b) => a > b ? a : b) / 5).ceil() * 5) -// .toDouble(); + const DailyGraphData({required this.thisWeek, required this.lastWeek}); -// final yLabels = [ -// maxValue.toInt(), -// (maxValue * 2 ~/ 3), -// (maxValue * 1 ~/ 3), -// 0, -// ]; -// const xLabels = ['월', '화', '수', '목', '금', '토', '일']; + factory DailyGraphData.fromJson(Map json) { + return DailyGraphData( + thisWeek: List.from(json['thisWeek'] ?? List.filled(7, 0)), + lastWeek: List.from(json['lastWeek'] ?? List.filled(7, 0)), + ); + } +} -// return Column( -// children: [ -// Expanded( -// child: Row( -// children: [ -// _buildYAxis(yLabels), -// Expanded( -// child: CustomPaint( -// painter: _LineGraphPainter( -// thisPeriod: data.thisWeek, -// lastPeriod: data.lastWeek, -// maxValue: maxValue, -// pointCount: 7, // ✅ 점 7개 -// ), -// ), -// ), -// ], -// ), -// ), -// _buildXAxis(xLabels), -// ], -// ); -// } +// ─────────────────────────────────────────────── +// 주간 꺾은선 그래프 위젯 +// ─────────────────────────────────────────────── -// // Y축 레이블 빌더 (스타일 유지) -// Widget _buildYAxis(List labels) { -// return Padding( -// padding: const EdgeInsets.only(right: 8), -// child: Column( -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// crossAxisAlignment: CrossAxisAlignment.end, -// children: labels -// .map( -// (l) => Text( -// '$l', -// style: const TextStyle(color: Color(0xFF444444), fontSize: 12), -// ), -// ) -// .toList(), -// ), -// ); -// } +/// 이번 주 vs 저번 주 요일별 인증 추이를 꺾은선 그래프로 표시 +class WeeklyLineGraph extends StatelessWidget { + final DailyGraphData data; -// // X축 레이블 빌더 (스타일 유지) -// Widget _buildXAxis(List labels) { -// return Padding( -// padding: const EdgeInsets.only(left: 24, top: 8), -// child: Row( -// children: labels -// .map( -// (l) => Expanded( -// child: Text( -// l, -// textAlign: TextAlign.center, -// style: const TextStyle( -// color: Color(0xFF444444), -// fontSize: 12, -// ), -// ), -// ), -// ) -// .toList(), -// ), -// ); -// } -// } + const WeeklyLineGraph({super.key, required this.data}); + + static const _xLabels = ['월', '화', '수', '목', '금', '토', '일']; + + @override + Widget build(BuildContext context) { + final allValues = [...data.thisWeek, ...data.lastWeek]; + final rawMax = allValues.isEmpty + ? 5 + : allValues.reduce((a, b) => a > b ? a : b); + // 주간은 하루 최대 인증 수가 소수이므로 1 단위로 올림 + final yMax = ((rawMax / 5).ceil() * 5).clamp(5, 999).toDouble(); + + return LineChartGrid( + columnCount: 7, + rowCount: 5, + xLabels: _xLabels, + yMax: yMax, + thisData: data.thisWeek, + lastData: data.lastWeek, + labelColor: AppColors.gray1, + ); + } +} diff --git a/lib/features/statistics/widgets/pie_graph.dart b/lib/features/statistics/widgets/pie_graph.dart index 6861d1a..3f5494a 100644 --- a/lib/features/statistics/widgets/pie_graph.dart +++ b/lib/features/statistics/widgets/pie_graph.dart @@ -16,138 +16,117 @@ class TagCount { // 나의 해냄 분포 원형 그래프 class PieGraph extends StatelessWidget { - final List tagCounts; // 태그별 데이터 + final List top3; // 1~3위: 각각 색상으로 표시 + final List rest; // 4위~: 이름/횟수 각각 표시 (gray4 텍스트) + final int restCount; // 4위~ 합산 횟수 (파이 차트 gray4 조각용) final int totalCount; // 총 해냄 횟수 - // 그래프 색상 팔레트 - static const List defaultColors = [ - Color(0xFF8979FF), - Color(0xFFFF928A), - Color(0xFF3BC3DE), - Color(0xFFFFD166), - Color(0xFF06D6A0), - Color(0xFFEF476F), - ]; - const PieGraph({ super.key, - required this.tagCounts, + required this.top3, + required this.rest, + required this.restCount, required this.totalCount, }); + @override Widget build(BuildContext context) { - if (tagCounts.isEmpty) return const SizedBox.shrink(); + if (top3.isEmpty) return const SizedBox.shrink(); - // 상위 3개 + 나머지 - final top3 = tagCounts.take(3).toList(); - final rest = tagCounts.skip(3).toList(); + // 파이 차트용: top3 각각 + 나머지 합산 gray4 하나 + final pieData = [ + ...top3, + if (restCount > 0) + TagCount(tag: '기타', count: restCount, color: AppColors.gray4), + ]; return StatisticsCard( title: '나의 해냄 분포', child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, - spacing: 12, + spacing: 10, children: [ - // 2. 차트 + 태그 영역 - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 10, + // 원형 파이 차트 + Padding( + padding: const EdgeInsets.symmetric(horizontal: 60), + child: AspectRatio( + aspectRatio: 1, + child: CustomPaint( + // ✅ 파이 차트는 pieData (top3 + 기타 합산) 사용 + painter: _PieChartPainter(tagCounts: pieData), + ), + ), + ), + + // 총 N번 해냄! + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + spacing: 2, children: [ - // 파이 차트 + 총 해냄 텍스트 - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 10, - children: [ - // 원형 파이 차트 영역 - Padding( - padding: const EdgeInsets.symmetric(horizontal: 60), - child: AspectRatio( - aspectRatio: 1, // 정사각형 유지 (원형 그래프용) - child: CustomPaint( - painter: _PieChartPainter(tagCounts: tagCounts), - ), - ), - ), - - // 총 N번 해냄! - Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.end, - spacing: 2, - children: [ - Text( - '총', - style: AppTypography.b3.copyWith( - color: AppColors.black, - ), - ), - Text( - '$totalCount번', - style: AppTypography.h3.copyWith( - color: AppColors.primaryAble, - ), - ), - Text( - '해냄!', - style: AppTypography.b3.copyWith( - color: AppColors.black, - ), - ), - ], - ), - - // 상위 3개 태그 (큰 폰트) - if (top3.isNotEmpty) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 60), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: top3 - .map((tag) => _buildTopTagItem(tag)) - .toList(), - ), - ), - - // 나머지 태그 (작은 폰트) - if (rest.isNotEmpty) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 50), - child: Column( - spacing: 1, - children: rest - .map((tag) => _buildRestTagRow(tag)) - .toList(), - ), - ), - ], + Text( + '총', + style: AppTypography.b3.copyWith(color: AppColors.black), + ), + Text( + '$totalCount번', + style: AppTypography.h3.copyWith(color: AppColors.primaryAble), + ), + Text( + '해냄!', + style: AppTypography.b3.copyWith(color: AppColors.black), ), ], ), + + // 1~3위: 큰 폰트 + 각각의 색상 + Padding( + padding: const EdgeInsets.symmetric(horizontal: 60), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + // ✅ 텍스트는 top3 그대로 사용 + children: top3.map((tag) => _buildTopTagItem(tag)).toList(), + ), + ), + + // 4위~: 작은 회색 폰트 + 이름/횟수 각각 표시 + if (rest.isNotEmpty) + Padding( + padding: const EdgeInsets.symmetric(horizontal: 50), + child: Column( + spacing: 1, + // ✅ rest는 각각 따로 표시 + children: rest.map((tag) => _buildRestTagRow(tag)).toList(), + ), + ), ], ), ); } - // 상위 3개 태그 아이템 + // 1~3위 태그 아이템 Widget _buildTopTagItem(TagCount tag) { return Column( mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, // ✅ start → center spacing: 2, children: [ - Text(tag.tag, style: AppTypography.b1.copyWith(color: AppColors.gray2)), + Text( + tag.tag, + style: AppTypography.b1.copyWith(color: AppColors.gray2), + textAlign: TextAlign.center, // ✅ 추가 + ), Text( '${tag.count}번', style: AppTypography.h3.copyWith(color: tag.color), + textAlign: TextAlign.center, // ✅ 추가 ), ], ); } - // 나머지 태그 행 + // 4위~ 태그 행 Widget _buildRestTagRow(TagCount tag) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -176,14 +155,14 @@ class _PieChartPainter extends CustomPainter { if (total == 0) return; final center = Offset(size.width / 2, size.height / 2); - final radius = 85.33; + const radius = 85.33; final rect = Rect.fromCircle(center: center, radius: radius); double startAngle = -pi / 2; final paint = Paint()..style = PaintingStyle.fill; for (final tag in tagCounts) { - final sweepAngle = (tag.count / total) * (2 * pi); // 원 + final sweepAngle = (tag.count / total) * (2 * pi); paint.color = tag.color; canvas.drawArc(rect, startAngle, sweepAngle, true, paint); startAngle += sweepAngle; From cdb32fabb58209c38b2b91a8d6cba3b750c27dea Mon Sep 17 00:00:00 2001 From: Seungvin Date: Fri, 8 May 2026 18:55:25 +0900 Subject: [PATCH 117/134] =?UTF-8?q?fix:=20=EA=B8=B0=ED=83=80=20=ED=95=AD?= =?UTF-8?q?=EB=AA=A9=20=ED=82=A4=EA=B0=92=20=EC=98=A4=ED=83=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/report/screens/report_screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/features/report/screens/report_screen.dart b/lib/features/report/screens/report_screen.dart index c7153f1..85311d2 100644 --- a/lib/features/report/screens/report_screen.dart +++ b/lib/features/report/screens/report_screen.dart @@ -45,7 +45,7 @@ class _ReportScreenState extends ConsumerState { 'title': '명의 도용/사칭', 'desc': '타인을 사칭하거나 저작권을 침해하는 이미지 사용', }, - {'key': 'ECT', 'title': '기타 (직접 입력)', 'desc': '위 항목에 해당하지 않는 구체적인 사유'}, + {'key': 'ETC', 'title': '기타 (직접 입력)', 'desc': '위 항목에 해당하지 않는 구체적인 사유'}, ]; @override From f92b1d69bec42febba86567a5724bb3f6bec0482 Mon Sep 17 00:00:00 2001 From: Chaeyeong_10 Date: Wed, 13 May 2026 17:34:11 +0900 Subject: [PATCH 118/134] =?UTF-8?q?=EC=9E=84=EC=8B=9C=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/feed/data/feed_repository.dart | 34 +++++++++++++++++++ lib/features/feed/provider/feed_provider.dart | 9 +++++ pubspec.lock | 20 +++++------ 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/lib/features/feed/data/feed_repository.dart b/lib/features/feed/data/feed_repository.dart index 5552a96..9f1985c 100644 --- a/lib/features/feed/data/feed_repository.dart +++ b/lib/features/feed/data/feed_repository.dart @@ -1,5 +1,7 @@ import 'package:dio/dio.dart'; import 'package:haenaem/features/challenge/models/challenge_model.dart'; +import 'package:haenaem/shared/models/challenge_base.dart'; +import 'package:haenaem/shared/models/search_challenge_card.dart'; class FeedRepository { final Dio _dio; @@ -61,4 +63,36 @@ class FeedRepository { rethrow; } } + + // AI 챌린지 추천 카드 데이터 가져오기 + Future> getAiRecommendations() async { + try { + final response = await _dio.post('/api/v1/rag/recommend/discovery'); + + if (response.statusCode == 200) { + final List data = response.data; + return data.map((item) { + return SearchChallengeCard( + // 1. ChallengeBase 매핑 (id, title 포함) + base: ChallengeBase( + id: item['id'], + title: item['title'], + //isLeader: false, // 탐색 탭에서는 기본적으로 리더가 아님 + ), + // 2. 참여자 수 (API: participantNumber -> 모델: participantCount) + participantCount: item['participantNumber'] ?? 0, + // 3. D-Day (API 명세서에 구체적인 필드가 없으므로 임시로 0 처리) + dDay: 0, + // 4. 태그 (API: 객체 리스트 -> 모델: String 리스트) + tags: (item['tags'] as List) + .map((tagObj) => tagObj['tag'] as String) + .toList(), + ); + }).toList(); + } + throw Exception('AI 추천 로드 실패'); + } catch (e) { + throw Exception('네트워크 에러: $e'); + } + } } diff --git a/lib/features/feed/provider/feed_provider.dart b/lib/features/feed/provider/feed_provider.dart index 3b0596d..ba520d6 100644 --- a/lib/features/feed/provider/feed_provider.dart +++ b/lib/features/feed/provider/feed_provider.dart @@ -3,6 +3,7 @@ import 'package:dio/dio.dart'; import 'package:haenaem/features/feed/data/feed_repository.dart'; import 'package:haenaem/features/feed/models/feed_model.dart'; import 'package:haenaem/features/auth/services/auth_service.dart'; +import 'package:haenaem/shared/models/search_challenge_card.dart'; // 1. Repository Provider 추가 (Dio 객체는 별도의 공통 Provider에서 가져오는 것이 좋습니다) final feedRepositoryProvider = Provider((ref) { @@ -201,3 +202,11 @@ final memberFeedProvider = repository: repository, ); }); + +// AI 추천 챌린지 리스트를 관리하는 Provider +final aiRecommendationProvider = FutureProvider>(( + ref, +) { + final repository = ref.watch(feedRepositoryProvider); + return repository.getAiRecommendations(); +}); diff --git a/pubspec.lock b/pubspec.lock index a9aacd6..6be68a5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -245,10 +245,10 @@ packages: dependency: transitive description: name: characters - sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.4.0" checked_yaml: dependency: transitive description: @@ -993,26 +993,26 @@ packages: dependency: transitive description: name: matcher - sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.18" + version: "0.12.17" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.13.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.16.0" mime: dependency: transitive description: @@ -1398,10 +1398,10 @@ packages: dependency: transitive description: name: test_api - sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.9" + version: "0.7.6" timing: dependency: transitive description: From 90816a6bc8283b3653d6c0dbe831302f7cee4872 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Wed, 13 May 2026 21:49:30 +0900 Subject: [PATCH 119/134] =?UTF-8?q?fix:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EC=B0=BD=EC=9C=BC=EB=A1=9C=20=EA=B0=95=EC=A0=9C?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=ED=95=98=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0=20-=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=B0=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/core/network/dio_provider.dart | 46 +++++++++---------- .../auth/signup/screens/auth_gate.dart | 6 +++ 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/lib/core/network/dio_provider.dart b/lib/core/network/dio_provider.dart index 975987f..0fc2b42 100644 --- a/lib/core/network/dio_provider.dart +++ b/lib/core/network/dio_provider.dart @@ -31,47 +31,47 @@ Dio dio(DioRef ref) { return handler.next(options); }, onError: (DioException e, handler) async { - // 1. 401 에러(토큰 만료) 발생 시 if (e.response?.statusCode == 401) { - debugPrint( - '⚠️ [401 Detected] 토큰 만료됨. 재발급 시도 중... (Path: ${e.requestOptions.path})', - ); - const storage = FlutterSecureStorage(); final refreshToken = await storage.read(key: 'refreshToken'); - if (refreshToken != null) { try { + // 🎯 토큰 갱신 전용 가벼운 Dio 생성 (인터셉터 없음) final refreshDio = Dio( BaseOptions(baseUrl: e.requestOptions.baseUrl), ); - debugPrint('🔄 [Refresh] 리프레시 토큰으로 전송 중: $refreshToken'); - final response = await refreshDio.post( '/api/token', data: {"refreshToken": refreshToken}, ); - // 성공 시 로그 (여기에 새 토큰 저장 로직이 추가되어야 합니다) - debugPrint('✅ [Refresh Success] 새로운 토큰 발급 완료: ${response.data}'); + // 1. 서버 응답에서 새 토큰 추출 (백엔드 응답 키값에 맞게 수정하세요) + final newAccessToken = response.data['accessToken']; + final newRefreshToken = response.data['refreshToken']; - // TODO: 여기서 발급받은 새 토큰을 storage에 저장하고 - // 원래 실패했던 요청(e.requestOptions)을 다시 시도(dio.fetch)하는 로직이 필요합니다. - } catch (err) { - // 2. 재발급 과정에서 발생한 상세 에러 로그 - if (err is DioException) { - debugPrint( - '❌ [Refresh Failed] 상태 코드: ${err.response?.statusCode}', + // 2. 새 토큰 스토리지에 저장 + await storage.write(key: 'accessToken', value: newAccessToken); + if (newRefreshToken != null) { + await storage.write( + key: 'refreshToken', + value: newRefreshToken, ); - debugPrint('❌ [Refresh Failed] 서버 메시지: ${err.response?.data}'); - debugPrint('❌ [Refresh Failed] 에러 타입: ${err.type}'); - } else { - debugPrint('❌ [Refresh Failed] 알 수 없는 에러: $err'); } + + // 3. 실패했던 원래 요청의 헤더를 새 토큰으로 변경 + e.requestOptions.headers['Authorization'] = + 'Bearer $newAccessToken'; + + // 4. 원래 요청 재시도 및 결과 반환 + final retryResponse = await dio.fetch(e.requestOptions); + return handler.resolve(retryResponse); + } catch (err) { + // 재발급 실패 시: 토큰 찌꺼기 삭제 + debugPrint("재발급 실패! 저장된 토큰 삭제"); + await storage.deleteAll(); + return handler.next(e); } - } else { - debugPrint('🚫 [Refresh Aborted] 저장된 리프레시 토큰이 없습니다.'); } } return handler.next(e); diff --git a/lib/features/auth/signup/screens/auth_gate.dart b/lib/features/auth/signup/screens/auth_gate.dart index ac9f213..9671471 100644 --- a/lib/features/auth/signup/screens/auth_gate.dart +++ b/lib/features/auth/signup/screens/auth_gate.dart @@ -38,6 +38,12 @@ class AuthGate extends ConsumerWidget { ); } + // 💡 에러가 발생한 경우 (예: 토큰 만료 후 재발급 실패 등) -> 로그인 화면으로 + if (profileSnapshot.hasError) { + debugPrint("⚠️ 프로필 로드 실패 (에러): 로그인 화면으로 안내"); + return const LoginScreen(); + } + // 프로필 정보가 있고, 특정 필드(예: 태그)가 비어있다면 가입 미완료로 간주 final user = profileSnapshot.data; From 3f45a58e73fcc3c580f80fb1c61ac7718e22b1a8 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Wed, 13 May 2026 21:53:58 +0900 Subject: [PATCH 120/134] =?UTF-8?q?feat:=20dotenv=EB=A5=BC=20=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=ED=95=9C=20=ED=99=98=EA=B2=BD=20=EB=B3=80=EC=88=98=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 ++ lib/features/auth/services/auth_service.dart | 9 ++++---- lib/main.dart | 5 +++- pubspec.lock | 24 +++++++++++++------- pubspec.yaml | 2 ++ 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 3820a95..20c5693 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,5 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release + +.env \ No newline at end of file diff --git a/lib/features/auth/services/auth_service.dart b/lib/features/auth/services/auth_service.dart index a8d2b8a..051ea48 100644 --- a/lib/features/auth/services/auth_service.dart +++ b/lib/features/auth/services/auth_service.dart @@ -5,11 +5,13 @@ import 'dart:math'; import 'package:crypto/crypto.dart'; import 'package:flutter_appauth/flutter_appauth.dart'; import 'package:dio/dio.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; import '../../../core/network/dio_provider.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; // 토큰 저장을 위해 필요 import 'package:haenaem/features/auth/signup/screens/signup_main_screen.dart'; import 'package:haenaem/features/main/screens/main_screen.dart'; import 'package:kakao_flutter_sdk_user/kakao_flutter_sdk_user.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; // 구글 OAuth 2.0 기반의 사용자 인증과 JWT 토큰의 생명주기(발급, 재발급, 파기)를 전담하는 클래스 // 서버로부터 받은 userStatus(NEW/ACTIVE)를 분석하여 사용자별 맞춤형 초기 화면 진입 경로를 제어 @@ -18,15 +20,14 @@ class AuthService { static const _storage = FlutterSecureStorage(); // 보안 저장소 // 구글 설정 정보 - static const String androidClientId = - '433865217738-m3uqqdv9lumpf1ne8e3bkpsbtsa6919i.apps.googleusercontent.com'; + static String androidClientId = dotenv.env['GOOGLE_ANDROID_CLIENT_ID'] ?? ''; static const String customScheme = 'com.googleusercontent.apps.433865217738-m3uqqdv9lumpf1ne8e3bkpsbtsa6919i'; static const String redirectUri = '$customScheme:/oauth2redirect'; // 카카오 설정 정보 - static const String kakaoRestApiKey = '9fdd13c0777c415d8fa4055b5b26a6c5'; - static const String kakaoNativeAppKey = '05a36f172ea2945260862834654385ea'; + static String kakaoRestApiKey = dotenv.env['KAKAO_REST_API_KEY'] ?? ''; + static String kakaoNativeAppKey = dotenv.env['KAKAO_NATIVE_APP_KEY'] ?? ''; // static const String kakaoRedirectUri = // 'https://hanaem.onrender.com/api/oauth/kakao/token'; diff --git a/lib/main.dart b/lib/main.dart index a553fcf..6691b7b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,7 @@ // 최초 작성자: 김채영 import 'package:flutter/material.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:intl/date_symbol_data_local.dart'; @@ -17,6 +18,8 @@ import 'package:kakao_flutter_sdk_user/kakao_flutter_sdk_user.dart'; void main() async { // 플러터 엔진 초기화 확인 WidgetsFlutterBinding.ensureInitialized(); + // .env 파일 로드 + await dotenv.load(fileName: ".env"); // 전역 에러 핸들러 FlutterError.onError = (FlutterErrorDetails details) { @@ -47,7 +50,7 @@ void main() async { await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); // 카카오 SDK 초기화 - KakaoSdk.init(nativeAppKey: '05a36f172ea2945260862834654385ea'); + KakaoSdk.init(nativeAppKey: dotenv.get('KAKAO_NATIVE_APP_KEY')); runApp(const ProviderScope(child: MyApp())); } diff --git a/pubspec.lock b/pubspec.lock index bd8cb7d..ff68792 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -245,10 +245,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" checked_yaml: dependency: transitive description: @@ -534,6 +534,14 @@ packages: url: "https://pub.dev" source: hosted version: "11.0.0" + flutter_dotenv: + dependency: "direct main" + description: + name: flutter_dotenv + sha256: d41da11fb497314fbf89811ec30af02d1d898b47980a129f0a8c0a1720460ba2 + url: "https://pub.dev" + source: hosted + version: "6.0.1" flutter_launcher_icons: dependency: "direct main" description: @@ -1009,18 +1017,18 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.18" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.13.0" meta: dependency: transitive description: @@ -1414,10 +1422,10 @@ packages: dependency: transitive description: name: test_api - sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" url: "https://pub.dev" source: hosted - version: "0.7.7" + version: "0.7.9" timing: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 7d9ed8f..98130b5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -64,6 +64,7 @@ dependencies: cupertino_icons: ^1.0.8 google_sign_in: ^7.2.0 dio: ^5.9.1 + flutter_dotenv: ^6.0.1 dev_dependencies: flutter_test: @@ -95,6 +96,7 @@ flutter: - assets/images/illustrations/ - assets/images/placeholders/ - assets/images/ + - .env # - images/a_dot_burr.jpeg From 78d214cd13c7200d285d317fb51f2e6ac7560b70 Mon Sep 17 00:00:00 2001 From: Seungvin Date: Wed, 13 May 2026 22:52:06 +0900 Subject: [PATCH 121/134] =?UTF-8?q?feat:=20=EB=84=A4=EC=9D=B4=EB=B2=84=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/auth/login/login_screen.dart | 95 +++++++++++++++++++- lib/features/auth/services/auth_service.dart | 55 ++++++++++++ 2 files changed, 148 insertions(+), 2 deletions(-) diff --git a/lib/features/auth/login/login_screen.dart b/lib/features/auth/login/login_screen.dart index 1c605ea..69d74f2 100644 --- a/lib/features/auth/login/login_screen.dart +++ b/lib/features/auth/login/login_screen.dart @@ -136,8 +136,42 @@ class LoginScreen extends StatelessWidget { backgroundColor: const Color(0xFF03C75A), textColor: Colors.white, iconPath: 'assets/images/icons/naver_logo.svg', - onTap: navigateToSignup, - //onTap = () {}, + onTap: () async { + // 1. 상태(state) 문자열 생성 (카카오의 PKCE 함수를 재사용하여 임의의 문자열 15자리 생성) + final state = AuthService.generatePkcePair()['challenge']! + .substring(0, 15); + final authUrl = AuthService.getNaverAuthUrl(state); + String? naverAuthCode; + + if (!context.mounted) return; + + // 2. 카카오처럼 바텀시트로 네이버 웹뷰 실행 + await showModalBottomSheet( + context: context, + isScrollControlled: true, + useSafeArea: true, + backgroundColor: Colors.transparent, + builder: (ctx) => Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(ctx).viewInsets.bottom, + ), + child: _buildNaverWebView( + context: ctx, + authUrl: authUrl, + onCodeCaptured: (code) => naverAuthCode = code, + ), + ), + ); + + // 3. 획득한 코드가 있다면 백엔드로 전송 + if (naverAuthCode != null && context.mounted) { + await AuthService.sendNaverAuthToBackend( + code: naverAuthCode!, + state: state, + context: context, + ); + } + }, ), const SizedBox(height: 30), @@ -294,3 +328,60 @@ class LoginScreen extends StatelessWidget { ); } } + +Widget _buildNaverWebView({ + required BuildContext context, + required String authUrl, + required Function(String) onCodeCaptured, +}) { + late final WebViewController controller; + + controller = WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setUserAgent( + "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36", + ) + ..setNavigationDelegate( + NavigationDelegate( + onNavigationRequest: (NavigationRequest request) { + final url = request.url; + + // 📍 [핵심] 백엔드의 네이버 콜백 주소 감지 + if (url.contains('/oauth/naver/callback')) { + debugPrint('🎣 [감지 성공] 네이버 콜백 주소가 포착되었습니다!'); + final uri = Uri.parse(url); + final code = uri.queryParameters['code']; + + if (code != null) { + debugPrint('✅ 획득한 네이버 인가 코드: $code'); + onCodeCaptured(code); + Navigator.pop(context); // 웹뷰 닫기 + return NavigationDecision.prevent; // 리다이렉트 방지 + } + } + return NavigationDecision.navigate; + }, + onPageStarted: (url) { + // 이중 체크 (만약 onNavigationRequest에서 못 잡았을 경우) + if (url.startsWith(AuthService.naverRedirectUri)) { + final uri = Uri.parse(url); + final code = uri.queryParameters['code']; + if (code != null) { + onCodeCaptured(code); + Navigator.pop(context); + } + } + }, + ), + ) + ..loadRequest(Uri.parse(authUrl)); + + return Container( + height: MediaQuery.of(context).size.height * 0.9, + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.vertical(top: Radius.circular(20)), + ), + child: WebViewWidget(controller: controller), + ); +} diff --git a/lib/features/auth/services/auth_service.dart b/lib/features/auth/services/auth_service.dart index 051ea48..520c70d 100644 --- a/lib/features/auth/services/auth_service.dart +++ b/lib/features/auth/services/auth_service.dart @@ -37,6 +37,11 @@ class AuthService { //static const String kakaoRedirectUri = //'kakao9fdd13c0777c415d8fa4055b5b26a6c5://oauth'; + // 네이버 설정 정보 + static String naverClientId = dotenv.env['NAVER_CLIENT_ID'] ?? ''; + static const String naverRedirectUri = + 'http://158.247.216.11:8080/oauth/naver/callback'; + // ♥️ 기존 서버 static final Dio _dio = Dio( BaseOptions(baseUrl: 'http://158.247.216.11:8080'), @@ -53,6 +58,56 @@ class AuthService { // ), // ); + // ---------------------------------------- + // 네이버 로그인 함수 + // ---------------------------------------- + + // 3. 네이버 인증 URL 생성 (네이버는 CSRF 방지를 위해 state 파라미터가 필수입니다) + static String getNaverAuthUrl(String state) { + final clientId = naverClientId; + final redirectUri = Uri.encodeComponent(naverRedirectUri); + + return 'https://nid.naver.com/oauth2.0/authorize' + '?response_type=code' + '&client_id=$clientId' + '&redirect_uri=$redirectUri' + '&state=$state'; + } + + // 4. 네이버 인가 코드를 서버로 전송 + static Future sendNaverAuthToBackend({ + required String code, + required String state, + required BuildContext context, + }) async { + try { + debugPrint("🚀 서버로 네이버 인가 데이터 전송 시작..."); + + final response = await _dio.post( + '/api/oauth/naver/token', // 📍 이 주소가 맞는지 백엔드 팀과 꼭 확인하세요! + data: { + "code": code, + "state": state, // 네이버는 검증을 위해 state도 같이 보내는 경우가 많습니다. + "fcmToken": "", + }, + options: Options(contentType: Headers.jsonContentType), + ); + + debugPrint("📥 네이버 로그인 서버 응답 코드: ${response.statusCode}"); + + if (response.statusCode == 200 && response.data != null) { + await _handleAuthResponse(response.data, context); + } + } on DioException catch (e) { + debugPrint('🌐 네이버 서버 통신 에러: ${e.response?.statusCode}'); + debugPrint('내용: ${e.response?.data}'); + } + } + + // ---------------------------------------- + // 카카오 로그인 함수 + // ---------------------------------------- + // 1. PKCE 쌍 생성 (RFC 7636 표준 방식) static Map generatePkcePair() { // 1-1. Verifier 생성: 표준에 정의된 [A-Z, a-z, 0-9, -, ., _, ~] 문자만 사용 From 25d33488c17fc67101fcf6a06181d9cf5526fa28 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 14 May 2026 14:12:22 +0900 Subject: [PATCH 122/134] feat: pull origin branch --- .env | 4 + linux/flutter/generated_plugins.cmake | 1 - pubspec.lock | 156 +++++++++++------------- windows/flutter/generated_plugins.cmake | 1 - 4 files changed, 74 insertions(+), 88 deletions(-) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 0000000..635ddc5 --- /dev/null +++ b/.env @@ -0,0 +1,4 @@ +GOOGLE_ANDROID_CLIENT_ID=433865217738-m3uqqdv9lumpf1ne8e3bkpsbtsa6919i.apps.googleusercontent.com +KAKAO_NATIVE_APP_KEY=05a36f172ea2945260862834654385ea +KAKAO_REST_API_KEY=9fdd13c0777c415d8fa4055b5b26a6c5 +NAVER_CLIENT_ID=BS2Upg_v4LgwRoqmfvPf \ No newline at end of file diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index a9cc2e1..aae2b5c 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -10,7 +10,6 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST - jni ) set(PLUGIN_BUNDLED_LIBRARIES) diff --git a/pubspec.lock b/pubspec.lock index bd8cb7d..a0a2f92 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: bda3b7b55958bfd867addc40d067b4b11f7b8846d57671f5b5a6e7f9a56fe3ad + sha256: afe15ce18a287d2f89da95566e62892df339b1936bbe9b83587df45b944ee72a url: "https://pub.dev" source: hosted - version: "1.3.69" + version: "1.3.67" analyzer: dependency: transitive description: @@ -69,10 +69,10 @@ packages: dependency: transitive description: name: async - sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" url: "https://pub.dev" source: hosted - version: "2.13.1" + version: "2.13.0" audioplayers: dependency: "direct main" description: @@ -197,10 +197,10 @@ packages: dependency: transitive description: name: built_value - sha256: "34e4067d30ce212937df995f03b69992eea683539ceeac7f679a1f1eba055b56" + sha256: "6ae8a6435a8c6520c7077b107e77f1fb4ba7009633259a4d49a8afd8e7efc5e9" url: "https://pub.dev" source: hosted - version: "8.12.6" + version: "8.12.4" camera: dependency: "direct main" description: @@ -229,10 +229,10 @@ packages: dependency: transitive description: name: camera_platform_interface - sha256: "7ac852d77699acee79f0d438b793feee26721841e50973576419ff5c6d95e9b7" + sha256: "98cfc9357e04bad617671b4c1f78a597f25f08003089dd94050709ae54effc63" url: "https://pub.dev" source: hosted - version: "2.13.0" + version: "2.12.0" camera_web: dependency: transitive description: @@ -333,10 +333,10 @@ packages: dependency: "direct main" description: name: cupertino_icons - sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd" + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 url: "https://pub.dev" source: hosted - version: "1.0.9" + version: "1.0.8" custom_lint_core: dependency: transitive description: @@ -461,50 +461,50 @@ packages: dependency: transitive description: name: firebase_core - sha256: d5a94b884dcb1e6d3430298e94bfe002238094cdfd5e29202d536ee2120f9158 + sha256: f0997fee80fbb6d2c658c5b88ae87ba1f9506b5b37126db64fc2e75d8e977fbb url: "https://pub.dev" source: hosted - version: "4.7.0" + version: "4.5.0" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - sha256: "0ecda14c1bfc9ed8cac303dd0f8d04a320811b479362a9a4efb14fd331a473ce" + sha256: cccb4f572325dc14904c02fcc7db6323ad62ba02536833dddb5c02cac7341c64 url: "https://pub.dev" source: hosted - version: "6.0.3" + version: "6.0.2" firebase_core_web: dependency: transitive description: name: firebase_core_web - sha256: dc5096257cd67292d34d78ceeb90836f02a4be921b5f3934311a02bb2376118c + sha256: "856ca92bf2d75a63761286ab8e791bda3a85184c2b641764433b619647acfca6" url: "https://pub.dev" source: hosted - version: "3.6.0" + version: "3.5.0" firebase_messaging: dependency: "direct main" description: name: firebase_messaging - sha256: e5c93e8e7a9b0513f94bb684d2cf100e32e7dcdf2949574386b1955fc9a9b96a + sha256: bd17823b70e629877904d384841cda72ed2cc197517404c0c90da5c0ba786a8c url: "https://pub.dev" source: hosted - version: "16.2.0" + version: "16.1.2" firebase_messaging_platform_interface: dependency: transitive description: name: firebase_messaging_platform_interface - sha256: "8cbb7d842e5071bba836452aff262f7db4b14bb3a0d00c1896cf176df886d65a" + sha256: "550435235cc7d53683f32bf0762c28ef8cfc20a8d36318a033676ae09526d7fb" url: "https://pub.dev" source: hosted - version: "4.7.9" + version: "4.7.7" firebase_messaging_web: dependency: transitive description: name: firebase_messaging_web - sha256: "8750bacf50573c0383535fc3f9c58c6a2f9dff5320a16a82c30631b9dad894f1" + sha256: "6b1b93ed90309fbce91c219e3cd32aa831e8eccaf4a61f3afaea1625479275d2" url: "https://pub.dev" source: hosted - version: "4.1.5" + version: "4.1.3" fixnum: dependency: transitive description: @@ -567,10 +567,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "38d1c268de9097ff59cf0e844ac38759fc78f76836d37edad06fa21e182055a0" + sha256: ee8068e0e1cd16c4a82714119918efdeed33b3ba7772c54b5d094ab53f9b7fd1 url: "https://pub.dev" source: hosted - version: "2.0.34" + version: "2.0.33" flutter_riverpod: dependency: "direct main" description: @@ -583,18 +583,18 @@ packages: dependency: "direct main" description: name: flutter_secure_storage - sha256: "8b302d17096ba88f911b7eb317c71d5e691da60a259549f42b38c658d1776d87" + sha256: da922f2aab2d733db7e011a6bcc4a825b844892d4edd6df83ff156b09a9b2e40 url: "https://pub.dev" source: hosted - version: "10.1.0" + version: "10.0.0" flutter_secure_storage_darwin: dependency: transitive description: name: flutter_secure_storage_darwin - sha256: "3af15a3cb2bf5b8b776832bd01776f8018766aece55623176e28b406481fb320" + sha256: "8878c25136a79def1668c75985e8e193d9d7d095453ec28730da0315dc69aee3" url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "0.2.0" flutter_secure_storage_linux: dependency: transitive description: @@ -615,10 +615,10 @@ packages: dependency: transitive description: name: flutter_secure_storage_web - sha256: "073a62b3aeb866ab4ce795f960413948e51e5a42a9b0c8333b6daf5bb3208a1c" + sha256: "6a1137df62b84b54261dca582c1c09ea72f4f9a4b2fcee21b025964132d5d0c3" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.0" flutter_secure_storage_windows: dependency: transitive description: @@ -689,18 +689,18 @@ packages: dependency: transitive description: name: google_sign_in_android - sha256: be0d0733a6a7c5da165879d844a239aa87587a3c767a9163faedde581f731f76 + sha256: f353140580797e01c1f35748810326f326664c52040b6f62d88e7d6d1cd30917 url: "https://pub.dev" source: hosted - version: "7.2.10" + version: "7.2.9" google_sign_in_ios: dependency: transitive description: name: google_sign_in_ios - sha256: ac1e4c1205267cb7999d1d81333fccffdfda29e853f434bbaf71525498bb6950 + sha256: "234fc2830b55d1bbeb7e05662967691f5994143ff43dc70d3f139d1bbb3b8fb2" url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "6.2.5" google_sign_in_platform_interface: dependency: transitive description: @@ -785,18 +785,18 @@ packages: dependency: "direct main" description: name: image_picker - sha256: "91c025426c2881c551100bce834e201c835a170151545f58d17da5180ca7d9ac" + sha256: "784210112be18ea55f69d7076e2c656a4e24949fa9e76429fe53af0c0f4fa320" url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.2.1" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: d5b3e1774af29c9ab00103afb0d4614070f924d2e0057ac867ec98800114793f + sha256: eda9b91b7e266d9041084a42d605a74937d996b87083395c5e47835916a86156 url: "https://pub.dev" source: hosted - version: "0.8.13+17" + version: "0.8.13+14" image_picker_for_web: dependency: transitive description: @@ -809,10 +809,10 @@ packages: dependency: transitive description: name: image_picker_ios - sha256: b9c4a438a9ff4f60808c9cf0039b93a42bb6c2211ef6ebb647394b2b3fa84588 + sha256: "956c16a42c0c708f914021666ffcd8265dde36e673c9fa68c81f7d085d9774ad" url: "https://pub.dev" source: hosted - version: "0.8.13+6" + version: "0.8.13+3" image_picker_linux: dependency: transitive description: @@ -861,22 +861,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" - jni: - dependency: transitive - description: - name: jni - sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f - url: "https://pub.dev" - source: hosted - version: "1.0.0" - jni_flutter: - dependency: transitive - description: - name: jni_flutter - sha256: "8b59e590786050b1cd866677dddaf76b1ade5e7bc751abe04b86e84d379d3ba6" - url: "https://pub.dev" - source: hosted - version: "1.0.1" js: dependency: transitive description: @@ -1081,10 +1065,10 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "69cbd515a62b94d32a7944f086b2f82b4ac40a1d45bebfc00813a430ab2dabcd" + sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.2.22" path_provider_foundation: dependency: transitive description: @@ -1233,10 +1217,10 @@ packages: dependency: "direct main" description: name: share_plus - sha256: "223873d106614442ea6f20db5a038685cc5b32a2fba81cdecaefbbae0523f7fa" + sha256: "14c8860d4de93d3a7e53af51bff479598c4e999605290756bbbe45cf65b37840" url: "https://pub.dev" source: hosted - version: "12.0.2" + version: "12.0.1" share_plus_platform_interface: dependency: transitive description: @@ -1249,18 +1233,18 @@ packages: dependency: transitive description: name: shared_preferences - sha256: c3025c5534b01739267eb7d76959bbc25a6d10f6988e1c2a3036940133dd10bf + sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64" url: "https://pub.dev" source: hosted - version: "2.5.5" + version: "2.5.4" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: e8d4762b1e2e8578fc4d0fd548cebf24afd24f49719c08974df92834565e2c53 + sha256: "8374d6200ab33ac99031a852eba4c8eb2170c4bf20778b3e2c9eccb45384fb41" url: "https://pub.dev" source: hosted - version: "2.4.23" + version: "2.4.21" shared_preferences_foundation: dependency: transitive description: @@ -1281,10 +1265,10 @@ packages: dependency: transitive description: name: shared_preferences_platform_interface - sha256: "649dc798a33931919ea356c4305c2d1f81619ea6e92244070b520187b5140ef9" + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.1" shared_preferences_web: dependency: transitive description: @@ -1454,18 +1438,18 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "3bb000251e55d4a209aa0e2e563309dc9bb2befea2295fd0cec1f51760aac572" + sha256: "767344bf3063897b5cf0db830e94f904528e6dd50a6dfaf839f0abf509009611" url: "https://pub.dev" source: hosted - version: "6.3.29" + version: "6.3.28" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0" + sha256: cfde38aa257dae62ffe79c87fab20165dfdf6988c1d31b58ebf59b9106062aad url: "https://pub.dev" source: hosted - version: "6.4.1" + version: "6.3.6" url_launcher_linux: dependency: transitive description: @@ -1494,10 +1478,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "85c81589622fbc87c1c683aaea164d3604a7777495a79d91e39ffcdec39ddb34" + sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" url: "https://pub.dev" source: hosted - version: "2.4.3" + version: "2.4.1" url_launcher_windows: dependency: transitive description: @@ -1518,10 +1502,10 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "6409a25046024f0f8c5d8a59fec314081e81f9d436b66ca4015a8b49772bf445" + sha256: "7076216a10d5c390315fbe536a30f1254c341e7543e6c4c8a815e591307772b1" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.1.20" vector_graphics_codec: dependency: transitive description: @@ -1534,10 +1518,10 @@ packages: dependency: transitive description: name: vector_graphics_compiler - sha256: "06f0c50f88a1a020f95138dcc14ef4d5a039ced3f89b386209e6763dfa2cefa0" + sha256: "5a88dd14c0954a5398af544651c7fb51b457a2a556949bfb25369b210ef73a74" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.0" vector_math: dependency: transitive description: @@ -1550,10 +1534,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360" + sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" url: "https://pub.dev" source: hosted - version: "15.2.0" + version: "15.0.2" watcher: dependency: transitive description: @@ -1598,26 +1582,26 @@ packages: dependency: transitive description: name: webview_flutter_android - sha256: ad5182eff9a550925330cb9f0cb038eddfdd5712aba8b77aa0f0400e50f6e688 + sha256: "2a03df01df2fd30b075d1e7f24c28aee593f2e5d5ac4c3c4283c5eda63717b24" url: "https://pub.dev" source: hosted - version: "4.12.0" + version: "4.10.13" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface - sha256: "1221c1b12f5278791042f2ec2841743784cf25c5a644e23d6680e5d718824f04" + sha256: "63d26ee3aca7256a83ccb576a50272edd7cfc80573a4305caa98985feb493ee0" url: "https://pub.dev" source: hosted - version: "2.15.1" + version: "2.14.0" webview_flutter_wkwebview: dependency: transitive description: name: webview_flutter_wkwebview - sha256: "82648217f537573e1ca9ae9952d3eacedca6ab5aee69dc84445fc763766dcea2" + sha256: "2df8fd9ada04d699b9db8e79aa783a16e5d89b69e5b74009b87e16b59912cf98" url: "https://pub.dev" source: hosted - version: "3.25.1" + version: "3.24.0" win32: dependency: transitive description: @@ -1651,5 +1635,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.10.0 <4.0.0" - flutter: ">=3.38.0" + dart: ">=3.9.2 <4.0.0" + flutter: ">=3.35.0" diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index e93c7e2..2fad67b 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -12,7 +12,6 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST - jni ) set(PLUGIN_BUNDLED_LIBRARIES) From 92b8e92d6277f37b07e259ec23a300070f34c294 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 14 May 2026 15:01:02 +0900 Subject: [PATCH 123/134] feat: pull origin branch --- pubspec.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index f591097..6694b79 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -245,10 +245,10 @@ packages: dependency: transitive description: name: characters - sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.4.0" checked_yaml: dependency: transitive description: @@ -1001,18 +1001,18 @@ packages: dependency: transitive description: name: matcher - sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.18" + version: "0.12.17" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.13.0" + version: "0.11.1" meta: dependency: transitive description: @@ -1406,10 +1406,10 @@ packages: dependency: transitive description: name: test_api - sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 url: "https://pub.dev" source: hosted - version: "0.7.9" + version: "0.7.7" timing: dependency: transitive description: From be24a66805f5a10083fdb0d387dc400d637088c2 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Thu, 14 May 2026 23:43:08 +0900 Subject: [PATCH 124/134] =?UTF-8?q?fix:=20=ED=94=BC=EB=93=9C=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=EA=B8=80=20=ED=8C=9D=EC=97=85=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20=EC=95=88=20=EB=9C=A8=EB=8A=94=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/feed/widgets/post_popup_menu.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/features/feed/widgets/post_popup_menu.dart b/lib/features/feed/widgets/post_popup_menu.dart index 76e744c..4f5af99 100644 --- a/lib/features/feed/widgets/post_popup_menu.dart +++ b/lib/features/feed/widgets/post_popup_menu.dart @@ -1,4 +1,5 @@ // 최초 작성자 : 강선욱 +import 'package:haenaem/features/user/data/user_repository.dart'; import 'package:intl/intl.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -15,6 +16,7 @@ import '../provider/post_detail_provider.dart'; import 'package:haenaem/features/challenge/verification/screens/challenge_verification_screen.dart'; import 'package:haenaem/features/report/screens/report_screen.dart'; import 'package:haenaem/features/report/provider/report_provider.dart'; +import 'package:haenaem/features/user/provider/user_provider.dart'; // 인증글 다이얼로그 (내 인증글일 경우와 타인의 인증글일 경우) class PostPopupMenu extends ConsumerWidget { @@ -23,11 +25,11 @@ class PostPopupMenu extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - // 1. 현재 로그인한 내 프로필 정보를 가져옵니다. - //final myProfileAsync = ref.watch(myProfileProvider); + // 1. user 전역값 가져오기 + final currentUser = ref.watch(currentUserProvider); // 2. 내 닉네임과 게시글 작성자 닉네임을 비교하여 '내 글' 여부 판단 - final bool isMine = post.isAuthor; + final bool isMine = (post.writer.id == currentUser?.id); // 2. [날짜 체크] 오늘 날짜 문자열(yyyy-MM-dd) 생성 final String todayStr = DateFormat('yyyy-MM-dd').format(DateTime.now()); From 6a9ee3893df26948526400993b13c00f4d2f324f Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Mon, 18 May 2026 10:53:20 +0900 Subject: [PATCH 125/134] =?UTF-8?q?refactor:=20=EC=95=88=20=EC=93=B0?= =?UTF-8?q?=EB=8A=94=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/widgets/MockData.dart | 190 ------------------ .../challenge/widgets/UserChallengeData.dart | 85 -------- 2 files changed, 275 deletions(-) delete mode 100644 lib/features/challenge/widgets/MockData.dart delete mode 100644 lib/features/challenge/widgets/UserChallengeData.dart diff --git a/lib/features/challenge/widgets/MockData.dart b/lib/features/challenge/widgets/MockData.dart deleted file mode 100644 index 2dacc01..0000000 --- a/lib/features/challenge/widgets/MockData.dart +++ /dev/null @@ -1,190 +0,0 @@ -// 최초 작성자 : 강선욱 -import 'package:haenaem/features/challenge/widgets/UserChallengeData.dart'; - -String imgUrl = "assets/images/testImage.jpg"; - -class MockData { - /// 특정 챌린지 이름을 기반으로 데이터를 찾아주는 함수 - static UserChallengeData getChallengeByName(String name) { - return getAllChallenges().firstWhere( - (element) => element.challengeName == name, - orElse: () => getAllChallenges().first, - ); - } - - /// 모든 챌린지 데이터를 반환 - static List getAllChallenges() { - return [_getRunningData(), _getStudyData(), _getCodingData()]; - } - - // --- 1. 매일 10분 러닝 (김해냄: 12회 인증, 5일 연속) --- - static UserChallengeData _getRunningData() { - return UserChallengeData( - challengeName: "졸업 프로젝트 코딩", - isHost: false, - totalCertCount: 12, - continuousCertCount: 5, - posts: [ - CertificationPost( - userName: "김해냄", - content: "sprint2가 끝났네요. 확실히 초반보다 코딩 속도가 붙는 것 같아요.", - date: DateTime(2026, 1, 20, 07, 30), - hasImage: true, - imageUrl: imgUrl, - likeCount: 24, // 최신글 좋아요 24개 - comments: [ - ChallengeComment( - id: "rc_1", - userName: "러닝메이트", - userBadge: "열정러너", - content: "팀원들 모두 끝까지 포기하지 마세요! 💻", - createdAt: DateTime(2026, 1, 20, 08, 05), - ), - ChallengeComment( - id: "rc_2", - userName: "비타민", - userBadge: "응원대장", - content: "연속 5일 인증 축하드려요! 불꽃 아이콘 너무 멋져요🔥", - createdAt: DateTime(2026, 1, 20, 08, 30), - ), - ChallengeComment( - id: "rc_3", - userName: "새벽반", - userBadge: "얼리버드", - content: "오늘 날씨 꽤 쌀쌀한데 고생하셨습니다!", - createdAt: DateTime(2026, 1, 20, 09, 10), - ), - ], - ), - CertificationPost( - content: "11일차 인증. 월요일 아침 성공!", - date: DateTime(2026, 1, 19, 07, 10), - hasImage: true, - imageUrl: imgUrl, - likeCount: 15, - ), - CertificationPost( - content: "10일차 인증. 인증하기 기능 구현 완료.", - date: DateTime(2026, 1, 18, 08, 45), - hasImage: true, - imageUrl: imgUrl, - likeCount: 12, - ), - CertificationPost( - content: "9일차 인증. 페이스 조절 중입니다.", - date: DateTime(2026, 1, 17, 07, 30), - hasImage: false, - likeCount: 8, - ), - CertificationPost( - content: "8일차 인증. 새로운 버그 발견!", - date: DateTime(2026, 1, 16, 07, 00), - hasImage: true, - imageUrl: imgUrl, - likeCount: 11, - ), - CertificationPost( - content: "7일차 인증. 일주일 달성 뿌듯하네요.", - date: DateTime(2026, 1, 15, 07, 20), - hasImage: true, - imageUrl: imgUrl, - likeCount: 20, - ), - CertificationPost( - content: "6일차 인증. 오늘은 가볍게 2시간만 코딩.", - date: DateTime(2026, 1, 14, 07, 50), - hasImage: false, - likeCount: 6, - ), - CertificationPost( - content: "5일차 인증. 습관이 되어가네요.", - date: DateTime(2026, 1, 13, 06, 30), - hasImage: true, - imageUrl: imgUrl, - likeCount: 14, - ), - CertificationPost( - content: "4일차 인증. 추위을 뚫고 카페에서 코딩!", - date: DateTime(2026, 1, 12, 07, 15), - hasImage: true, - imageUrl: imgUrl, - likeCount: 9, - ), - CertificationPost( - content: "3일차 인증. 작심삼일 고비 완료.", - date: DateTime(2026, 1, 11, 08, 00), - hasImage: false, - likeCount: 7, - ), - CertificationPost( - content: "2일차 인증. 상쾌한 아침 공기.", - date: DateTime(2026, 1, 10, 07, 30), - hasImage: true, - imageUrl: imgUrl, - likeCount: 13, - ), - CertificationPost( - content: "1일차 인증. 오늘부터 시작합니다!", - date: DateTime(2026, 1, 9, 07, 40), - hasImage: true, - imageUrl: imgUrl, - likeCount: 18, - ), - ], - ); - } - - // --- 2. 모각공 (김해냄: 8회 인증) --- - static UserChallengeData _getStudyData() { - return UserChallengeData( - challengeName: "모각공", - isHost: false, - totalCertCount: 8, - continuousCertCount: 2, - posts: List.generate(8, (index) { - int day = 19 - index; - return CertificationPost( - userName: "김해냄", - content: "${8 - index}회차 공부 인증입니다. 오늘도 집중 성공!", - date: DateTime(2026, 1, day, 15, 00), - hasImage: index % 2 == 0, - imageUrl: index % 2 == 0 ? imgUrl : null, - likeCount: 5 + (index * 3), // 좋아요 수 데이터 추가 - comments: index == 0 - ? [ - ChallengeComment( - id: "sc_1", - userName: "공부벌레", - userBadge: "독서실지기", - content: "열공하시네요! 화이팅입니다.", - createdAt: DateTime(2026, 1, 19, 16, 20), - ), - ] - : [], - ); - }), - ); - } - - // --- 3. 모각코 (김해냄 : 20회 인증, 방장) --- - static UserChallengeData _getCodingData() { - return UserChallengeData( - challengeName: "모각코", - isHost: true, - totalCertCount: 20, - continuousCertCount: 10, - posts: List.generate(20, (index) { - int day = 20 - index; - return CertificationPost( - userName: "김해냄", - content: "${20 - index}회차 코딩 인증. 데이터 모델링 작업 중입니다.", - date: DateTime(2026, 1, day, 23, 00), - hasImage: index < 5, // 최근 5개만 이미지 있음 - imageUrl: index < 5 ? imgUrl : null, - likeCount: (index == 0) ? 32 : (20 - index) * 2, // 최신글은 32개, 나머지는 계산식 - comments: [], - ); - }), - ); - } -} diff --git a/lib/features/challenge/widgets/UserChallengeData.dart b/lib/features/challenge/widgets/UserChallengeData.dart deleted file mode 100644 index d6db355..0000000 --- a/lib/features/challenge/widgets/UserChallengeData.dart +++ /dev/null @@ -1,85 +0,0 @@ -// 최초 작성자 : 강선욱 -/// 사용자의 챌린지 전체 현황 및 인증글 데이터를 담는 모델 -class UserChallengeData { - final String challengeName; // 챌린지 이름 - final bool isHost; - final int totalCertCount; // 인증 완료 일수 - final int continuousCertCount; // 인증 연속 일수 - final List posts; // 인증글 리스트 - - UserChallengeData({ - required this.challengeName, - required this.isHost, - required this.totalCertCount, - required this.continuousCertCount, - required this.posts, - }); - - /// 1. 최신순으로 정렬된 인증글 리스트 반환 - List get sortedPosts { - // 원본 리스트를 보존하기 위해 복사본을 정렬하여 반환합니다. - return List.from(posts)..sort((a, b) => b.date.compareTo(a.date)); - } - - /// 2. 특정 연도와 월에 해당하는 인증글만 필터링 (캘린더용) - List getPostsByMonth(int year, int month) { - return posts.where((post) { - return post.date.year == year && post.date.month == month; - }).toList(); - } - - /// 3. 특정 날짜(일)에 딱 맞는 인증글 찾기 (캘린더 클릭용) - /// 해당 날짜에 글이 없으면 null을 반환합니다. - CertificationPost? getPostByDay(DateTime day) { - final filtered = posts.where( - (post) => - post.date.year == day.year && - post.date.month == day.month && - post.date.day == day.day, - ); - - return filtered.isEmpty ? null : filtered.first; - } -} - -/// 개별 인증글 상세 정보 모델 -class CertificationPost { - final String? userName; // 작성자 이름 (피드 화면에서 필요) - final String content; // 인증글 내용 - final DateTime date; // 인증글 날짜 - final bool hasImage; // 인증글 사진 유무 - final String? imageUrl; // (선택) 사진이 있다면 이미지 경로 - final int likeCount; // 인증글 좋아요 수 - final List comments; // 해당 글에 달린 댓글 리스트 - - CertificationPost({ - this.userName = "김해냄", // 기본값 설정 가능 - required this.content, - required this.date, - required this.hasImage, - this.imageUrl, - required this.likeCount, - this.comments = const [], // 초기값은 빈 리스트 - }); -} - -/// 댓글 정보 모델 -class ChallengeComment { - final String id; // 댓글 고유 ID - final String userName; // 작성자 이름 (예: 김코딩) - final String userBadge; // 작성자 칭호/배지 (예: 올빼미) - final String? profileUrl; // 프로필 이미지 경로 (Asset) - final String content; // 댓글 내용 - final DateTime createdAt; // 작성일시 - final bool isMyComment; // 본인 댓글 여부 (수정/삭제 권한 분기용) - - ChallengeComment({ - required this.id, - required this.userName, - required this.userBadge, - this.profileUrl, - required this.content, - required this.createdAt, - this.isMyComment = false, - }); -} From 617763870f2438bd929bb56a7495fdd25496605e Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Mon, 18 May 2026 10:58:09 +0900 Subject: [PATCH 126/134] =?UTF-8?q?fix:=20api=EC=97=90=EC=84=9C=20title?= =?UTF-8?q?=EA=B0=92=EC=9D=84=20=EC=A3=BC=EA=B8=B0=20=EB=95=8C=EB=AC=B8?= =?UTF-8?q?=EC=97=90=20=ED=94=84=EB=A1=A0=ED=8A=B8=EC=97=90=EC=84=9C=20tit?= =?UTF-8?q?le=EA=B0=92=EC=9D=84=20=EB=A7=8C=EB=93=9C=EB=8A=94=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=EC=9D=80=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/feed/widgets/feed_post_card.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/features/feed/widgets/feed_post_card.dart b/lib/features/feed/widgets/feed_post_card.dart index 1b2952e..5b538ae 100644 --- a/lib/features/feed/widgets/feed_post_card.dart +++ b/lib/features/feed/widgets/feed_post_card.dart @@ -98,7 +98,7 @@ class FeedPostCard extends ConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '${post.title} ${post.totalSuccessDays}일차', + post.title, style: AppTypography.b3.copyWith(color: AppColors.black), ), const SizedBox(height: 4), // 간격 추가 From 16061d14987140bb570623f105b957ac162e0015 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Mon, 18 May 2026 10:59:46 +0900 Subject: [PATCH 127/134] =?UTF-8?q?feat:=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=EC=A0=95=EB=B3=B4=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feed/widgets/post_popup_menu.dart | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/features/feed/widgets/post_popup_menu.dart b/lib/features/feed/widgets/post_popup_menu.dart index 4f5af99..bbb8922 100644 --- a/lib/features/feed/widgets/post_popup_menu.dart +++ b/lib/features/feed/widgets/post_popup_menu.dart @@ -17,6 +17,7 @@ import 'package:haenaem/features/challenge/verification/screens/challenge_verifi import 'package:haenaem/features/report/screens/report_screen.dart'; import 'package:haenaem/features/report/provider/report_provider.dart'; import 'package:haenaem/features/user/provider/user_provider.dart'; +import 'package:haenaem/shared/screens/challenge_detail_screen.dart'; // 인증글 다이얼로그 (내 인증글일 경우와 타인의 인증글일 경우) class PostPopupMenu extends ConsumerWidget { @@ -25,6 +26,15 @@ class PostPopupMenu extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + // 💡 Post 객체 내부 데이터 상태 확인용 로그 + debugPrint('--- [Post Data Check] ---'); + debugPrint('Post ID: ${post.id}'); + debugPrint('Challenge ID: ${post.challengeId}'); // 0이 나온다면 매핑 오류 확률 99% + debugPrint('Challenge Title: ${post.challengeTitle}'); + debugPrint('Writer ID: ${post.writer.id}'); + debugPrint('Post Date: ${post.date}'); + debugPrint('--------------------------'); + // 1. user 전역값 가져오기 final currentUser = ref.watch(currentUserProvider); @@ -219,15 +229,22 @@ class PostPopupMenu extends ConsumerWidget { break; case 'view_challenge': - // TODO: 챌린지 상세(소개) 페이지로 이동하거나 탭을 전환하는 로직 - debugPrint('🚀 [Action] 챌린지 보기 클릭'); - // TODO: Navigator.push(...) 혹은 현재 탭 전환 로직 추가 + debugPrint('보내는 ID: ${post.challengeId}'); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ChallengeDetailScreen( + // post 객체 내에 저장된 challenge 관련 정보를 전달합니다. + challengeId: post.challengeId, + challengeTitle: post.challengeTitle, + ), + ), + ); + + debugPrint( + '🚀 [Action] ChallengeDetailScreen으로 이동 (ID: ${post.challengeId})', + ); break; - // case 'complain': - // ScaffoldMessenger.of( - // context, - // ).showSnackBar(const SnackBar(content: Text("신고가 접수되었습니다."))); - // break; case 'report': Navigator.push( context, From 8e8131934d6d559bda0bf4189154c9ade1caa391 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Mon, 18 May 2026 11:04:31 +0900 Subject: [PATCH 128/134] =?UTF-8?q?refactor:=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EB=B0=8F=20=EC=9E=84=ED=8F=AC=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../widgets/notification_settings_dialog.dart} | 0 .../verification/screens/challenge_verification_screen.dart | 2 +- .../widgets/verification_cancel_dialog.dart | 0 lib/features/feed/screens/challenge_search_screen.dart | 2 -- lib/features/feed/widgets/challenge_search_card.dart | 2 +- .../feed => shared}/screens/challenge_detail_screen.dart | 4 ++-- 6 files changed, 4 insertions(+), 6 deletions(-) rename lib/features/challenge/{widgets/NotificationSettingsDialog.dart => detail/widgets/notification_settings_dialog.dart} (100%) rename lib/features/challenge/{ => verification}/widgets/verification_cancel_dialog.dart (100%) rename lib/{features/feed => shared}/screens/challenge_detail_screen.dart (97%) diff --git a/lib/features/challenge/widgets/NotificationSettingsDialog.dart b/lib/features/challenge/detail/widgets/notification_settings_dialog.dart similarity index 100% rename from lib/features/challenge/widgets/NotificationSettingsDialog.dart rename to lib/features/challenge/detail/widgets/notification_settings_dialog.dart diff --git a/lib/features/challenge/verification/screens/challenge_verification_screen.dart b/lib/features/challenge/verification/screens/challenge_verification_screen.dart index 7d39180..df6f31a 100644 --- a/lib/features/challenge/verification/screens/challenge_verification_screen.dart +++ b/lib/features/challenge/verification/screens/challenge_verification_screen.dart @@ -24,7 +24,7 @@ import '../widgets/ai_success_box.dart'; import '../widgets/ai_fail_box.dart'; import 'package:haenaem/features/challenge/verification/widgets/reverification_guide_box.dart'; import '../widgets/verification_submit_button.dart'; -import 'package:haenaem/features/challenge/widgets/verification_cancel_dialog.dart'; +import 'package:haenaem/features/challenge/verification/widgets/verification_cancel_dialog.dart'; // 챌린지 인증하기 화면 class ChallengeVerificationScreen extends ConsumerStatefulWidget { diff --git a/lib/features/challenge/widgets/verification_cancel_dialog.dart b/lib/features/challenge/verification/widgets/verification_cancel_dialog.dart similarity index 100% rename from lib/features/challenge/widgets/verification_cancel_dialog.dart rename to lib/features/challenge/verification/widgets/verification_cancel_dialog.dart diff --git a/lib/features/feed/screens/challenge_search_screen.dart b/lib/features/feed/screens/challenge_search_screen.dart index 5fe0a35..ce3ab92 100644 --- a/lib/features/feed/screens/challenge_search_screen.dart +++ b/lib/features/feed/screens/challenge_search_screen.dart @@ -3,13 +3,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:haenaem/features/feed/screens/challenge_detail_screen.dart'; // 챌린지 소개 화면 뷰 재활용 import 'package:flutter_riverpod/flutter_riverpod.dart'; //import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; // import 'package:haenaem/features/challenge/models/challenge_model.dart'; // import 'package:haenaem/features/user/models/user_model.dart'; import '../provider/challenge_search_provider.dart'; -import 'package:haenaem/shared/models/search_challenge_card.dart'; import '../widgets/challenge_search_card.dart'; import 'package:haenaem/shared/models/user.dart'; import 'package:haenaem/features/user/provider/user_provider.dart'; diff --git a/lib/features/feed/widgets/challenge_search_card.dart b/lib/features/feed/widgets/challenge_search_card.dart index 6e95814..fa4dfb1 100644 --- a/lib/features/feed/widgets/challenge_search_card.dart +++ b/lib/features/feed/widgets/challenge_search_card.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:haenaem/features/feed/screens/challenge_detail_screen.dart'; +import 'package:haenaem/shared/screens/challenge_detail_screen.dart'; import 'package:haenaem/shared/models/search_challenge_card.dart'; // 모델 임포트 class ChallengeSearchCard extends StatelessWidget { diff --git a/lib/features/feed/screens/challenge_detail_screen.dart b/lib/shared/screens/challenge_detail_screen.dart similarity index 97% rename from lib/features/feed/screens/challenge_detail_screen.dart rename to lib/shared/screens/challenge_detail_screen.dart index 63ed2f2..6adb946 100644 --- a/lib/features/feed/screens/challenge_detail_screen.dart +++ b/lib/shared/screens/challenge_detail_screen.dart @@ -5,7 +5,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; // import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; -import '../provider/challenge_participate_provider.dart'; +import '../../features/feed/provider/challenge_participate_provider.dart'; import 'package:haenaem/shared/provider/challenge_detail_provider.dart'; import 'package:haenaem/shared/widgets/challenge_detail_content.dart'; import 'package:haenaem/features/feed/widgets/enter_confirm_dialog.dart'; @@ -60,7 +60,7 @@ class _ChallengeDetailScreenState extends ConsumerState { onPressed: () => Navigator.pop(context), ), title: Text( - "챌린지 상세정보", + widget.challengeTitle, style: AppTypography.h3.copyWith(color: AppColors.black), ), centerTitle: true, From 0ca79a7163a4a8f08a1cd0e5b52986ffb9d83dfa Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 19 May 2026 19:22:54 +0900 Subject: [PATCH 129/134] =?UTF-8?q?refactor:=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/detail/widgets/challenge_popup_menu.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/features/challenge/detail/widgets/challenge_popup_menu.dart b/lib/features/challenge/detail/widgets/challenge_popup_menu.dart index 6c20b88..10ece9b 100644 --- a/lib/features/challenge/detail/widgets/challenge_popup_menu.dart +++ b/lib/features/challenge/detail/widgets/challenge_popup_menu.dart @@ -6,7 +6,7 @@ import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/features/challenge/invite/screens/challenge_invite_screen.dart'; import 'package:haenaem/features/challenge/detail/widgets/exit_confirm_dialog.dart'; -import 'package:haenaem/features/challenge/widgets/NotificationSettingsDialog.dart'; +import 'package:haenaem/features/challenge/detail/widgets/notification_settings_dialog.dart'; import 'package:haenaem/features/challenge/settings/screens/challenge_settings_screen.dart'; // import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; // 추가 import '../provider/challenge_leave_provider.dart'; From a977178f65811feea572c374b0005aadf10be7b5 Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 19 May 2026 22:18:41 +0900 Subject: [PATCH 130/134] =?UTF-8?q?refactor:=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../widgets/notification_settings_dialog.dart} | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) rename lib/features/challenge/{widgets/NotificationSettingsDialog.dart => detail/widgets/notification_settings_dialog.dart} (98%) diff --git a/lib/features/challenge/widgets/NotificationSettingsDialog.dart b/lib/features/challenge/detail/widgets/notification_settings_dialog.dart similarity index 98% rename from lib/features/challenge/widgets/NotificationSettingsDialog.dart rename to lib/features/challenge/detail/widgets/notification_settings_dialog.dart index 868c624..eb45b65 100644 --- a/lib/features/challenge/widgets/NotificationSettingsDialog.dart +++ b/lib/features/challenge/detail/widgets/notification_settings_dialog.dart @@ -77,7 +77,12 @@ class _NotificationSettingsDialogState "전체 알림", "모든 알림 받기", allNotifications, - (val) => setState(() => allNotifications = val), + (val) => setState(() { + allNotifications = val; + dailyReminder = val; + mateReaction = val; + mateVerification = val; + }), ), _buildDailyReminderSection(), _buildSwitchRow( From a57945877b049e4766ff6cf9f9cfd6aa1caf507f Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 19 May 2026 22:19:03 +0900 Subject: [PATCH 131/134] =?UTF-8?q?feat:=20=EC=A0=84=EC=B2=B4=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=ED=86=A0=EA=B8=80=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/features/challenge/detail/widgets/challenge_popup_menu.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/features/challenge/detail/widgets/challenge_popup_menu.dart b/lib/features/challenge/detail/widgets/challenge_popup_menu.dart index 6c20b88..10ece9b 100644 --- a/lib/features/challenge/detail/widgets/challenge_popup_menu.dart +++ b/lib/features/challenge/detail/widgets/challenge_popup_menu.dart @@ -6,7 +6,7 @@ import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:haenaem/features/challenge/invite/screens/challenge_invite_screen.dart'; import 'package:haenaem/features/challenge/detail/widgets/exit_confirm_dialog.dart'; -import 'package:haenaem/features/challenge/widgets/NotificationSettingsDialog.dart'; +import 'package:haenaem/features/challenge/detail/widgets/notification_settings_dialog.dart'; import 'package:haenaem/features/challenge/settings/screens/challenge_settings_screen.dart'; // import 'package:haenaem/features/challenge/provider/challenge_provider.dart'; // 추가 import '../provider/challenge_leave_provider.dart'; From 7c18e872f5c63926dfb72ae34eafa8d4c02f32bf Mon Sep 17 00:00:00 2001 From: sunwook <117016927+nuk0325@users.noreply.github.com> Date: Tue, 19 May 2026 22:35:10 +0900 Subject: [PATCH 132/134] =?UTF-8?q?feat:=20=EC=A0=84=EC=B2=B4=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=ED=86=A0=EA=B8=80=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../widgets/notification_settings_dialog.dart | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/lib/features/challenge/detail/widgets/notification_settings_dialog.dart b/lib/features/challenge/detail/widgets/notification_settings_dialog.dart index eb45b65..9aee8a0 100644 --- a/lib/features/challenge/detail/widgets/notification_settings_dialog.dart +++ b/lib/features/challenge/detail/widgets/notification_settings_dialog.dart @@ -89,13 +89,27 @@ class _NotificationSettingsDialogState "메이트 반응 소식", "다른 참여자들이 내 인증글에 반응 시 알림", mateReaction, - (val) => setState(() => mateReaction = val), + (val) => setState(() { + mateReaction = val; + if (!val) { + allNotifications = false; + } else if (dailyReminder && mateVerification) { + allNotifications = true; + } + }), ), _buildSwitchRow( "메이트 인증 소식", "다른 참여자들이 인증 완료 시 알림", mateVerification, - (val) => setState(() => mateVerification = val), + (val) => setState(() { + mateVerification = val; + if (!val) { + allNotifications = false; + } else if (dailyReminder && mateReaction) { + allNotifications = true; + } + }), ), const SizedBox(height: 24), @@ -134,7 +148,7 @@ class _NotificationSettingsDialogState String title, String subtitle, bool value, - ValueChanged onChanged, + ValueChanged? onChanged, ) { return Padding( padding: const EdgeInsets.symmetric(vertical: 10), @@ -197,11 +211,18 @@ class _NotificationSettingsDialogState "일일 리마인더", "매일 $selectedTime 알림", dailyReminder, - (val) => setState(() => dailyReminder = val), + (val) => setState(() { + dailyReminder = val; + if (!val) { + allNotifications = false; + } else if (mateReaction && mateVerification) { + allNotifications = true; + } + }), ), // 2. 리마인더가 활성화되었을 때만 드롭다운 표시 - if (dailyReminder) + if (dailyReminder && allNotifications) Padding( padding: const EdgeInsets.only(bottom: 20), child: GestureDetector( From 7bac60c19b272cc9eb8a5c6b79219fe9ef413048 Mon Sep 17 00:00:00 2001 From: Chaeyeong_10 Date: Wed, 20 May 2026 16:38:37 +0900 Subject: [PATCH 133/134] =?UTF-8?q?fix:=20=ED=83=80=EC=9E=84=EC=8A=A4?= =?UTF-8?q?=ED=83=AC=ED=94=84=20=EC=9D=B4=EC=8A=88=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/src/main/AndroidManifest.xml | 4 +- et --hard HEAD@{3} | 79 +++++++++++++++++ lib/core/utils/image_utils.dart | 36 ++++++++ lib/features/auth/services/auth_service.dart | 2 +- .../screens/camera_edit_screen.dart | 88 ++++++++++++------- .../challenge_verification_screen.dart | 6 +- linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 48 ++++++++++ pubspec.yaml | 1 + windows/flutter/generated_plugins.cmake | 1 + 11 files changed, 230 insertions(+), 38 deletions(-) create mode 100644 et --hard HEAD@{3} create mode 100644 lib/core/utils/image_utils.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 8bbcb0b..87182bb 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -63,8 +63,8 @@ diff --git a/et --hard HEAD@{3} b/et --hard HEAD@{3} new file mode 100644 index 0000000..e612536 --- /dev/null +++ b/et --hard HEAD@{3} @@ -0,0 +1,79 @@ +30eb8b1 (HEAD -> feat/statistics, origin/refactor, refactor) HEAD@{0}: reset: moving to origin/refactor +3f50f26 HEAD@{1}: checkout: moving from refactor to feat/statistics +30eb8b1 (HEAD -> feat/statistics, origin/refactor, refactor) HEAD@{2}: checkout: moving from feat/statistics to refactor +3f50f26 HEAD@{3}: commit (merge): merge: 네이버 로그인 코드 병합 완료 +27b85fa HEAD@{4}: checkout: moving from refactor to feat/statistics +30eb8b1 (HEAD -> feat/statistics, origin/refactor, refactor) HEAD@{5}: pull origin refactor: Fast-forward +3d3348e HEAD@{6}: checkout: moving from feat/statistics to refactor +27b85fa HEAD@{7}: commit (merge): feat:AI 추천 기능 및 UI 수정 완료 +f92b1d6 HEAD@{8}: checkout: moving from refactor to feat/statistics +3d3348e HEAD@{9}: pull origin refactor: Fast-forward +9d7ce6b (fix/issues) HEAD@{10}: reset: moving to HEAD +9d7ce6b (fix/issues) HEAD@{11}: checkout: moving from feat/statistics to refactor +f92b1d6 HEAD@{12}: commit: 임시 저장 +9d228b8 HEAD@{13}: merge origin/refactor: Fast-forward +04c0575 (origin/feat/statistics) HEAD@{14}: commit: feat: 통계 페이지 3개 위젯 구현 +b3cab05 (origin/refactor-change-baseurl, refactor-change-baseurl) HEAD@{15}: checkout: moving from refactor-change-baseurl to feat/statistics +b3cab05 (origin/refactor-change-baseurl, refactor-change-baseurl) HEAD@{16}: commit: refactor: baseurl 변경 +eead793 (origin/refactor-user-provider, refactor-user-provider) HEAD@{17}: checkout: moving from refactor-user-provider to refactor-change-baseurl +eead793 (origin/refactor-user-provider, refactor-user-provider) HEAD@{18}: commit: refactor: 프로필 & 나의 챌린지 리팩토링 +177b93b HEAD@{19}: commit: refactor: 챌린지 생성 리팩토링 +830a843 HEAD@{20}: reset: moving to origin/refactor-user-provider +830a843 HEAD@{21}: checkout: moving from refactor-user-provider to refactor-user-provider +830a843 HEAD@{22}: commit (merge): Merge remote-tracking branch 'origin/refactor-my-page' into refactor-user-provider +e1a8e94 HEAD@{23}: commit: refactor: 카카오 로그인 구현 및 User와 UserDetail 모델 분리 +8ce49e5 HEAD@{24}: merge origin/refactor: Merge made by the 'ort' strategy. +8cc0021 HEAD@{25}: commit: chore: refactor 합치기 전 현재 상태 저장 +a54c030 HEAD@{26}: merge origin/refactor: Merge made by the 'ort' strategy. +9b30968 HEAD@{27}: commit: feat:카카오 로그인 구현 +ef8f269 HEAD@{28}: checkout: moving from refactor to refactor-user-provider +9d7ce6b (fix/issues) HEAD@{29}: reset: moving to HEAD +9d7ce6b (fix/issues) HEAD@{30}: reset: moving to 9d7ce6b +ef8f269 HEAD@{31}: checkout: moving from fix/issues to refactor +9d7ce6b (fix/issues) HEAD@{32}: reset: moving to HEAD +9d7ce6b (fix/issues) HEAD@{33}: reset: moving to 9d7ce6b +ef8f269 HEAD@{34}: checkout: moving from refactor to fix/issues +ef8f269 HEAD@{35}: checkout: moving from fix/issues to refactor +ef8f269 HEAD@{36}: commit: refactor: 전역 유저 상태 관리 도입 +9d7ce6b (fix/issues) HEAD@{37}: commit (merge): chore: refactor 브랜치 병합 및 충돌 해결 +97e6049 HEAD@{38}: commit: feat: 앱 배포 +9e3ee61 (origin/develop) HEAD@{39}: pull origin develop: Fast-forward +5599a83 (origin/fix/issues) HEAD@{40}: commit: fix: 인증글 생성, 사진 검증 수정 완료 +1347873 HEAD@{41}: pull origin develop: Merge made by the 'ort' strategy. +c139e85 HEAD@{42}: commit: feature: 카카오 로그인 구현 중 - develop 병합 전 저장 +293c078 HEAD@{43}: commit: fix: 리팩토링, 디자인 수정, 여러 가지 이슈 해결 +6cb2e93 HEAD@{44}: merge develop: Merge made by the 'ort' strategy. +c43dbc7 HEAD@{45}: checkout: moving from develop to fix/issues +fba21d7 (develop) HEAD@{46}: pull origin develop: Fast-forward +d7da869 (origin/main, origin/HEAD, main, fix/issues-and-tests) HEAD@{47}: checkout: moving from fix/issues to develop +c43dbc7 HEAD@{48}: commit: fix: 챌린지 생성 주 1회 추가 및 캘린더 수정 +d7da869 (origin/main, origin/HEAD, main, fix/issues-and-tests) HEAD@{49}: checkout: moving from main to fix/issues +d7da869 (origin/main, origin/HEAD, main, fix/issues-and-tests) HEAD@{50}: reset: moving to develop +9a68473 HEAD@{51}: pull origin main: Fast-forward +e5b42ac HEAD@{52}: reset: moving to HEAD +e5b42ac HEAD@{53}: checkout: moving from develop to main +d7da869 (origin/main, origin/HEAD, main, fix/issues-and-tests) HEAD@{54}: checkout: moving from fix/issues-and-tests to develop +d7da869 (origin/main, origin/HEAD, main, fix/issues-and-tests) HEAD@{55}: merge develop: Fast-forward +d2f537d HEAD@{56}: checkout: moving from develop to fix/issues-and-tests +d7da869 (origin/main, origin/HEAD, main, fix/issues-and-tests) HEAD@{57}: pull origin develop: Fast-forward +9ef5f52 HEAD@{58}: checkout: moving from fix/issues-and-tests to develop +d2f537d HEAD@{59}: commit: fix: 챌린지 삭제 api 호출 로직 복구 +f7d9005 HEAD@{60}: merge origin/develop: Fast-forward +c395bee HEAD@{61}: commit: fix: 회원 탈퇴 화면 진입 이슈 해결 +f54380b HEAD@{62}: pull origin develop: Fast-forward +8029fc1 HEAD@{63}: commit: fix: 파일명 오타 수정, 디자인 수정, 약간의 리팩토링 +f273597 HEAD@{64}: commit: main 충돌 해결 +6b3d5eb HEAD@{65}: commit (merge): chore: merge fix/design-and-errors and resolve conflicts +9ef5f52 HEAD@{66}: checkout: moving from develop to fix/issues-and-tests +9ef5f52 HEAD@{67}: pull origin develop: Fast-forward +85c13c4 HEAD@{68}: checkout: moving from fix/design-and-errors to develop +5fa53cc (fix/design-and-errors) HEAD@{69}: commit: feat: 챌린지 생성 및 상세정보 태그 이슈 해결 & 위임/나가기 테스트 완료 +decea39 HEAD@{70}: merge develop: Merge made by the 'ort' strategy. +3ccf576 HEAD@{71}: checkout: moving from develop to fix/design-and-errors +85c13c4 HEAD@{72}: pull origin develop: Fast-forward +0033e7e HEAD@{73}: checkout: moving from fix/design-and-errors to develop +3ccf576 HEAD@{74}: commit: 나가기 및 위임 다이얼로그 리팩토링 +252a1e4 HEAD@{75}: commit: fix: 디자인 수정 및 여러 가지 에러 해결 +c4bb493 (feature/profile-edit) HEAD@{76}: checkout: moving from feature/profile-edit to fix/design-and-errors +c4bb493 (feature/profile-edit) HEAD@{77}: pull origin develop: Merge made by the 'ort' strategy. +cc9d42c HEAD@{78}: checkout: moving from de \ No newline at end of file diff --git a/lib/core/utils/image_utils.dart b/lib/core/utils/image_utils.dart new file mode 100644 index 0000000..9afda6f --- /dev/null +++ b/lib/core/utils/image_utils.dart @@ -0,0 +1,36 @@ +// 최초 작성자: 김채영 +import 'dart:io'; +import 'dart:typed_data'; +import 'package:flutter/material.dart'; +import 'package:flutter_image_compress/flutter_image_compress.dart'; +import 'package:path_provider/path_provider.dart'; + +// 클라우더리 용량 이슈 때문에 필요한 인증글의 이미지 압축 유틸 함수 +Future compressImageFile(File file) async { + final tempDir = await getTemporaryDirectory(); + final targetPath = + '${tempDir.path}/compressed_${DateTime.now().millisecondsSinceEpoch}.jpg'; + + final XFile? result = await FlutterImageCompress.compressAndGetFile( + file.absolute.path, + targetPath, + quality: 80, // 80 정도면 육안상 차이 거의 없음 + minWidth: 1080, // 긴 쪽 기준 최대 해상도 + minHeight: 1080, + format: CompressFormat.jpeg, + ); + + // ✅ 압축 전후 크기 비교 로그 + final int originalSize = await file.length(); + final int compressedSize = result != null + ? await File(result.path).length() + : 0; + + debugPrint('🖼️ 압축 전: ${(originalSize / 1024).toStringAsFixed(1)} KB'); + debugPrint('🖼️ 압축 후: ${(compressedSize / 1024).toStringAsFixed(1)} KB'); + debugPrint( + '🖼️ 압축률: ${((1 - compressedSize / originalSize) * 100).toStringAsFixed(1)}%', + ); + + return result != null ? File(result.path) : file; // 실패 시 원본 반환 +} diff --git a/lib/features/auth/services/auth_service.dart b/lib/features/auth/services/auth_service.dart index 520c70d..a007432 100644 --- a/lib/features/auth/services/auth_service.dart +++ b/lib/features/auth/services/auth_service.dart @@ -32,7 +32,7 @@ class AuthService { // 'https://hanaem.onrender.com/api/oauth/kakao/token'; static const String kakaoRedirectUri = - 'https://hanaem.onrender.com/oauth/kakao/callback'; + 'http://158.247.216.11:8080/oauth/kakao/callback'; //static const String kakaoRedirectUri = //'kakao9fdd13c0777c415d8fa4055b5b26a6c5://oauth'; diff --git a/lib/features/challenge/verification/screens/camera_edit_screen.dart b/lib/features/challenge/verification/screens/camera_edit_screen.dart index 06ed48c..17691b5 100644 --- a/lib/features/challenge/verification/screens/camera_edit_screen.dart +++ b/lib/features/challenge/verification/screens/camera_edit_screen.dart @@ -1,6 +1,8 @@ // 최초 작성자 : 김채영 import 'dart:io'; import 'dart:typed_data'; +import 'dart:ui' as ui; +import 'package:flutter/rendering.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:intl/intl.dart'; @@ -10,6 +12,8 @@ import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; import 'package:image/image.dart' as img; +final GlobalKey _repaintKey = GlobalKey(); + // 카메라로 촬영했을 때의 편집 화면 class CameraEditScreen extends StatefulWidget { final File imageFile; @@ -159,31 +163,35 @@ class _CameraEditScreenState extends State { // 현재 기기의 화면 너비 가져오기 final double screenWidth = MediaQuery.of(context).size.width; - return Container( - width: screenWidth, // 너비: 화면 가득 - height: screenWidth, - clipBehavior: Clip.antiAlias, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(12)), - child: Stack( - children: [ - // 배경 이미지 (회전 적용) - Positioned.fill( - child: RotatedBox( - quarterTurns: _rotationTurns, - child: Image.memory(_imageData!, fit: BoxFit.cover), + return RepaintBoundary( + // ✅ 추가 + key: _repaintKey, // ✅ 추가 + child: Container( + width: screenWidth, // 너비: 화면 가득 + height: screenWidth, + clipBehavior: Clip.antiAlias, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12)), + child: Stack( + children: [ + // 배경 이미지 (회전 적용) + Positioned.fill( + child: RotatedBox( + quarterTurns: _rotationTurns, + child: Image.memory(_imageData!, fit: BoxFit.cover), + ), ), - ), - // 타임스탬프 (자르기 모드가 아닐 때만 보임) - Positioned( - right: 16, - bottom: 16, - child: Text( - _timestamp, - textAlign: TextAlign.right, - style: AppTypography.h1.copyWith(color: Colors.white), + // 타임스탬프 (자르기 모드가 아닐 때만 보임) + Positioned( + right: 40, + bottom: 16, + child: Text( + _timestamp, + textAlign: TextAlign.right, + style: AppTypography.h1.copyWith(color: Colors.white), + ), ), - ), - ], + ], + ), ), ); } @@ -266,19 +274,31 @@ class _CameraEditScreenState extends State { Future _saveAndReturn() async { if (_imageData == null) return; - // 회전이 적용된 경우 물리적으로 이미지 회전 처리 - Uint8List finalData = _imageData!; - if (_rotationTurns != 0) { - finalData = rotateImageBytes(finalData, _rotationTurns); - } + try { + // RepaintBoundary로 화면에 보이는 그대로 캡처 (타임스탬프 포함) + final RenderRepaintBoundary boundary = + _repaintKey.currentContext!.findRenderObject() + as RenderRepaintBoundary; - final tempDir = await getTemporaryDirectory(); - final file = File( - '${tempDir.path}/camera_edited_${DateTime.now().millisecondsSinceEpoch}.png', - ); - await file.writeAsBytes(finalData); + // pixelRatio를 높이면 캡처 해상도가 올라감 (3.0 권장) + final ui.Image image = await boundary.toImage(pixelRatio: 3.0); + final ByteData? byteData = await image.toByteData( + format: ui.ImageByteFormat.png, + ); + + if (byteData == null) return; + final Uint8List finalData = byteData.buffer.asUint8List(); - if (mounted) Navigator.pop(context, file); + final tempDir = await getTemporaryDirectory(); + final file = File( + '${tempDir.path}/camera_edited_${DateTime.now().millisecondsSinceEpoch}.png', + ); + await file.writeAsBytes(finalData); + + if (mounted) Navigator.pop(context, file); + } catch (e) { + debugPrint('이미지 캡처 에러: $e'); + } } } diff --git a/lib/features/challenge/verification/screens/challenge_verification_screen.dart b/lib/features/challenge/verification/screens/challenge_verification_screen.dart index df6f31a..13dfa6e 100644 --- a/lib/features/challenge/verification/screens/challenge_verification_screen.dart +++ b/lib/features/challenge/verification/screens/challenge_verification_screen.dart @@ -1,6 +1,7 @@ // 최초 작성자 : 김채영 import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:haenaem/core/utils/image_utils.dart'; import 'package:image_picker/image_picker.dart'; import 'package:photo_manager/photo_manager.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -367,10 +368,13 @@ class _ChallengeVerificationScreenState Future _runImageVerification(File file) async { setState(() => _verifyStatus = ImageVerificationStatus.loading); + // 먼저 압축 + final File compressed = await compressImageFile(file); + // 1. 서버에 사진 검증 및 임시 업로드 요청 (Notifier 호출) final int? tempId = await ref .read(imageVerifyNotifierProvider.notifier) - .verify(file, widget.challengeId); + .verify(compressed, widget.challengeId); if (mounted) { setState(() { diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index aae2b5c..a9cc2e1 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -10,6 +10,7 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + jni ) set(PLUGIN_BUNDLED_LIBRARIES) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 1bd911d..312398c 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -10,6 +10,7 @@ import file_selector_macos import firebase_core import firebase_messaging import flutter_appauth +import flutter_image_compress_macos import flutter_secure_storage_darwin import google_sign_in_ios import path_provider_foundation @@ -25,6 +26,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) FlutterAppauthPlugin.register(with: registry.registrar(forPlugin: "FlutterAppauthPlugin")) + FlutterImageCompressMacosPlugin.register(with: registry.registrar(forPlugin: "FlutterImageCompressMacosPlugin")) FlutterSecureStorageDarwinPlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStorageDarwinPlugin")) FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 6694b79..84d20eb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -542,6 +542,54 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.1" + flutter_image_compress: + dependency: "direct main" + description: + name: flutter_image_compress + sha256: "51d23be39efc2185e72e290042a0da41aed70b14ef97db362a6b5368d0523b27" + url: "https://pub.dev" + source: hosted + version: "2.4.0" + flutter_image_compress_common: + dependency: transitive + description: + name: flutter_image_compress_common + sha256: c5c5d50c15e97dd7dc72ff96bd7077b9f791932f2076c5c5b6c43f2c88607bfb + url: "https://pub.dev" + source: hosted + version: "1.0.6" + flutter_image_compress_macos: + dependency: transitive + description: + name: flutter_image_compress_macos + sha256: "20019719b71b743aba0ef874ed29c50747461e5e8438980dfa5c2031898f7337" + url: "https://pub.dev" + source: hosted + version: "1.0.3" + flutter_image_compress_ohos: + dependency: transitive + description: + name: flutter_image_compress_ohos + sha256: e76b92bbc830ee08f5b05962fc78a532011fcd2041f620b5400a593e96da3f51 + url: "https://pub.dev" + source: hosted + version: "0.0.3" + flutter_image_compress_platform_interface: + dependency: transitive + description: + name: flutter_image_compress_platform_interface + sha256: "579cb3947fd4309103afe6442a01ca01e1e6f93dc53bb4cbd090e8ce34a41889" + url: "https://pub.dev" + source: hosted + version: "1.0.5" + flutter_image_compress_web: + dependency: transitive + description: + name: flutter_image_compress_web + sha256: b9b141ac7c686a2ce7bb9a98176321e1182c9074650e47bb140741a44b6f5a96 + url: "https://pub.dev" + source: hosted + version: "0.1.5" flutter_launcher_icons: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 1bbb5dc..4625f69 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -58,6 +58,7 @@ dependencies: firebase_messaging: ^16.1.1 kakao_flutter_sdk: ^1.10.0 url_launcher: ^6.3.2 + flutter_image_compress: ^2.4.0 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 2fad67b..e93c7e2 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -12,6 +12,7 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + jni ) set(PLUGIN_BUNDLED_LIBRARIES) From 1bfb7120a83e7b6f49962556dfcc1ac21967135a Mon Sep 17 00:00:00 2001 From: Chaeyeong_10 Date: Fri, 22 May 2026 01:02:10 +0900 Subject: [PATCH 134/134] =?UTF-8?q?fix:=20env=20=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 4 - et --hard HEAD@{3} | 79 --- .../detail/widgets/challenge_popup_menu.dart | 3 +- .../widgets/notification_settings_dialog.dart | 658 ++++++++++++------ .../feed/provider/post_detail_provider.dart | 20 +- .../feed/provider/post_detail_provider.g.dart | 2 +- .../feed/screens/challenge_search_screen.dart | 1 + .../feed/widgets/post_popup_menu.dart | 2 +- .../challenge_notification_repository.dart | 124 ++++ .../challenge_notification_repository.g.dart | 30 + .../data/notification_repository.dart | 32 +- .../data/push_notification_repository.dart | 187 +++++ .../data/push_notification_repository.g.dart | 30 + .../challenge_notification_settings_dto.dart | 57 ++ .../push_notification_settings_dto.dart | 43 ++ .../provider/push_notification_provider.dart | 293 +++++--- .../statistics/widgets/pie_graph.dart | 16 +- .../push_notification_settings_screen.dart | 493 ++++++++++--- lib/features/user/widgets/logout_dialog.dart | 10 +- linux/flutter/generated_plugins.cmake | 1 - pubspec.lock | 8 +- windows/flutter/generated_plugins.cmake | 1 - 22 files changed, 1595 insertions(+), 499 deletions(-) delete mode 100644 .env delete mode 100644 et --hard HEAD@{3} create mode 100644 lib/features/notification/data/challenge_notification_repository.dart create mode 100644 lib/features/notification/data/challenge_notification_repository.g.dart create mode 100644 lib/features/notification/data/push_notification_repository.dart create mode 100644 lib/features/notification/data/push_notification_repository.g.dart create mode 100644 lib/features/notification/models/challenge_notification_settings_dto.dart create mode 100644 lib/features/notification/models/push_notification_settings_dto.dart diff --git a/.env b/.env deleted file mode 100644 index 635ddc5..0000000 --- a/.env +++ /dev/null @@ -1,4 +0,0 @@ -GOOGLE_ANDROID_CLIENT_ID=433865217738-m3uqqdv9lumpf1ne8e3bkpsbtsa6919i.apps.googleusercontent.com -KAKAO_NATIVE_APP_KEY=05a36f172ea2945260862834654385ea -KAKAO_REST_API_KEY=9fdd13c0777c415d8fa4055b5b26a6c5 -NAVER_CLIENT_ID=BS2Upg_v4LgwRoqmfvPf \ No newline at end of file diff --git a/et --hard HEAD@{3} b/et --hard HEAD@{3} deleted file mode 100644 index e612536..0000000 --- a/et --hard HEAD@{3} +++ /dev/null @@ -1,79 +0,0 @@ -30eb8b1 (HEAD -> feat/statistics, origin/refactor, refactor) HEAD@{0}: reset: moving to origin/refactor -3f50f26 HEAD@{1}: checkout: moving from refactor to feat/statistics -30eb8b1 (HEAD -> feat/statistics, origin/refactor, refactor) HEAD@{2}: checkout: moving from feat/statistics to refactor -3f50f26 HEAD@{3}: commit (merge): merge: 네이버 로그인 코드 병합 완료 -27b85fa HEAD@{4}: checkout: moving from refactor to feat/statistics -30eb8b1 (HEAD -> feat/statistics, origin/refactor, refactor) HEAD@{5}: pull origin refactor: Fast-forward -3d3348e HEAD@{6}: checkout: moving from feat/statistics to refactor -27b85fa HEAD@{7}: commit (merge): feat:AI 추천 기능 및 UI 수정 완료 -f92b1d6 HEAD@{8}: checkout: moving from refactor to feat/statistics -3d3348e HEAD@{9}: pull origin refactor: Fast-forward -9d7ce6b (fix/issues) HEAD@{10}: reset: moving to HEAD -9d7ce6b (fix/issues) HEAD@{11}: checkout: moving from feat/statistics to refactor -f92b1d6 HEAD@{12}: commit: 임시 저장 -9d228b8 HEAD@{13}: merge origin/refactor: Fast-forward -04c0575 (origin/feat/statistics) HEAD@{14}: commit: feat: 통계 페이지 3개 위젯 구현 -b3cab05 (origin/refactor-change-baseurl, refactor-change-baseurl) HEAD@{15}: checkout: moving from refactor-change-baseurl to feat/statistics -b3cab05 (origin/refactor-change-baseurl, refactor-change-baseurl) HEAD@{16}: commit: refactor: baseurl 변경 -eead793 (origin/refactor-user-provider, refactor-user-provider) HEAD@{17}: checkout: moving from refactor-user-provider to refactor-change-baseurl -eead793 (origin/refactor-user-provider, refactor-user-provider) HEAD@{18}: commit: refactor: 프로필 & 나의 챌린지 리팩토링 -177b93b HEAD@{19}: commit: refactor: 챌린지 생성 리팩토링 -830a843 HEAD@{20}: reset: moving to origin/refactor-user-provider -830a843 HEAD@{21}: checkout: moving from refactor-user-provider to refactor-user-provider -830a843 HEAD@{22}: commit (merge): Merge remote-tracking branch 'origin/refactor-my-page' into refactor-user-provider -e1a8e94 HEAD@{23}: commit: refactor: 카카오 로그인 구현 및 User와 UserDetail 모델 분리 -8ce49e5 HEAD@{24}: merge origin/refactor: Merge made by the 'ort' strategy. -8cc0021 HEAD@{25}: commit: chore: refactor 합치기 전 현재 상태 저장 -a54c030 HEAD@{26}: merge origin/refactor: Merge made by the 'ort' strategy. -9b30968 HEAD@{27}: commit: feat:카카오 로그인 구현 -ef8f269 HEAD@{28}: checkout: moving from refactor to refactor-user-provider -9d7ce6b (fix/issues) HEAD@{29}: reset: moving to HEAD -9d7ce6b (fix/issues) HEAD@{30}: reset: moving to 9d7ce6b -ef8f269 HEAD@{31}: checkout: moving from fix/issues to refactor -9d7ce6b (fix/issues) HEAD@{32}: reset: moving to HEAD -9d7ce6b (fix/issues) HEAD@{33}: reset: moving to 9d7ce6b -ef8f269 HEAD@{34}: checkout: moving from refactor to fix/issues -ef8f269 HEAD@{35}: checkout: moving from fix/issues to refactor -ef8f269 HEAD@{36}: commit: refactor: 전역 유저 상태 관리 도입 -9d7ce6b (fix/issues) HEAD@{37}: commit (merge): chore: refactor 브랜치 병합 및 충돌 해결 -97e6049 HEAD@{38}: commit: feat: 앱 배포 -9e3ee61 (origin/develop) HEAD@{39}: pull origin develop: Fast-forward -5599a83 (origin/fix/issues) HEAD@{40}: commit: fix: 인증글 생성, 사진 검증 수정 완료 -1347873 HEAD@{41}: pull origin develop: Merge made by the 'ort' strategy. -c139e85 HEAD@{42}: commit: feature: 카카오 로그인 구현 중 - develop 병합 전 저장 -293c078 HEAD@{43}: commit: fix: 리팩토링, 디자인 수정, 여러 가지 이슈 해결 -6cb2e93 HEAD@{44}: merge develop: Merge made by the 'ort' strategy. -c43dbc7 HEAD@{45}: checkout: moving from develop to fix/issues -fba21d7 (develop) HEAD@{46}: pull origin develop: Fast-forward -d7da869 (origin/main, origin/HEAD, main, fix/issues-and-tests) HEAD@{47}: checkout: moving from fix/issues to develop -c43dbc7 HEAD@{48}: commit: fix: 챌린지 생성 주 1회 추가 및 캘린더 수정 -d7da869 (origin/main, origin/HEAD, main, fix/issues-and-tests) HEAD@{49}: checkout: moving from main to fix/issues -d7da869 (origin/main, origin/HEAD, main, fix/issues-and-tests) HEAD@{50}: reset: moving to develop -9a68473 HEAD@{51}: pull origin main: Fast-forward -e5b42ac HEAD@{52}: reset: moving to HEAD -e5b42ac HEAD@{53}: checkout: moving from develop to main -d7da869 (origin/main, origin/HEAD, main, fix/issues-and-tests) HEAD@{54}: checkout: moving from fix/issues-and-tests to develop -d7da869 (origin/main, origin/HEAD, main, fix/issues-and-tests) HEAD@{55}: merge develop: Fast-forward -d2f537d HEAD@{56}: checkout: moving from develop to fix/issues-and-tests -d7da869 (origin/main, origin/HEAD, main, fix/issues-and-tests) HEAD@{57}: pull origin develop: Fast-forward -9ef5f52 HEAD@{58}: checkout: moving from fix/issues-and-tests to develop -d2f537d HEAD@{59}: commit: fix: 챌린지 삭제 api 호출 로직 복구 -f7d9005 HEAD@{60}: merge origin/develop: Fast-forward -c395bee HEAD@{61}: commit: fix: 회원 탈퇴 화면 진입 이슈 해결 -f54380b HEAD@{62}: pull origin develop: Fast-forward -8029fc1 HEAD@{63}: commit: fix: 파일명 오타 수정, 디자인 수정, 약간의 리팩토링 -f273597 HEAD@{64}: commit: main 충돌 해결 -6b3d5eb HEAD@{65}: commit (merge): chore: merge fix/design-and-errors and resolve conflicts -9ef5f52 HEAD@{66}: checkout: moving from develop to fix/issues-and-tests -9ef5f52 HEAD@{67}: pull origin develop: Fast-forward -85c13c4 HEAD@{68}: checkout: moving from fix/design-and-errors to develop -5fa53cc (fix/design-and-errors) HEAD@{69}: commit: feat: 챌린지 생성 및 상세정보 태그 이슈 해결 & 위임/나가기 테스트 완료 -decea39 HEAD@{70}: merge develop: Merge made by the 'ort' strategy. -3ccf576 HEAD@{71}: checkout: moving from develop to fix/design-and-errors -85c13c4 HEAD@{72}: pull origin develop: Fast-forward -0033e7e HEAD@{73}: checkout: moving from fix/design-and-errors to develop -3ccf576 HEAD@{74}: commit: 나가기 및 위임 다이얼로그 리팩토링 -252a1e4 HEAD@{75}: commit: fix: 디자인 수정 및 여러 가지 에러 해결 -c4bb493 (feature/profile-edit) HEAD@{76}: checkout: moving from feature/profile-edit to fix/design-and-errors -c4bb493 (feature/profile-edit) HEAD@{77}: pull origin develop: Merge made by the 'ort' strategy. -cc9d42c HEAD@{78}: checkout: moving from de \ No newline at end of file diff --git a/lib/features/challenge/detail/widgets/challenge_popup_menu.dart b/lib/features/challenge/detail/widgets/challenge_popup_menu.dart index 10ece9b..f25eb46 100644 --- a/lib/features/challenge/detail/widgets/challenge_popup_menu.dart +++ b/lib/features/challenge/detail/widgets/challenge_popup_menu.dart @@ -124,7 +124,8 @@ class ChallengePopupMenu extends ConsumerWidget { // 알림 설정 로직 호출 showDialog( context: context, - builder: (context) => const NotificationSettingsDialog(), + builder: (context) => + NotificationSettingsDialog(challengeId: challengeId), ); break; case 'invite': diff --git a/lib/features/challenge/detail/widgets/notification_settings_dialog.dart b/lib/features/challenge/detail/widgets/notification_settings_dialog.dart index 9aee8a0..85cd219 100644 --- a/lib/features/challenge/detail/widgets/notification_settings_dialog.dart +++ b/lib/features/challenge/detail/widgets/notification_settings_dialog.dart @@ -1,27 +1,216 @@ // 최초 작성자 : 강선욱 +// 수정: 김채영 (피그마 디자인 반영) import 'package:flutter/material.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:haenaem/core/theme/app_colors.dart'; import 'package:haenaem/core/theme/app_typography.dart'; -import 'package:flutter/cupertino.dart'; +import 'package:haenaem/features/notification/data/challenge_notification_repository.dart'; + +class NotificationSettingsDialog extends ConsumerStatefulWidget { + final int challengeId; -// 챌린지 알림 설정 다이얼로그 -class NotificationSettingsDialog extends StatefulWidget { - const NotificationSettingsDialog({super.key}); + const NotificationSettingsDialog({super.key, required this.challengeId}); @override - State createState() => + ConsumerState createState() => _NotificationSettingsDialogState(); } class _NotificationSettingsDialogState - extends State { - // 스위치 상태 변수들 - bool allNotifications = true; - bool dailyReminder = true; - bool mateReaction = true; - bool mateVerification = true; - String selectedTime = "오후 9시"; + extends ConsumerState { + // ── 스위치 상태 ─────────────────────────────────────── + bool allNotifications = false; + bool dailyReminder = false; + bool likesNotification = false; + bool commentsNotification = false; + bool mateVerification = false; + String selectedTime = '오후 9시'; + bool _isLoading = true; + + // ── 전역 설정에 의해 비활성화된 항목 ──────────────────── + bool _reminderDisabledByGlobal = false; + bool _likesDisabledByGlobal = false; + bool _commentsDisabledByGlobal = false; + bool _verificationDisabledByGlobal = false; + + @override + void initState() { + super.initState(); + _loadChallengeSettings(); + } + + // ── 초기 로드 ───────────────────────────────────────── + + Future _loadChallengeSettings() async { + try { + final dto = await ref + .read(challengeNotificationRepositoryProvider) + .getChallengeNotificationSettings(widget.challengeId); + + // 🔔 임시 로그 + debugPrint( + '===== 🔔 챌린지 알림 설정 조회 결과 (challengeId: ${widget.challengeId}) =====', + ); + debugPrint('🔔 전체 알림: ${dto.challengeAllPushEnabled}'); + debugPrint('🔔 일일 리마인더: ${dto.dailyReminderPushEnabled}'); + debugPrint('🔔 일일 리마인더 시간: ${dto.dailyReminderTime}'); + debugPrint( + '🔔 일일 리마인더 전역 차단: ${dto.dailyReminderDisabledByGlobalSetting}', + ); + debugPrint('🔔 좋아요: ${dto.likesPushEnabled}'); + debugPrint('🔔 좋아요 전역 차단: ${dto.likesDisabledByGlobalSetting}'); + debugPrint('🔔 댓글: ${dto.commentsPushEnabled}'); + debugPrint('🔔 댓글 전역 차단: ${dto.commentsDisabledByGlobalSetting}'); + debugPrint('🔔 멤버 인증: ${dto.memberCertificationPushEnabled}'); + debugPrint( + '🔔 멤버 인증 전역 차단: ${dto.memberCertificationDisabledByGlobalSetting}', + ); + debugPrint( + '=================================================================', + ); + + setState(() { + allNotifications = dto.challengeAllPushEnabled; + dailyReminder = dto.dailyReminderPushEnabled; + likesNotification = dto.likesPushEnabled; + commentsNotification = dto.commentsPushEnabled; + mateVerification = dto.memberCertificationPushEnabled; + selectedTime = _convertToDisplayTime(dto.dailyReminderTime); + + _reminderDisabledByGlobal = dto.dailyReminderDisabledByGlobalSetting; + _likesDisabledByGlobal = dto.likesDisabledByGlobalSetting; + _commentsDisabledByGlobal = dto.commentsDisabledByGlobalSetting; + _verificationDisabledByGlobal = + dto.memberCertificationDisabledByGlobalSetting; + + _isLoading = false; + }); + } catch (e) { + debugPrint('챌린지 알림 설정 로드 실패: $e'); + setState(() => _isLoading = false); + } + } + + // ── 시간 변환 헬퍼 ──────────────────────────────────── + + String _convertToDisplayTime(String serverTime) { + final hour = int.parse(serverTime.split(':')[0]); + if (hour == 0) return '오전 12시'; + if (hour < 12) return '오전 $hour시'; + if (hour == 12) return '오후 12시'; + return '오후 ${hour - 12}시'; + } + + String _convertToServerTime(String period, String hourStr) { + int hour = int.parse(hourStr.replaceAll('시', '')); + if (period == '오후' && hour != 12) hour += 12; + if (period == '오전' && hour == 12) hour = 0; + return '${hour.toString().padLeft(2, '0')}:00'; + } + + // ── 전체 알림 동기화 헬퍼 ──────────────────────────── + + void _syncAllNotifications() { + allNotifications = + dailyReminder && + likesNotification && + commentsNotification && + mateVerification; + } + + // ── 토글 핸들러 ─────────────────────────────────────── + + Future _toggleAll(bool val) async { + if (_isLoading) return; + setState(() => _isLoading = true); + + final success = await ref + .read(challengeNotificationRepositoryProvider) + .setChallengeAllNotification(widget.challengeId, val); + + if (success) { + setState(() { + allNotifications = val; + dailyReminder = val; + likesNotification = val; + commentsNotification = val; + mateVerification = val; + }); + } + setState(() => _isLoading = false); + } + + Future _toggleReminder(bool val) async { + if (_isLoading) return; + setState(() => _isLoading = true); + + final success = await ref + .read(challengeNotificationRepositoryProvider) + .setChallengeReminderNotification(widget.challengeId, val); + + if (success) { + setState(() { + dailyReminder = val; + _syncAllNotifications(); + }); + } + setState(() => _isLoading = false); + } + + Future _toggleLikes(bool val) async { + if (_isLoading) return; + setState(() => _isLoading = true); + + final success = await ref + .read(challengeNotificationRepositoryProvider) + .setChallengeLikesNotification(widget.challengeId, val); + + if (success) { + setState(() { + likesNotification = val; + _syncAllNotifications(); + }); + } + setState(() => _isLoading = false); + } + + Future _toggleComments(bool val) async { + if (_isLoading) return; + setState(() => _isLoading = true); + + final success = await ref + .read(challengeNotificationRepositoryProvider) + .setChallengeCommentsNotification(widget.challengeId, val); + + if (success) { + setState(() { + commentsNotification = val; + _syncAllNotifications(); + }); + } + setState(() => _isLoading = false); + } + + Future _toggleVerification(bool val) async { + if (_isLoading) return; + setState(() => _isLoading = true); + + final success = await ref + .read(challengeNotificationRepositoryProvider) + .setChallengeVerificationNotification(widget.challengeId, val); + + if (success) { + setState(() { + mateVerification = val; + _syncAllNotifications(); + }); + } + setState(() => _isLoading = false); + } + + // ── UI ──────────────────────────────────────────────── @override Widget build(BuildContext context) { @@ -33,10 +222,8 @@ class _NotificationSettingsDialogState clipBehavior: Clip.antiAlias, child: Column( mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, children: [ - // 1. 헤더 영역 + // ── 헤더 ───────────────────────────────────── Container( width: double.infinity, padding: const EdgeInsets.all(20), @@ -48,10 +235,9 @@ class _NotificationSettingsDialogState ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - '알림 설정', + '챌린지 알림 설정', style: AppTypography.h3.copyWith(color: AppColors.black), ), GestureDetector( @@ -68,75 +254,84 @@ class _NotificationSettingsDialogState ), ), - // 3. 설정 리스트 및 버튼 영역 - Padding( - padding: const EdgeInsets.fromLTRB(16, 10, 16, 12), - child: Column( - children: [ - _buildSwitchRow( - "전체 알림", - "모든 알림 받기", - allNotifications, - (val) => setState(() { - allNotifications = val; - dailyReminder = val; - mateReaction = val; - mateVerification = val; - }), - ), - _buildDailyReminderSection(), - _buildSwitchRow( - "메이트 반응 소식", - "다른 참여자들이 내 인증글에 반응 시 알림", - mateReaction, - (val) => setState(() { - mateReaction = val; - if (!val) { - allNotifications = false; - } else if (dailyReminder && mateVerification) { - allNotifications = true; - } - }), - ), - _buildSwitchRow( - "메이트 인증 소식", - "다른 참여자들이 인증 완료 시 알림", - mateVerification, - (val) => setState(() { - mateVerification = val; - if (!val) { - allNotifications = false; - } else if (dailyReminder && mateReaction) { - allNotifications = true; - } - }), - ), - const SizedBox(height: 24), - - // 완료 버튼 - SizedBox( - width: double.infinity, - height: 50, - child: ElevatedButton( - onPressed: () => Navigator.pop(context), - style: ElevatedButton.styleFrom( - backgroundColor: AppColors.primaryAble, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + // ── 본문 ───────────────────────────────────── + _isLoading + ? const Padding( + padding: EdgeInsets.symmetric(vertical: 40), + child: CircularProgressIndicator( + color: AppColors.primaryAble, + ), + ) + : Padding( + padding: const EdgeInsets.symmetric( + horizontal: 20, + vertical: 16, + ), + child: Column( + spacing: 20, + children: [ + _buildSwitchRow( + '전체 알림', + '모든 알림 받기', + allNotifications, + _toggleAll, ), - elevation: 0, - ), - child: const Text( - '완료', - style: TextStyle( - color: Colors.white, - fontSize: 16, - fontWeight: FontWeight.bold, + _buildDailyReminderSection(), + _buildSwitchRowWithGlobalWarning( + '내 글 좋아요', + "내 게시물에 '좋아요' 반응이 올 때 알림", + likesNotification, + _likesDisabledByGlobal ? null : _toggleLikes, + disabledByGlobal: _likesDisabledByGlobal, ), - ), + _buildSwitchRowWithGlobalWarning( + '댓글', + '내 글에 새로운 댓글이 달릴 때 알림', + commentsNotification, + _commentsDisabledByGlobal ? null : _toggleComments, + disabledByGlobal: _commentsDisabledByGlobal, + ), + _buildSwitchRowWithGlobalWarning( + '멤버 인증 소식', + '다른 참여자들이 인증 완료 시 알림', + mateVerification, + _verificationDisabledByGlobal + ? null + : _toggleVerification, + disabledByGlobal: _verificationDisabledByGlobal, + ), + ], ), ), - ], + + // ── 완료 버튼 ───────────────────────────────── + Container( + width: double.infinity, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + decoration: const BoxDecoration( + border: Border(top: BorderSide(width: 1, color: AppColors.gray4)), + ), + child: SizedBox( + width: double.infinity, + height: 48, + child: ElevatedButton( + onPressed: () => Navigator.pop(context), + style: ElevatedButton.styleFrom( + backgroundColor: AppColors.primaryAble, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + elevation: 0, + ), + child: const Text( + '완료', + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + ), ), ), ], @@ -144,146 +339,219 @@ class _NotificationSettingsDialogState ); } + // ── 기본 스위치 행 ────────────────────────────────────── + Widget _buildSwitchRow( String title, String subtitle, bool value, ValueChanged? onChanged, ) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - // 텍스트 영역 - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - title, - style: AppTypography.b1.copyWith(color: AppColors.black), - ), - Text( - subtitle, - style: AppTypography.b2.copyWith(color: AppColors.gray2), - ), - ], - ), + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: AppTypography.b1.copyWith(color: AppColors.black), + ), + Text( + subtitle, + style: AppTypography.b2.copyWith(color: AppColors.gray2), + ), + ], ), + ), + _buildSwitch(value, onChanged), + ], + ); + } - // 스위치 영역: 이미지와 동일한 초록색 테마 적용 - Transform.scale( - scale: 0.8, - alignment: Alignment.centerRight, - child: Switch( - value: value, - onChanged: onChanged, - activeTrackColor: AppColors.primaryAble, - activeThumbColor: Colors.white, - inactiveTrackColor: AppColors.disable, // 이미지와 유사한 연회색 - inactiveThumbColor: Colors.white, - - // 테두리 제거 - trackOutlineColor: const WidgetStatePropertyAll( - Colors.transparent, - ), + // ── 전역 비활성화 안내 문구 포함 스위치 행 ────────────── - // 비활성화 시에도 버튼 크기가 작아지지 않도록 설정 - thumbIcon: WidgetStateProperty.all( - const Icon(null), - ), // 아이콘 공간 강제 확보 - thumbColor: const WidgetStatePropertyAll(Colors.white), + Widget _buildSwitchRowWithGlobalWarning( + String title, + String subtitle, + bool value, + ValueChanged? onChanged, { + bool disabledByGlobal = false, + }) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: AppTypography.b1.copyWith( + color: disabledByGlobal + ? AppColors.gray2 + : AppColors.black, + ), + ), + Text( + subtitle, + style: AppTypography.b2.copyWith(color: AppColors.gray2), + ), + ], + ), + ), + _buildSwitch( + value, + (_isLoading || disabledByGlobal) ? null : onChanged, + ), + ], + ), + if (disabledByGlobal) + Padding( + padding: const EdgeInsets.only(top: 4), + child: Text( + '전체 푸시 알림 설정에서 해당 알림이 꺼져 있습니다.', + style: AppTypography.c1.copyWith(color: AppColors.primaryAble), ), ), - ], + ], + ); + } + + // ── 공통 스위치 위젯 ──────────────────────────────────── + + Widget _buildSwitch(bool value, ValueChanged? onChanged) { + return Transform.scale( + scale: 0.8, + alignment: Alignment.centerRight, + child: Switch( + value: value, + onChanged: onChanged, + activeTrackColor: AppColors.primaryAble, + activeThumbColor: Colors.white, + inactiveTrackColor: AppColors.disable, + inactiveThumbColor: Colors.white, + trackOutlineColor: const WidgetStatePropertyAll(Colors.transparent), + thumbIcon: WidgetStateProperty.all(const Icon(null)), + thumbColor: const WidgetStatePropertyAll(Colors.white), ), ); } + // ── 일일 리마인더 섹션 ────────────────────────────────── + Widget _buildDailyReminderSection() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 1. 상단 스위치 행 - _buildSwitchRow( - "일일 리마인더", - "매일 $selectedTime 알림", - dailyReminder, - (val) => setState(() { - dailyReminder = val; - if (!val) { - allNotifications = false; - } else if (mateReaction && mateVerification) { - allNotifications = true; - } - }), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '일일 리마인더', + style: AppTypography.b1.copyWith( + color: _reminderDisabledByGlobal + ? AppColors.gray2 + : AppColors.black, + ), + ), + Text( + '매일 $selectedTime 알림', + style: AppTypography.b2.copyWith(color: AppColors.gray2), + ), + ], + ), + ), + _buildSwitch( + dailyReminder, + (_isLoading || _reminderDisabledByGlobal) + ? null + : _toggleReminder, + ), + ], ), - - // 2. 리마인더가 활성화되었을 때만 드롭다운 표시 - if (dailyReminder && allNotifications) - Padding( - padding: const EdgeInsets.only(bottom: 20), - child: GestureDetector( - onTap: () => _showTimePicker(context), // 터치 시 피커 호출 - child: Container( - width: double.infinity, - height: 48, - padding: const EdgeInsets.symmetric(horizontal: 20), - decoration: BoxDecoration( - color: AppColors.gray5, - borderRadius: BorderRadius.circular(12), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(selectedTime, style: AppTypography.b2), - SvgPicture.asset( + if (dailyReminder && !_reminderDisabledByGlobal) ...[ + const SizedBox(height: 4), + GestureDetector( + onTap: () => _showTimePicker(context), + child: Container( + width: double.infinity, + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: AppColors.gray5, + borderRadius: BorderRadius.circular(8), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + selectedTime, + style: AppTypography.b2.copyWith(color: AppColors.gray3), + ), + Opacity( + opacity: 0.5, + child: SvgPicture.asset( 'assets/images/icons/big_down_arrow.svg', + width: 16, + height: 16, colorFilter: const ColorFilter.mode( AppColors.gray2, BlendMode.srcIn, ), ), - ], - ), + ), + ], ), ), ), + ], + if (_reminderDisabledByGlobal) + Padding( + padding: const EdgeInsets.only(top: 4), + child: Text( + '전체 푸시 알림 설정에서 해당 알림이 꺼져 있습니다.', + style: AppTypography.c1.copyWith(color: AppColors.primaryAble), + ), + ), ], ); } + // ── 시간 피커 ─────────────────────────────────────────── + void _showTimePicker(BuildContext context) { - final List hours = List.generate(12, (i) => "${i + 1}시"); - String currentPeriod = selectedTime.contains("오후") ? "오후" : "오전"; + final List hours = List.generate(12, (i) => '${i + 1}시'); + String currentPeriod = selectedTime.contains('오후') ? '오후' : '오전'; String currentHour = selectedTime.split(' ').last; int initialHourIndex = hours.indexOf(currentHour); if (initialHourIndex == -1) initialHourIndex = 8; showDialog( context: context, - barrierColor: Colors.black.withAlpha(100), // 기존 투명도 유지 + barrierColor: Colors.black.withAlpha(100), builder: (context) => StatefulBuilder( builder: (context, setDialogState) => AlertDialog( shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(20), // 다이얼로그 전체 곡률 유지 + borderRadius: BorderRadius.circular(20), ), - actionsAlignment: MainAxisAlignment.center, backgroundColor: Colors.white, - contentPadding: const EdgeInsets.fromLTRB( - 20, - 20, - 20, - 0, - ), // 하단 여백 제거하여 버튼 밀착 + contentPadding: const EdgeInsets.fromLTRB(20, 20, 20, 0), content: SizedBox( width: MediaQuery.of(context).size.width * 0.8, child: Column( mainAxisSize: MainAxisSize.min, children: [ - // 1. 오전/오후 선택용 애니메이션 버튼 Padding( padding: const EdgeInsets.symmetric(horizontal: 24), child: _buildAnimatedPeriodSelector( @@ -292,15 +560,11 @@ class _NotificationSettingsDialogState setDialogState(() => currentPeriod = newPeriod), ), ), - const SizedBox(height: 24), - - // 2. 시간 선택 휠 SizedBox( - height: 150, // 휠의 높이를 원하는 만큼 고정 (너무 늘어나지 않음) + height: 150, child: Stack( children: [ - // 중앙 하이라이트 바 Center( child: Container( height: 40, @@ -330,20 +594,22 @@ class _NotificationSettingsDialogState ], ), ), - const SizedBox(height: 20), - Padding( padding: const EdgeInsets.only( bottom: 16, left: 16, right: 16, - ), // 하단과 좌우 여백 설정 + ), child: TextButton( onPressed: () { - setState( - () => selectedTime = "$currentPeriod $currentHour", + final newTime = '$currentPeriod $currentHour'; + final serverTime = _convertToServerTime( + currentPeriod, + currentHour, ); + setState(() => selectedTime = newTime); + // TODO: 챌린지별 리마인더 시간 변경 API 생기면 연동 Navigator.pop(context); }, style: TextButton.styleFrom( @@ -356,7 +622,7 @@ class _NotificationSettingsDialogState ), ), child: Text( - "완료", + '완료', style: AppTypography.b1.copyWith( color: AppColors.primaryAble, fontWeight: FontWeight.bold, @@ -378,34 +644,31 @@ class _NotificationSettingsDialogState ) { return Container( height: 48, - padding: const EdgeInsets.all(4), // 테두리와 내부 버튼 사이의 여백 + padding: const EdgeInsets.all(4), decoration: BoxDecoration( - color: AppColors.gray4, // 배경색 (이미지 b77188의 연회색) + color: AppColors.gray4, borderRadius: BorderRadius.circular(12), ), child: LayoutBuilder( builder: (context, constraints) { - // 전체 너비의 절반에서 패딩(4)을 뺀 값이 움직이는 배경의 너비가 됩니다. - double width = constraints.maxWidth / 2; - + final double width = constraints.maxWidth / 2; return Stack( children: [ - // 1. 배경에서 움직이는 흰색 하이라이트 박스 AnimatedAlign( - duration: const Duration(milliseconds: 250), // 애니메이션 속도 - curve: Curves.easeInOut, // 부드러운 가속도 곡선 - alignment: currentPeriod == "오전" + duration: const Duration(milliseconds: 250), + curve: Curves.easeInOut, + alignment: currentPeriod == '오전' ? Alignment.centerLeft : Alignment.centerRight, child: Container( - width: width - 4, // 좌우 여백을 고려한 너비 + width: width - 4, height: double.infinity, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), boxShadow: [ BoxShadow( - color: Colors.black.withAlpha(20), // 미세한 그림자 효과 + color: Colors.black.withAlpha(20), blurRadius: 4, offset: const Offset(0, 2), ), @@ -413,14 +676,11 @@ class _NotificationSettingsDialogState ), ), ), - - // 2. 상단 텍스트 레이어 (오전, 오후) Row( - children: ["오전", "오후"].map((p) { - bool isSelected = currentPeriod == p; + children: ['오전', '오후'].map((p) { + final bool isSelected = currentPeriod == p; return Expanded( child: GestureDetector( - // 투명한 영역을 클릭해도 인식되도록 설정 behavior: HitTestBehavior.opaque, onTap: () => onPeriodChanged(p), child: Center( diff --git a/lib/features/feed/provider/post_detail_provider.dart b/lib/features/feed/provider/post_detail_provider.dart index cbfea9c..9679d14 100644 --- a/lib/features/feed/provider/post_detail_provider.dart +++ b/lib/features/feed/provider/post_detail_provider.dart @@ -3,6 +3,8 @@ import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:haenaem/shared/models/post.dart'; // 💡 FeedRepository가 있는 경로를 임포트해주세요. (feed_provider.dart 내부에 있다면 해당 파일 임포트) import '../data/feed_repository.dart'; +import '../../../../shared/provider/post_provider.dart'; // monthlyChallengePostsProvider +import 'package:haenaem/shared/provider/challenge_detail_provider.dart'; part 'post_detail_provider.g.dart'; @@ -89,13 +91,29 @@ class PostDeleteNotifier extends _$PostDeleteNotifier { @override AsyncValue build() => const AsyncValue.data(null); - Future removeArticle(int postId) async { + Future removeArticle(int postId, int challengeId) async { state = const AsyncValue.loading(); final result = await AsyncValue.guard( () => ref.read(feedRepositoryProvider).deleteArticle(postId), ); + if (!result.hasError) { + final now = DateTime.now(); + // ✅ 캘린더 목록 갱신 + ref.invalidate( + monthlyChallengePostsProvider( + challengeId: challengeId, + year: now.year, + month: now.month, + ), + ); + // ✅ 상세 캐시 제거 + ref.invalidate(postDetailProvider(postId: postId)); + // ✅ 인증 여부 상태도 갱신 (인증하기 버튼 활성화) + ref.invalidate(challengeDetailProvider(challengeId: challengeId)); + } + state = result; return !result.hasError; } diff --git a/lib/features/feed/provider/post_detail_provider.g.dart b/lib/features/feed/provider/post_detail_provider.g.dart index 767d89f..6366bc1 100644 --- a/lib/features/feed/provider/post_detail_provider.g.dart +++ b/lib/features/feed/provider/post_detail_provider.g.dart @@ -180,7 +180,7 @@ final postUpdateNotifierProvider = typedef _$PostUpdateNotifier = AutoDisposeNotifier>; String _$postDeleteNotifierHash() => - r'93485d48e410be62a04958383fa5104316a65079'; + r'07b47c44d9e04acef1f1ede70e94a8534f8a4285'; /// See also [PostDeleteNotifier]. @ProviderFor(PostDeleteNotifier) diff --git a/lib/features/feed/screens/challenge_search_screen.dart b/lib/features/feed/screens/challenge_search_screen.dart index 0ba333c..8bfb095 100644 --- a/lib/features/feed/screens/challenge_search_screen.dart +++ b/lib/features/feed/screens/challenge_search_screen.dart @@ -9,6 +9,7 @@ import '../widgets/challenge_search_card.dart'; import 'package:haenaem/shared/models/user.dart'; import 'package:haenaem/features/user/provider/user_provider.dart'; import 'package:haenaem/features/feed/provider/feed_provider.dart'; +import 'package:haenaem/shared/models/search_challenge_card.dart'; class ChallengeSearchScreen extends ConsumerStatefulWidget { const ChallengeSearchScreen({super.key}); diff --git a/lib/features/feed/widgets/post_popup_menu.dart b/lib/features/feed/widgets/post_popup_menu.dart index bbb8922..9188bb6 100644 --- a/lib/features/feed/widgets/post_popup_menu.dart +++ b/lib/features/feed/widgets/post_popup_menu.dart @@ -201,7 +201,7 @@ class PostPopupMenu extends ConsumerWidget { // 💡 삭제 시도 final success = await ref .read(postDeleteNotifierProvider.notifier) - .removeArticle(post.id); + .removeArticle(post.id, post.challengeId); if (success && context.mounted) { ScaffoldMessenger.of( diff --git a/lib/features/notification/data/challenge_notification_repository.dart b/lib/features/notification/data/challenge_notification_repository.dart new file mode 100644 index 0000000..2edc3e8 --- /dev/null +++ b/lib/features/notification/data/challenge_notification_repository.dart @@ -0,0 +1,124 @@ +// 최초 작성자: 김채영 +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:haenaem/core/network/dio_provider.dart'; +import 'package:haenaem/features/notification/models/challenge_notification_settings_dto.dart'; + +part 'challenge_notification_repository.g.dart'; + +@riverpod +ChallengeNotificationRepository challengeNotificationRepository( + ChallengeNotificationRepositoryRef ref, +) { + final dio = ref.watch(dioProvider); + return ChallengeNotificationRepository(dio); +} + +class ChallengeNotificationRepository { + final Dio _dio; + ChallengeNotificationRepository(this._dio); + + // ── 설정 조회 ─────────────────────────────────────────── + + /// GET /api/fcm/notification/challenge/{challengeId}/settings + Future getChallengeNotificationSettings( + int challengeId, + ) async { + try { + final response = await _dio.get( + '/api/fcm/notification/challenge/$challengeId/settings', + ); + return ChallengeNotificationSettingsDto.fromJson(response.data); + } on DioException catch (e) { + throw Exception('챌린지 알림 설정 조회 실패: ${e.response?.statusCode}'); + } + } + + // ── 설정 변경 ─────────────────────────────────────────── + + /// PUT /api/fcm/notification/challenge/{challengeId}/all + Future setChallengeAllNotification( + int challengeId, + bool enabled, + ) async { + try { + await _dio.put( + '/api/fcm/notification/challenge/$challengeId/all', + data: {'enabled': enabled}, + ); + return true; + } on DioException catch (e) { + debugPrint('챌린지 전체 알림 설정 실패: ${e.response?.data}'); + return false; + } + } + + /// PUT /api/fcm/notification/challenge/{challengeId}/daily-reminder + Future setChallengeReminderNotification( + int challengeId, + bool enabled, + ) async { + try { + await _dio.put( + '/api/fcm/notification/challenge/$challengeId/daily-reminder', + data: {'enabled': enabled}, + ); + return true; + } on DioException catch (e) { + debugPrint('챌린지 리마인더 알림 설정 실패: ${e.response?.data}'); + return false; + } + } + + /// PUT /api/fcm/notification/challenge/{challengeId}/likes + Future setChallengeLikesNotification( + int challengeId, + bool enabled, + ) async { + try { + await _dio.put( + '/api/fcm/notification/challenge/$challengeId/likes', + data: {'enabled': enabled}, + ); + return true; + } on DioException catch (e) { + debugPrint('챌린지 좋아요 알림 설정 실패: ${e.response?.data}'); + return false; + } + } + + /// PUT /api/fcm/notification/challenge/{challengeId}/comments + Future setChallengeCommentsNotification( + int challengeId, + bool enabled, + ) async { + try { + await _dio.put( + '/api/fcm/notification/challenge/$challengeId/comments', + data: {'enabled': enabled}, + ); + return true; + } on DioException catch (e) { + debugPrint('챌린지 댓글 알림 설정 실패: ${e.response?.data}'); + return false; + } + } + + /// PUT /api/fcm/notification/challenge/{challengeId}/member-certification + Future setChallengeVerificationNotification( + int challengeId, + bool enabled, + ) async { + try { + await _dio.put( + '/api/fcm/notification/challenge/$challengeId/member-certification', + data: {'enabled': enabled}, + ); + return true; + } on DioException catch (e) { + debugPrint('챌린지 멤버 인증 알림 설정 실패: ${e.response?.data}'); + return false; + } + } +} diff --git a/lib/features/notification/data/challenge_notification_repository.g.dart b/lib/features/notification/data/challenge_notification_repository.g.dart new file mode 100644 index 0000000..04c1dc8 --- /dev/null +++ b/lib/features/notification/data/challenge_notification_repository.g.dart @@ -0,0 +1,30 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'challenge_notification_repository.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$challengeNotificationRepositoryHash() => + r'41c3aeea4df09e6c7268ca48038900de3b0f227d'; + +/// See also [challengeNotificationRepository]. +@ProviderFor(challengeNotificationRepository) +final challengeNotificationRepositoryProvider = + AutoDisposeProvider.internal( + challengeNotificationRepository, + name: r'challengeNotificationRepositoryProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$challengeNotificationRepositoryHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +typedef ChallengeNotificationRepositoryRef = + AutoDisposeProviderRef; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/notification/data/notification_repository.dart b/lib/features/notification/data/notification_repository.dart index 3b03bfd..289f212 100644 --- a/lib/features/notification/data/notification_repository.dart +++ b/lib/features/notification/data/notification_repository.dart @@ -1,5 +1,4 @@ // 최초 작성자: 정승빈 -// 알림 조회, 읽음 처리, 수락/거절 API import 'package:dio/dio.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:haenaem/core/network/dio_provider.dart'; @@ -9,16 +8,17 @@ part 'notification_repository.g.dart'; @riverpod NotificationRepository notificationRepository(NotificationRepositoryRef ref) { - final dio = ref.watch(dioProvider); // ← 공통 Dio 주입 + final dio = ref.watch(dioProvider); return NotificationRepository(dio); } class NotificationRepository { final Dio _dio; - NotificationRepository(this._dio); - // 알림 목록 조회 + // ── 알림 목록 ────────────────────────────────────────── + + /// 알림 목록 페이징 조회 Future> getNotifications({required int page}) async { try { final response = await _dio.get( @@ -27,14 +27,13 @@ class NotificationRepository { ); return response.data; } on DioException catch (e) { - print('❌ [Noti Repo Error]: ${e.response?.data}'); - throw Exception('알림 목록을 불러오는데 실패했습니다: ${e.response?.statusCode}'); - } catch (e) { - throw Exception('알 수 없는 오류 발생: $e'); + throw Exception('알림 목록 조회 실패: ${e.response?.statusCode}'); } } - // 챌린지 초대 목록 조회 + // ── 챌린지 초대 ───────────────────────────────────────── + + /// 챌린지 초대 목록 조회 Future> getChallengeInvites() async { try { final response = await _dio.get('/api/challenges/invites'); @@ -47,21 +46,17 @@ class NotificationRepository { ) .toList(); } on DioException catch (e) { - print('❌ [초대 조회 에러]: ${e.response?.data}'); - throw Exception('초대 목록을 불러오는데 실패했습니다.'); - } catch (e) { - throw Exception('초대 조회 중 알 수 없는 오류 발생: $e'); + throw Exception('초대 목록 조회 실패: ${e.response?.statusCode}'); } } - // 챌린지 초대 수락 + /// 챌린지 초대 수락 Future acceptChallengeInvite(int challengeId) async { try { await _dio.post('/api/challenges/$challengeId/invites/accept'); } on DioException catch (e) { final data = e.response?.data; String errorMessage = '초대 수락에 실패했습니다.'; - if (data != null && data is Map) { final reason = data['reason']; if (reason == 'CHALLENGE_INVITE_NOT_FOUND') { @@ -71,18 +66,15 @@ class NotificationRepository { } } throw Exception(errorMessage); - } catch (e) { - throw Exception('알 수 없는 오류가 발생했습니다.'); } } - // 챌린지 초대 거절 + /// 챌린지 초대 거절 Future rejectChallengeInvite(int challengeId) async { try { await _dio.post('/api/challenges/$challengeId/invites/reject'); } on DioException catch (e) { - print('❌ [거절 에러]: ${e.response?.data}'); - throw Exception('초대 거절 실패'); + throw Exception('초대 거절 실패: ${e.response?.statusCode}'); } } } diff --git a/lib/features/notification/data/push_notification_repository.dart b/lib/features/notification/data/push_notification_repository.dart new file mode 100644 index 0000000..dcc1086 --- /dev/null +++ b/lib/features/notification/data/push_notification_repository.dart @@ -0,0 +1,187 @@ +// 최초 작성자: 김채영 +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:haenaem/core/network/dio_provider.dart'; +import 'package:haenaem/features/notification/models/push_notification_settings_dto.dart'; + +part 'push_notification_repository.g.dart'; + +@riverpod +PushNotificationRepository pushNotificationRepository( + PushNotificationRepositoryRef ref, +) { + final dio = ref.watch(dioProvider); + return PushNotificationRepository(dio); +} + +class PushNotificationRepository { + final Dio _dio; + PushNotificationRepository(this._dio); + + // ── 설정 조회 ─────────────────────────────────────────── + + /// GET /api/fcm/notification/settings + Future getNotificationSettings() async { + try { + final response = await _dio.get('/api/fcm/notification/settings'); + return PushNotificationSettingsDto.fromJson(response.data); + } on DioException catch (e) { + throw Exception('알림 설정 조회 실패: ${e.response?.statusCode}'); + } + } + + // ── 전체 알림 ──────────────────────────────────────────── + + /// PUT /api/fcm/notification/all + Future setAllNotification(bool enabled) async { + try { + await _dio.put('/api/fcm/notification/all', data: {'enabled': enabled}); + return true; + } on DioException catch (e) { + debugPrint('전체 알림 설정 실패: ${e.response?.data}'); + return false; + } + } + + // ── 소셜 알림 ──────────────────────────────────────────── + + /// PUT /api/fcm/notification/all-likes + Future setAllLikesNotification(bool enabled) async { + try { + await _dio.put( + '/api/fcm/notification/all-likes', + data: {'enabled': enabled}, + ); + return true; + } on DioException catch (e) { + debugPrint('전체 좋아요 알림 설정 실패: ${e.response?.data}'); + return false; + } + } + + /// PUT /api/fcm/notification/all-comments + Future setAllCommentsNotification(bool enabled) async { + try { + await _dio.put( + '/api/fcm/notification/all-comments', + data: {'enabled': enabled}, + ); + return true; + } on DioException catch (e) { + debugPrint('전체 댓글 알림 설정 실패: ${e.response?.data}'); + return false; + } + } + + /// PUT /api/fcm/notification/friend + Future setFriendNotification(bool enabled) async { + try { + await _dio.put( + '/api/fcm/notification/friend', + data: {'enabled': enabled}, + ); + return true; + } on DioException catch (e) { + debugPrint('친구 알림 설정 실패: ${e.response?.data}'); + return false; + } + } + + /// PUT /api/fcm/notification/all-member-certification + Future setAllMemberCertificationNotification(bool enabled) async { + try { + await _dio.put( + '/api/fcm/notification/all-member-certification', + data: {'enabled': enabled}, + ); + return true; + } on DioException catch (e) { + debugPrint('전체 멤버 인증 알림 설정 실패: ${e.response?.data}'); + return false; + } + } + + // ── 챌린지 섹션 알림 ───────────────────────────────────── + + /// PUT /api/fcm/notification/challenge-invite + Future setChallengeInviteNotification(bool enabled) async { + try { + await _dio.put( + '/api/fcm/notification/challenge-invite', + data: {'enabled': enabled}, + ); + return true; + } on DioException catch (e) { + debugPrint('챌린지 초대 알림 설정 실패: ${e.response?.data}'); + return false; + } + } + + /// PUT /api/fcm/notification/motivation-message + Future setMotivationNotification(bool enabled) async { + try { + await _dio.put( + '/api/fcm/notification/motivation-message', + data: {'enabled': enabled}, + ); + return true; + } on DioException catch (e) { + debugPrint('동기부여 알림 설정 실패: ${e.response?.data}'); + return false; + } + } + + /// PUT /api/fcm/notification/daily-reminder + Future setDailyReminderNotification(bool enabled) async { + try { + await _dio.put( + '/api/fcm/notification/daily-reminder', + data: {'enabled': enabled}, + ); + return true; + } on DioException catch (e) { + debugPrint('일일 리마인더 알림 설정 실패: ${e.response?.data}'); + return false; + } + } + + // ── 실패 방지 리마인더 시간 ────────────────────────────── + + /// GET /api/notification/reminder/time + Future getWeeklyReminderTime() async { + try { + final response = await _dio.get('/api/notification/reminder/time'); + final time = response.data['notificationTime']; + if (time == null) return null; + + if (time is String) { + return time.substring(0, 5); // "21:00:00" → "21:00" + } else if (time is Map) { + final hour = time['hour'] as int; + final minute = time['minute'] as int; + return '${hour.toString().padLeft(2, '0')}:${minute.toString().padLeft(2, '0')}'; + } + return null; + } on DioException catch (e) { + throw Exception('실패 방지 리마인더 시간 조회 실패: ${e.response?.statusCode}'); + } + } + + /// PUT /api/notification/reminder/time + Future setWeeklyReminderTime(String timeString) async { + try { + debugPrint('📤 실패 방지 리마인더 시간 전송: $timeString'); // ✅ 추가 + await _dio.put( + '/api/notification/reminder/time', + data: {'notificationTime': timeString}, + ); + debugPrint('✅ 실패 방지 리마인더 시간 설정 성공'); // ✅ 추가 + return true; + } on DioException catch (e) { + debugPrint('❌ 실패 방지 리마인더 시간 설정 실패: ${e.response?.data}'); + debugPrint('❌ 상태 코드: ${e.response?.statusCode}'); + return false; + } + } +} diff --git a/lib/features/notification/data/push_notification_repository.g.dart b/lib/features/notification/data/push_notification_repository.g.dart new file mode 100644 index 0000000..305c011 --- /dev/null +++ b/lib/features/notification/data/push_notification_repository.g.dart @@ -0,0 +1,30 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'push_notification_repository.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$pushNotificationRepositoryHash() => + r'051900f137067448f5b1a7ac5eddf38003190f51'; + +/// See also [pushNotificationRepository]. +@ProviderFor(pushNotificationRepository) +final pushNotificationRepositoryProvider = + AutoDisposeProvider.internal( + pushNotificationRepository, + name: r'pushNotificationRepositoryProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$pushNotificationRepositoryHash, + dependencies: null, + allTransitiveDependencies: null, + ); + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +typedef PushNotificationRepositoryRef = + AutoDisposeProviderRef; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/features/notification/models/challenge_notification_settings_dto.dart b/lib/features/notification/models/challenge_notification_settings_dto.dart new file mode 100644 index 0000000..be75bd8 --- /dev/null +++ b/lib/features/notification/models/challenge_notification_settings_dto.dart @@ -0,0 +1,57 @@ +// 최초 작성자: 김채영 +class ChallengeNotificationSettingsDto { + final bool challengeAllPushEnabled; + final bool dailyReminderPushEnabled; + final String dailyReminderTime; // "HH:mm" 형식 + final bool dailyReminderDisabledByGlobalSetting; + final bool likesPushEnabled; + final bool likesDisabledByGlobalSetting; + final bool commentsPushEnabled; + final bool commentsDisabledByGlobalSetting; + final bool memberCertificationPushEnabled; + final bool memberCertificationDisabledByGlobalSetting; + + const ChallengeNotificationSettingsDto({ + required this.challengeAllPushEnabled, + required this.dailyReminderPushEnabled, + required this.dailyReminderTime, + required this.dailyReminderDisabledByGlobalSetting, + required this.likesPushEnabled, + required this.likesDisabledByGlobalSetting, + required this.commentsPushEnabled, + required this.commentsDisabledByGlobalSetting, + required this.memberCertificationPushEnabled, + required this.memberCertificationDisabledByGlobalSetting, + }); + + factory ChallengeNotificationSettingsDto.fromJson(Map json) { + // String("21:00:00") 또는 Map({ hour: 21, ... }) 둘 다 처리 + String timeStr = '21:00'; + final time = json['dailyReminderTime']; + if (time != null) { + if (time is String) { + timeStr = time.substring(0, 5); + } else if (time is Map) { + timeStr = '${(time['hour'] as int).toString().padLeft(2, '0')}:00'; + } + } + + return ChallengeNotificationSettingsDto( + challengeAllPushEnabled: json['challengeAllPushEnabled'] ?? false, + dailyReminderPushEnabled: json['dailyReminderPushEnabled'] ?? false, + dailyReminderTime: timeStr, + dailyReminderDisabledByGlobalSetting: + json['dailyReminderDisabledByGlobalSetting'] ?? false, + likesPushEnabled: json['likesPushEnabled'] ?? false, + likesDisabledByGlobalSetting: + json['likesDisabledByGlobalSetting'] ?? false, + commentsPushEnabled: json['commentsPushEnabled'] ?? false, + commentsDisabledByGlobalSetting: + json['commentsDisabledByGlobalSetting'] ?? false, + memberCertificationPushEnabled: + json['memberCertificationPushEnabled'] ?? false, + memberCertificationDisabledByGlobalSetting: + json['memberCertificationDisabledByGlobalSetting'] ?? false, + ); + } +} diff --git a/lib/features/notification/models/push_notification_settings_dto.dart b/lib/features/notification/models/push_notification_settings_dto.dart new file mode 100644 index 0000000..2b475b7 --- /dev/null +++ b/lib/features/notification/models/push_notification_settings_dto.dart @@ -0,0 +1,43 @@ +// 최초 작성자: 김채영 + +class PushNotificationSettingsDto { + final bool allPushNotificationEnabled; + final bool friendPushNotificationEnabled; + final bool allLikesPushNotificationEnabled; + final bool allCommentsPushNotificationEnabled; + final bool allMemberCertificationPushNotificationEnabled; + final bool challengeInvitePushNotificationEnabled; + final bool motivationPushNotificationEnabled; + final bool dailyReminderPushNotificationEnabled; + + const PushNotificationSettingsDto({ + required this.allPushNotificationEnabled, + required this.friendPushNotificationEnabled, + required this.allLikesPushNotificationEnabled, + required this.allCommentsPushNotificationEnabled, + required this.allMemberCertificationPushNotificationEnabled, + required this.challengeInvitePushNotificationEnabled, + required this.motivationPushNotificationEnabled, + required this.dailyReminderPushNotificationEnabled, + }); + + factory PushNotificationSettingsDto.fromJson(Map json) { + return PushNotificationSettingsDto( + allPushNotificationEnabled: json['allPushNotificationEnabled'] ?? false, + friendPushNotificationEnabled: + json['friendPushNotificationEnabled'] ?? false, + allLikesPushNotificationEnabled: + json['allLikesPushNotificationEnabled'] ?? false, + allCommentsPushNotificationEnabled: + json['allCommentsPushNotificationEnabled'] ?? false, + allMemberCertificationPushNotificationEnabled: + json['allMemberCertificationPushNotificationEnabled'] ?? false, + challengeInvitePushNotificationEnabled: + json['challengeInvitePushNotificationEnabled'] ?? false, + motivationPushNotificationEnabled: + json['motivationPushNotificationEnabled'] ?? false, + dailyReminderPushNotificationEnabled: + json['dailyReminderPushNotificationEnabled'] ?? false, + ); + } +} diff --git a/lib/features/notification/provider/push_notification_provider.dart b/lib/features/notification/provider/push_notification_provider.dart index 3e510d0..d118066 100644 --- a/lib/features/notification/provider/push_notification_provider.dart +++ b/lib/features/notification/provider/push_notification_provider.dart @@ -1,124 +1,257 @@ -// 최초 작성자 : 김채영 -import 'package:flutter_riverpod/flutter_riverpod.dart'; +// 최초 작성자: 강선욱 import 'package:flutter/foundation.dart'; -import 'package:haenaem/features/notification/services/fcm_service.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:haenaem/features/notification/data/push_notification_repository.dart'; +import 'package:haenaem/features/notification/models/push_notification_settings_dto.dart'; + +// ── 상태 모델 ───────────────────────────────────────────── class PushNotificationSettings { final bool allNotifications; + final bool friendRequestNotifications; final bool likeNotifications; final bool commentNotifications; - final bool friendRequestNotifications; + final bool memberAuthNotifications; final bool challengeInviteNotifications; final bool motivationNotifications; - final bool dailyReminder; // 일일 리마인더 필드 추가 - final bool memberAuthNotifications; + final bool dailyReminder; + final String weeklyReminderTime; - PushNotificationSettings({ - this.allNotifications = true, - this.likeNotifications = true, - this.commentNotifications = true, + const PushNotificationSettings({ + this.allNotifications = false, this.friendRequestNotifications = false, - this.challengeInviteNotifications = true, - this.motivationNotifications = true, - this.dailyReminder = true, // 기본값 true + this.likeNotifications = false, + this.commentNotifications = false, this.memberAuthNotifications = false, + this.challengeInviteNotifications = false, + this.motivationNotifications = false, + this.dailyReminder = false, + this.weeklyReminderTime = '21:00', }); PushNotificationSettings copyWith({ bool? allNotifications, + bool? friendRequestNotifications, bool? likeNotifications, bool? commentNotifications, - bool? friendRequestNotifications, + bool? memberAuthNotifications, bool? challengeInviteNotifications, bool? motivationNotifications, bool? dailyReminder, - bool? memberAuthNotifications, + String? reminderTime, + bool? weeklyReminder, + String? weeklyReminderTime, }) { return PushNotificationSettings( allNotifications: allNotifications ?? this.allNotifications, - likeNotifications: likeNotifications ?? this.likeNotifications, - commentNotifications: commentNotifications ?? this.commentNotifications, friendRequestNotifications: friendRequestNotifications ?? this.friendRequestNotifications, + likeNotifications: likeNotifications ?? this.likeNotifications, + commentNotifications: commentNotifications ?? this.commentNotifications, + memberAuthNotifications: + memberAuthNotifications ?? this.memberAuthNotifications, challengeInviteNotifications: challengeInviteNotifications ?? this.challengeInviteNotifications, motivationNotifications: motivationNotifications ?? this.motivationNotifications, dailyReminder: dailyReminder ?? this.dailyReminder, - memberAuthNotifications: - memberAuthNotifications ?? this.memberAuthNotifications, + weeklyReminderTime: weeklyReminderTime ?? this.weeklyReminderTime, ); } } +// ── Notifier ────────────────────────────────────────────── + class PushNotificationSettingsNotifier extends StateNotifier { - final Ref ref; // 1. Ref 추가 (서비스 호출을 위해) - - PushNotificationSettingsNotifier(this.ref) - : super(PushNotificationSettings()); - - void toggle(String key, bool value) async { - if (key == 'all') { - // ✅ 서버 API 호출 - final success = await ref - .read(fcmServiceProvider) - .updateAllNotificationStatus(value); - - if (success) { - // 성공 시 모든 스위치 상태 변경 - state = PushNotificationSettings( - allNotifications: value, - likeNotifications: value, - commentNotifications: value, - friendRequestNotifications: value, - challengeInviteNotifications: value, - motivationNotifications: value, - dailyReminder: value, - memberAuthNotifications: value, - ); - } else { - // 실패 시 에러 처리 (필요시 토스트 메시지 등 추가) - debugPrint("전체 알림 설정 변경에 실패했습니다."); - } - } else { - // 개별 알림 로직 (나중에 개별 API 생기면 여기에 추가) - switch (key) { - case 'like': - state = state.copyWith(likeNotifications: value); - break; - case 'comment': - state = state.copyWith(commentNotifications: value); - break; - case 'friend': - state = state.copyWith(friendRequestNotifications: value); - break; - case 'invite': - state = state.copyWith(challengeInviteNotifications: value); - break; - case 'motivation': - state = state.copyWith(motivationNotifications: value); - break; - case 'reminder': - state = state.copyWith(dailyReminder: value); - break; - case 'memberAuth': - state = state.copyWith(memberAuthNotifications: value); - break; - } - - if (value == false) { - state = state.copyWith(allNotifications: false); - } + final Ref _ref; + + PushNotificationSettingsNotifier(this._ref) + : super(const PushNotificationSettings()) { + _loadInitialSettings(); + } + + PushNotificationRepository get _repo => + _ref.read(pushNotificationRepositoryProvider); + + // ── 초기 로드 ───────────────────────────────────────── + + Future _loadInitialSettings() async { + try { + final results = await Future.wait([ + _repo.getNotificationSettings(), + _repo.getWeeklyReminderTime(), // 실패 방지 리마인더 시간 + ]); + + final dto = results[0] as PushNotificationSettingsDto; + final weeklyReminderTimeStr = results[1] as String?; + + // ✅ 임시 로그 + debugPrint('===== 🔔 푸시 알림 설정 조회 결과 ====='); + debugPrint('🔔 전체 알림: ${dto.allPushNotificationEnabled}'); + debugPrint('🔔 친구 알림: ${dto.friendPushNotificationEnabled}'); + debugPrint('🔔 좋아요: ${dto.allLikesPushNotificationEnabled}'); + debugPrint('🔔 댓글: ${dto.allCommentsPushNotificationEnabled}'); + debugPrint( + '🔔 멤버 인증: ${dto.allMemberCertificationPushNotificationEnabled}', + ); + debugPrint('🔔 챌린지 초대: ${dto.challengeInvitePushNotificationEnabled}'); + debugPrint('🔔 동기부여: ${dto.motivationPushNotificationEnabled}'); + debugPrint('🔔 일일 리마인더: ${dto.dailyReminderPushNotificationEnabled}'); + debugPrint('🔔 실패 방지 리마인더 시간: $weeklyReminderTimeStr'); + debugPrint('======================================='); + + state = PushNotificationSettings( + allNotifications: dto.allPushNotificationEnabled, + friendRequestNotifications: dto.friendPushNotificationEnabled, + likeNotifications: dto.allLikesPushNotificationEnabled, + commentNotifications: dto.allCommentsPushNotificationEnabled, + memberAuthNotifications: + dto.allMemberCertificationPushNotificationEnabled, + challengeInviteNotifications: + dto.challengeInvitePushNotificationEnabled, + motivationNotifications: dto.motivationPushNotificationEnabled, + dailyReminder: dto.dailyReminderPushNotificationEnabled, + weeklyReminderTime: weeklyReminderTimeStr ?? '21:00', + ); + } catch (e) { + debugPrint('알림 설정 초기 로드 실패: $e'); + } + } + + /// DTO → 상태 반영 (전체 알림 토글 시에도 재사용) + void _applyDto(PushNotificationSettingsDto dto) { + state = state.copyWith( + allNotifications: dto.allPushNotificationEnabled, + friendRequestNotifications: dto.friendPushNotificationEnabled, + likeNotifications: dto.allLikesPushNotificationEnabled, + commentNotifications: dto.allCommentsPushNotificationEnabled, + memberAuthNotifications: + dto.allMemberCertificationPushNotificationEnabled, + challengeInviteNotifications: dto.challengeInvitePushNotificationEnabled, + motivationNotifications: dto.motivationPushNotificationEnabled, + dailyReminder: dto.dailyReminderPushNotificationEnabled, + ); + } + + // ── 전체 알림 토글 ──────────────────────────────────── + + Future toggleAll(bool value) async { + final success = await _repo.setAllNotification(value); + if (!success) return; + + // 서버가 모든 항목을 일괄 변경하므로 재조회해서 상태 동기화 + try { + final dto = await _repo.getNotificationSettings(); + _applyDto(dto); + } catch (e) { + // 재조회 실패 시 로컬에서 일괄 적용 + debugPrint('전체 알림 설정 후 재조회 실패, 로컬 반영: $e'); + state = state.copyWith( + allNotifications: value, + friendRequestNotifications: value, + likeNotifications: value, + commentNotifications: value, + memberAuthNotifications: value, + challengeInviteNotifications: value, + motivationNotifications: value, + dailyReminder: value, + ); + } + } + + // ────────────── 소셜 알림 토글 ─────────────── + /// 좋아요 알림 토글 + Future toggleLikes(bool value) async { + final success = await _repo.setAllLikesNotification(value); + if (success) { + state = state.copyWith( + likeNotifications: value, + allNotifications: value ? state.allNotifications : false, + ); + } + } + + /// 댓글 알림 토글 + Future toggleComments(bool value) async { + final success = await _repo.setAllCommentsNotification(value); + if (success) { + state = state.copyWith( + commentNotifications: value, + allNotifications: value ? state.allNotifications : false, + ); } } + + /// 친구 알림 토글 + Future toggleFriend(bool value) async { + final success = await _repo.setFriendNotification(value); + if (success) { + state = state.copyWith( + friendRequestNotifications: value, + allNotifications: value ? state.allNotifications : false, + ); + } + } + + /// 멤버 인증 알림 토글 + Future toggleMemberAuth(bool value) async { + final success = await _repo.setAllMemberCertificationNotification(value); + if (success) { + state = state.copyWith( + memberAuthNotifications: value, + allNotifications: value ? state.allNotifications : false, + ); + } + } + + // ────────────── 챌린지 알림 토글 ─────────────── + + /// 챌린지 초대 알림 토글 + Future toggleChallengeInvite(bool value) async { + final success = await _repo.setChallengeInviteNotification(value); + if (success) { + state = state.copyWith( + challengeInviteNotifications: value, + allNotifications: value ? state.allNotifications : false, + ); + } + } + + /// 동기부여 메시지 알림 토글 + Future toggleMotivation(bool value) async { + final success = await _repo.setMotivationNotification(value); + if (success) { + state = state.copyWith( + motivationNotifications: value, + allNotifications: value ? state.allNotifications : false, + ); + } + } + + /// 일일 리마인더 토글 (시간 설정 API 없음) + Future toggleDailyReminder(bool value) async { + final success = await _repo.setDailyReminderNotification(value); + if (success) { + state = state.copyWith( + dailyReminder: value, + allNotifications: value ? state.allNotifications : false, + ); + } + } + + /// 실패 방지 리마인더 시간 변경 + Future updateWeeklyReminderTime(String timeString) async { + state = state.copyWith(weeklyReminderTime: timeString); + final success = await _repo.setWeeklyReminderTime(timeString); + if (!success) debugPrint('실패 방지 리마인더 시간 서버 저장 실패'); + } } -// 2. 프로바이더 정의 수정 +// ── Provider ────────────────────────────────────────────── + final pushNotificationProvider = StateNotifierProvider< PushNotificationSettingsNotifier, PushNotificationSettings - >((ref) { - return PushNotificationSettingsNotifier(ref); // ref 전달 - }); + >((ref) => PushNotificationSettingsNotifier(ref)); diff --git a/lib/features/statistics/widgets/pie_graph.dart b/lib/features/statistics/widgets/pie_graph.dart index 3f5494a..8cb0875 100644 --- a/lib/features/statistics/widgets/pie_graph.dart +++ b/lib/features/statistics/widgets/pie_graph.dart @@ -31,7 +31,21 @@ class PieGraph extends StatelessWidget { @override Widget build(BuildContext context) { - if (top3.isEmpty) return const SizedBox.shrink(); + // ✅ 데이터 없을 때 빈 상태 UI + if (top3.isEmpty) { + return StatisticsCard( + title: '나의 해냄 분포', + child: SizedBox( + height: 120, + child: Center( + child: Text( + '아직 완료한 챌린지가 없어요', + style: AppTypography.b2.copyWith(color: AppColors.gray3), + ), + ), + ), + ); + } // 파이 차트용: top3 각각 + 나머지 합산 gray4 하나 final pieData = [ diff --git a/lib/features/user/screens/settings/push_notification_settings_screen.dart b/lib/features/user/screens/settings/push_notification_settings_screen.dart index 2777d30..c855bd6 100644 --- a/lib/features/user/screens/settings/push_notification_settings_screen.dart +++ b/lib/features/user/screens/settings/push_notification_settings_screen.dart @@ -1,5 +1,6 @@ -// 최초 작성자 : 김채영 +// 최초 작성자: 김채영 import 'package:flutter/material.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; import '../../../../core/theme/app_colors.dart'; @@ -8,11 +9,285 @@ import '../../../../shared/widgets/custom_switch.dart'; import '../../../notification/provider/push_notification_provider.dart'; // 푸시 알림 설정 화면 -class PushNotificationSettingsScreen extends ConsumerWidget { +class PushNotificationSettingsScreen extends ConsumerStatefulWidget { const PushNotificationSettingsScreen({super.key}); @override - Widget build(BuildContext context, WidgetRef ref) { + ConsumerState createState() => + _PushNotificationSettingsScreenState(); +} + +class _PushNotificationSettingsScreenState + extends ConsumerState { + // ── 시간 변환 헬퍼 ──────────────────────────────────────── + String _convertToDisplayTime(String serverTime) { + final hour = int.parse(serverTime.split(':')[0]); + if (hour == 0) return '오전 12시'; + if (hour < 12) return '오전 $hour시'; + if (hour == 12) return '오후 12시'; + return '오후 ${hour - 12}시'; + } + + String _convertToServerTime(String period, String hourStr) { + int hour = int.parse(hourStr.replaceAll('시', '')); + if (period == '오후' && hour != 12) hour += 12; + if (period == '오전' && hour == 12) hour = 0; + return '${hour.toString().padLeft(2, '0')}:00'; + } + + // ── 공통 시간 피커 ──────────────────────────────────────── + void _showTimePicker( + BuildContext context, + String currentDisplayTime, + void Function(String serverTime) onConfirm, + ) { + final List hours = List.generate(12, (i) => '${i + 1}시'); + String currentPeriod = currentDisplayTime.contains('오후') ? '오후' : '오전'; + String currentHour = currentDisplayTime.split(' ').last; + int initialHourIndex = hours.indexOf(currentHour); + if (initialHourIndex == -1) initialHourIndex = 8; + + showDialog( + context: context, + barrierColor: Colors.black.withAlpha(100), + builder: (context) => StatefulBuilder( + builder: (context, setDialogState) => AlertDialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + backgroundColor: Colors.white, + contentPadding: const EdgeInsets.fromLTRB(20, 20, 20, 0), + content: SizedBox( + width: MediaQuery.of(context).size.width * 0.8, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: _buildAnimatedPeriodSelector( + currentPeriod, + (newPeriod) => + setDialogState(() => currentPeriod = newPeriod), + ), + ), + const SizedBox(height: 24), + SizedBox( + height: 150, + child: Stack( + children: [ + Center( + child: Container( + height: 40, + margin: const EdgeInsets.symmetric(horizontal: 24), + decoration: BoxDecoration( + color: AppColors.gray4.withAlpha(100), + borderRadius: BorderRadius.circular(10), + ), + ), + ), + CupertinoPicker( + itemExtent: 40, + scrollController: FixedExtentScrollController( + initialItem: initialHourIndex, + ), + onSelectedItemChanged: (index) => + setDialogState(() => currentHour = hours[index]), + selectionOverlay: const SizedBox.shrink(), + children: hours + .map( + (h) => Center( + child: Text(h, style: AppTypography.b1), + ), + ) + .toList(), + ), + ], + ), + ), + const SizedBox(height: 20), + Padding( + padding: const EdgeInsets.only( + bottom: 16, + left: 16, + right: 16, + ), + child: TextButton( + onPressed: () { + final serverTime = _convertToServerTime( + currentPeriod, + currentHour, + ); + onConfirm(serverTime); // ✅ 콜백으로 처리 + Navigator.pop(context); + }, + style: TextButton.styleFrom( + backgroundColor: Colors.transparent, + foregroundColor: AppColors.primaryAble, + minimumSize: const Size(double.infinity, 52), + padding: EdgeInsets.zero, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + child: Text( + '완료', + style: AppTypography.b1.copyWith( + color: AppColors.primaryAble, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), + ), + ), + ), + ); + } + + Widget _buildAnimatedPeriodSelector( + String currentPeriod, + Function(String) onPeriodChanged, + ) { + return Container( + height: 48, + padding: const EdgeInsets.all(4), + decoration: BoxDecoration( + color: AppColors.gray4, + borderRadius: BorderRadius.circular(12), + ), + child: LayoutBuilder( + builder: (context, constraints) { + final double width = constraints.maxWidth / 2; + return Stack( + children: [ + AnimatedAlign( + duration: const Duration(milliseconds: 250), + curve: Curves.easeInOut, + alignment: currentPeriod == '오전' + ? Alignment.centerLeft + : Alignment.centerRight, + child: Container( + width: width - 4, + height: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(20), + blurRadius: 4, + offset: const Offset(0, 2), + ), + ], + ), + ), + ), + Row( + children: ['오전', '오후'].map((p) { + final bool isSelected = currentPeriod == p; + return Expanded( + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () => onPeriodChanged(p), + child: Center( + child: AnimatedDefaultTextStyle( + duration: const Duration(milliseconds: 250), + style: AppTypography.b2.copyWith( + color: isSelected ? Colors.black : AppColors.gray2, + fontWeight: isSelected + ? FontWeight.bold + : FontWeight.normal, + ), + child: Text(p), + ), + ), + ), + ); + }).toList(), + ), + ], + ); + }, + ), + ); + } + + Widget _buildWeeklyReminderSection( + PushNotificationSettings settings, + PushNotificationSettingsNotifier notifier, + ) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 타이틀 + 설명 (스위치 없음) + Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '실패 방지 리마인더', + style: AppTypography.b1.copyWith( + color: AppColors.black, + fontWeight: FontWeight.w500, + ), + ), + Text( + '챌린지 실패를 방지하는 주간 리마인더 알림', + style: AppTypography.b2.copyWith(color: AppColors.gray2), + ), + ], + ), + ), + ], + ), + // 시간 피커 드롭다운 (항상 표시) + const SizedBox(height: 4), + GestureDetector( + onTap: () => _showTimePicker( + context, + _convertToDisplayTime(settings.weeklyReminderTime), + (serverTime) => notifier.updateWeeklyReminderTime(serverTime), + ), + child: Container( + width: double.infinity, + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: AppColors.gray5, + borderRadius: BorderRadius.circular(8), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + _convertToDisplayTime(settings.weeklyReminderTime), + style: AppTypography.b2.copyWith(color: AppColors.gray3), + ), + Opacity( + opacity: 0.5, + child: SvgPicture.asset( + 'assets/images/icons/big_down_arrow.svg', + width: 16, + height: 16, + colorFilter: const ColorFilter.mode( + AppColors.gray2, + BlendMode.srcIn, + ), + ), + ), + ], + ), + ), + ), + ], + ); + } + + @override + Widget build(BuildContext context) { final settings = ref.watch(pushNotificationProvider); final notifier = ref.read(pushNotificationProvider.notifier); @@ -21,6 +296,7 @@ class PushNotificationSettingsScreen extends ConsumerWidget { appBar: AppBar( backgroundColor: Colors.white, elevation: 0, + surfaceTintColor: Colors.white, leading: IconButton( icon: SvgPicture.asset( 'assets/images/icons/arrow_left.svg', @@ -40,94 +316,104 @@ class PushNotificationSettingsScreen extends ConsumerWidget { centerTitle: true, ), body: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 10), - _buildSwitchRow( - title: '전체 알림', - subtitle: '모든 알림 받기', - value: settings.allNotifications, - onChanged: (val) => notifier.toggle('all', val), - isMain: true, - ), - const Padding( - padding: EdgeInsets.only(left: 20, right: 20, top: 20, bottom: 0), - child: Divider(color: AppColors.gray4, height: 1), - ), - - _buildSectionHeader('소셜'), - _buildSwitchRow( - title: '내 글 좋아요', - subtitle: "내 게시물에 '좋아요' 반응이 올 때 알림", - value: settings.likeNotifications, - onChanged: (val) => notifier.toggle('like', val), - ), - _buildSwitchRow( - title: '댓글', - subtitle: '내 글에 새로운 댓글이 달릴 때 알림', - value: settings.commentNotifications, - onChanged: (val) => notifier.toggle('comment', val), - ), - _buildSwitchRow( - title: '친구 신청', - subtitle: '나에게 새로운 친구 요청이 도착할 때 알림', - value: settings.friendRequestNotifications, - onChanged: (val) => notifier.toggle('friend', val), - ), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // ── 전체 알림 ─────────────────────────────── + const SizedBox(height: 16), + _buildSwitchRow( + title: '전체 알림', + subtitle: '모든 알림 받기', + value: settings.allNotifications, + onChanged: (val) => notifier.toggleAll(val), + isMain: true, + ), + const SizedBox(height: 20), + const Divider(color: AppColors.gray4, height: 1), + const SizedBox(height: 20), - _buildSectionHeader('챌린지'), - _buildSwitchRow( - title: '챌린지 초대', - subtitle: '새로운 챌린지 참여 제안을 받았을 때 알림', - value: settings.challengeInviteNotifications, - onChanged: (val) => notifier.toggle('invite', val), - ), - _buildSwitchRow( - title: '동기부여 메시지', - subtitle: '꾸준한 챌린지 참여를 돕는 응원 푸시 알림', - value: settings.motivationNotifications, - onChanged: (val) => notifier.toggle('motivation', val), - ), - _buildSwitchRow( - title: '일일 리마인더 (전체)', - subtitle: '리마인더 알림 통합 관리', - value: settings.dailyReminder, // 전용 필드로 수정 - onChanged: (val) => notifier.toggle('reminder', val), - ), + // ── 소셜 섹션 ──────────────────────────────── + _buildSectionHeader('소셜'), + const SizedBox(height: 10), + Column( + spacing: 20, + children: [ + _buildSwitchRow( + title: '내 글 좋아요', + subtitle: "내 게시물에 '좋아요' 반응이 올 때 알림", + value: settings.likeNotifications, + onChanged: (val) => notifier.toggleLikes(val), + ), + _buildSwitchRow( + title: '댓글', + subtitle: '내 글에 새로운 댓글이 달릴 때 알림', + value: settings.commentNotifications, + onChanged: (val) => notifier.toggleComments(val), + ), + _buildSwitchRow( + title: '친구 신청', + subtitle: '나에게 새로운 친구 요청이 도착할 때 알림', + value: settings.friendRequestNotifications, + onChanged: (val) => notifier.toggleFriend(val), + ), + _buildSwitchRow( + title: '멤버 인증 소식 (전체)', + subtitle: '멤버 인증 알림 통합 관리', + value: settings.memberAuthNotifications, + onChanged: (val) => notifier.toggleMemberAuth(val), + ), + ], + ), + const SizedBox(height: 42), - _buildSectionHeader('커뮤니티 활동'), - _buildSwitchRow( - title: '멤버 반응 소식 (전체)', - subtitle: '멤버 반응 알림 통합 관리', - value: settings.likeNotifications, // 좋아요/댓글 등 소식 연결 - onChanged: (val) => notifier.toggle('like', val), - ), - _buildSwitchRow( - title: '멤버 인증 소식 (전체)', - subtitle: '멤버 인증 알림 통합 관리', - value: settings.memberAuthNotifications, - onChanged: (val) => notifier.toggle('memberAuth', val), - ), - const SizedBox(height: 40), - ], + // ── 챌린지 섹션 ────────────────────────────── + _buildSectionHeader('챌린지'), + const SizedBox(height: 10), + Column( + spacing: 20, + children: [ + _buildSwitchRow( + title: '챌린지 초대', + subtitle: '새로운 챌린지 참여 제안을 받았을 때 알림', + value: settings.challengeInviteNotifications, + onChanged: (val) => notifier.toggleChallengeInvite(val), + ), + _buildSwitchRow( + title: '동기부여 메시지', + subtitle: '꾸준한 챌린지 참여를 돕는 응원 푸시 알림', + value: settings.motivationNotifications, + onChanged: (val) => notifier.toggleMotivation(val), + ), + // ── 일일 리마인더 (시간 피커 없음) ────────────── + _buildSwitchRow( + title: '일일 리마인더 (전체)', + subtitle: '리마인더 알림 통합 관리', + value: settings.dailyReminder, + onChanged: (val) => notifier.toggleDailyReminder(val), + ), + // ── 실패 방지 리마인더 ───────────────────── + _buildWeeklyReminderSection(settings, notifier), + ], + ), + const SizedBox(height: 100), + ], + ), ), ), ); } - // 섹션 제목 위젯 + // ── 섹션 헤더 ──────────────────────────────────────────── Widget _buildSectionHeader(String title) { - return Padding( - padding: const EdgeInsets.only(left: 20, top: 20, bottom: 10), - child: Text( - title, - style: AppTypography.b1.copyWith(color: AppColors.gray1), - ), + return Text( + title, + style: AppTypography.b1.copyWith(color: AppColors.gray1), ); } - // 토글 타일 위젯 + // ── 스위치 행 ──────────────────────────────────────────── Widget _buildSwitchRow({ required String title, required String subtitle, @@ -135,33 +421,30 @@ class PushNotificationSettingsScreen extends ConsumerWidget { required ValueChanged onChanged, bool isMain = false, }) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - title, - style: AppTypography.b1.copyWith( - color: AppColors.black, - fontWeight: isMain ? FontWeight.w600 : FontWeight.w500, - ), - ), - Text( - subtitle, - style: AppTypography.b2.copyWith(color: AppColors.gray2), + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: AppTypography.b1.copyWith( + color: AppColors.black, + fontWeight: isMain ? FontWeight.w600 : FontWeight.w500, ), - ], - ), + ), + Text( + subtitle, + style: AppTypography.b2.copyWith(color: AppColors.gray2), + ), + ], ), - // 2. 커스텀 스위치 적용 - CustomSwitch(value: value, onChanged: onChanged), - ], - ), + ), + CustomSwitch(value: value, onChanged: onChanged), + ], ); } } diff --git a/lib/features/user/widgets/logout_dialog.dart b/lib/features/user/widgets/logout_dialog.dart index 659a9a8..b575313 100644 --- a/lib/features/user/widgets/logout_dialog.dart +++ b/lib/features/user/widgets/logout_dialog.dart @@ -8,6 +8,7 @@ import '../../../../core/theme/app_typography.dart'; import 'package:haenaem/features/notification/services/fcm_service.dart'; import 'package:haenaem/features/auth/services/auth_service.dart'; import 'package:haenaem/features/auth/signup/screens/auth_gate.dart'; +import 'package:haenaem/features/notification/provider/push_notification_provider.dart'; class LogoutDialog extends ConsumerWidget { const LogoutDialog({super.key}); @@ -55,11 +56,18 @@ class LogoutDialog extends ConsumerWidget { // Navigator.pop(context); // 2. FCM 토큰 삭제 (알림 방지) - await ref.read(fcmServiceProvider).deleteFcmToken(); + try { + await ref.read(fcmServiceProvider).deleteFcmToken(); + } catch (e) { + debugPrint('FCM 토큰 삭제 실패 (로그아웃은 계속 진행): $e'); + } // 3. 로그아웃 API 호출 및 로컬 데이터 삭제 await AuthService.logout(); + // ✅ 알림 설정 상태 초기화 + ref.invalidate(pushNotificationProvider); + // 4. 화면 이동 (context가 유효한지 확인 후 실행) if (context.mounted) { // rootNavigator: true를 사용하여 최상단 네비게이터 기준으로 이동 diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index a9cc2e1..aae2b5c 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -10,7 +10,6 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST - jni ) set(PLUGIN_BUNDLED_LIBRARIES) diff --git a/pubspec.lock b/pubspec.lock index 84d20eb..c8289f0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1065,10 +1065,10 @@ packages: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.16.0" mime: dependency: transitive description: @@ -1454,10 +1454,10 @@ packages: dependency: transitive description: name: test_api - sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.7" + version: "0.7.6" timing: dependency: transitive description: diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index e93c7e2..2fad67b 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -12,7 +12,6 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST - jni ) set(PLUGIN_BUNDLED_LIBRARIES)

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 JPDHLkV1l4{N~Zt- diff --git a/assets/images/profiles/user3.png b/assets/images/profiles/user3.png deleted file mode 100644 index d3e9c87d5d47f4251afcc4d1306c70a590f761ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 505341 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 JPDHLkV1l4{N~Zt- diff --git a/assets/images/profiles/user2.png b/assets/images/profiles/user2.png deleted file mode 100644 index d3e9c87d5d47f4251afcc4d1306c70a590f761ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 505341 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