From a659aafd6f20097ff85e2dfa020536c4024b3b86 Mon Sep 17 00:00:00 2001 From: akuby21 <39649594+akuby21@users.noreply.github.com> Date: Sat, 2 Dec 2023 01:12:21 +0900 Subject: [PATCH 01/14] Feat : AccountDetailPage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 계좌 상세항목 보는 페이지 생성 --- lib/main.dart | 6 + lib/view/account_detail_page.dart | 190 ++++++++++++++++++++++++++++++ lib/view/mypage_page.dart | 6 +- 3 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 lib/view/account_detail_page.dart diff --git a/lib/main.dart b/lib/main.dart index 0f65c1fb..46d57ad9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,6 +5,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:groupsettlement2/view/account_add_page.dart'; +import 'package:groupsettlement2/view/account_detail_page.dart'; import 'package:groupsettlement2/view/group_create_page.dart'; import 'package:groupsettlement2/view/group_main_page.dart'; import 'package:groupsettlement2/view/group_select_page.dart'; @@ -192,6 +193,11 @@ final GoRouter _router = GoRouter( builder: (context,state) { return AccountAddPage(); } + ), + GoRoute(path: 'AccountDetail', + builder: (context,state) { + return AccountDetailPage(); + } ) ] ), diff --git a/lib/view/account_detail_page.dart b/lib/view/account_detail_page.dart new file mode 100644 index 00000000..986444fb --- /dev/null +++ b/lib/view/account_detail_page.dart @@ -0,0 +1,190 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:groupsettlement2/view/shared_basic_widget.dart'; +import 'package:groupsettlement2/viewmodel/UserViewModel.dart'; + +import '../design_element.dart'; + +class AccountDetailPage extends ConsumerStatefulWidget { + const AccountDetailPage({Key? key}) : super(key: key); + + @override + ConsumerState createState() => _AccountDetailPageState(); +} + +class _AccountDetailPageState extends ConsumerState { + + @override + Widget build(BuildContext context) { + final Size size = MediaQuery.of(context).size; + final provider = ref.watch(userProvider); + print(provider.userData.accountInfo.length); + return Scaffold( + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(left:20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(width:1,height:size.height*0.12), + Text("마이페이지", + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.w400, + ) + ), + SizedBox(height:size.height*0.02), + Text("나의 계좌 목록", + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + ), + ) + ], + ), + ), + SizedBox(height:size.height*0.05), + Column( + children: List.generate(provider.userData.accountInfo.length, (index){ + String account = provider.userData.accountInfo[index]; + return oneAccount(accountNum: account,nickName: "임시",bankName: "대구은행",isFavorite: index == 0,); + }) + ), + + ], + ), + + bottomNavigationBar: CustomBottomNavigationBar(index: 4,isIn: false), + ); + } +} + +class oneAccount extends StatefulWidget { + final String nickName; + final String bankName; + final String accountNum; + final bool isFavorite; + const oneAccount({Key? key,required this.nickName, required this.accountNum, required this.bankName,required this.isFavorite}) : super(key: key); + + @override + State createState() => _oneAccountState(); +} + +class _oneAccountState extends State { + bool viewDetail = false; + @override + Widget build(BuildContext context) { + final Size size = MediaQuery.of(context).size; + double fontsize = widget.isFavorite ? 15 : 14; + double detailSize = widget.isFavorite ? size.height*0.22 : size.height*0.2; + double simpleSize = widget.isFavorite ? size.height*0.11 : size.height*0.075; + return GestureDetector( + onTap:(){ + setState(() { + viewDetail = !viewDetail; + }); + }, + child: AnimatedContainer( + duration: Duration(milliseconds: 10), + height: viewDetail ? detailSize : simpleSize, + child: SingleChildScrollView( + physics: NeverScrollableScrollPhysics(), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + widget.isFavorite ? Text("대표 계좌", + style: TextStyle( + color: color1, + fontSize:20, + fontWeight: FontWeight.w600 + ), + ) : SizedBox.shrink(), + Text(widget.nickName, + style: TextStyle( + fontSize: widget.isFavorite ? 20 : 17, + fontWeight: FontWeight.w600, + ), + ), + Row( + children: [ + Text(widget.bankName+" ", + style: TextStyle( + fontSize: fontsize, + fontWeight: FontWeight.w500, + ), + ), + viewDetail ? SizedBox.shrink(): Text(widget.accountNum, + style: TextStyle( + fontSize: fontsize, + fontWeight: FontWeight.w500, + ), + ) + ], + ), + viewDetail ? Text(widget.accountNum, + style: TextStyle( + fontSize: fontsize, + fontWeight: FontWeight.w500, + ), + ) : Divider(), + SizedBox(height:10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + width:size.width*0.42, + height: 60, + child: OutlinedButton( + onPressed: (){ + }, + style: OutlinedButton.styleFrom( + backgroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + child: Text("계좌 수정", + style: TextStyle( + color: Colors.black, + fontSize: 16, + fontWeight: FontWeight.w600, + ), + )) + ), + Container( + width:size.width*0.42, + height: 60, + child: OutlinedButton( + onPressed: (){ + }, + style: OutlinedButton.styleFrom( + backgroundColor: color1, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + child: Text("계좌 삭제", + style: TextStyle( + color:Colors.white, + fontSize: 16, + fontWeight: FontWeight.w600, + ), + )) + ), + ], + ), + Divider(), + + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/view/mypage_page.dart b/lib/view/mypage_page.dart index 623756b6..0a1cd805 100644 --- a/lib/view/mypage_page.dart +++ b/lib/view/mypage_page.dart @@ -189,7 +189,9 @@ class _MyPageState extends ConsumerState { ) ), GestureDetector( - onTap:(){}, + onTap:(){ + context.push("/MyPage/AccountDetail"); + }, child:const Text( "자세히 보기>", style: TextStyle( @@ -293,7 +295,7 @@ class _MyPageState extends ConsumerState { ), ), bottomNavigationBar: const CustomBottomNavigationBar( - index: 0, + index: 4, isIn: true, ), ); From 74f2e4676fe7cbabe5fb6e2427f6b7ad85d81da6 Mon Sep 17 00:00:00 2001 From: akuby21 <39649594+akuby21@users.noreply.github.com> Date: Sat, 2 Dec 2023 03:10:17 +0900 Subject: [PATCH 02/14] =?UTF-8?q?Fix=20:=20account,=20alarm=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/class/class_account.dart | 14 ++++++-------- lib/view/account_add_page.dart | 19 +++++++++++++------ lib/view/account_detail_page.dart | 7 ++++--- lib/view/mypage_page.dart | 8 +++++--- lib/view/notification_page.dart | 2 +- lib/viewmodel/UserViewModel.dart | 3 ++- 6 files changed, 31 insertions(+), 22 deletions(-) diff --git a/lib/class/class_account.dart b/lib/class/class_account.dart index fb1ee4b9..9715ac3a 100644 --- a/lib/class/class_account.dart +++ b/lib/class/class_account.dart @@ -9,13 +9,11 @@ class Account { String? accountHolder; String? accountAlias; - Account ({ - this.accountId, - this.bank, - this.accountNum, - this.accountHolder, - this.accountAlias - }); + + Account(){ + ModelUuid uuid = ModelUuid(); + accountId = uuid.randomId; + } Account.fromJson(dynamic json) { accountId = json['accountid']; @@ -33,7 +31,7 @@ class Account { 'accountalias' : accountAlias, }; - void creatAccount(String userid) async { + void createAccount(String userid) async { await FirebaseFirestore.instance.collection("accountlist").doc(accountId).set(toJson()); } diff --git a/lib/view/account_add_page.dart b/lib/view/account_add_page.dart index 5c33caa7..0cb9ee3f 100644 --- a/lib/view/account_add_page.dart +++ b/lib/view/account_add_page.dart @@ -2,18 +2,21 @@ import 'dart:math'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:groupsettlement2/view/shared_basic_widget.dart'; +import 'package:groupsettlement2/viewmodel/UserViewModel.dart'; +import '../class/class_account.dart'; import '../design_element.dart'; -class AccountAddPage extends StatefulWidget { +class AccountAddPage extends ConsumerStatefulWidget { const AccountAddPage({Key? key}) : super(key: key); @override - State createState() => _AccountAddPageState(); + ConsumerState createState() => _AccountAddPageState(); } -class _AccountAddPageState extends State { +class _AccountAddPageState extends ConsumerState { final List _banks = ["하나은행","국민은행","외환은행","기업은행","부산은행","신한은행","대구은행"]; String? bank; bool _makeFavorite = false; @@ -21,6 +24,7 @@ class _AccountAddPageState extends State { Widget build(BuildContext context) { final Size size = MediaQuery.of(context).size; String accountNum = ""; String ownerName = ""; + final provider = ref.watch(userProvider); return Scaffold( extendBodyBehindAppBar: true, appBar: AppBar( @@ -155,9 +159,12 @@ class _AccountAddPageState extends State { margin: EdgeInsets.only(bottom: 20), child: OutlinedButton( onPressed: (){ - print(bank); - print(ownerName); - print(accountNum); + // Account account = Account(); + // account.accountNum = accountNum; + // account.accountAlias = ; + // account.accountHolder = ownerName; + // account.bank = bank; + // provider.addAccount(account); }, style: OutlinedButton.styleFrom( backgroundColor: Color(0xFF454545), diff --git a/lib/view/account_detail_page.dart b/lib/view/account_detail_page.dart index 986444fb..fab7820d 100644 --- a/lib/view/account_detail_page.dart +++ b/lib/view/account_detail_page.dart @@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:groupsettlement2/view/shared_basic_widget.dart'; import 'package:groupsettlement2/viewmodel/UserViewModel.dart'; +import '../class/class_account.dart'; import '../design_element.dart'; class AccountDetailPage extends ConsumerStatefulWidget { @@ -48,9 +49,9 @@ class _AccountDetailPageState extends ConsumerState { ), SizedBox(height:size.height*0.05), Column( - children: List.generate(provider.userData.accountInfo.length, (index){ - String account = provider.userData.accountInfo[index]; - return oneAccount(accountNum: account,nickName: "임시",bankName: "대구은행",isFavorite: index == 0,); + children: List.generate(provider.accounts.length, (index){ + Account account = provider.accounts[index]; + return oneAccount(accountNum: account.accountNum.toString(),nickName: account.accountAlias!,bankName: account.bank!,isFavorite: index == 0,); }) ), diff --git a/lib/view/mypage_page.dart b/lib/view/mypage_page.dart index 0a1cd805..1216015a 100644 --- a/lib/view/mypage_page.dart +++ b/lib/view/mypage_page.dart @@ -5,6 +5,7 @@ import 'package:go_router/go_router.dart'; import 'package:groupsettlement2/view/shared_basic_widget.dart'; import 'package:flutter/services.dart'; +import '../class/class_account.dart'; import '../design_element.dart'; import '../viewmodel/UserViewModel.dart'; class MyPage extends ConsumerStatefulWidget { @@ -19,6 +20,7 @@ class _MyPageState extends ConsumerState { Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; var uvm = ref.watch(userProvider); + Account mainAccount = uvm.accounts.first; String inputName = ""; return Scaffold( body:SingleChildScrollView( @@ -214,7 +216,7 @@ class _MyPageState extends ConsumerState { children: [ GestureDetector( onTap: ()async{ - await Clipboard.setData(ClipboardData(text: uvm.userData.accountInfo.first)); + await Clipboard.setData(ClipboardData(text: uvm.accounts.first.accountNum.toString())); ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: const Center( child: Text( @@ -227,7 +229,7 @@ class _MyPageState extends ConsumerState { behavior: SnackBarBehavior.floating, )); }, - child: Text(uvm.userData.accountInfo.first, + child: Text(mainAccount.bank!+" "+mainAccount.accountNum.toString(), style: const TextStyle( fontWeight: FontWeight.w500, fontSize: 16, @@ -236,7 +238,7 @@ class _MyPageState extends ConsumerState { ), ), ), - Text("자유 지정 가능한 계좌 이름", + Text(mainAccount.accountAlias!, style: TextStyle( fontSize: 20, fontWeight: FontWeight.w600 diff --git a/lib/view/notification_page.dart b/lib/view/notification_page.dart index ba843ae2..2b610380 100644 --- a/lib/view/notification_page.dart +++ b/lib/view/notification_page.dart @@ -246,7 +246,7 @@ class _oneNotificationState extends State { return GestureDetector( onTap: (){ setState(() { - + print(widget.alarm.route); if(read == Colors.grey){ read = Colors.black; } else{ diff --git a/lib/viewmodel/UserViewModel.dart b/lib/viewmodel/UserViewModel.dart index d8b24493..fb25444f 100644 --- a/lib/viewmodel/UserViewModel.dart +++ b/lib/viewmodel/UserViewModel.dart @@ -42,6 +42,7 @@ class UserViewModel extends ChangeNotifier { fetchUser(userData.serviceUserId!); fetchSettlement(0, initialStmCount); fetchAlarm(userData.serviceUserId!); + fetchAccount(); return; } @@ -223,7 +224,7 @@ class UserViewModel extends ChangeNotifier { final userRef = db.collection("userlist").doc(userData.serviceUserId); db.runTransaction((transaction) async { userData.accountInfo.add(account.accountId!); - account.creatAccount(userData.serviceUserId!); + account.createAccount(userData.serviceUserId!); transaction.update(userRef, userData.toJson()); }).then( (value) { From 62ead2a1b3d3129ec1a77a31bd46dde434711dd9 Mon Sep 17 00:00:00 2001 From: akuby21 <39649594+akuby21@users.noreply.github.com> Date: Mon, 4 Dec 2023 03:35:55 +0900 Subject: [PATCH 03/14] Feat : MyPage with Account MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 계좌 기능을 연동한 마이페이지 개선 --- lib/view/mypage_page.dart | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/view/mypage_page.dart b/lib/view/mypage_page.dart index 1216015a..75aac10c 100644 --- a/lib/view/mypage_page.dart +++ b/lib/view/mypage_page.dart @@ -20,7 +20,6 @@ class _MyPageState extends ConsumerState { Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; var uvm = ref.watch(userProvider); - Account mainAccount = uvm.accounts.first; String inputName = ""; return Scaffold( body:SingleChildScrollView( @@ -99,7 +98,7 @@ class _MyPageState extends ConsumerState { ScaffoldMessenger.of(context).showSnackBar(const SnackBar( content: Text( '이름은 공백이 될 수 없습니다.'), - duration: Duration(seconds: 3), + duration: Duration(milliseconds: 1000), )); return; } @@ -110,7 +109,7 @@ class _MyPageState extends ConsumerState { ScaffoldMessenger.of(context).showSnackBar(const SnackBar( content: Text( '성공적으로 이름을 변경했습니다.'), - duration: Duration(seconds: 3), + duration: Duration(milliseconds: 1000), )); }, style: OutlinedButton.styleFrom( @@ -222,14 +221,14 @@ class _MyPageState extends ConsumerState { child: Text( '계좌번호가 복사되었습니다.'), ), - duration: const Duration(milliseconds: 1500), + duration: const Duration(milliseconds: 1000), width: size.width*0.5, backgroundColor: color1, shape: StadiumBorder(), behavior: SnackBarBehavior.floating, )); }, - child: Text(mainAccount.bank!+" "+mainAccount.accountNum.toString(), + child: Text(uvm.accounts.first.bank!+" "+uvm.accounts.first.accountNum.toString(), style: const TextStyle( fontWeight: FontWeight.w500, fontSize: 16, @@ -238,7 +237,7 @@ class _MyPageState extends ConsumerState { ), ), ), - Text(mainAccount.accountAlias!, + Text(uvm.accounts.first.accountAlias!, style: TextStyle( fontSize: 20, fontWeight: FontWeight.w600 From c647ec13f94291fd4580ea96b1d6077819c4a44b Mon Sep 17 00:00:00 2001 From: akuby21 <39649594+akuby21@users.noreply.github.com> Date: Mon, 4 Dec 2023 03:37:12 +0900 Subject: [PATCH 04/14] Feat : Adding Features to notificationPage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 알림 클릭 시 해당하는 뷰로 이동 기능, 알림이 온지 얼마나 지났는지, 사소한 디자인 변경 --- lib/view/notification_page.dart | 99 ++++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 27 deletions(-) diff --git a/lib/view/notification_page.dart b/lib/view/notification_page.dart index 2b610380..a6fc4b57 100644 --- a/lib/view/notification_page.dart +++ b/lib/view/notification_page.dart @@ -1,10 +1,16 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:go_router/go_router.dart'; import 'package:groupsettlement2/view/shared_basic_widget.dart'; import 'package:groupsettlement2/viewmodel/UserViewModel.dart'; +import 'package:intl/intl.dart'; import '../class/class_alarm.dart'; +import '../class/class_group.dart'; +import '../class/class_settlement.dart'; +import '../class/class_user.dart'; +import '../common_fireservice.dart'; import '../design_element.dart'; class NotificationPage extends ConsumerStatefulWidget { @@ -70,11 +76,11 @@ class _NotificationPageState extends ConsumerState with Ticker indicator: UnderlineTabIndicator( borderSide: BorderSide(width:3,color: cp.color), ), - //indicatorSize: TabBarIndicatorSize.values.first, + indicatorSize: TabBarIndicatorSize.tab, isScrollable: true, tabs:[ Container( - width:size.width*0.3, + width:size.width*0.25, child: Tab( text: "보낼 정산", @@ -87,7 +93,7 @@ class _NotificationPageState extends ConsumerState with Ticker ), ), Container( - width:size.width*0.1, + width:size.width*0.25, child: Tab( text: "기타", ), @@ -230,29 +236,53 @@ class _NotificationPageState extends ConsumerState with Ticker } } -class oneNotification extends StatefulWidget { +class oneNotification extends ConsumerStatefulWidget { final Alarm alarm; final Size size; const oneNotification({Key? key, required this.alarm,required this.size}) : super(key: key); @override - State createState() => _oneNotificationState(); + ConsumerState createState() => _oneNotificationState(); } -class _oneNotificationState extends State { - Color read = Colors.black; +class _oneNotificationState extends ConsumerState { + @override Widget build(BuildContext context) { + + final provider = ref.watch(userProvider); + + Color read = widget.alarm.isRead == true ? Colors.grey : Colors.black; + DateTime dt = widget.alarm.time != null + ? DateTime.parse(widget.alarm.time!.toDate().toString()) + : DateTime.utc(1000, 01, 01); + String timeAgo; + + if(DateTime.now().month - dt.month > 0){ + timeAgo = (DateTime.now().month - dt.month).toString() + "달 전"; + } else if(DateTime.now().day - dt.day > 0){ + timeAgo = (DateTime.now().day - dt.day).toString() + "일 전"; + } else if(DateTime.now().hour - dt.hour > 0){ + timeAgo = (DateTime.now().hour - dt.hour).toString() + "시간 전"; + } else if(DateTime.now().minute - dt.minute > 0){ + timeAgo = (DateTime.now().minute - dt.minute).toString() + "분 전"; + } else { + timeAgo = "방금"; + } + return GestureDetector( - onTap: (){ - setState(() { - print(widget.alarm.route); - if(read == Colors.grey){ - read = Colors.black; - } else{ - read = Colors.grey; - } - }); + onTap: ()async{ + print(widget.alarm.category); + var extra = await provider.linkAlarm(widget.alarm); + print(extra); + context.push(widget.alarm.route!,extra: extra); + + if(widget.alarm.isRead == false) { + widget.alarm.isRead = true; + } + await FireService().updateDoc("alarmlist/${provider.userData.serviceUserId}/myalarmlist", widget.alarm.alarmId!, widget.alarm.toJson()); + + }, child: Container( width: widget.size.width*0.9, @@ -260,19 +290,34 @@ class _oneNotificationState extends State { crossAxisAlignment: CrossAxisAlignment.start, children:[ SizedBox(height:10), - Text(widget.alarm.title!, - style: TextStyle( - fontWeight: FontWeight.w600, - fontSize: 18, - color: read, - ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(widget.alarm.title!, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 18, + color: read, + ), + ), + Text(timeAgo.toString(), + style: TextStyle( + fontWeight: FontWeight.w400, + fontSize: 13, + color: read, + ), + ) + ], ), SizedBox(height:5), - Text(widget.alarm.body == null ? "\n" : widget.alarm.body!, - style: TextStyle( - fontWeight: FontWeight.w500, - fontSize: 15, - color: read, + Container( + height:widget.size.height*0.03, + child: Text(widget.alarm.body == null ? "\n" : widget.alarm.body!, + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + color: read, + ), ), ), SizedBox(height:10), From 423bac76abec616c5babc7a483f3c7c7f197ce4a Mon Sep 17 00:00:00 2001 From: akuby21 <39649594+akuby21@users.noreply.github.com> Date: Mon, 4 Dec 2023 03:38:30 +0900 Subject: [PATCH 05/14] Refactor : Changed parameter for child widget --- lib/view/account_detail_page.dart | 247 +++++++++++++++++------------- 1 file changed, 140 insertions(+), 107 deletions(-) diff --git a/lib/view/account_detail_page.dart b/lib/view/account_detail_page.dart index fab7820d..4eaf14c6 100644 --- a/lib/view/account_detail_page.dart +++ b/lib/view/account_detail_page.dart @@ -15,7 +15,7 @@ class AccountDetailPage extends ConsumerStatefulWidget { } class _AccountDetailPageState extends ConsumerState { - + int viewDetailIndex = -1; @override Widget build(BuildContext context) { final Size size = MediaQuery.of(context).size; @@ -50,8 +50,16 @@ class _AccountDetailPageState extends ConsumerState { SizedBox(height:size.height*0.05), Column( children: List.generate(provider.accounts.length, (index){ - Account account = provider.accounts[index]; - return oneAccount(accountNum: account.accountNum.toString(),nickName: account.accountAlias!,bankName: account.bank!,isFavorite: index == 0,); + return GestureDetector( + onTap: (){ + setState(() { + viewDetailIndex = viewDetailIndex == index ? -1 : index; + }); + }, + child: oneAccount( + account: provider.accounts[index], + isFavorite: index == 0, + viewDetail: viewDetailIndex == index,)); }) ), @@ -63,127 +71,152 @@ class _AccountDetailPageState extends ConsumerState { } } -class oneAccount extends StatefulWidget { - final String nickName; - final String bankName; - final String accountNum; +class oneAccount extends ConsumerStatefulWidget { + final Account account; final bool isFavorite; - const oneAccount({Key? key,required this.nickName, required this.accountNum, required this.bankName,required this.isFavorite}) : super(key: key); + final bool viewDetail; + const oneAccount({Key? key,required this.account,required this.isFavorite,required this.viewDetail}) : super(key: key); @override - State createState() => _oneAccountState(); + ConsumerState createState() => _oneAccountState(); } -class _oneAccountState extends State { - bool viewDetail = false; +class _oneAccountState extends ConsumerState { + @override Widget build(BuildContext context) { + bool viewDetail = widget.viewDetail; final Size size = MediaQuery.of(context).size; double fontsize = widget.isFavorite ? 15 : 14; - double detailSize = widget.isFavorite ? size.height*0.22 : size.height*0.2; - double simpleSize = widget.isFavorite ? size.height*0.11 : size.height*0.075; - return GestureDetector( - onTap:(){ - setState(() { - viewDetail = !viewDetail; - }); - }, - child: AnimatedContainer( - duration: Duration(milliseconds: 10), - height: viewDetail ? detailSize : simpleSize, - child: SingleChildScrollView( - physics: NeverScrollableScrollPhysics(), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - widget.isFavorite ? Text("대표 계좌", - style: TextStyle( - color: color1, - fontSize:20, - fontWeight: FontWeight.w600 - ), - ) : SizedBox.shrink(), - Text(widget.nickName, - style: TextStyle( - fontSize: widget.isFavorite ? 20 : 17, - fontWeight: FontWeight.w600, + double detailSize = widget.isFavorite ? size.height*0.23 : size.height*0.18; + double simpleSize = widget.isFavorite ? size.height*0.11 : size.height*0.08; + final provider = ref.watch(userProvider); + return AnimatedContainer( + curve: Curves.fastEaseInToSlowEaseOut, + duration: Duration(milliseconds: 500), + height: viewDetail ? detailSize : simpleSize, + child: SingleChildScrollView( + physics: NeverScrollableScrollPhysics(), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + widget.isFavorite ? Text("대표 계좌", + style: TextStyle( + color: color1, + fontSize:20, + fontWeight: FontWeight.w600 + ), + ) : SizedBox.shrink(), + Text(widget.account.accountAlias!, + style: TextStyle( + fontSize: widget.isFavorite ? 20 : 17, + fontWeight: FontWeight.w600, + ), ), - ), - Row( - children: [ - Text(widget.bankName+" ", - style: TextStyle( - fontSize: fontsize, - fontWeight: FontWeight.w500, + Row( + children: [ + Text(widget.account.bank!+" ", + style: TextStyle( + fontSize: fontsize, + fontWeight: FontWeight.w500, + ), ), + viewDetail ? SizedBox.shrink(): Text(widget.account.accountNum!.toString(), + style: TextStyle( + fontSize: fontsize, + fontWeight: FontWeight.w500, + ), + ) + ], + ), + viewDetail ? Text(widget.account.accountNum!.toString(), + style: TextStyle( + fontSize: fontsize, + fontWeight: FontWeight.w500, ), - viewDetail ? SizedBox.shrink(): Text(widget.accountNum, - style: TextStyle( - fontSize: fontsize, - fontWeight: FontWeight.w500, - ), + ) : Divider(), + SizedBox(height:10), + + + ], + ), + ), + Container( + height: 80, + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.7), + ), + const BoxShadow( + color: Color(0xFFF4F4F4), + spreadRadius: -2.0, + blurRadius: 4.0, ) - ], - ), - viewDetail ? Text(widget.accountNum, - style: TextStyle( - fontSize: fontsize, - fontWeight: FontWeight.w500, + ] + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + width:size.width*0.44, + height: 55, + margin: EdgeInsets.only(left:15), + child: OutlinedButton( + onPressed: (){ + provider.accounts.remove(widget.account); + provider.accounts.insert(0,widget.account); + + }, + style: OutlinedButton.styleFrom( + backgroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + side: const BorderSide( + color: Color(0xFFD9D9D9), + ), + ), + child: Text("계좌 수정", + style: TextStyle( + color: Colors.black, + fontSize: 16, + fontWeight: FontWeight.w600, + ), + )) ), - ) : Divider(), - SizedBox(height:10), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - width:size.width*0.42, - height: 60, - child: OutlinedButton( - onPressed: (){ - }, - style: OutlinedButton.styleFrom( - backgroundColor: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), + Container( + width:size.width*0.44, + height: 55, + margin: EdgeInsets.only(right:15), + child: OutlinedButton( + onPressed: (){ + }, + style: OutlinedButton.styleFrom( + backgroundColor: color1, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), ), - child: Text("계좌 수정", - style: TextStyle( - color: Colors.black, - fontSize: 16, - fontWeight: FontWeight.w600, - ), - )) - ), - Container( - width:size.width*0.42, - height: 60, - child: OutlinedButton( - onPressed: (){ - }, - style: OutlinedButton.styleFrom( - backgroundColor: color1, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), + side: const BorderSide( + color: Colors.transparent ), - child: Text("계좌 삭제", - style: TextStyle( - color:Colors.white, - fontSize: 16, - fontWeight: FontWeight.w600, - ), - )) - ), - ], - ), - Divider(), - - ], + ), + child: Text("계좌 삭제", + style: TextStyle( + color:Colors.white, + fontSize: 16, + fontWeight: FontWeight.w600, + ), + )) + ), + ], + ), ), - ), + ], ), ), ); From e330e66334be43fa0979aa4228ecad34e1188a57 Mon Sep 17 00:00:00 2001 From: akuby21 <39649594+akuby21@users.noreply.github.com> Date: Mon, 4 Dec 2023 03:39:09 +0900 Subject: [PATCH 06/14] Feat : account add page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 실제 계좌 추가 가능 계좌번호 숫자 아닐 시 에러 메시지 출력 --- lib/view/account_add_page.dart | 61 ++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/lib/view/account_add_page.dart b/lib/view/account_add_page.dart index 0cb9ee3f..7a353f77 100644 --- a/lib/view/account_add_page.dart +++ b/lib/view/account_add_page.dart @@ -2,6 +2,7 @@ import 'dart:math'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:groupsettlement2/view/shared_basic_widget.dart'; import 'package:groupsettlement2/viewmodel/UserViewModel.dart'; @@ -19,11 +20,12 @@ class AccountAddPage extends ConsumerStatefulWidget { class _AccountAddPageState extends ConsumerState { final List _banks = ["하나은행","국민은행","외환은행","기업은행","부산은행","신한은행","대구은행"]; String? bank; + String accountNum = ""; String ownerName = ""; String accountNickname = ""; bool _makeFavorite = false; @override Widget build(BuildContext context) { final Size size = MediaQuery.of(context).size; - String accountNum = ""; String ownerName = ""; + final provider = ref.watch(userProvider); return Scaffold( extendBodyBehindAppBar: true, @@ -85,7 +87,23 @@ class _AccountAddPageState extends ConsumerState { color: Colors.black, ), ), - SizedBox(height:size.height*0.12), + SizedBox(height:size.height*0.06), + Text("계좌 별명을 입력해주세요.", + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w500, + color: Colors.black, + ), + ), + TextField( + decoration: InputDecoration( + hintText: "계좌 별명", + ), + onChanged: (val){ + accountNickname = val; + }, + ), + SizedBox(height:20), Text("은행사를 선택해주세요.", style: TextStyle( fontSize: 18, @@ -94,10 +112,9 @@ class _AccountAddPageState extends ConsumerState { ), ), Container( - width: size.width*0.9, + width: size.width*0.4, child: DropdownButton( isExpanded: true, - value: bank, items: _banks.map((e)=> DropdownMenuItem(child: Text(e),value: e,)).toList(), @@ -119,6 +136,13 @@ class _AccountAddPageState extends ConsumerState { ), ), TextField( + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], + decoration: InputDecoration( + hintText: "계좌번호 ('-'기호를 제외하고 입력\)", + ), onChanged: (val){ accountNum = val; }, @@ -132,6 +156,9 @@ class _AccountAddPageState extends ConsumerState { ), ), TextField( + decoration: InputDecoration( + hintText: "예금주ㅅ", + ), onChanged: (val){ ownerName = val; }, @@ -145,6 +172,9 @@ class _AccountAddPageState extends ConsumerState { contentPadding: EdgeInsets.zero, dense : true, activeColor: Colors.black, + checkboxShape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(100) + ), onChanged: (val){ setState(() { _makeFavorite = !_makeFavorite; @@ -159,12 +189,23 @@ class _AccountAddPageState extends ConsumerState { margin: EdgeInsets.only(bottom: 20), child: OutlinedButton( onPressed: (){ - // Account account = Account(); - // account.accountNum = accountNum; - // account.accountAlias = ; - // account.accountHolder = ownerName; - // account.bank = bank; - // provider.addAccount(account); + Account account = Account(); + try{ + account.accountNum = int.parse(accountNum); + }catch(e){ + print(e); + ScaffoldMessenger.of(context).showSnackBar(const SnackBar( + content: Text( + '계좌번호에는 숫자만 넣어주세요.'), + duration: Duration(seconds: 2), + )); + return; + } + account.accountAlias = accountNickname; + account.accountHolder = ownerName; + account.bank = bank; + + provider.addAccount(account,_makeFavorite); }, style: OutlinedButton.styleFrom( backgroundColor: Color(0xFF454545), From 775bb617f4944963d1f8080f06c3b7a5ffdcb903 Mon Sep 17 00:00:00 2001 From: akuby21 <39649594+akuby21@users.noreply.github.com> Date: Mon, 4 Dec 2023 03:40:47 +0900 Subject: [PATCH 07/14] Refactor : added methods for notification, accountAdd page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 알람 클릭시 뷰로 이동하는 linkAlarm구현, alarm의 route를 통해 어디로 갈지 케이스 나눔 addAccount 메서드에 isFavorite을 넣어 true일시 대표 계좌로 추가 --- lib/viewmodel/UserViewModel.dart | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/viewmodel/UserViewModel.dart b/lib/viewmodel/UserViewModel.dart index fb25444f..432e8b66 100644 --- a/lib/viewmodel/UserViewModel.dart +++ b/lib/viewmodel/UserViewModel.dart @@ -51,6 +51,20 @@ class UserViewModel extends ChangeNotifier { ..sort((e1, e2) => e2.key.time!.compareTo(e1.key.time!))); } + Future> linkAlarm(Alarm alarm)async{ + if(alarm.route == "/MyPage"){ + return []; + } else if(alarm.route == "/GroupSelect/GroupMain"){ + Group group = await Group().getGroupByGroupId(alarm.args[1]); + return [userData,group]; + } else if(alarm.route == "/SettlementInformation"){ + Settlement stm = await Settlement().getSettlementBySettlementId(alarm.args[0]); + Group group = await Group().getGroupByGroupId(alarm.args[1]); + return [stm,group,userData]; + } + return []; + } + Future editUsername(String newName) async{ userData.name = newName; FireService().updateDoc("userlist", userData.serviceUserId!, userData.toJson()); @@ -190,11 +204,6 @@ class UserViewModel extends ChangeNotifier { notifyListeners(); } - //해당 알림 클릭시 이동할 페이지 지정(미구현) - void linkAlarm() { - - } - Future deleteAlarm(int category, Alarm removeAlarm) async { final alarmRef = db.collection("alarmlist/" + userData.serviceUserId! + "/myalarmlist"); @@ -220,10 +229,14 @@ class UserViewModel extends ChangeNotifier { } - void addAccount(Account account) async { + void addAccount(Account account,bool isFavorite) async { final userRef = db.collection("userlist").doc(userData.serviceUserId); db.runTransaction((transaction) async { - userData.accountInfo.add(account.accountId!); + if(isFavorite){ + userData.accountInfo.insert(0,account.accountId!); + } else { + userData.accountInfo.add(account.accountId!); + } account.createAccount(userData.serviceUserId!); transaction.update(userRef, userData.toJson()); }).then( From 53e2c8e0a09a50f456a92b78a8ad51b69ec12bd5 Mon Sep 17 00:00:00 2001 From: akuby21 <39649594+akuby21@users.noreply.github.com> Date: Mon, 4 Dec 2023 15:36:09 +0900 Subject: [PATCH 08/14] Refactor : Group pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 그룹 선택 화면에 시간 표시 - 가장 최근 생성된 정산으로부터 지난 시간 그룹 메인 화면의 정산 생성 버튼 --- lib/view/group_main_page.dart | 35 ++++++++++++++++---------------- lib/view/group_select_page.dart | 21 +++++++++---------- lib/view/notification_page.dart | 17 +--------------- lib/viewmodel/UserViewModel.dart | 34 +++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 44 deletions(-) diff --git a/lib/view/group_main_page.dart b/lib/view/group_main_page.dart index 56c22f09..ea07ceab 100644 --- a/lib/view/group_main_page.dart +++ b/lib/view/group_main_page.dart @@ -25,11 +25,11 @@ class _GroupMainPageState extends ConsumerState { int i = 0; @override Widget build(BuildContext context) { - final gvm = ref.watch(groupProvider); + final provider = ref.watch(groupProvider); Size size = MediaQuery.of(context).size; if (isFirst) { Future(() { - gvm.settingGroupViewModel(widget.info[0], widget.info[1]); + provider.settingGroupViewModel(widget.info[0], widget.info[1]); }); ref .watch(bottomSheetSliderChangeNotifierProvider.notifier) @@ -41,7 +41,7 @@ class _GroupMainPageState extends ConsumerState { final bottomsheetValue = ref.watch(bottomSheetSliderChangeNotifierProvider); Map countMap = Map(); - gvm.settlementInGroup.forEach((settlement) { + provider.settlementInGroup.forEach((settlement) { if (countMap.containsKey(settlement.masterUserId)) { countMap[settlement.masterUserId!] = countMap[settlement.masterUserId!]! + 1; @@ -60,7 +60,7 @@ class _GroupMainPageState extends ConsumerState { } }); - gvm.serviceUsers.forEach((user) { + provider.serviceUsers.forEach((user) { if (user.serviceUserId == mostCommonName) commonStmName = user.name!; }); @@ -86,7 +86,7 @@ class _GroupMainPageState extends ConsumerState { ), Row(children: [ Text( - gvm.myGroup.groupName ?? "", + provider.myGroup.groupName ?? "", style: const TextStyle( color: Colors.black, fontSize: 30, @@ -112,8 +112,8 @@ class _GroupMainPageState extends ConsumerState { onPressed: () { Navigator.of(context).pop(); setState(() { - gvm.updateGroup( - gvm.myGroup.groupId!, inputName); + provider.updateGroup( + provider.myGroup.groupId!, inputName); }); }, style: OutlinedButton.styleFrom( @@ -179,7 +179,7 @@ class _GroupMainPageState extends ConsumerState { text: " ", ), TextSpan( - text: gvm.settlementInGroup.length.toString(), + text: provider.settlementInGroup.length.toString(), style: const TextStyle( color: Color(0xFFFE5F55), fontSize: 25, @@ -207,13 +207,13 @@ class _GroupMainPageState extends ConsumerState { SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( - children: List.generate(gvm.settlementInGroup.length, + children: List.generate(provider.settlementInGroup.length, (index) { - Settlement settlement = gvm.settlementInGroup[index]; + Settlement settlement = provider.settlementInGroup[index]; return StmItem( size: size, masterId: settlement.masterUserId!, - userId: gvm.userData.serviceUserId!, + userId: provider.userData.serviceUserId!, settlement: settlement); })), ), @@ -236,7 +236,7 @@ class _GroupMainPageState extends ConsumerState { TextSpan( children: [ TextSpan( - text: '${gvm.myGroup.groupName} 그룹에서 가장 많이 \n', + text: '${provider.myGroup.groupName} 그룹에서 가장 많이 \n', style: TextStyle( color: Colors.black, fontSize: 15, @@ -271,7 +271,8 @@ class _GroupMainPageState extends ConsumerState { SizedBox(height: 20), GestureDetector( onTap: () { - // context.push(); + context.push( + "/SettlementCreate", extra: [provider.myGroup, provider.userData]); }, child: Padding( padding: EdgeInsets.only(right: 15), @@ -349,7 +350,7 @@ class _GroupMainPageState extends ConsumerState { EdgeInsets.only(left: size.width * 0.65), child: Text.rich(TextSpan(children: [ TextSpan( - text: "${gvm.serviceUsers.length} ", + text: "${provider.serviceUsers.length} ", style: TextStyle( color: Color(0xFFFE5F55), fontSize: 20, @@ -418,7 +419,7 @@ class _GroupMainPageState extends ConsumerState { SizedBox(height: 20), Column( children: List.generate( - (gvm.serviceUsers.length / 4) + (provider.serviceUsers.length / 4) .toInt() + 1, (index) { return Row( @@ -427,7 +428,7 @@ class _GroupMainPageState extends ConsumerState { try { return oneUser( flag: false, - user: gvm.serviceUsers[ + user: provider.serviceUsers[ index * 4 + innerIndex]); } on RangeError catch (e) { @@ -517,7 +518,7 @@ class _GroupMainPageState extends ConsumerState { ServiceUser user = ServiceUser(); if (inputName != null) { - gvm.addByDirect( + provider.addByDirect( inputName!); } else { ScaffoldMessenger.of( diff --git a/lib/view/group_select_page.dart b/lib/view/group_select_page.dart index ee1bb241..a6ed73f9 100644 --- a/lib/view/group_select_page.dart +++ b/lib/view/group_select_page.dart @@ -5,6 +5,7 @@ import 'package:go_router/go_router.dart'; import 'package:groupsettlement2/class/class_user.dart'; import 'package:groupsettlement2/view/shared_basic_widget.dart'; import '../class/class_group.dart'; +import '../class/class_settlement.dart'; import '../design_element.dart'; import '../viewmodel/UserViewModel.dart'; @@ -115,13 +116,14 @@ class OneGroup extends ConsumerStatefulWidget { class _OneGroupState extends ConsumerState { @override Widget build(BuildContext context) { - var uvm = ref.watch(userProvider); + var provider = ref.watch(userProvider); + return Column( children: [ GestureDetector( onTap: () { context.push("/GroupSelect/GroupMain", - extra: [uvm.userData, widget.group.groupId!]); + extra: [provider.userData, widget.group.groupId!]); }, child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -167,15 +169,12 @@ class _OneGroupState extends ConsumerState { ), ], ), - GestureDetector( - onTap: () {}, - child: const Padding( - padding: EdgeInsets.only(bottom: 25), - child: Text("시간", - style: TextStyle( - color: Color(0xFF838383), - )), - ), + Padding( + padding: EdgeInsets.only(bottom: 25), + child: Text(provider.getGroupRecentActivityTime(widget.group), + style: TextStyle( + color: Color(0xFF838383), + )), ) ]), ), diff --git a/lib/view/notification_page.dart b/lib/view/notification_page.dart index a6fc4b57..9ef94b8c 100644 --- a/lib/view/notification_page.dart +++ b/lib/view/notification_page.dart @@ -253,22 +253,7 @@ class _oneNotificationState extends ConsumerState { final provider = ref.watch(userProvider); Color read = widget.alarm.isRead == true ? Colors.grey : Colors.black; - DateTime dt = widget.alarm.time != null - ? DateTime.parse(widget.alarm.time!.toDate().toString()) - : DateTime.utc(1000, 01, 01); - String timeAgo; - - if(DateTime.now().month - dt.month > 0){ - timeAgo = (DateTime.now().month - dt.month).toString() + "달 전"; - } else if(DateTime.now().day - dt.day > 0){ - timeAgo = (DateTime.now().day - dt.day).toString() + "일 전"; - } else if(DateTime.now().hour - dt.hour > 0){ - timeAgo = (DateTime.now().hour - dt.hour).toString() + "시간 전"; - } else if(DateTime.now().minute - dt.minute > 0){ - timeAgo = (DateTime.now().minute - dt.minute).toString() + "분 전"; - } else { - timeAgo = "방금"; - } + String timeAgo = provider.getTimeAgo(widget.alarm.time!); return GestureDetector( onTap: ()async{ diff --git a/lib/viewmodel/UserViewModel.dart b/lib/viewmodel/UserViewModel.dart index 432e8b66..1d5db97d 100644 --- a/lib/viewmodel/UserViewModel.dart +++ b/lib/viewmodel/UserViewModel.dart @@ -279,6 +279,40 @@ class UserViewModel extends ChangeNotifier { notifyListeners(); } + String getGroupRecentActivityTime(Group group){ + Settlement recentStm = Settlement(); + if(group.settlements.isEmpty){ + return ""; + } + for(var stm in settlementInfo.keys){ + if(stm.settlementId == group.settlements.last){ + recentStm = stm; + } + } + return getTimeAgo(recentStm.time!); + } + + String getTimeAgo(Timestamp time){ + DateTime dt = time != null + ? DateTime.parse(time!.toDate().toString()) + : DateTime.utc(1000, 01, 01); + String timeAgo; + + if(DateTime.now().month - dt.month > 0){ + timeAgo = (DateTime.now().month - dt.month).toString() + "개월 전"; + } else if(DateTime.now().day - dt.day > 0){ + timeAgo = (DateTime.now().day - dt.day).toString() + "일 전"; + } else if(DateTime.now().hour - dt.hour > 0){ + timeAgo = (DateTime.now().hour - dt.hour).toString() + "시간 전"; + } else if(DateTime.now().minute - dt.minute > 0){ + timeAgo = (DateTime.now().minute - dt.minute).toString() + "분 전"; + } else { + timeAgo = "방금"; + } + + return timeAgo; + } + double getCurrentMoney(Settlement settlement) { double currentMoney = 0; From 9e5c9546158b140ede993e414b9f83be159107a9 Mon Sep 17 00:00:00 2001 From: akuby21 <39649594+akuby21@users.noreply.github.com> Date: Mon, 4 Dec 2023 15:36:37 +0900 Subject: [PATCH 09/14] Refactor : Main page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 사소한 위젯 구성수정 --- lib/view/main_page.dart | 125 +++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 60 deletions(-) diff --git a/lib/view/main_page.dart b/lib/view/main_page.dart index 86b453e5..22af455e 100644 --- a/lib/view/main_page.dart +++ b/lib/view/main_page.dart @@ -718,15 +718,15 @@ class _RecentSettlementState extends ConsumerState { @override Widget build(BuildContext context) { - var mvm = ref.watch(userProvider); + var provider = ref.watch(userProvider); bool masterFlag = - widget.settlement.masterUserId == mvm.userData.serviceUserId; - barSize = widget.size.width * 0.67; - currentMoney = mvm.getCurrentMoney(widget.settlement); - totalPrice = mvm.getTotalPrice(widget.settlement); + widget.settlement.masterUserId == provider.userData.serviceUserId; + barSize = widget.size.width * 0.64; + currentMoney = provider.getCurrentMoney(widget.settlement); + totalPrice = provider.getTotalPrice(widget.settlement); if (!masterFlag) { - sendMoney = mvm.getSendMoney(widget.settlement); - _didSend = widget.settlement.checkSent[mvm.userData.serviceUserId] == 2; + sendMoney = provider.getSendMoney(widget.settlement); + _didSend = widget.settlement.checkSent[provider.userData.serviceUserId] == 2; } dt = widget.settlement.time != null ? DateTime.parse(widget.settlement.time!.toDate().toString()) @@ -736,12 +736,12 @@ class _RecentSettlementState extends ConsumerState { GestureDetector( onTap: () { context.go( - "/SettlementInformation", extra: [widget.settlement, mvm.myGroup[mvm.myGroup.indexWhere((group) { + "/SettlementInformation", extra: [widget.settlement, provider.myGroup[provider.myGroup.indexWhere((group) { if (group.groupId == widget.settlement.groupId){ return true; } return false; - })], mvm.userData]); + })], provider.userData]); }, child: Row( mainAxisAlignment: MainAxisAlignment.center, @@ -796,7 +796,7 @@ class _RecentSettlementState extends ConsumerState { ])), Padding( padding: const EdgeInsets.only(top: 20, left: 5), - child: Text(mvm.getGroupName(widget.settlement), + child: Text(provider.getGroupName(widget.settlement), style: TextStyle( color: Colors.grey, fontWeight: FontWeight.w600)), @@ -814,58 +814,63 @@ class _RecentSettlementState extends ConsumerState { child: Divider(), ), Row( - //mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: EdgeInsets.only(left: 10), - child: Text(masterFlag ? "받을 금액" : "보낼 금액", - style: TextStyle( - color: Colors.grey, - fontSize: 12, - fontWeight: FontWeight.w600)), - ), - Padding( - padding: EdgeInsets.only(left: 10), - child: Text( - masterFlag - ? priceToString.format(currentMoney) - : _didSend - ? "송금 완료" - : priceToString.format(sendMoney), - style: TextStyle( - color: masterFlag ? color1 : color2, - fontWeight: FontWeight.w600, - fontSize: 20)), - ), - Text( - masterFlag - ? " / ${priceToString.format(totalPrice)}" - : "", - style: TextStyle( - color: Colors.grey, - fontSize: 15, - fontWeight: FontWeight.w800)), - Padding( - padding: const EdgeInsets.only(left: 35), - child: Text( - masterFlag - ? currentMoney == totalPrice - ? "정산이 완료되었습니다" - : "" - : widget.settlement.checkSent[mvm - .userData.serviceUserId] == - 2 - ? "" - : "항목을 눌러 송금 확인하기", - //정산 완료 확인 체크필요 - style: TextStyle( - color: masterFlag ? color1 : color2, - fontWeight: FontWeight.w600, - fontSize: 13, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + //mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: EdgeInsets.only(left: 10), + child: Text(masterFlag ? "받을 금액" : "보낼 금액", + style: TextStyle( + color: Colors.grey, + fontSize: 12, + fontWeight: FontWeight.w600)), ), + Padding( + padding: EdgeInsets.only(left: 10), + child: Text( + masterFlag + ? priceToString.format(currentMoney) + : _didSend + ? "송금 완료" + : priceToString.format(sendMoney), + style: TextStyle( + color: masterFlag ? color1 : color2, + fontWeight: FontWeight.w600, + fontSize: 20)), + ), + Text( + masterFlag + ? " / ${priceToString.format(totalPrice)}" + : "", + style: TextStyle( + color: Colors.grey, + fontSize: 15, + fontWeight: FontWeight.w800)), + ]), + Padding( + padding: const EdgeInsets.only(right:10), + child: Text( + masterFlag + ? currentMoney == totalPrice + ? "정산이 완료되었습니다" + : "" + : widget.settlement.checkSent[provider + .userData.serviceUserId] == + 2 + ? "" + : "항목을 눌러 송금 확인하기", + //정산 완료 확인 체크필요 + style: TextStyle( + color: masterFlag ? color1 : color2, + fontWeight: FontWeight.w600, + fontSize: 13, ), - ) - ]), + ), + ) + ], + ), Padding( padding: EdgeInsets.symmetric(horizontal: 10), child: Divider(), From e7e7762f58baeaa0ef7aa29060c7dfd27e6fb5ae Mon Sep 17 00:00:00 2001 From: akuby21 <39649594+akuby21@users.noreply.github.com> Date: Mon, 4 Dec 2023 15:43:51 +0900 Subject: [PATCH 10/14] Fix : SimpleSettlementer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이상한 곳에 0 이 붙던 현상 해결 --- lib/view/main_page.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/view/main_page.dart b/lib/view/main_page.dart index 22af455e..cedc4ada 100644 --- a/lib/view/main_page.dart +++ b/lib/view/main_page.dart @@ -581,7 +581,7 @@ class _SimpleSettlementerResState extends State { @override Widget build(BuildContext context) { - bool isRealNum = widget.res == widget.res.toInt(); + bool isInt = widget.res == widget.res.toInt(); double res = widget.res * 1; return SingleChildScrollView( scrollDirection: Axis.horizontal, @@ -612,16 +612,16 @@ class _SimpleSettlementerResState extends State { AnimatedDigitWidget( fractionDigits: 0, duration: Duration(seconds: 1), - value: isRealNum ? res : res.toInt(), + value: isInt ? res : res.toInt(), enableSeparator: true, - suffix: isRealNum ? "원" : ".", + suffix: isInt ? "원" : ".", textStyle: TextStyle( fontSize: 30, fontWeight: FontWeight.w600, color: color1, ), ), - isRealNum && (res * 100 % 100) / 10 < 1 ? SizedBox.shrink() : AnimatedDigitWidget( + (res * 10 % 10) > 1 || isInt ? SizedBox.shrink() : AnimatedDigitWidget( value: 0, textStyle: TextStyle( textBaseline: TextBaseline.alphabetic, @@ -630,7 +630,7 @@ class _SimpleSettlementerResState extends State { color: Colors.grey, ), ), - isRealNum ? SizedBox.shrink() : AnimatedDigitWidget( + isInt ? SizedBox.shrink() : AnimatedDigitWidget( duration: Duration(seconds: 1), value : res * 100 % 100, enableSeparator: true, From 19ddf4a5a49d20229f2018fe9bfd3451db34489e Mon Sep 17 00:00:00 2001 From: akuby21 <39649594+akuby21@users.noreply.github.com> Date: Tue, 5 Dec 2023 15:51:00 +0900 Subject: [PATCH 11/14] Refactor : widget tree change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit stack -> positioned 구조에서 column -> row , container로 변경 --- lib/view/main_page.dart | 132 +++++++++++++++++++--------------------- 1 file changed, 64 insertions(+), 68 deletions(-) diff --git a/lib/view/main_page.dart b/lib/view/main_page.dart index cedc4ada..175e7607 100644 --- a/lib/view/main_page.dart +++ b/lib/view/main_page.dart @@ -583,6 +583,7 @@ class _SimpleSettlementerResState extends State { Widget build(BuildContext context) { bool isInt = widget.res == widget.res.toInt(); double res = widget.res * 1; + Size size = MediaQuery.of(context).size; return SingleChildScrollView( scrollDirection: Axis.horizontal, physics: const NeverScrollableScrollPhysics(), @@ -591,72 +592,67 @@ class _SimpleSettlementerResState extends State { duration: Duration(milliseconds: widget.flag ? 700 : 300), width: widget.flag ? 1000 : 0, height: 100, - child: Stack( - children: [ - Positioned( - top: 10, - left: 20, - child: Text("1인당", - style: TextStyle( - fontWeight: FontWeight.w600, - )), - ), - Positioned( - top: 25, - left: 80, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.baseline, - textBaseline: TextBaseline.ideographic, - children: [ - AnimatedDigitWidget( - fractionDigits: 0, - duration: Duration(seconds: 1), - value: isInt ? res : res.toInt(), - enableSeparator: true, - suffix: isInt ? "원" : ".", - textStyle: TextStyle( - fontSize: 30, - fontWeight: FontWeight.w600, - color: color1, - ), - ), - (res * 10 % 10) > 1 || isInt ? SizedBox.shrink() : AnimatedDigitWidget( - value: 0, - textStyle: TextStyle( - textBaseline: TextBaseline.alphabetic, - fontSize: 18, - fontWeight: FontWeight.w600, - color: Colors.grey, - ), + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(left:20,top:5), + child: Text("1인당", + style: TextStyle( + fontWeight: FontWeight.w600, + )), + ), + Container( + width: size.width*0.6, + margin: EdgeInsets.only(right:20), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.baseline, + textBaseline: TextBaseline.ideographic, + children: [ + AnimatedDigitWidget( + fractionDigits: 0, + duration: Duration(seconds: 1), + value: isInt ? res : res.toInt(), + enableSeparator: true, + suffix: isInt ? "원" : ".", + textStyle: TextStyle( + fontSize: 30, + fontWeight: FontWeight.w600, + color: color1, + ), + ), + (res * 10 % 10) > 1 || isInt ? SizedBox.shrink() : AnimatedDigitWidget( + value: 0, + textStyle: TextStyle( + textBaseline: TextBaseline.alphabetic, + fontSize: 18, + fontWeight: FontWeight.w600, + color: Colors.grey, + ), + ), + isInt ? SizedBox.shrink() : AnimatedDigitWidget( + duration: Duration(seconds: 1), + value : res * 100 % 100, + enableSeparator: true, + suffix: "원", + textStyle: TextStyle( + textBaseline: TextBaseline.alphabetic, + fontSize: 18, + fontWeight: FontWeight.w600, + color: Colors.grey, + ), + ) + ], ), - isInt ? SizedBox.shrink() : AnimatedDigitWidget( - duration: Duration(seconds: 1), - value : res * 100 % 100, - enableSeparator: true, - suffix: "원", - textStyle: TextStyle( - textBaseline: TextBaseline.alphabetic, - fontSize: 18, - fontWeight: FontWeight.w600, - color: Colors.grey, - ), - ) - ], - ) - // child: Text("${priceToString.format(widget.res)}원", - // textAlign: TextAlign.start, - // style: TextStyle( - // fontSize: 30, - // fontWeight: FontWeight.w600, - // color: color1, - // ) - // ), - ), - Positioned( - top: 13, - left: 265, - child: Stack( + ), + ], + ), + Stack( children: [ SizedBox( height: 60, @@ -687,9 +683,9 @@ class _SimpleSettlementerResState extends State { fontSize: 15)), ) ], - ), - ) - ], + ) + ], + ), )), ); } From 026333f15dd7b09eff6845411b152daffa2d755e Mon Sep 17 00:00:00 2001 From: akuby21 <39649594+akuby21@users.noreply.github.com> Date: Tue, 5 Dec 2023 15:51:47 +0900 Subject: [PATCH 12/14] Refactor : Snackbar clear MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 스낵바 표시시에 기존에 표시되고있던 스낵바는 clear시킴 --- lib/view/account_add_page.dart | 8 ++++++++ lib/view/group_create_page.dart | 2 ++ lib/view/group_main_page.dart | 1 + lib/view/group_settlement_list_page.dart | 1 + lib/view/mypage_page.dart | 3 +++ lib/view/receipt_edit_page.dart | 2 ++ 6 files changed, 17 insertions(+) diff --git a/lib/view/account_add_page.dart b/lib/view/account_add_page.dart index 7a353f77..0abaa923 100644 --- a/lib/view/account_add_page.dart +++ b/lib/view/account_add_page.dart @@ -194,6 +194,7 @@ class _AccountAddPageState extends ConsumerState { account.accountNum = int.parse(accountNum); }catch(e){ print(e); + ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).showSnackBar(const SnackBar( content: Text( '계좌번호에는 숫자만 넣어주세요.'), @@ -206,6 +207,13 @@ class _AccountAddPageState extends ConsumerState { account.bank = bank; provider.addAccount(account,_makeFavorite); + Navigator.of(context).pop(); + ScaffoldMessenger.of(context).clearSnackBars(); + ScaffoldMessenger.of(context).showSnackBar(const SnackBar( + content: Text( + '성공적으로 계좌를 등록했어요.'), + duration: Duration(seconds: 2), + )); }, style: OutlinedButton.styleFrom( backgroundColor: Color(0xFF454545), diff --git a/lib/view/group_create_page.dart b/lib/view/group_create_page.dart index f55e34e9..ddb46434 100644 --- a/lib/view/group_create_page.dart +++ b/lib/view/group_create_page.dart @@ -280,6 +280,7 @@ class _GroupCreatePageState extends ConsumerState { if (inputName != "") { provider.addByDirect(inputName); } else { + ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context) .showSnackBar( const SnackBar( @@ -376,6 +377,7 @@ class _GroupCreatePageState extends ConsumerState { child: GestureDetector( onTap: () { if (inputGroupName == "") { + ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('그룹명은 공백이 될 수 없습니다'), diff --git a/lib/view/group_main_page.dart b/lib/view/group_main_page.dart index ea07ceab..bf6fd2a5 100644 --- a/lib/view/group_main_page.dart +++ b/lib/view/group_main_page.dart @@ -521,6 +521,7 @@ class _GroupMainPageState extends ConsumerState { provider.addByDirect( inputName!); } else { + ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of( context) .showSnackBar( diff --git a/lib/view/group_settlement_list_page.dart b/lib/view/group_settlement_list_page.dart index 73cd7f3e..c0526120 100644 --- a/lib/view/group_settlement_list_page.dart +++ b/lib/view/group_settlement_list_page.dart @@ -352,6 +352,7 @@ class _GroupSettlementListPageState Navigator.of(context).pop(); } } else { + ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context) .showSnackBar(SnackBar( content: diff --git a/lib/view/mypage_page.dart b/lib/view/mypage_page.dart index 75aac10c..b1bd6742 100644 --- a/lib/view/mypage_page.dart +++ b/lib/view/mypage_page.dart @@ -95,6 +95,7 @@ class _MyPageState extends ConsumerState { child: OutlinedButton( onPressed: () { if(inputName == ""){ + ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).showSnackBar(const SnackBar( content: Text( '이름은 공백이 될 수 없습니다.'), @@ -106,6 +107,7 @@ class _MyPageState extends ConsumerState { setState(() { uvm.editUsername(inputName); }); + ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).showSnackBar(const SnackBar( content: Text( '성공적으로 이름을 변경했습니다.'), @@ -216,6 +218,7 @@ class _MyPageState extends ConsumerState { GestureDetector( onTap: ()async{ await Clipboard.setData(ClipboardData(text: uvm.accounts.first.accountNum.toString())); + ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: const Center( child: Text( diff --git a/lib/view/receipt_edit_page.dart b/lib/view/receipt_edit_page.dart index 2cd00532..9b8f262f 100644 --- a/lib/view/receipt_edit_page.dart +++ b/lib/view/receipt_edit_page.dart @@ -345,6 +345,7 @@ class _EditReceiptState extends ConsumerState { return; } } catch (e) { + ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text( '${index + 1}번째 항목의 수량이 잘못되었어요. : ${countController[index].text}'), @@ -357,6 +358,7 @@ class _EditReceiptState extends ConsumerState { .parse(priceController[index].text) .toInt(); } catch (e) { + ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text( '${index + 1}번째 항목의 가격이 잘못되었어요. : ${priceController[index].text}'), From 09c8d41dce8f9edabff0d3fcb4f5ceddddd7e753 Mon Sep 17 00:00:00 2001 From: akuby21 <39649594+akuby21@users.noreply.github.com> Date: Tue, 5 Dec 2023 15:58:49 +0900 Subject: [PATCH 13/14] =?UTF-8?q?Fix=20:=20=EA=B5=AC=EC=A1=B0=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/view/account_detail_page.dart | 3 +++ lib/viewmodel/UserViewModel.dart | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/view/account_detail_page.dart b/lib/view/account_detail_page.dart index 4eaf14c6..3f17c201 100644 --- a/lib/view/account_detail_page.dart +++ b/lib/view/account_detail_page.dart @@ -195,6 +195,9 @@ class _oneAccountState extends ConsumerState { margin: EdgeInsets.only(right:15), child: OutlinedButton( onPressed: (){ + setState(() { + provider.deleteAccount(widget.account, provider.accounts.indexOf(widget.account)); + }); }, style: OutlinedButton.styleFrom( backgroundColor: color1, diff --git a/lib/viewmodel/UserViewModel.dart b/lib/viewmodel/UserViewModel.dart index 1d5db97d..2164f12e 100644 --- a/lib/viewmodel/UserViewModel.dart +++ b/lib/viewmodel/UserViewModel.dart @@ -233,12 +233,13 @@ class UserViewModel extends ChangeNotifier { final userRef = db.collection("userlist").doc(userData.serviceUserId); db.runTransaction((transaction) async { if(isFavorite){ - userData.accountInfo.insert(0,account.accountId!); + accounts.insert(0,account); } else { - userData.accountInfo.add(account.accountId!); + accounts.add(account); } account.createAccount(userData.serviceUserId!); transaction.update(userRef, userData.toJson()); + notifyListeners(); }).then( (value) { print("DocumentSnapshot successfully updated!"); //성공 메시지 @@ -263,9 +264,10 @@ class UserViewModel extends ChangeNotifier { final userRef = db.collection("userlist").doc(userData.serviceUserId); final accountRef = db.collection("accountlist").doc(account.accountId); db.runTransaction((transaction) async { - userData.accountInfo.removeAt(index); + accounts.removeAt(index); transaction.delete(accountRef); transaction.update(userRef, userData.toJson()); + notifyListeners(); }).then( (value) { print("DocumentSnapshot successfully updated!"); //성공 메시지 From 5bcba749b17cedc5061adb04ed727750dc8d7050 Mon Sep 17 00:00:00 2001 From: akuby21 <39649594+akuby21@users.noreply.github.com> Date: Wed, 6 Dec 2023 00:59:49 +0900 Subject: [PATCH 14/14] Fix : typo --- lib/view/account_add_page.dart | 4 +++- lib/view/main_page.dart | 35 ++++++++++++++++------------------ 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/lib/view/account_add_page.dart b/lib/view/account_add_page.dart index 0abaa923..e0ff4541 100644 --- a/lib/view/account_add_page.dart +++ b/lib/view/account_add_page.dart @@ -27,6 +27,7 @@ class _AccountAddPageState extends ConsumerState { final Size size = MediaQuery.of(context).size; final provider = ref.watch(userProvider); + return Scaffold( extendBodyBehindAppBar: true, appBar: AppBar( @@ -156,8 +157,9 @@ class _AccountAddPageState extends ConsumerState { ), ), TextField( + controller: TextEditingController()..text = provider.userData.name!, decoration: InputDecoration( - hintText: "예금주ㅅ", + hintText: "예금주", ), onChanged: (val){ ownerName = val; diff --git a/lib/view/main_page.dart b/lib/view/main_page.dart index 175e7607..2b78523e 100644 --- a/lib/view/main_page.dart +++ b/lib/view/main_page.dart @@ -97,25 +97,22 @@ class _MainPage extends ConsumerState { height: 1, decoration: const BoxDecoration(color: Color(0xFFF4F4F4)), ), - Padding( - padding: const EdgeInsets.only(left: 0, right: 0), - child: Container( - width: double.infinity, - height: 200, - decoration: BoxDecoration(color: Colors.white, boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.7), - blurRadius: 7, - ) - ]), - child: const Center( - child: Text("문구 들어갈 위치", - style: TextStyle( - color: Colors.red, - fontWeight: FontWeight.w600, - fontSize: 15)), - )), - ), + Container( + width: double.infinity, + height: 200, + decoration: BoxDecoration(color: Colors.white, boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.7), + blurRadius: 7, + ) + ]), + child: const Center( + child: Text("문구 들어갈 위치", + style: TextStyle( + color: Colors.red, + fontWeight: FontWeight.w600, + fontSize: 15)), + )), Container( width: double.infinity, height: 160,