From 5280153cd0d63d8d29f8ac28f4e2f586a9f02caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Wed, 20 Nov 2024 15:52:48 +0900 Subject: [PATCH 01/15] =?UTF-8?q?feat:=20safeArea=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/feature/night_study/night_study.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/feature/night_study/night_study.dart b/lib/feature/night_study/night_study.dart index bbd6f56..bf8dbc4 100644 --- a/lib/feature/night_study/night_study.dart +++ b/lib/feature/night_study/night_study.dart @@ -88,10 +88,11 @@ class _NightStudyScreenState extends State { ), ), ), - bottomNavigationBar: EasierDodamBottomNavigationBar( + bottomNavigationBar: SafeArea(child: EasierDodamBottomNavigationBar( selectedIndex: _selectedIndex, onItemTapped: _onItemTapped, ), + ), ); } } \ No newline at end of file From e0fe8316d1e9cb51f00f21850f19dccf9fe3e943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Thu, 21 Nov 2024 11:57:48 +0900 Subject: [PATCH 02/15] =?UTF-8?q?feat:=20=EC=A4=91=EA=B0=84=EC=BB=A4?= =?UTF-8?q?=EB=B0=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/feature/night_study/night_study.dart | 53 ++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/lib/feature/night_study/night_study.dart b/lib/feature/night_study/night_study.dart index bf8dbc4..46a55f9 100644 --- a/lib/feature/night_study/night_study.dart +++ b/lib/feature/night_study/night_study.dart @@ -73,14 +73,58 @@ class _NightStudyScreenState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox(height: 23), Text( "현재 신청된 심자", style: EasierDodamStyles.body1, textAlign: TextAlign.start, ), - SizedBox(), - // You can add more content here + SizedBox( + height: 12, + width: double.infinity, + ), + Container( + //프레임 시작 + decoration: BoxDecoration( + color: EasierDodamColors.staticWhite, + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.08), + spreadRadius: 0, + blurRadius: 4, + offset: Offset(0, 4), + ) + ] + ), + margin: const EdgeInsets.symmetric(horizontal: 12), + height: 106, + width: 380, + child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 8, + width: 12, + ), + Container(//수락됨 + height: 24, + width: 52, + alignment: Alignment.center, + child: Text( + "수락됨", + style: EasierDodamStyles.label1.copyWith( + color: EasierDodamColors.staticWhite + ).copyWith(fontSize: 12) + ), + decoration: BoxDecoration( + color: EasierDodamColors.primary300, + borderRadius: BorderRadius.circular(12), + ), + ), + ], + ), + + ) ], ), ); @@ -88,7 +132,8 @@ class _NightStudyScreenState extends State { ), ), ), - bottomNavigationBar: SafeArea(child: EasierDodamBottomNavigationBar( + bottomNavigationBar: SafeArea( + child: EasierDodamBottomNavigationBar( selectedIndex: _selectedIndex, onItemTapped: _onItemTapped, ), From f1abed6aeb998a14017c0690bbb73395e0fdc2ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Mon, 25 Nov 2024 11:27:00 +0900 Subject: [PATCH 03/15] =?UTF-8?q?feat:=20=EC=8B=AC=EC=9E=90=20=ED=94=84?= =?UTF-8?q?=EB=A6=AC=EC=85=8B=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Podfile.lock | 2 +- .../night_study/item/night_study_item.dart | 184 +++++++++++++ .../item/night_study_present_item.dart | 119 ++++++++ lib/feature/night_study/night_study.dart | 257 +++++++++++------- .../item/night_study_create_time_item.dart | 55 ++++ .../night_study_create.dart | 226 +++++++++++++++ .../night_study_create_navigation.dart | 1 + .../night_study_create_viewmodel.dart | 30 ++ lib/local/dao/nigh_study_dao.dart | 32 +++ lib/local/dao/out_dao.dart | 2 - lib/local/easier_dodam_database.dart | 7 +- lib/local/easier_dodam_database.g.dart | 139 ++++++++++ lib/local/entity/night_study_entity.dart | 60 ++++ lib/main.dart | 25 +- pubspec.lock | 32 +-- 15 files changed, 1049 insertions(+), 122 deletions(-) create mode 100644 lib/feature/night_study/item/night_study_item.dart create mode 100644 lib/feature/night_study/item/night_study_present_item.dart create mode 100644 lib/feature/night_study/night_study_create/item/night_study_create_time_item.dart create mode 100644 lib/feature/night_study/night_study_create/night_study_create.dart create mode 100644 lib/feature/night_study/night_study_create/night_study_create_navigation.dart create mode 100644 lib/feature/night_study/night_study_create/night_study_create_viewmodel.dart create mode 100644 lib/local/dao/nigh_study_dao.dart create mode 100644 lib/local/entity/night_study_entity.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 238dcf3..bafc646 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -32,4 +32,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796 -COCOAPODS: 1.16.2 +COCOAPODS: 1.15.2 diff --git a/lib/feature/night_study/item/night_study_item.dart b/lib/feature/night_study/item/night_study_item.dart new file mode 100644 index 0000000..9aa9c9f --- /dev/null +++ b/lib/feature/night_study/item/night_study_item.dart @@ -0,0 +1,184 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import '../../../component/theme/color.dart'; +import '../../../component/theme/style.dart'; +import '../../../utiles/utile.dart'; + +enum TagType { PENDING, APPROVE, REJECT } +enum PlaceType { PROGRAM1, PROGRAM2, PROGRAM3 } + +extension PlaceTypeExtension on PlaceType { + String get name { + switch (this) { + case PlaceType.PROGRAM1: + return "프로그래밍 1실"; + case PlaceType.PROGRAM2: + return "프로그래밍 2실"; + case PlaceType.PROGRAM3: + return "프로그래밍 3실"; + } + } +} + + class NightStudyItem extends StatelessWidget { + + final TagType tagType; + final Function() onClickTrash; + final String? rejectReason; + final TimeOfDay startAt; + final TimeOfDay endAt; + + const NightStudyItem({ + super.key, + required this.tagType, + required this.onClickTrash, + this.rejectReason, + required this.startAt, + required this.endAt, + }); + + @override + Widget build(BuildContext context) { + + final hour = timeOfDayDifference(TimeOfDay.now(), endAt) ~/ 60; + final minute = timeOfDayDifference(TimeOfDay.now(), endAt) % 60; + + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(10)), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.08), + spreadRadius: 0, + blurRadius: 4, + offset: const Offset(0, 4), // changes position of shadow + ), + ], + ), + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 8, + horizontal: 12, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + decoration: BoxDecoration( + color: switch (tagType) { + TagType.PENDING => EasierDodamColors.gray600, + TagType.APPROVE => EasierDodamColors.primary300, + TagType.REJECT => EasierDodamColors.staticRed + }, + borderRadius: BorderRadius.circular(12), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 4.0, + horizontal: 10.0, + ), + child: Text( + switch (tagType) { + TagType.PENDING => "대기중", + TagType.APPROVE => "수락됨", + TagType.REJECT => "거절됨", + }, + style: EasierDodamStyles.label1.copyWith( + fontSize: 12.0, + color: EasierDodamColors.staticWhite, + ), + ), + ), + ), + Material( + color: EasierDodamColors.staticWhite, + child: InkWell( + onTap: onClickTrash, + child: SizedBox( + width: 24, + height: 24, + child: Image.asset("assets/images/ic_trash.png"), + ), + ), + ) + ], + ), + const SizedBox( + height: 12, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + hour > 0 ? "$hour시간" : "$minute분", + style: EasierDodamStyles.label2, + ), + SizedBox( + width: 2, + ), + Text( + "남음", + style: EasierDodamStyles.label2.copyWith( + fontSize: 12.0, + ), + ) + ], + ), + const SizedBox( + height: 12, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + "시작", + style: EasierDodamStyles.label2.copyWith( + fontSize: 12.0, + ), + ), + const SizedBox( + width: 2, + ), + Text( + "${startAt.hour}시 ${startAt.minute}분", + style: EasierDodamStyles.label2, + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + "복귀", + style: EasierDodamStyles.label2.copyWith( + fontSize: 12.0, + ), + ), + const SizedBox( + width: 2, + ), + Text( + "${endAt.hour}시 ${endAt.minute}분", + style: EasierDodamStyles.label2, + ), + ], + ), + ], + ), + ], + ), + ), + ); + } +} diff --git a/lib/feature/night_study/item/night_study_present_item.dart b/lib/feature/night_study/item/night_study_present_item.dart new file mode 100644 index 0000000..0e9855a --- /dev/null +++ b/lib/feature/night_study/item/night_study_present_item.dart @@ -0,0 +1,119 @@ +import 'package:flutter/material.dart'; + +class NightStudyPresentItem extends StatelessWidget { + final String presetTitle; + final String reason; + final List places; + final bool doNeedPhone; + final String phoneReason; + final String startDate; + final String endDate; + final Function() onClickCreate; + + const NightStudyPresentItem({ + super.key, + required this.presetTitle, + required this.reason, + required this.places, + required this.doNeedPhone, + required this.phoneReason, + required this.startDate, + required this.endDate, + required this.onClickCreate, + }); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("심자 프리셋 생성하기"), + ), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("프리셋 제목", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + TextField( + decoration: InputDecoration(hintText: "프리셋#1"), + ), + SizedBox(height: 16), + Text("사유", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + TextField( + decoration: InputDecoration(hintText: reason), + ), + SizedBox(height: 16), + Text("장소 선택", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + DropdownButton( + value: places.first, + items: places.map((place) { + return DropdownMenuItem( + value: place, + child: Text(place), + ); + }).toList(), + onChanged: (value) {}, + ), + SizedBox(height: 16), + Row( + children: [ + Checkbox( + value: doNeedPhone, + onChanged: (value) {}, + ), + Text("휴대폰 사용"), + ], + ), + if (doNeedPhone) + TextField( + decoration: InputDecoration(hintText: "사유: $phoneReason"), + ), + SizedBox(height: 16), + Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("심자 시작", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + TextButton( + onPressed: () {}, + child: Text(startDate), + ), + ], + ), + ), + SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("심자 종료", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + TextButton( + onPressed: () {}, + child: Text(endDate), + ), + ], + ), + ), + ], + ), + ], + ), + ), + bottomNavigationBar: Padding( + padding: const EdgeInsets.all(16.0), + child: ElevatedButton( + onPressed: onClickCreate, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.blue, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + child: Text("생성하기", style: TextStyle(color: Colors.white, fontSize: 16)), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/feature/night_study/night_study.dart b/lib/feature/night_study/night_study.dart index 46a55f9..a44866a 100644 --- a/lib/feature/night_study/night_study.dart +++ b/lib/feature/night_study/night_study.dart @@ -1,11 +1,14 @@ import 'package:easier_dodam/component/appbar.dart'; import 'package:easier_dodam/component/bottom_navigation_bar.dart'; +import 'package:easier_dodam/component/modal_bottom_sheet_container.dart'; import 'package:easier_dodam/component/theme/color.dart'; import 'package:easier_dodam/component/theme/style.dart'; -import 'package:easier_dodam/feature/night_study/night_study_viewmodel.dart'; +import 'package:easier_dodam/feature/night_study/night_study_create/night_study_create_navigation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'night_study_viewmodel.dart'; + class NightStudyScreen extends StatefulWidget { const NightStudyScreen({super.key}); @@ -14,7 +17,8 @@ class NightStudyScreen extends StatefulWidget { } class _NightStudyScreenState extends State { - final TextEditingController _reasonTextFieldController = TextEditingController(); + final TextEditingController _reasonTextFieldController = + TextEditingController(); int _selectedIndex = 0; @@ -24,25 +28,23 @@ class _NightStudyScreenState extends State { }); } - void _onPlusClick() { - showDialog( + void _onPlusClick(BuildContext context) { + showModalBottomSheet( context: context, - builder: (context) => AlertDialog( - title: Text("심자 추가"), - content: Text("심자를 추가하시겠습니까?"), - actions: [ - TextButton( - onPressed: () => Navigator.of(context).pop(), - child: Text("취소"), - ), - TextButton( - onPressed: () { - Navigator.of(context).pop(); + builder: (context) { + return ChangeNotifierProvider.value( + value: NightStudyViewmodel(), + child: Consumer( + builder: ( + BuildContext context, + NightStudyViewmodel value, + Widget? child, + ) { + return _bottomWidget(context, NightStudyViewmodel()); }, - child: Text("확인"), ), - ], - ), + ); + }, ); } @@ -54,90 +56,157 @@ class _NightStudyScreenState extends State { @override Widget build(BuildContext context) { - return Scaffold( - appBar: PreferredSize( - preferredSize: Size.fromHeight(60), - child: EasierDodamDefaultAppbar( - title: '심자', - onPlusClick: _onPlusClick, + return Consumer(builder: + (BuildContext context, NightStudyViewmodel viewModel, Widget? child) { + return Scaffold( + appBar: PreferredSize( + preferredSize: Size.fromHeight(60), + child: EasierDodamDefaultAppbar( + title: '심자', + onPlusClick: () => _onPlusClick(context), + ), ), - ), - body: SafeArea( - child: ChangeNotifierProvider( - create: (_) => NightStudyViewmodel(), - child: Consumer( - builder: (context, provider, child) { - return Container( - color: EasierDodamColors.staticWhite, - margin: const EdgeInsets.symmetric(horizontal: 16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "현재 신청된 심자", - style: EasierDodamStyles.body1, - textAlign: TextAlign.start, - ), - SizedBox( - height: 12, - width: double.infinity, - ), - Container( - //프레임 시작 - decoration: BoxDecoration( - color: EasierDodamColors.staticWhite, - borderRadius: BorderRadius.circular(20), - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.08), - spreadRadius: 0, - blurRadius: 4, - offset: Offset(0, 4), - ) - ] + body: SafeArea( + child: ChangeNotifierProvider( + create: (_) => NightStudyViewmodel(), + child: Consumer( + builder: (context, provider, child) { + return Container( + color: EasierDodamColors.staticWhite, + margin: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "현재 신청된 심자", + style: EasierDodamStyles.body1, + textAlign: TextAlign.start, + ), + SizedBox( + height: 12, + width: double.infinity, ), - margin: const EdgeInsets.symmetric(horizontal: 12), - height: 106, - width: 380, - child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 8, - width: 12, - ), - Container(//수락됨 - height: 24, - width: 52, - alignment: Alignment.center, - child: Text( - "수락됨", - style: EasierDodamStyles.label1.copyWith( - color: EasierDodamColors.staticWhite - ).copyWith(fontSize: 12) + Container( + //프레임 시작 + padding: EdgeInsets.symmetric(vertical: 8, horizontal: 12), + decoration: BoxDecoration( + color: EasierDodamColors.staticWhite, + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.08), + spreadRadius: 0, + blurRadius: 4, + offset: Offset(0, 4), + ) + ]), + margin: const EdgeInsets.symmetric(horizontal: 12), + height: 106, + width: 380, + child: Column( + // mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 8, + width: 12, ), - decoration: BoxDecoration( - color: EasierDodamColors.primary300, - borderRadius: BorderRadius.circular(12), + Container( + //수락됨 + height: 24, + width: 52, + alignment: Alignment.center, + child: Text("수락됨", + style: EasierDodamStyles.label1 + .copyWith( + color: EasierDodamColors.staticWhite) + .copyWith(fontSize: 12)), + decoration: BoxDecoration( + color: EasierDodamColors.primary300, + borderRadius: BorderRadius.circular(12), + ), ), - ), - ], - ), + ], + ), + ) + ], + ), + ); + }, + ), + ), + ), + bottomNavigationBar: SafeArea( + child: EasierDodamBottomNavigationBar( + selectedIndex: _selectedIndex, + onItemTapped: _onItemTapped, + ), + ), + ); + }); + } - ) - ], + Widget _bottomWidget(BuildContext context, NightStudyViewmodel viewModel) { + return ModalBottomSheetContainer( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, + ), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: 44, + width: 380, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8, + ), + child: Text("심자 신청하기", style: EasierDodamStyles.title1), ), - ); - }, + ), + SizedBox( + height: 8, + ), + Material( //프리셋 생성 시작 + color: EasierDodamColors.staticWhite, + child: InkWell( + onTap: () { + Navigator.pushReplacementNamed( + context, + nightStudyCreateRoute, + ); + }, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8, + ), + child: Row( + children: [ + Image.asset( + width: 24, + height: 24, + "assets/images/ic_plus.png", + color: EasierDodamColors.gray700, + ), + SizedBox( + width: 8, + ), + Text( + "새로운 프리셋 만들기", + style: EasierDodamStyles.body2, + ) + ], + ), + ), + ), + ), + ], ), ), ), - bottomNavigationBar: SafeArea( - child: EasierDodamBottomNavigationBar( - selectedIndex: _selectedIndex, - onItemTapped: _onItemTapped, - ), - ), ); } -} \ No newline at end of file +} + diff --git a/lib/feature/night_study/night_study_create/item/night_study_create_time_item.dart b/lib/feature/night_study/night_study_create/item/night_study_create_time_item.dart new file mode 100644 index 0000000..edeb332 --- /dev/null +++ b/lib/feature/night_study/night_study_create/item/night_study_create_time_item.dart @@ -0,0 +1,55 @@ +import 'package:easier_dodam/component/theme/color.dart'; +import 'package:easier_dodam/component/theme/style.dart'; +import 'package:flutter/material.dart'; + +class NightStudyCreateTimeItem extends StatelessWidget { + final String title; + final String buttonText; + final Function() onButtonClick; + + const NightStudyCreateTimeItem( + {super.key, + required this.title, + required this.buttonText, + required this.onButtonClick}); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: EasierDodamStyles.label1.copyWith( + height: 1.5, + color: EasierDodamColors.gray500, + ), + ), + InkWell( + onTap: onButtonClick, + child: Container( + decoration: BoxDecoration( + border: const Border.fromBorderSide( + BorderSide(width: 1.0, color: EasierDodamColors.gray500), + ), + borderRadius: BorderRadius.circular(10.0), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 15, + horizontal: 34.5, + ), + child: Text( + buttonText, + style: EasierDodamStyles.label1.copyWith( + height: 1.5, + color: EasierDodamColors.staticBlack, + ), + ), + ), + ), + ) + ], + ); + } +} diff --git a/lib/feature/night_study/night_study_create/night_study_create.dart b/lib/feature/night_study/night_study_create/night_study_create.dart new file mode 100644 index 0000000..924faf8 --- /dev/null +++ b/lib/feature/night_study/night_study_create/night_study_create.dart @@ -0,0 +1,226 @@ +import 'package:easier_dodam/feature/night_study/night_study_create/night_study_create_viewmodel.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import '../../../component/preset_appbar.dart'; +import '../../../component/textfield.dart'; +import '../../../component/theme/color.dart'; +import '../../../component/theme/style.dart'; +import '../item/night_study_item.dart'; +import '../item/night_study_present_item.dart'; +import 'item/night_study_create_time_item.dart'; + +class NightStudyCreateScreen extends StatefulWidget { + const NightStudyCreateScreen({super.key}); + + @override + State createState() => _NightStudyCreateState(); +} + +class _NightStudyCreateState extends State { + final TextEditingController _titleTextFieldController = TextEditingController(); + final TextEditingController _contentTextFieldController = TextEditingController(); + final TextEditingController _reasonTextFieldController = TextEditingController(); + + TimeOfDay startAt = TimeOfDay.now(); + TimeOfDay endAt = adjustTimeOfDay(TimeOfDay.now(), hoursToAdd: 3); + + PlaceType? selectedPlace; + bool doNeedPhone = false; + + @override + void dispose() { + _titleTextFieldController.dispose(); + _contentTextFieldController.dispose(); + _reasonTextFieldController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return ChangeNotifierProvider( + create: (_) => NightStudyCreateViewModel(), + child: Consumer( + builder: (context, provider, child) { + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60), + child: EasierDodamDefaultPresetAppbar( + title: "심자 프리셋 생성하기", + onLeftArrowClick: () { + Navigator.pop(context); + }, + ), + ), + body: SafeArea( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Column( + children: [ + EasierDodamTextField( + labelText: "프리셋 제목", + hintText: "프리셋 제목을 입력해주세요.", + controller: _titleTextFieldController, + ), + const SizedBox(height: 12), + EasierDodamTextField( + labelText: "사유", + hintText: "사유를 입력해주세요.", + controller: _contentTextFieldController, + ), + const SizedBox(height: 12), + DropdownButton( + value: selectedPlace, + hint: const Text("장소를 선택하세요"), + items: PlaceType.values.map((place) { + return DropdownMenuItem( + value: place, + child: Text(place.name), + ); + }).toList(), + onChanged: (PlaceType? value) { + setState(() { + selectedPlace = value; + }); + }, + ), + const SizedBox(height: 12), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text("휴대폰 필요 여부", style: TextStyle(fontSize: 16)), + Switch( + value: doNeedPhone, + onChanged: (value) { + setState(() { + doNeedPhone = value; + if (!doNeedPhone) { + _reasonTextFieldController.clear(); + } + }); + }, + ), + ], + ), + if (doNeedPhone) + EasierDodamTextField( + labelText: "휴대폰 필요 사유", + hintText: "휴대폰이 필요한 이유를 입력해주세요.", + controller: _reasonTextFieldController, + ), + const SizedBox(height: 12), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + NightStudyCreateTimeItem( + title: "심자 시작", + buttonText: "${startAt.hour}시 ${startAt.minute}분", + onButtonClick: () async { + final time = await showTimePicker( + context: context, + initialTime: startAt, + ); + if (time != null) { + final diffMin = timeOfDayDifference(time, endAt); + setState(() { + startAt = time; + if (diffMin < 0) { + endAt = time; + } + }); + } + }, + ), + NightStudyCreateTimeItem( + title: "심자 종료", + buttonText: "${endAt.hour}시 ${endAt.minute}분", + onButtonClick: () async { + final time = await showTimePicker( + context: context, + initialTime: endAt, + ); + if (time != null) { + setState(() { + endAt = time; + }); + } + }, + ), + ], + ), + const Spacer(), + SizedBox( + width: double.infinity, + height: 56.0, + child: MaterialButton( + height: 56.0, + color: EasierDodamColors.primary300, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12.0), + ), + child: const Text( + "생성하기", + style: EasierDodamStyles.body2, + ), + textColor: EasierDodamColors.staticWhite, + onPressed: () async { + if (selectedPlace == null) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text("장소를 선택해주세요.")), + ); + return; + } + if (doNeedPhone && _reasonTextFieldController.text.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text("휴대폰 필요 사유를 입력해주세요.")), + ); + return; + } + await provider.createNightStudy( + place: selectedPlace!, + content: _contentTextFieldController.text, + doNeedPhone: doNeedPhone, + reasonForPhone: _reasonTextFieldController.text, + startAt: startAt, + endAt: endAt, + ); + Navigator.pop(context); + }, + ), + ), + const SizedBox(height: 8), + ], + ), + ), + ), + ); + }, + ), + ); + } + + static TimeOfDay adjustTimeOfDay(TimeOfDay time, {required int hoursToAdd}) { + final now = DateTime.now(); + final timeAsDateTime = DateTime( + now.year, + now.month, + now.day, + time.hour, + time.minute, + ); + + final adjustedTimeAsDateTime = timeAsDateTime.add(Duration(hours: hoursToAdd)); + + return TimeOfDay( + hour: adjustedTimeAsDateTime.hour, + minute: adjustedTimeAsDateTime.minute, + ); + } + + static int timeOfDayDifference(TimeOfDay start, TimeOfDay end) { + final startMinutes = start.hour * 60 + start.minute; + final endMinutes = end.hour * 60 + end.minute; + return endMinutes - startMinutes; + } +} \ No newline at end of file diff --git a/lib/feature/night_study/night_study_create/night_study_create_navigation.dart b/lib/feature/night_study/night_study_create/night_study_create_navigation.dart new file mode 100644 index 0000000..55938e3 --- /dev/null +++ b/lib/feature/night_study/night_study_create/night_study_create_navigation.dart @@ -0,0 +1 @@ +const nightStudyCreateRoute = "night_study_create"; \ No newline at end of file diff --git a/lib/feature/night_study/night_study_create/night_study_create_viewmodel.dart b/lib/feature/night_study/night_study_create/night_study_create_viewmodel.dart new file mode 100644 index 0000000..cf35eec --- /dev/null +++ b/lib/feature/night_study/night_study_create/night_study_create_viewmodel.dart @@ -0,0 +1,30 @@ +import 'package:easier_dodam/local/database_manager.dart'; +import 'package:easier_dodam/local/entity/night_study_entity.dart'; +import 'package:flutter/material.dart'; + +import '../item/night_study_item.dart'; + +class NightStudyCreateViewModel with ChangeNotifier { + Future createNightStudy({ + required PlaceType place, + required String content, + required bool doNeedPhone, + required String reasonForPhone, + required TimeOfDay startAt, + required TimeOfDay endAt + }) async { + final database = await DatabaseManager.getDatabase(); + await database.nightStudyDao.insertNightStudyEntity(NightStudyEntity( + place: place, + content: content, + doNeedPhone: doNeedPhone, + reasonForPhone: reasonForPhone, + startAt: startAt, + endAt: endAt + )); + + print(await database.nightStudyDao.findAllEntities()); + + return true; + } +} diff --git a/lib/local/dao/nigh_study_dao.dart b/lib/local/dao/nigh_study_dao.dart new file mode 100644 index 0000000..956f3cf --- /dev/null +++ b/lib/local/dao/nigh_study_dao.dart @@ -0,0 +1,32 @@ +import 'package:floor/floor.dart'; + +import '../entity/night_study_entity.dart'; + +@dao +abstract class NighStudyDao { + @Query('SELECT * FROM $_tableName WHERE id = :id') + Future findOutEntityById(int id); + + @Query('SELECT * FROM $_tableName') + Future> findAllEntities(); + + @Query('SELECT * FROM $_tableName') + Stream> findAllEntitiesWithStream(); + + @Query('DELETE FROM $_tableName WHERE id = :id') + Future deleteOutEntityById(int id); + + @insert + Future insertNightStudyEntity(NightStudyEntity nightStudyEntity); + + @update + Future updateNightStudyEntity(NightStudyEntity nightStudyEntity); + + @delete + Future deleteNightStudyEntity(NightStudyEntity nightStudyEntity); + + @Query("DELETE FROM night_study") + Future deleteAllNightStudyEntities(); + + static const String _tableName = "night_study"; +} \ No newline at end of file diff --git a/lib/local/dao/out_dao.dart b/lib/local/dao/out_dao.dart index 1d94913..9fd4035 100644 --- a/lib/local/dao/out_dao.dart +++ b/lib/local/dao/out_dao.dart @@ -1,5 +1,3 @@ -import 'dart:ffi'; - import 'package:easier_dodam/local/entity/out_entity.dart'; import 'package:floor/floor.dart'; diff --git a/lib/local/easier_dodam_database.dart b/lib/local/easier_dodam_database.dart index f847a98..fa4ff62 100644 --- a/lib/local/easier_dodam_database.dart +++ b/lib/local/easier_dodam_database.dart @@ -1,16 +1,21 @@ import 'dart:async'; +import 'package:easier_dodam/local/dao/nigh_study_dao.dart'; import 'package:easier_dodam/local/dao/out_dao.dart'; import 'package:floor/floor.dart'; import 'package:sqflite/sqflite.dart' as sqflite; +import '../feature/night_study/item/night_study_item.dart'; +import '../feature/night_study/item/night_study_present_item.dart'; import 'conventer/time_of_day_converter.dart'; +import 'entity/night_study_entity.dart'; import 'entity/out_entity.dart'; part "easier_dodam_database.g.dart"; @TypeConverters([TimeOfDayConverter]) -@Database(version: 1, entities: [OutEntity]) +@Database(version: 1, entities: [OutEntity, NightStudyEntity]) abstract class EasierDodamDatabase extends FloorDatabase { OutDao get outDao; + NighStudyDao get nightStudyDao; } diff --git a/lib/local/easier_dodam_database.g.dart b/lib/local/easier_dodam_database.g.dart index 4b79cfd..f1591e2 100644 --- a/lib/local/easier_dodam_database.g.dart +++ b/lib/local/easier_dodam_database.g.dart @@ -76,6 +76,8 @@ class _$EasierDodamDatabase extends EasierDodamDatabase { OutDao? _outDaoInstance; + NighStudyDao? _nightStudyDaoInstance; + Future open( String path, List migrations, [ @@ -99,6 +101,8 @@ class _$EasierDodamDatabase extends EasierDodamDatabase { onCreate: (database, version) async { await database.execute( 'CREATE TABLE IF NOT EXISTS `out` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT NOT NULL, `reason` TEXT NOT NULL, `startAt` TEXT NOT NULL, `endAt` TEXT NOT NULL)'); + await database.execute( + 'CREATE TABLE IF NOT EXISTS `night_study` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `place` INTEGER NOT NULL, `content` TEXT NOT NULL, `doNeedPhone` INTEGER NOT NULL, `reasonForPhone` TEXT NOT NULL, `startAt` TEXT NOT NULL, `endAt` TEXT NOT NULL)'); await callback?.onCreate?.call(database, version); }, @@ -110,6 +114,11 @@ class _$EasierDodamDatabase extends EasierDodamDatabase { OutDao get outDao { return _outDaoInstance ??= _$OutDao(database, changeListener); } + + @override + NighStudyDao get nightStudyDao { + return _nightStudyDaoInstance ??= _$NighStudyDao(database, changeListener); + } } class _$OutDao extends OutDao { @@ -229,5 +238,135 @@ class _$OutDao extends OutDao { } } +class _$NighStudyDao extends NighStudyDao { + _$NighStudyDao( + this.database, + this.changeListener, + ) : _queryAdapter = QueryAdapter(database, changeListener), + _nightStudyEntityInsertionAdapter = InsertionAdapter( + database, + 'night_study', + (NightStudyEntity item) => { + 'id': item.id, + 'place': item.place.index, + 'content': item.content, + 'doNeedPhone': item.doNeedPhone ? 1 : 0, + 'reasonForPhone': item.reasonForPhone, + 'startAt': _timeOfDayConverter.encode(item.startAt), + 'endAt': _timeOfDayConverter.encode(item.endAt) + }, + changeListener), + _nightStudyEntityUpdateAdapter = UpdateAdapter( + database, + 'night_study', + ['id'], + (NightStudyEntity item) => { + 'id': item.id, + 'place': item.place.index, + 'content': item.content, + 'doNeedPhone': item.doNeedPhone ? 1 : 0, + 'reasonForPhone': item.reasonForPhone, + 'startAt': _timeOfDayConverter.encode(item.startAt), + 'endAt': _timeOfDayConverter.encode(item.endAt) + }, + changeListener), + _nightStudyEntityDeletionAdapter = DeletionAdapter( + database, + 'night_study', + ['id'], + (NightStudyEntity item) => { + 'id': item.id, + 'place': item.place.index, + 'content': item.content, + 'doNeedPhone': item.doNeedPhone ? 1 : 0, + 'reasonForPhone': item.reasonForPhone, + 'startAt': _timeOfDayConverter.encode(item.startAt), + 'endAt': _timeOfDayConverter.encode(item.endAt) + }, + changeListener); + + final sqflite.DatabaseExecutor database; + + final StreamController changeListener; + + final QueryAdapter _queryAdapter; + + final InsertionAdapter _nightStudyEntityInsertionAdapter; + + final UpdateAdapter _nightStudyEntityUpdateAdapter; + + final DeletionAdapter _nightStudyEntityDeletionAdapter; + + @override + Future findOutEntityById(int id) async { + return _queryAdapter.query('SELECT * FROM night_study WHERE id = ?1', + mapper: (Map row) => NightStudyEntity( + id: row['id'] as int?, + place: PlaceType.values[row['place'] as int], + content: row['content'] as String, + doNeedPhone: (row['doNeedPhone'] as int) != 0, + reasonForPhone: row['reasonForPhone'] as String, + startAt: _timeOfDayConverter.decode(row['startAt'] as String), + endAt: _timeOfDayConverter.decode(row['endAt'] as String)), + arguments: [id]); + } + + @override + Future> findAllEntities() async { + return _queryAdapter.queryList('SELECT * FROM night_study', + mapper: (Map row) => NightStudyEntity( + id: row['id'] as int?, + place: PlaceType.values[row['place'] as int], + content: row['content'] as String, + doNeedPhone: (row['doNeedPhone'] as int) != 0, + reasonForPhone: row['reasonForPhone'] as String, + startAt: _timeOfDayConverter.decode(row['startAt'] as String), + endAt: _timeOfDayConverter.decode(row['endAt'] as String))); + } + + @override + Stream> findAllEntitiesWithStream() { + return _queryAdapter.queryListStream('SELECT * FROM night_study', + mapper: (Map row) => NightStudyEntity( + id: row['id'] as int?, + place: PlaceType.values[row['place'] as int], + content: row['content'] as String, + doNeedPhone: (row['doNeedPhone'] as int) != 0, + reasonForPhone: row['reasonForPhone'] as String, + startAt: _timeOfDayConverter.decode(row['startAt'] as String), + endAt: _timeOfDayConverter.decode(row['endAt'] as String)), + queryableName: 'night_study', + isView: false); + } + + @override + Future deleteOutEntityById(int id) async { + await _queryAdapter.queryNoReturn('DELETE FROM night_study WHERE id = ?1', + arguments: [id]); + } + + @override + Future deleteAllNightStudyEntities() async { + await _queryAdapter.queryNoReturn('DELETE FROM night_study'); + } + + @override + Future insertNightStudyEntity(NightStudyEntity nightStudyEntity) async { + await _nightStudyEntityInsertionAdapter.insert( + nightStudyEntity, OnConflictStrategy.abort); + } + + @override + Future updateNightStudyEntity(NightStudyEntity nightStudyEntity) async { + await _nightStudyEntityUpdateAdapter.update( + nightStudyEntity, OnConflictStrategy.abort); + } + + @override + Future deleteNightStudyEntity(NightStudyEntity nightStudyEntity) async { + await _nightStudyEntityDeletionAdapter.delete(nightStudyEntity); + } +} + // ignore_for_file: unused_element final _timeOfDayConverter = TimeOfDayConverter(); diff --git a/lib/local/entity/night_study_entity.dart b/lib/local/entity/night_study_entity.dart new file mode 100644 index 0000000..860104d --- /dev/null +++ b/lib/local/entity/night_study_entity.dart @@ -0,0 +1,60 @@ +import 'package:floor/floor.dart'; +import 'package:flutter/material.dart'; + +import '../../feature/night_study/item/night_study_item.dart'; + +@Entity(tableName: "night_study") +class NightStudyEntity { + @PrimaryKey(autoGenerate: true) + final int? id; + + final PlaceType place; + + final String content; + + final bool doNeedPhone; + + final String reasonForPhone; + + final TimeOfDay startAt; + + final TimeOfDay endAt; + + NightStudyEntity({ + this.id, + required this.place, + required this.content, + required this.doNeedPhone, + required this.reasonForPhone, + required this.startAt, + required this.endAt, + }); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is NightStudyEntity && + runtimeType == other.runtimeType && + id == other.id && + place == other.place && + content == other.content && + doNeedPhone == other.doNeedPhone && + reasonForPhone == other.reasonForPhone && + startAt == other.startAt && + endAt == other.endAt; + + @override + int get hashCode => + id.hashCode ^ + place.hashCode ^ + content.hashCode ^ + doNeedPhone.hashCode ^ + reasonForPhone.hashCode ^ + startAt.hashCode ^ + endAt.hashCode; + + @override + String toString() { + return 'NightStudyEntity(id: $id, place: $place, content: $content, doNeedPhone: $doNeedPhone, reasonForPhone: $reasonForPhone, startAt: $startAt, endAt: $endAt)'; + } +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 666c262..149f7ba 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,7 @@ import 'package:easier_dodam/component/theme/color.dart'; import 'package:easier_dodam/feature/login/login_navigation.dart'; +import 'package:easier_dodam/feature/night_study/night_study_create/night_study_create.dart'; +import 'package:easier_dodam/feature/night_study/night_study_viewmodel.dart'; import 'package:easier_dodam/feature/out/out.dart'; import 'package:easier_dodam/feature/out_create/out_create.dart'; import 'package:easier_dodam/feature/out_create/out_create_navigation.dart'; @@ -9,6 +11,7 @@ import 'package:provider/provider.dart'; import 'feature/login/login.dart'; import 'feature/night_study/night_study.dart'; +import 'feature/night_study/night_study_create/night_study_create_navigation.dart'; import 'feature/night_study/night_study_navigation.dart'; import 'feature/out/out_navigation.dart'; import 'feature/out/out_viewmodel.dart'; @@ -34,18 +37,24 @@ class MyApp extends StatelessWidget { fontFamily: "Pretendard", scaffoldBackgroundColor: EasierDodamColors.staticWhite, ), - initialRoute: loginRoute, + initialRoute: nightStudyCreateRoute, routes: { - nightStudyRoute: (context) => NightStudyScreen(), - loginRoute: (context) => LoginScreen(), + nightStudyRoute: (context) => ChangeNotifierProvider( + create: (_) => NightStudyViewmodel(), + child: NightStudyScreen(), + ), outRoute: (context) => ChangeNotifierProvider( - create: (_) => OutViewModel(), - child: OutScreen(), - ), + create: (_) => OutViewModel(), + child: OutScreen(), + ), outCreateRoute: (context) => OutCreateScreen(), "test": (context) => Scaffold( - body: Text("test"), - ) + body: Text("test"), + ), + nightStudyCreateRoute: (context) => ChangeNotifierProvider( + create: (_) => NightStudyViewmodel(), + child: NightStudyCreateScreen(), + ), }, ); } diff --git a/pubspec.lock b/pubspec.lock index 4902d36..598a0d8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -295,10 +295,10 @@ packages: dependency: "direct main" description: name: flutter_svg - sha256: "578bd8c508144fdaffd4f77b8ef2d8c523602275cd697cc3db284dbd762ef4ce" + sha256: "936d9c1c010d3e234d1672574636f3352b4941ca3decaddd3cafaeb9ad49c471" url: "https://pub.dev" source: hosted - version: "2.0.14" + version: "2.0.15" flutter_test: dependency: "direct dev" description: flutter @@ -364,10 +364,10 @@ packages: dependency: transitive description: name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf url: "https://pub.dev" source: hosted - version: "0.6.7" + version: "0.7.1" json_annotation: dependency: "direct main" description: @@ -380,10 +380,10 @@ packages: dependency: "direct main" description: name: json_serializable - sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b + sha256: c2fcb3920cf2b6ae6845954186420fca40bc0a8abcc84903b7801f17d7050d7c url: "https://pub.dev" source: hosted - version: "6.8.0" + version: "6.9.0" leak_tracker: dependency: transitive description: @@ -580,10 +580,10 @@ packages: dependency: transitive description: name: shelf_web_socket - sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" + sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67 url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -633,26 +633,26 @@ packages: dependency: transitive description: name: sqflite_common - sha256: "4468b24876d673418a7b7147e5a08a715b4998a7ae69227acafaab762e0e5490" + sha256: "761b9740ecbd4d3e66b8916d784e581861fd3c3553eda85e167bc49fdb68f709" url: "https://pub.dev" source: hosted - version: "2.5.4+5" + version: "2.5.4+6" sqflite_common_ffi: dependency: transitive description: name: sqflite_common_ffi - sha256: d316908f1537725427ff2827a5c5f3b2c1bc311caed985fe3c9b10939c9e11ca + sha256: b8ba78c1b72a9ee6c2323b06af95d43fd13e03d90c8369cb454fd7f629a72588 url: "https://pub.dev" source: hosted - version: "2.3.4" + version: "2.3.4+3" sqflite_common_ffi_web: dependency: transitive description: name: sqflite_common_ffi_web - sha256: f540ad769e5fd31aabe77bfa6e774fdd36145a83e33cdc39239f310c5f8559c3 + sha256: "61ea702e7aba727f28be7ead00b84c19c745cd4a4934d0c41473303df11ac9ea" url: "https://pub.dev" source: hosted - version: "0.4.5+3" + version: "0.4.5+4" sqflite_darwin: dependency: transitive description: @@ -777,10 +777,10 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "773c9522d66d523e1c7b25dfb95cc91c26a1e17b107039cfe147285e92de7878" + sha256: "27d5fefe86fb9aace4a9f8375b56b3c292b64d8c04510df230f849850d912cb7" url: "https://pub.dev" source: hosted - version: "1.1.14" + version: "1.1.15" vector_graphics_codec: dependency: transitive description: From dac93c6c60b3bbac78cd7c9f136746acd8347546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Mon, 25 Nov 2024 21:26:15 +0900 Subject: [PATCH 04/15] chore: save preset --- .../item/night_study_present_item.dart | 21 +++--- lib/feature/night_study/night_study.dart | 21 ++++++ .../night_study_create.dart | 2 + .../night_study_create_viewmodel.dart | 4 ++ .../night_study/night_study_viewmodel.dart | 66 ++++++++++++++----- lib/local/conventer/place_type_converter.dart | 15 +++++ lib/local/dao/nigh_study_dao.dart | 4 +- lib/local/easier_dodam_database.dart | 4 +- lib/local/easier_dodam_database.g.dart | 31 ++++++--- lib/local/entity/night_study_entity.dart | 13 +++- .../night_study/night_study_data_source.dart | 34 ++++++++-- .../request/night_study_request.dart | 8 ++- .../request/night_study_request.g.dart | 18 +++-- 13 files changed, 187 insertions(+), 54 deletions(-) create mode 100644 lib/local/conventer/place_type_converter.dart diff --git a/lib/feature/night_study/item/night_study_present_item.dart b/lib/feature/night_study/item/night_study_present_item.dart index 0e9855a..988a70a 100644 --- a/lib/feature/night_study/item/night_study_present_item.dart +++ b/lib/feature/night_study/item/night_study_present_item.dart @@ -1,24 +1,27 @@ +import 'package:easier_dodam/feature/night_study/item/night_study_item.dart'; import 'package:flutter/material.dart'; class NightStudyPresentItem extends StatelessWidget { final String presetTitle; final String reason; - final List places; + final PlaceType place; final bool doNeedPhone; final String phoneReason; final String startDate; final String endDate; + final Function() onTrashClick; final Function() onClickCreate; const NightStudyPresentItem({ super.key, required this.presetTitle, required this.reason, - required this.places, + required this.place, required this.doNeedPhone, required this.phoneReason, required this.startDate, required this.endDate, + required this.onTrashClick, required this.onClickCreate, }); @@ -26,7 +29,7 @@ class NightStudyPresentItem extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text("심자 프리셋 생성하기"), + title: const Text("심자 프리셋 생성하기"), ), body: Padding( padding: const EdgeInsets.all(16.0), @@ -44,12 +47,12 @@ class NightStudyPresentItem extends StatelessWidget { ), SizedBox(height: 16), Text("장소 선택", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), - DropdownButton( - value: places.first, - items: places.map((place) { - return DropdownMenuItem( - value: place, - child: Text(place), + DropdownButton( + value: place, + items: PlaceType.values.map((placeType) { + return DropdownMenuItem( + value: placeType, + child: Text(placeType.toString().split('.').last), ); }).toList(), onChanged: (value) {}, diff --git a/lib/feature/night_study/night_study.dart b/lib/feature/night_study/night_study.dart index 5c21bfc..124e697 100644 --- a/lib/feature/night_study/night_study.dart +++ b/lib/feature/night_study/night_study.dart @@ -3,6 +3,7 @@ import 'package:easier_dodam/component/bottom_navigation_bar.dart'; import 'package:easier_dodam/component/modal_bottom_sheet_container.dart'; import 'package:easier_dodam/component/theme/color.dart'; import 'package:easier_dodam/component/theme/style.dart'; +import 'package:easier_dodam/feature/night_study/item/night_study_present_item.dart'; import 'package:easier_dodam/feature/night_study/night_study_create/night_study_create_navigation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -169,6 +170,26 @@ class _NightStudyScreenState extends State { SizedBox( height: 8, ), + ...viewModel.nightStudyEntities + .map( + (data) => NightStudyPresentItem( + presetTitle: data.title, + reason: data.reason, + place: data.place, + doNeedPhone: data.doNeedPhone, + phoneReason: data.reasonForPhone, + startDate: "${data.startAt} ${data.startAt.minute}", + endDate: "${data.endAt.hour} ${data.endAt.minute}", + onTrashClick: () { + viewModel.removeEntity(data.id ?? 0); + }, + onClickCreate: () async { + Navigator.pop(context); + await viewModel.nightStudy(data); + }, + ), + ) + .toList(), Material( //프리셋 생성 시작 color: EasierDodamColors.staticWhite, child: InkWell( diff --git a/lib/feature/night_study/night_study_create/night_study_create.dart b/lib/feature/night_study/night_study_create/night_study_create.dart index b47fe6c..20ce653 100644 --- a/lib/feature/night_study/night_study_create/night_study_create.dart +++ b/lib/feature/night_study/night_study_create/night_study_create.dart @@ -192,6 +192,8 @@ class _NightStudyCreateState extends State { return; } await provider.createNightStudy( + title: _titleTextFieldController.text, + reason: _contentTextFieldController.text, place: selectedPlace!, content: _contentTextFieldController.text, doNeedPhone: doNeedPhone, diff --git a/lib/feature/night_study/night_study_create/night_study_create_viewmodel.dart b/lib/feature/night_study/night_study_create/night_study_create_viewmodel.dart index e361b04..903b002 100644 --- a/lib/feature/night_study/night_study_create/night_study_create_viewmodel.dart +++ b/lib/feature/night_study/night_study_create/night_study_create_viewmodel.dart @@ -7,6 +7,8 @@ import '../item/night_study_item.dart'; class NightStudyCreateViewModel with ChangeNotifier { Future createNightStudy({ required PlaceType place, + required String title, + required String reason, required String content, required bool doNeedPhone, required String reasonForPhone, @@ -15,6 +17,8 @@ class NightStudyCreateViewModel with ChangeNotifier { }) async { final database = await DatabaseManager.getDatabase(); await database.nightStudyDao.insertNightStudyEntity(NightStudyEntity( + title: title, + reason: reason, place: place, content: content, doNeedPhone: doNeedPhone, diff --git a/lib/feature/night_study/night_study_viewmodel.dart b/lib/feature/night_study/night_study_viewmodel.dart index fed089b..d93d369 100644 --- a/lib/feature/night_study/night_study_viewmodel.dart +++ b/lib/feature/night_study/night_study_viewmodel.dart @@ -1,32 +1,64 @@ -import 'package:easier_dodam/remote/night_study/night_study_data_source.dart'; -import 'package:easier_dodam/remote/night_study/response/night_study_response.dart'; +import 'dart:async'; + +import 'package:easier_dodam/feature/night_study/item/night_study_item.dart'; import 'package:flutter/cupertino.dart'; +import '../../local/database_manager.dart'; +import '../../local/entity/night_study_entity.dart'; import '../../remote/core/base_response.dart'; +import '../../remote/night_study/night_study_data_source.dart'; +import '../../remote/night_study/response/night_study_response.dart'; -class NightStudyViewmodel with ChangeNotifier{ +class NightStudyViewmodel with ChangeNotifier { late NightStudyDataSource _nightStudyDataSource; - String _testState = ""; - String get testState => _testState; + bool _isLoading = false; + bool get isLoading => _isLoading; + + List _nightStudyEntities = List.empty(); + List get nightStudyEntities => _nightStudyEntities; + + List _nightStudyResponses = List.empty(); + List get nightStudyResponses => _nightStudyResponses; - NightStudyViewmodel(){ + StreamSubscription>? _nightStudyStreamSubscription; + + NightStudyViewmodel() { _nightStudyDataSource = NightStudyDataSource(); + _getNightStudyEntities(); + } + + void _getNightStudyEntities() async { + final database = await DatabaseManager.getDatabase(); + _nightStudyStreamSubscription = database.nightStudyDao.findAllEntitiesWithStream().listen((data) { + _nightStudyResponses = data; + notifyListeners(); + }); + } + + void removeEntity(int id) async { + final database = await DatabaseManager.getDatabase(); + await database.nightStudyDao.deleteNightStudyEntityById(id); } - Future nightStudy( - String place, - String content, - bool doNeedPhone, - String reasonForPhone, - String startAt, - String endAt - ) async { - final BaseResponse response = - await _nightStudyDataSource.nightStudy(place, content, doNeedPhone, reasonForPhone, startAt, endAt); + Future nightStudy(NightStudyEntity nightStudyEntity) async { + await _nightStudyDataSource.postNightStudy( + nightStudyEntity.title, + nightStudyEntity.reason, + nightStudyEntity.place, + nightStudyEntity.content, + nightStudyEntity.doNeedPhone, + nightStudyEntity.reasonForPhone, + nightStudyEntity.startAt, + nightStudyEntity.endAt + ); notifyListeners(); return true; } - + @override + void dispose() { + _nightStudyStreamSubscription?.cancel(); + super.dispose(); + } } \ No newline at end of file diff --git a/lib/local/conventer/place_type_converter.dart b/lib/local/conventer/place_type_converter.dart new file mode 100644 index 0000000..bd6753a --- /dev/null +++ b/lib/local/conventer/place_type_converter.dart @@ -0,0 +1,15 @@ +import 'package:floor/floor.dart'; + +import '../../feature/night_study/item/night_study_item.dart'; + +class PlaceTypeConverter extends TypeConverter { + @override + PlaceType decode(String databaseValue) { + return PlaceType.values.firstWhere((e) => e.toString() == 'PlaceType.' + databaseValue); + } + + @override + String encode(PlaceType value) { + return value.toString().split('.').last; + } +} \ No newline at end of file diff --git a/lib/local/dao/nigh_study_dao.dart b/lib/local/dao/nigh_study_dao.dart index 956f3cf..5be7d4b 100644 --- a/lib/local/dao/nigh_study_dao.dart +++ b/lib/local/dao/nigh_study_dao.dart @@ -5,7 +5,7 @@ import '../entity/night_study_entity.dart'; @dao abstract class NighStudyDao { @Query('SELECT * FROM $_tableName WHERE id = :id') - Future findOutEntityById(int id); + Future findNightStudyEntityById(int id); @Query('SELECT * FROM $_tableName') Future> findAllEntities(); @@ -14,7 +14,7 @@ abstract class NighStudyDao { Stream> findAllEntitiesWithStream(); @Query('DELETE FROM $_tableName WHERE id = :id') - Future deleteOutEntityById(int id); + Future deleteNightStudyEntityById(int id); @insert Future insertNightStudyEntity(NightStudyEntity nightStudyEntity); diff --git a/lib/local/easier_dodam_database.dart b/lib/local/easier_dodam_database.dart index 89f59f8..34406e4 100644 --- a/lib/local/easier_dodam_database.dart +++ b/lib/local/easier_dodam_database.dart @@ -5,15 +5,15 @@ import 'package:easier_dodam/local/dao/out_dao.dart'; import 'package:floor/floor.dart'; import 'package:sqflite/sqflite.dart' as sqflite; -import '../feature/night_study/item/night_study_item.dart'; import 'conventer/datetime_converter.dart'; +import 'conventer/place_type_converter.dart'; import 'conventer/time_of_day_converter.dart'; import 'entity/night_study_entity.dart'; import 'entity/out_entity.dart'; part "easier_dodam_database.g.dart"; -@TypeConverters([TimeOfDayConverter, DatetimeConverter]) +@TypeConverters([TimeOfDayConverter, DatetimeConverter, PlaceTypeConverter]) @Database(version: 1, entities: [OutEntity, NightStudyEntity]) abstract class EasierDodamDatabase extends FloorDatabase { OutDao get outDao; diff --git a/lib/local/easier_dodam_database.g.dart b/lib/local/easier_dodam_database.g.dart index eaec2cb..1666c34 100644 --- a/lib/local/easier_dodam_database.g.dart +++ b/lib/local/easier_dodam_database.g.dart @@ -102,7 +102,7 @@ class _$EasierDodamDatabase extends EasierDodamDatabase { await database.execute( 'CREATE TABLE IF NOT EXISTS `out` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT NOT NULL, `reason` TEXT NOT NULL, `startAt` TEXT NOT NULL, `endAt` TEXT NOT NULL)'); await database.execute( - 'CREATE TABLE IF NOT EXISTS `night_study` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `place` INTEGER NOT NULL, `content` TEXT NOT NULL, `doNeedPhone` INTEGER NOT NULL, `reasonForPhone` TEXT NOT NULL, `startAt` TEXT NOT NULL, `endAt` TEXT NOT NULL)'); + 'CREATE TABLE IF NOT EXISTS `night_study` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT NOT NULL, `reason` TEXT NOT NULL, `place` TEXT NOT NULL, `content` TEXT NOT NULL, `doNeedPhone` INTEGER NOT NULL, `reasonForPhone` TEXT NOT NULL, `startAt` TEXT NOT NULL, `endAt` TEXT NOT NULL)'); await callback?.onCreate?.call(database, version); }, @@ -248,7 +248,9 @@ class _$NighStudyDao extends NighStudyDao { 'night_study', (NightStudyEntity item) => { 'id': item.id, - 'place': item.place.index, + 'title': item.title, + 'reason': item.reason, + 'place': _placeTypeConverter.encode(item.place), 'content': item.content, 'doNeedPhone': item.doNeedPhone ? 1 : 0, 'reasonForPhone': item.reasonForPhone, @@ -262,7 +264,9 @@ class _$NighStudyDao extends NighStudyDao { ['id'], (NightStudyEntity item) => { 'id': item.id, - 'place': item.place.index, + 'title': item.title, + 'reason': item.reason, + 'place': _placeTypeConverter.encode(item.place), 'content': item.content, 'doNeedPhone': item.doNeedPhone ? 1 : 0, 'reasonForPhone': item.reasonForPhone, @@ -276,7 +280,9 @@ class _$NighStudyDao extends NighStudyDao { ['id'], (NightStudyEntity item) => { 'id': item.id, - 'place': item.place.index, + 'title': item.title, + 'reason': item.reason, + 'place': _placeTypeConverter.encode(item.place), 'content': item.content, 'doNeedPhone': item.doNeedPhone ? 1 : 0, 'reasonForPhone': item.reasonForPhone, @@ -298,11 +304,13 @@ class _$NighStudyDao extends NighStudyDao { final DeletionAdapter _nightStudyEntityDeletionAdapter; @override - Future findOutEntityById(int id) async { + Future findNightStudyEntityById(int id) async { return _queryAdapter.query('SELECT * FROM night_study WHERE id = ?1', mapper: (Map row) => NightStudyEntity( id: row['id'] as int?, - place: PlaceType.values[row['place'] as int], + title: row['title'] as String, + reason: row['reason'] as String, + place: _placeTypeConverter.decode(row['place'] as String), content: row['content'] as String, doNeedPhone: (row['doNeedPhone'] as int) != 0, reasonForPhone: row['reasonForPhone'] as String, @@ -316,7 +324,9 @@ class _$NighStudyDao extends NighStudyDao { return _queryAdapter.queryList('SELECT * FROM night_study', mapper: (Map row) => NightStudyEntity( id: row['id'] as int?, - place: PlaceType.values[row['place'] as int], + title: row['title'] as String, + reason: row['reason'] as String, + place: _placeTypeConverter.decode(row['place'] as String), content: row['content'] as String, doNeedPhone: (row['doNeedPhone'] as int) != 0, reasonForPhone: row['reasonForPhone'] as String, @@ -329,7 +339,9 @@ class _$NighStudyDao extends NighStudyDao { return _queryAdapter.queryListStream('SELECT * FROM night_study', mapper: (Map row) => NightStudyEntity( id: row['id'] as int?, - place: PlaceType.values[row['place'] as int], + title: row['title'] as String, + reason: row['reason'] as String, + place: _placeTypeConverter.decode(row['place'] as String), content: row['content'] as String, doNeedPhone: (row['doNeedPhone'] as int) != 0, reasonForPhone: row['reasonForPhone'] as String, @@ -340,7 +352,7 @@ class _$NighStudyDao extends NighStudyDao { } @override - Future deleteOutEntityById(int id) async { + Future deleteNightStudyEntityById(int id) async { await _queryAdapter.queryNoReturn('DELETE FROM night_study WHERE id = ?1', arguments: [id]); } @@ -371,3 +383,4 @@ class _$NighStudyDao extends NighStudyDao { // ignore_for_file: unused_element final _timeOfDayConverter = TimeOfDayConverter(); final _datetimeConverter = DatetimeConverter(); +final _placeTypeConverter = PlaceTypeConverter(); diff --git a/lib/local/entity/night_study_entity.dart b/lib/local/entity/night_study_entity.dart index fbcc8ed..f057d5d 100644 --- a/lib/local/entity/night_study_entity.dart +++ b/lib/local/entity/night_study_entity.dart @@ -1,5 +1,4 @@ import 'package:floor/floor.dart'; -import 'package:flutter/material.dart'; import '../../feature/night_study/item/night_study_item.dart'; @@ -8,6 +7,10 @@ class NightStudyEntity { @PrimaryKey(autoGenerate: true) final int? id; + final String title; + + final String reason; + final PlaceType place; final String content; @@ -22,6 +25,8 @@ class NightStudyEntity { NightStudyEntity({ this.id, + required this.title, + required this.reason, required this.place, required this.content, required this.doNeedPhone, @@ -36,6 +41,8 @@ class NightStudyEntity { other is NightStudyEntity && runtimeType == other.runtimeType && id == other.id && + title == other.title && + reason == other.reason && place == other.place && content == other.content && doNeedPhone == other.doNeedPhone && @@ -46,6 +53,8 @@ class NightStudyEntity { @override int get hashCode => id.hashCode ^ + title.hashCode ^ + reason.hashCode ^ place.hashCode ^ content.hashCode ^ doNeedPhone.hashCode ^ @@ -55,6 +64,6 @@ class NightStudyEntity { @override String toString() { - return 'NightStudyEntity(id: $id, place: $place, content: $content, doNeedPhone: $doNeedPhone, reasonForPhone: $reasonForPhone, startAt: $startAt, endAt: $endAt)'; + return 'NightStudyEntity(id: $id, title: $title, reason: $reason, place: $place, content: $content, doNeedPhone: $doNeedPhone, reasonForPhone: $reasonForPhone, startAt: $startAt, endAt: $endAt)'; } } \ No newline at end of file diff --git a/lib/remote/night_study/night_study_data_source.dart b/lib/remote/night_study/night_study_data_source.dart index ccde3e2..9349a6b 100644 --- a/lib/remote/night_study/night_study_data_source.dart +++ b/lib/remote/night_study/night_study_data_source.dart @@ -4,15 +4,19 @@ import 'package:easier_dodam/remote/core/url.dart'; import 'package:easier_dodam/remote/night_study/request/night_study_request.dart'; import 'package:easier_dodam/remote/night_study/response/night_study_response.dart'; +import '../../feature/night_study/item/night_study_item.dart'; + class NightStudyDataSource{ - Future> nightStudy( - String place, + Future> postNightStudy( + String title, + String reason, + PlaceType place, String content, bool doNeedPhone, String reasonForPhone, - String startAt, - String endAt) async { + DateTime startAt, + DateTime endAt) async { return await CoreClient.post( url: EasierDodamUrl.NIGHT_STUDY, body: NightStudyRequest( @@ -28,4 +32,26 @@ class NightStudyDataSource{ ); } + Future> getMyNightStudies() async{ + final response = await CoreClient.get>( + url: EasierDodamUrl.NIGHT_STUDY, + listDecoder: (data) { + return data + .map((item) => NightStudyResponse.fromJson(item as Map)) + .toList(); + }, + ); + return response.data; + } + + Future deleteMyNightStudy(int id) async { + final response = await CoreClient.delete( + url: EasierDodamUrl.NIGHT_STUDY + "/$id", + ); + + print(response.message); + + return true; + } + } \ No newline at end of file diff --git a/lib/remote/night_study/request/night_study_request.dart b/lib/remote/night_study/request/night_study_request.dart index 5900b05..ba6bcb9 100644 --- a/lib/remote/night_study/request/night_study_request.dart +++ b/lib/remote/night_study/request/night_study_request.dart @@ -1,15 +1,17 @@ import 'package:json_annotation/json_annotation.dart'; +import '../../../feature/night_study/item/night_study_item.dart'; + part 'night_study_request.g.dart'; @JsonSerializable() class NightStudyRequest{ - String place; + PlaceType place; String content; bool doNeedPhone; String reasonForPhone; - String startAt; - String endAt; + DateTime startAt; + DateTime endAt; NightStudyRequest( { diff --git a/lib/remote/night_study/request/night_study_request.g.dart b/lib/remote/night_study/request/night_study_request.g.dart index 39de93e..7cb951e 100644 --- a/lib/remote/night_study/request/night_study_request.g.dart +++ b/lib/remote/night_study/request/night_study_request.g.dart @@ -8,20 +8,26 @@ part of 'night_study_request.dart'; NightStudyRequest _$NightStudyRequestFromJson(Map json) => NightStudyRequest( - place: json['place'] as String, + place: $enumDecode(_$PlaceTypeEnumMap, json['place']), content: json['content'] as String, doNeedPhone: json['doNeedPhone'] as bool, reasonForPhone: json['reasonForPhone'] as String, - endAt: json['endAt'] as String, - startAt: json['startAt'] as String, + endAt: DateTime.parse(json['endAt'] as String), + startAt: DateTime.parse(json['startAt'] as String), ); Map _$NightStudyRequestToJson(NightStudyRequest instance) => { - 'place': instance.place, + 'place': _$PlaceTypeEnumMap[instance.place]!, 'content': instance.content, 'doNeedPhone': instance.doNeedPhone, 'reasonForPhone': instance.reasonForPhone, - 'startAt': instance.startAt, - 'endAt': instance.endAt, + 'startAt': instance.startAt.toIso8601String(), + 'endAt': instance.endAt.toIso8601String(), }; + +const _$PlaceTypeEnumMap = { + PlaceType.PROGRAM1: 'PROGRAM1', + PlaceType.PROGRAM2: 'PROGRAM2', + PlaceType.PROGRAM3: 'PROGRAM3', +}; From 7cc65c4cf7c6cfdfcc0c5623213a9245a83b4c89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Mon, 25 Nov 2024 22:24:56 +0900 Subject: [PATCH 05/15] chore: load my preset --- .../night_study/item/night_study_item.dart | 8 +- .../item/night_study_present_item.dart | 122 ------------------ .../item/night_study_preset_item.dart | 111 ++++++++++++++++ lib/feature/night_study/night_study.dart | 34 ++++- .../night_study_create.dart | 5 +- .../night_study/night_study_viewmodel.dart | 19 ++- lib/main.dart | 6 +- .../request/night_study_request.g.dart | 6 +- 8 files changed, 170 insertions(+), 141 deletions(-) delete mode 100644 lib/feature/night_study/item/night_study_present_item.dart create mode 100644 lib/feature/night_study/item/night_study_preset_item.dart diff --git a/lib/feature/night_study/item/night_study_item.dart b/lib/feature/night_study/item/night_study_item.dart index 2a5ce09..739ab0a 100644 --- a/lib/feature/night_study/item/night_study_item.dart +++ b/lib/feature/night_study/item/night_study_item.dart @@ -6,16 +6,16 @@ import '../../../component/theme/style.dart'; import '../../../utiles/utile.dart'; enum TagType { PENDING, APPROVE, REJECT } -enum PlaceType { PROGRAM1, PROGRAM2, PROGRAM3 } +enum PlaceType { PROGRAMMING_1, PROGRAMMING_2, PROGRAMMING_3 } extension PlaceTypeExtension on PlaceType { String get name { switch (this) { - case PlaceType.PROGRAM1: + case PlaceType.PROGRAMMING_1: return "프로그래밍 1실"; - case PlaceType.PROGRAM2: + case PlaceType.PROGRAMMING_2: return "프로그래밍 2실"; - case PlaceType.PROGRAM3: + case PlaceType.PROGRAMMING_3: return "프로그래밍 3실"; } } diff --git a/lib/feature/night_study/item/night_study_present_item.dart b/lib/feature/night_study/item/night_study_present_item.dart deleted file mode 100644 index 988a70a..0000000 --- a/lib/feature/night_study/item/night_study_present_item.dart +++ /dev/null @@ -1,122 +0,0 @@ -import 'package:easier_dodam/feature/night_study/item/night_study_item.dart'; -import 'package:flutter/material.dart'; - -class NightStudyPresentItem extends StatelessWidget { - final String presetTitle; - final String reason; - final PlaceType place; - final bool doNeedPhone; - final String phoneReason; - final String startDate; - final String endDate; - final Function() onTrashClick; - final Function() onClickCreate; - - const NightStudyPresentItem({ - super.key, - required this.presetTitle, - required this.reason, - required this.place, - required this.doNeedPhone, - required this.phoneReason, - required this.startDate, - required this.endDate, - required this.onTrashClick, - required this.onClickCreate, - }); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text("심자 프리셋 생성하기"), - ), - body: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text("프리셋 제목", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), - TextField( - decoration: InputDecoration(hintText: "프리셋#1"), - ), - SizedBox(height: 16), - Text("사유", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), - TextField( - decoration: InputDecoration(hintText: reason), - ), - SizedBox(height: 16), - Text("장소 선택", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), - DropdownButton( - value: place, - items: PlaceType.values.map((placeType) { - return DropdownMenuItem( - value: placeType, - child: Text(placeType.toString().split('.').last), - ); - }).toList(), - onChanged: (value) {}, - ), - SizedBox(height: 16), - Row( - children: [ - Checkbox( - value: doNeedPhone, - onChanged: (value) {}, - ), - Text("휴대폰 사용"), - ], - ), - if (doNeedPhone) - TextField( - decoration: InputDecoration(hintText: "사유: $phoneReason"), - ), - SizedBox(height: 16), - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text("심자 시작", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), - TextButton( - onPressed: () {}, - child: Text(startDate), - ), - ], - ), - ), - SizedBox(width: 16), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text("심자 종료", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), - TextButton( - onPressed: () {}, - child: Text(endDate), - ), - ], - ), - ), - ], - ), - ], - ), - ), - bottomNavigationBar: Padding( - padding: const EdgeInsets.all(16.0), - child: ElevatedButton( - onPressed: onClickCreate, - style: ElevatedButton.styleFrom( - backgroundColor: Colors.blue, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - ), - child: Text("생성하기", style: TextStyle(color: Colors.white, fontSize: 16)), - ), - ), - ); - } -} \ No newline at end of file diff --git a/lib/feature/night_study/item/night_study_preset_item.dart b/lib/feature/night_study/item/night_study_preset_item.dart new file mode 100644 index 0000000..91b4b59 --- /dev/null +++ b/lib/feature/night_study/item/night_study_preset_item.dart @@ -0,0 +1,111 @@ +import 'package:easier_dodam/feature/night_study/item/night_study_item.dart'; +import 'package:flutter/material.dart'; + +import '../../../component/theme/color.dart'; +import '../../../component/theme/style.dart'; + +class NightStudyPresetItem extends StatelessWidget { + final String presetTitle; + final String reason; + final PlaceType place; + final bool doNeedPhone; + final String phoneReason; + final String startDate; + final String endDate; + final Function() onTrashClick; + final Function() onClickCreate; + + const NightStudyPresetItem({ + super.key, + required this.presetTitle, + required this.reason, + required this.place, + required this.doNeedPhone, + required this.phoneReason, + required this.startDate, + required this.endDate, + required this.onTrashClick, + required this.onClickCreate, + }); + + @override + Widget build(BuildContext context) { + return Material( + color: EasierDodamColors.staticWhite, + child: InkWell( + onTap: onClickCreate, + child: Padding( + padding: EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + presetTitle, + style: EasierDodamStyles.body2 + .copyWith(color: EasierDodamColors.gray700), + ), + SizedBox( + height: 4, + ), + Text( + "사유 : $reason", + style: EasierDodamStyles.body2 + .copyWith(color: EasierDodamColors.gray600), + ), + SizedBox( + height: 4, + ), + Row( + children: [ + Text( + "시작", + style: + EasierDodamStyles.body2.copyWith(fontSize: 12.0), + ), + Text( + " $startDate", + style: + EasierDodamStyles.body2.copyWith(fontSize: 14.0), + ), + Expanded(child: SizedBox()), + Text( + "종료", + style: + EasierDodamStyles.body2.copyWith(fontSize: 12.0), + ), + Text( + " $endDate", + style: + EasierDodamStyles.body2.copyWith(fontSize: 14.0), + ), + ], + ) + ], + ), + ), + SizedBox( + width: 4, + ), + SizedBox( + width: 24, + height: 24, + child: InkWell( + onTap: onTrashClick, + child: Image.asset( + "assets/images/ic_trash.png", + color: EasierDodamColors.gray700, + ), + ), + ) + ], + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/feature/night_study/night_study.dart b/lib/feature/night_study/night_study.dart index 124e697..629b1c8 100644 --- a/lib/feature/night_study/night_study.dart +++ b/lib/feature/night_study/night_study.dart @@ -3,7 +3,7 @@ import 'package:easier_dodam/component/bottom_navigation_bar.dart'; import 'package:easier_dodam/component/modal_bottom_sheet_container.dart'; import 'package:easier_dodam/component/theme/color.dart'; import 'package:easier_dodam/component/theme/style.dart'; -import 'package:easier_dodam/feature/night_study/item/night_study_present_item.dart'; +import 'package:easier_dodam/feature/night_study/item/night_study_preset_item.dart'; import 'package:easier_dodam/feature/night_study/night_study_create/night_study_create_navigation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -64,7 +64,25 @@ class _NightStudyScreenState extends State { preferredSize: Size.fromHeight(60), child: EasierDodamDefaultAppbar( title: '심자', - onPlusClick: () => _onPlusClick(context), + onPlusClick: () { + showModalBottomSheet( + context: context, + builder: (context) { + return ChangeNotifierProvider.value( + value: viewModel, + child: Consumer( + builder: ( + BuildContext context, + NightStudyViewmodel value, + Widget? child, + ) { + return _bottomWidget(context, viewModel); + }, + ), + ); + }, + ); + }, ), ), body: SafeArea( @@ -172,7 +190,7 @@ class _NightStudyScreenState extends State { ), ...viewModel.nightStudyEntities .map( - (data) => NightStudyPresentItem( + (data) => NightStudyPresetItem( presetTitle: data.title, reason: data.reason, place: data.place, @@ -190,6 +208,16 @@ class _NightStudyScreenState extends State { ), ) .toList(), + SizedBox( + height: 8, + ), + Divider( + height: 1, + color: EasierDodamColors.gray600, + ), + SizedBox( + height: 8, + ), Material( //프리셋 생성 시작 color: EasierDodamColors.staticWhite, child: InkWell( diff --git a/lib/feature/night_study/night_study_create/night_study_create.dart b/lib/feature/night_study/night_study_create/night_study_create.dart index 20ce653..109104a 100644 --- a/lib/feature/night_study/night_study_create/night_study_create.dart +++ b/lib/feature/night_study/night_study_create/night_study_create.dart @@ -7,7 +7,6 @@ import '../../../component/textfield.dart'; import '../../../component/theme/color.dart'; import '../../../component/theme/style.dart'; import '../item/night_study_item.dart'; -import '../item/night_study_present_item.dart'; import 'item/night_study_create_time_item.dart'; class NightStudyCreateScreen extends StatefulWidget { @@ -205,7 +204,9 @@ class _NightStudyCreateState extends State { }, ), ), - const SizedBox(height: 8), + const SizedBox( + height: 8 + ), ], ), ), diff --git a/lib/feature/night_study/night_study_viewmodel.dart b/lib/feature/night_study/night_study_viewmodel.dart index d93d369..0d34391 100644 --- a/lib/feature/night_study/night_study_viewmodel.dart +++ b/lib/feature/night_study/night_study_viewmodel.dart @@ -18,8 +18,8 @@ class NightStudyViewmodel with ChangeNotifier { List _nightStudyEntities = List.empty(); List get nightStudyEntities => _nightStudyEntities; - List _nightStudyResponses = List.empty(); - List get nightStudyResponses => _nightStudyResponses; + List _nightStudyResponses = List.empty(); + List get nightStudyResponses => _nightStudyResponses; StreamSubscription>? _nightStudyStreamSubscription; @@ -31,7 +31,7 @@ class NightStudyViewmodel with ChangeNotifier { void _getNightStudyEntities() async { final database = await DatabaseManager.getDatabase(); _nightStudyStreamSubscription = database.nightStudyDao.findAllEntitiesWithStream().listen((data) { - _nightStudyResponses = data; + _nightStudyEntities = data; notifyListeners(); }); } @@ -41,6 +41,14 @@ class NightStudyViewmodel with ChangeNotifier { await database.nightStudyDao.deleteNightStudyEntityById(id); } + Future getMyNightStudies() async { + setIsLoading(true); + final nightStudies = await _nightStudyDataSource.getMyNightStudies(); + setIsLoading(false); + _nightStudyResponses = nightStudies; + notifyListeners(); + } + Future nightStudy(NightStudyEntity nightStudyEntity) async { await _nightStudyDataSource.postNightStudy( nightStudyEntity.title, @@ -56,6 +64,11 @@ class NightStudyViewmodel with ChangeNotifier { return true; } + void setIsLoading(bool isLoading) { + _isLoading = isLoading; + notifyListeners(); + } + @override void dispose() { _nightStudyStreamSubscription?.cancel(); diff --git a/lib/main.dart b/lib/main.dart index 9897340..653db41 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -43,6 +43,7 @@ class MyApp extends StatelessWidget { create: (_) => NightStudyViewmodel(), child: NightStudyScreen(), ), + loginRoute: (context) => LoginScreen(), outRoute: (context) => ChangeNotifierProvider( create: (_) => OutViewModel(), child: OutScreen(), @@ -51,10 +52,7 @@ class MyApp extends StatelessWidget { "test": (context) => Scaffold( body: Text("test"), ), - nightStudyCreateRoute: (context) => ChangeNotifierProvider( - create: (_) => NightStudyViewmodel(), - child: NightStudyCreateScreen(), - ), + nightStudyCreateRoute: (context) => NightStudyCreateScreen(), }, ); } diff --git a/lib/remote/night_study/request/night_study_request.g.dart b/lib/remote/night_study/request/night_study_request.g.dart index 7cb951e..699cfd2 100644 --- a/lib/remote/night_study/request/night_study_request.g.dart +++ b/lib/remote/night_study/request/night_study_request.g.dart @@ -27,7 +27,7 @@ Map _$NightStudyRequestToJson(NightStudyRequest instance) => }; const _$PlaceTypeEnumMap = { - PlaceType.PROGRAM1: 'PROGRAM1', - PlaceType.PROGRAM2: 'PROGRAM2', - PlaceType.PROGRAM3: 'PROGRAM3', + PlaceType.PROGRAMMING_1: 'PROGRAM1', + PlaceType.PROGRAMMING_2: 'PROGRAM2', + PlaceType.PROGRAMMING_3: 'PROGRAM3', }; From 9d47eaeb821a3b7691a3d99b1a25e6ca2f7edf97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Mon, 25 Nov 2024 22:40:55 +0900 Subject: [PATCH 06/15] chore: chore night_study loading --- lib/feature/night_study/night_study.dart | 183 +++++++++++++----- .../night_study/night_study_viewmodel.dart | 8 + .../request/night_study_request.g.dart | 6 +- .../response/night_study_response.dart | 12 +- .../response/night_study_response.g.dart | 28 ++- 5 files changed, 172 insertions(+), 65 deletions(-) diff --git a/lib/feature/night_study/night_study.dart b/lib/feature/night_study/night_study.dart index 629b1c8..c1be2c0 100644 --- a/lib/feature/night_study/night_study.dart +++ b/lib/feature/night_study/night_study.dart @@ -3,8 +3,11 @@ import 'package:easier_dodam/component/bottom_navigation_bar.dart'; import 'package:easier_dodam/component/modal_bottom_sheet_container.dart'; import 'package:easier_dodam/component/theme/color.dart'; import 'package:easier_dodam/component/theme/style.dart'; +import 'package:easier_dodam/feature/night_study/item/night_study_item.dart'; import 'package:easier_dodam/feature/night_study/item/night_study_preset_item.dart'; import 'package:easier_dodam/feature/night_study/night_study_create/night_study_create_navigation.dart'; +import 'package:easier_dodam/remote/night_study/response/night_study_response.dart'; +import 'package:easier_dodam/utiles/utile.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -97,57 +100,23 @@ class _NightStudyScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "현재 신청된 심자", + viewModel.isLoading ? "" : "현재 신청된 심자", style: EasierDodamStyles.body1, textAlign: TextAlign.start, ), - SizedBox( - height: 12, - width: double.infinity, + _loading(viewModel.isLoading), + _notExitsNightStudy( + viewModel.nightStudyResponses.isEmpty && + !viewModel.isLoading, + () { + viewModel.getMyNightStudies(); + }, + ), + ..._nightStudyItemsView( + viewModel.nightStudyResponses, + viewModel.isLoading, + (item) => {viewModel.deleteMyOut(item.id)}, ), - Container( - //프레임 시작 - padding: EdgeInsets.symmetric(vertical: 8, horizontal: 12), - decoration: BoxDecoration( - color: EasierDodamColors.staticWhite, - borderRadius: BorderRadius.circular(20), - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.08), - spreadRadius: 0, - blurRadius: 4, - offset: Offset(0, 4), - ) - ]), - margin: const EdgeInsets.symmetric(horizontal: 12), - height: 106, - width: 380, - child: Column( - // mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 8, - width: 12, - ), - Container( - //수락됨 - height: 24, - width: 52, - alignment: Alignment.center, - child: Text("수락됨", - style: EasierDodamStyles.label1 - .copyWith( - color: EasierDodamColors.staticWhite) - .copyWith(fontSize: 12)), - decoration: BoxDecoration( - color: EasierDodamColors.primary300, - borderRadius: BorderRadius.circular(12), - ), - ), - ], - ), - ) ], ), ); @@ -257,5 +226,125 @@ class _NightStudyScreenState extends State { ), ); } + + Widget _loading(bool isLoading) { + if (isLoading) { + return Center( + child: Container( + width: 50, + height: 50, + child: CircularProgressIndicator( + backgroundColor: EasierDodamColors.staticWhite, + color: EasierDodamColors.primary300, + ), + ), + ); + } else { + return SizedBox(); + } + } + + Widget _notExitsNightStudy(bool isExit, Function() onClick) { + if (isExit) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(10)), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.08), + spreadRadius: 0, + blurRadius: 4, + offset: const Offset(0, 4), // changes position of shadow + ), + ], + ), + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 8, + horizontal: 12, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + width: 40, + height: 40, + child: Image.asset("assets/images/ic_happy.png"), + ), + SizedBox( + height: 12, + ), + Text( + "현재 신청된 심자가 없어요", + style: EasierDodamStyles.label1, + ), + SizedBox( + height: 12, + ), + Material( + color: EasierDodamColors.staticWhite, + child: InkWell( + onTap: onClick, + child: Container( + width: double.infinity, + height: 42, + decoration: BoxDecoration( + border: const Border.fromBorderSide( + BorderSide( + width: 1.0, color: EasierDodamColors.gray500), + ), + borderRadius: BorderRadius.circular(8.0), + ), + child: Center( + child: Text( + "새로고침", + style: EasierDodamStyles.label1, + ), + ), + ), + ), + ) + ], + ), + ), + ); + } else { + return SizedBox(); + } + } + + List _nightStudyItemsView( + List items, + bool isLoading, + Function(NightStudyResponse) onClickTrash, + ) { + if (isLoading) { + return List.empty(); + } + return items + .map((item) => Column( + children: [ + SizedBox( + height: 12, + ), + NightStudyItem( + tagType: switch (item.allowCheck) { + Status.ALLOWED => TagType.APPROVE, + Status.PENDING => TagType.PENDING, + Status.REJECTED => TagType.REJECT, + }, + onClickTrash: () { + onClickTrash(item); + }, + startAt: item.startAt, + endAt: item.endAt, + ), + ], + )) + .toList(); + } + } diff --git a/lib/feature/night_study/night_study_viewmodel.dart b/lib/feature/night_study/night_study_viewmodel.dart index 0d34391..1579859 100644 --- a/lib/feature/night_study/night_study_viewmodel.dart +++ b/lib/feature/night_study/night_study_viewmodel.dart @@ -49,6 +49,14 @@ class NightStudyViewmodel with ChangeNotifier { notifyListeners(); } + void deleteMyOut(int id) async { + setIsLoading(true); + await _nightStudyDataSource.deleteMyNightStudy(id); + _nightStudyResponses.removeWhere((data) => data.id == id); + setIsLoading(false); + notifyListeners(); + } + Future nightStudy(NightStudyEntity nightStudyEntity) async { await _nightStudyDataSource.postNightStudy( nightStudyEntity.title, diff --git a/lib/remote/night_study/request/night_study_request.g.dart b/lib/remote/night_study/request/night_study_request.g.dart index 699cfd2..96ad105 100644 --- a/lib/remote/night_study/request/night_study_request.g.dart +++ b/lib/remote/night_study/request/night_study_request.g.dart @@ -27,7 +27,7 @@ Map _$NightStudyRequestToJson(NightStudyRequest instance) => }; const _$PlaceTypeEnumMap = { - PlaceType.PROGRAMMING_1: 'PROGRAM1', - PlaceType.PROGRAMMING_2: 'PROGRAM2', - PlaceType.PROGRAMMING_3: 'PROGRAM3', + PlaceType.PROGRAMMING_1: 'PROGRAMMING_1', + PlaceType.PROGRAMMING_2: 'PROGRAMMING_2', + PlaceType.PROGRAMMING_3: 'PROGRAMMING_3', }; diff --git a/lib/remote/night_study/response/night_study_response.dart b/lib/remote/night_study/response/night_study_response.dart index fe37e2c..604e7d7 100644 --- a/lib/remote/night_study/response/night_study_response.dart +++ b/lib/remote/night_study/response/night_study_response.dart @@ -4,19 +4,21 @@ import 'package:json_annotation/json_annotation.dart'; part 'night_study_response.g.dart'; +enum Status { ALLOWED, PENDING, REJECTED } + @JsonSerializable() class NightStudyResponse extends BaseObject{ int id; String content; - String allowCheck; + Status allowCheck; bool isPhone; String reason; StudentResponse student; String place; - String startAt; - String endAt; - String createdAt; - String? checkedAt; + DateTime startAt; + DateTime endAt; + DateTime createdAt; + DateTime? checkedAt; NightStudyResponse( { diff --git a/lib/remote/night_study/response/night_study_response.g.dart b/lib/remote/night_study/response/night_study_response.g.dart index 80ade5e..914d866 100644 --- a/lib/remote/night_study/response/night_study_response.g.dart +++ b/lib/remote/night_study/response/night_study_response.g.dart @@ -10,29 +10,37 @@ NightStudyResponse _$NightStudyResponseFromJson(Map json) => NightStudyResponse( id: (json['id'] as num).toInt(), content: json['content'] as String, - allowCheck: json['allowCheck'] as String, + allowCheck: $enumDecode(_$StatusEnumMap, json['allowCheck']), isPhone: json['isPhone'] as bool, reason: json['reason'] as String, student: StudentResponse.fromJson(json['student'] as Map), place: json['place'] as String, - startAt: json['startAt'] as String, - endAt: json['endAt'] as String, - createdAt: json['createdAt'] as String, - checkedAt: json['checkedAt'] as String?, + startAt: DateTime.parse(json['startAt'] as String), + endAt: DateTime.parse(json['endAt'] as String), + createdAt: DateTime.parse(json['createdAt'] as String), + checkedAt: json['checkedAt'] == null + ? null + : DateTime.parse(json['checkedAt'] as String), ); Map _$NightStudyResponseToJson(NightStudyResponse instance) => { 'id': instance.id, 'content': instance.content, - 'allowCheck': instance.allowCheck, + 'allowCheck': _$StatusEnumMap[instance.allowCheck]!, 'isPhone': instance.isPhone, 'reason': instance.reason, 'student': instance.student, 'place': instance.place, - 'startAt': instance.startAt, - 'endAt': instance.endAt, - 'createdAt': instance.createdAt, - 'checkedAt': instance.checkedAt, + 'startAt': instance.startAt.toIso8601String(), + 'endAt': instance.endAt.toIso8601String(), + 'createdAt': instance.createdAt.toIso8601String(), + 'checkedAt': instance.checkedAt?.toIso8601String(), }; + +const _$StatusEnumMap = { + Status.ALLOWED: 'ALLOWED', + Status.PENDING: 'PENDING', + Status.REJECTED: 'REJECTED', +}; From 92a1b99af5300cc11d982ecc514512ea9e1e34cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Mon, 25 Nov 2024 23:15:32 +0900 Subject: [PATCH 07/15] =?UTF-8?q?refactor:=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/feature/night_study/night_study.dart | 29 +++++------------------- lib/feature/out/out.dart | 15 ++++++++++++ lib/main.dart | 7 ++---- 3 files changed, 23 insertions(+), 28 deletions(-) diff --git a/lib/feature/night_study/night_study.dart b/lib/feature/night_study/night_study.dart index c1be2c0..f64ba07 100644 --- a/lib/feature/night_study/night_study.dart +++ b/lib/feature/night_study/night_study.dart @@ -32,26 +32,6 @@ class _NightStudyScreenState extends State { }); } - void _onPlusClick(BuildContext context) { - showModalBottomSheet( - context: context, - builder: (context) { - return ChangeNotifierProvider.value( - value: NightStudyViewmodel(), - child: Consumer( - builder: ( - BuildContext context, - NightStudyViewmodel value, - Widget? child, - ) { - return _bottomWidget(context, NightStudyViewmodel()); - }, - ), - ); - }, - ); - } - @override void dispose() { _reasonTextFieldController.dispose(); @@ -60,7 +40,8 @@ class _NightStudyScreenState extends State { @override Widget build(BuildContext context) { - return Consumer(builder: + return Consumer( + builder: (BuildContext context, NightStudyViewmodel viewModel, Widget? child) { return Scaffold( appBar: PreferredSize( @@ -89,8 +70,10 @@ class _NightStudyScreenState extends State { ), ), body: SafeArea( - child: ChangeNotifierProvider( - create: (_) => NightStudyViewmodel(), + child: RefreshIndicator( + onRefresh: () async { + return viewModel.getMyNightStudies(); + }, child: Consumer( builder: (context, provider, child) { return Container( diff --git a/lib/feature/out/out.dart b/lib/feature/out/out.dart index 7f33a27..9baf493 100644 --- a/lib/feature/out/out.dart +++ b/lib/feature/out/out.dart @@ -21,6 +21,15 @@ class OutScreen extends StatefulWidget { } class _OutScreenState extends State with WidgetsBindingObserver { + + int _selectedIndex = 2; + + void _onItemTapped(int index) { + setState(() { + _selectedIndex = index; + }); + } + @override void initState() { super.initState(); @@ -110,6 +119,12 @@ class _OutScreenState extends State with WidgetsBindingObserver { ), ), ), + bottomNavigationBar: SafeArea( + child: EasierDodamBottomNavigationBar( + selectedIndex: _selectedIndex, + onItemTapped: _onItemTapped, + ), + ), ); }, ); diff --git a/lib/main.dart b/lib/main.dart index 653db41..153d1a9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -17,8 +17,8 @@ import 'feature/out/out_navigation.dart'; import 'feature/out/out_viewmodel.dart'; void main() async { - WidgetsFlutterBinding.ensureInitialized(); // 추가 - await FlutterConfig.loadEnvVariables(); // 추가 + WidgetsFlutterBinding.ensureInitialized(); + await FlutterConfig.loadEnvVariables(); runApp(const MyApp()); } @@ -49,9 +49,6 @@ class MyApp extends StatelessWidget { child: OutScreen(), ), outCreateRoute: (context) => OutCreateScreen(), - "test": (context) => Scaffold( - body: Text("test"), - ), nightStudyCreateRoute: (context) => NightStudyCreateScreen(), }, ); From 3a56f2ce5233ca28b17f5d253bcd174f09882d02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Mon, 25 Nov 2024 23:40:31 +0900 Subject: [PATCH 08/15] chore: bottomBar routing --- lib/feature/night_study/night_study.dart | 17 ++++++++++++++++- lib/feature/out/out.dart | 17 ++++++++++++++++- lib/main.dart | 2 +- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/lib/feature/night_study/night_study.dart b/lib/feature/night_study/night_study.dart index f64ba07..0e4b0f8 100644 --- a/lib/feature/night_study/night_study.dart +++ b/lib/feature/night_study/night_study.dart @@ -11,6 +11,8 @@ import 'package:easier_dodam/utiles/utile.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import '../out/out_navigation.dart'; +import 'night_study_navigation.dart'; import 'night_study_viewmodel.dart'; class NightStudyScreen extends StatefulWidget { @@ -24,12 +26,25 @@ class _NightStudyScreenState extends State { final TextEditingController _reasonTextFieldController = TextEditingController(); - int _selectedIndex = 3; + int _selectedIndex = 2; void _onItemTapped(int index) { setState(() { _selectedIndex = index; }); + + switch (index) { + case 0: + break; + case 1: + Navigator.pushReplacementNamed(context, outRoute); + break; + case 2: + Navigator.pushReplacementNamed(context, nightStudyRoute); + break; + case 3: + break; + } } @override diff --git a/lib/feature/out/out.dart b/lib/feature/out/out.dart index 9baf493..53fe387 100644 --- a/lib/feature/out/out.dart +++ b/lib/feature/out/out.dart @@ -2,7 +2,9 @@ import 'package:easier_dodam/component/appbar.dart'; import 'package:easier_dodam/component/modal_bottom_sheet_container.dart'; import 'package:easier_dodam/component/theme/color.dart'; import 'package:easier_dodam/component/theme/style.dart'; +import 'package:easier_dodam/feature/night_study/night_study_navigation.dart'; import 'package:easier_dodam/feature/out/item/out_item.dart'; +import 'package:easier_dodam/feature/out/out_navigation.dart'; import 'package:easier_dodam/feature/out/out_viewmodel.dart'; import 'package:easier_dodam/feature/out_create/out_create_navigation.dart'; import 'package:easier_dodam/remote/out/response/out_response.dart'; @@ -22,12 +24,25 @@ class OutScreen extends StatefulWidget { class _OutScreenState extends State with WidgetsBindingObserver { - int _selectedIndex = 2; + int _selectedIndex = 1; void _onItemTapped(int index) { setState(() { _selectedIndex = index; }); + + switch (index) { + case 0: + break; + case 1: + Navigator.pushReplacementNamed(context, outRoute); + break; + case 2: + Navigator.pushReplacementNamed(context, nightStudyRoute); + break; + case 3: + break; + } } @override diff --git a/lib/main.dart b/lib/main.dart index 153d1a9..8953581 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -37,7 +37,7 @@ class MyApp extends StatelessWidget { fontFamily: "Pretendard", scaffoldBackgroundColor: EasierDodamColors.staticWhite, ), - initialRoute: nightStudyRoute, + initialRoute: loginRoute, routes: { nightStudyRoute: (context) => ChangeNotifierProvider( create: (_) => NightStudyViewmodel(), From 203e61b3fcd6ef671a62282045e33e6ed9cf51de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Mon, 25 Nov 2024 23:43:01 +0900 Subject: [PATCH 09/15] refactor: add notifyListeners() --- lib/feature/night_study/night_study_viewmodel.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/feature/night_study/night_study_viewmodel.dart b/lib/feature/night_study/night_study_viewmodel.dart index 1579859..41db7d5 100644 --- a/lib/feature/night_study/night_study_viewmodel.dart +++ b/lib/feature/night_study/night_study_viewmodel.dart @@ -39,6 +39,7 @@ class NightStudyViewmodel with ChangeNotifier { void removeEntity(int id) async { final database = await DatabaseManager.getDatabase(); await database.nightStudyDao.deleteNightStudyEntityById(id); + notifyListeners(); } Future getMyNightStudies() async { From 3df26e5163ac97dc4fcc6ba89366cdfde3e172ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Tue, 26 Nov 2024 00:59:54 +0900 Subject: [PATCH 10/15] refactor: connect server --- .../night_study/item/night_study_item.dart | 6 +-- .../item/night_study_preset_item.dart | 6 +-- lib/feature/night_study/night_study.dart | 38 +++++++++---------- .../night_study_create.dart | 1 - .../night_study_create_viewmodel.dart | 2 - .../night_study/night_study_viewmodel.dart | 2 - lib/local/easier_dodam_database.g.dart | 8 +--- lib/local/entity/night_study_entity.dart | 7 +--- lib/remote/core/core_client.dart | 9 +++-- .../night_study/night_study_data_source.dart | 32 ++++++++-------- .../request/night_study_request.dart | 2 +- .../request/night_study_request.g.dart | 10 +---- .../response/night_study_response.dart | 8 +--- 13 files changed, 52 insertions(+), 79 deletions(-) diff --git a/lib/feature/night_study/item/night_study_item.dart b/lib/feature/night_study/item/night_study_item.dart index 739ab0a..ed8309c 100644 --- a/lib/feature/night_study/item/night_study_item.dart +++ b/lib/feature/night_study/item/night_study_item.dart @@ -12,11 +12,11 @@ extension PlaceTypeExtension on PlaceType { String get name { switch (this) { case PlaceType.PROGRAMMING_1: - return "프로그래밍 1실"; + return "프로그래밍1실"; case PlaceType.PROGRAMMING_2: - return "프로그래밍 2실"; + return "프로그래밍2실"; case PlaceType.PROGRAMMING_3: - return "프로그래밍 3실"; + return "프로그래밍3실"; } } } diff --git a/lib/feature/night_study/item/night_study_preset_item.dart b/lib/feature/night_study/item/night_study_preset_item.dart index 91b4b59..c3f5808 100644 --- a/lib/feature/night_study/item/night_study_preset_item.dart +++ b/lib/feature/night_study/item/night_study_preset_item.dart @@ -6,8 +6,8 @@ import '../../../component/theme/style.dart'; class NightStudyPresetItem extends StatelessWidget { final String presetTitle; - final String reason; final PlaceType place; + final String content; final bool doNeedPhone; final String phoneReason; final String startDate; @@ -18,8 +18,8 @@ class NightStudyPresetItem extends StatelessWidget { const NightStudyPresetItem({ super.key, required this.presetTitle, - required this.reason, required this.place, + required this.content, required this.doNeedPhone, required this.phoneReason, required this.startDate, @@ -53,7 +53,7 @@ class NightStudyPresetItem extends StatelessWidget { height: 4, ), Text( - "사유 : $reason", + "사유 : $context", style: EasierDodamStyles.body2 .copyWith(color: EasierDodamColors.gray600), ), diff --git a/lib/feature/night_study/night_study.dart b/lib/feature/night_study/night_study.dart index 0e4b0f8..8859ae2 100644 --- a/lib/feature/night_study/night_study.dart +++ b/lib/feature/night_study/night_study.dart @@ -159,8 +159,8 @@ class _NightStudyScreenState extends State { .map( (data) => NightStudyPresetItem( presetTitle: data.title, - reason: data.reason, place: data.place, + content: data.content, doNeedPhone: data.doNeedPhone, phoneReason: data.reasonForPhone, startDate: "${data.startAt} ${data.startAt.minute}", @@ -323,24 +323,24 @@ class _NightStudyScreenState extends State { } return items .map((item) => Column( - children: [ - SizedBox( - height: 12, - ), - NightStudyItem( - tagType: switch (item.allowCheck) { - Status.ALLOWED => TagType.APPROVE, - Status.PENDING => TagType.PENDING, - Status.REJECTED => TagType.REJECT, - }, - onClickTrash: () { - onClickTrash(item); - }, - startAt: item.startAt, - endAt: item.endAt, - ), - ], - )) + children: [ + SizedBox( + height: 12, + ), + NightStudyItem( + tagType: switch (item.allowCheck) { + Status.ALLOWED => TagType.APPROVE, + Status.PENDING => TagType.PENDING, + Status.REJECTED => TagType.REJECT, + }, + onClickTrash: () { + onClickTrash(item); + }, + startAt: item.startAt, + endAt: item.endAt, + ), + ], + )) .toList(); } diff --git a/lib/feature/night_study/night_study_create/night_study_create.dart b/lib/feature/night_study/night_study_create/night_study_create.dart index 109104a..7e4476e 100644 --- a/lib/feature/night_study/night_study_create/night_study_create.dart +++ b/lib/feature/night_study/night_study_create/night_study_create.dart @@ -192,7 +192,6 @@ class _NightStudyCreateState extends State { } await provider.createNightStudy( title: _titleTextFieldController.text, - reason: _contentTextFieldController.text, place: selectedPlace!, content: _contentTextFieldController.text, doNeedPhone: doNeedPhone, diff --git a/lib/feature/night_study/night_study_create/night_study_create_viewmodel.dart b/lib/feature/night_study/night_study_create/night_study_create_viewmodel.dart index 903b002..c03d04d 100644 --- a/lib/feature/night_study/night_study_create/night_study_create_viewmodel.dart +++ b/lib/feature/night_study/night_study_create/night_study_create_viewmodel.dart @@ -8,7 +8,6 @@ class NightStudyCreateViewModel with ChangeNotifier { Future createNightStudy({ required PlaceType place, required String title, - required String reason, required String content, required bool doNeedPhone, required String reasonForPhone, @@ -18,7 +17,6 @@ class NightStudyCreateViewModel with ChangeNotifier { final database = await DatabaseManager.getDatabase(); await database.nightStudyDao.insertNightStudyEntity(NightStudyEntity( title: title, - reason: reason, place: place, content: content, doNeedPhone: doNeedPhone, diff --git a/lib/feature/night_study/night_study_viewmodel.dart b/lib/feature/night_study/night_study_viewmodel.dart index 41db7d5..528f4a8 100644 --- a/lib/feature/night_study/night_study_viewmodel.dart +++ b/lib/feature/night_study/night_study_viewmodel.dart @@ -60,8 +60,6 @@ class NightStudyViewmodel with ChangeNotifier { Future nightStudy(NightStudyEntity nightStudyEntity) async { await _nightStudyDataSource.postNightStudy( - nightStudyEntity.title, - nightStudyEntity.reason, nightStudyEntity.place, nightStudyEntity.content, nightStudyEntity.doNeedPhone, diff --git a/lib/local/easier_dodam_database.g.dart b/lib/local/easier_dodam_database.g.dart index 1666c34..3f4f135 100644 --- a/lib/local/easier_dodam_database.g.dart +++ b/lib/local/easier_dodam_database.g.dart @@ -102,7 +102,7 @@ class _$EasierDodamDatabase extends EasierDodamDatabase { await database.execute( 'CREATE TABLE IF NOT EXISTS `out` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT NOT NULL, `reason` TEXT NOT NULL, `startAt` TEXT NOT NULL, `endAt` TEXT NOT NULL)'); await database.execute( - 'CREATE TABLE IF NOT EXISTS `night_study` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT NOT NULL, `reason` TEXT NOT NULL, `place` TEXT NOT NULL, `content` TEXT NOT NULL, `doNeedPhone` INTEGER NOT NULL, `reasonForPhone` TEXT NOT NULL, `startAt` TEXT NOT NULL, `endAt` TEXT NOT NULL)'); + 'CREATE TABLE IF NOT EXISTS `night_study` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT NOT NULL, `place` TEXT NOT NULL, `content` TEXT NOT NULL, `doNeedPhone` INTEGER NOT NULL, `reasonForPhone` TEXT NOT NULL, `startAt` TEXT NOT NULL, `endAt` TEXT NOT NULL)'); await callback?.onCreate?.call(database, version); }, @@ -249,7 +249,6 @@ class _$NighStudyDao extends NighStudyDao { (NightStudyEntity item) => { 'id': item.id, 'title': item.title, - 'reason': item.reason, 'place': _placeTypeConverter.encode(item.place), 'content': item.content, 'doNeedPhone': item.doNeedPhone ? 1 : 0, @@ -265,7 +264,6 @@ class _$NighStudyDao extends NighStudyDao { (NightStudyEntity item) => { 'id': item.id, 'title': item.title, - 'reason': item.reason, 'place': _placeTypeConverter.encode(item.place), 'content': item.content, 'doNeedPhone': item.doNeedPhone ? 1 : 0, @@ -281,7 +279,6 @@ class _$NighStudyDao extends NighStudyDao { (NightStudyEntity item) => { 'id': item.id, 'title': item.title, - 'reason': item.reason, 'place': _placeTypeConverter.encode(item.place), 'content': item.content, 'doNeedPhone': item.doNeedPhone ? 1 : 0, @@ -309,7 +306,6 @@ class _$NighStudyDao extends NighStudyDao { mapper: (Map row) => NightStudyEntity( id: row['id'] as int?, title: row['title'] as String, - reason: row['reason'] as String, place: _placeTypeConverter.decode(row['place'] as String), content: row['content'] as String, doNeedPhone: (row['doNeedPhone'] as int) != 0, @@ -325,7 +321,6 @@ class _$NighStudyDao extends NighStudyDao { mapper: (Map row) => NightStudyEntity( id: row['id'] as int?, title: row['title'] as String, - reason: row['reason'] as String, place: _placeTypeConverter.decode(row['place'] as String), content: row['content'] as String, doNeedPhone: (row['doNeedPhone'] as int) != 0, @@ -340,7 +335,6 @@ class _$NighStudyDao extends NighStudyDao { mapper: (Map row) => NightStudyEntity( id: row['id'] as int?, title: row['title'] as String, - reason: row['reason'] as String, place: _placeTypeConverter.decode(row['place'] as String), content: row['content'] as String, doNeedPhone: (row['doNeedPhone'] as int) != 0, diff --git a/lib/local/entity/night_study_entity.dart b/lib/local/entity/night_study_entity.dart index f057d5d..80452a9 100644 --- a/lib/local/entity/night_study_entity.dart +++ b/lib/local/entity/night_study_entity.dart @@ -9,8 +9,6 @@ class NightStudyEntity { final String title; - final String reason; - final PlaceType place; final String content; @@ -26,7 +24,6 @@ class NightStudyEntity { NightStudyEntity({ this.id, required this.title, - required this.reason, required this.place, required this.content, required this.doNeedPhone, @@ -42,7 +39,6 @@ class NightStudyEntity { runtimeType == other.runtimeType && id == other.id && title == other.title && - reason == other.reason && place == other.place && content == other.content && doNeedPhone == other.doNeedPhone && @@ -54,7 +50,6 @@ class NightStudyEntity { int get hashCode => id.hashCode ^ title.hashCode ^ - reason.hashCode ^ place.hashCode ^ content.hashCode ^ doNeedPhone.hashCode ^ @@ -64,6 +59,6 @@ class NightStudyEntity { @override String toString() { - return 'NightStudyEntity(id: $id, title: $title, reason: $reason, place: $place, content: $content, doNeedPhone: $doNeedPhone, reasonForPhone: $reasonForPhone, startAt: $startAt, endAt: $endAt)'; + return 'NightStudyEntity(id: $id, title: $title, place: $place, content: $content, doNeedPhone: $doNeedPhone, reasonForPhone: $reasonForPhone, startAt: $startAt, endAt: $endAt)'; } } \ No newline at end of file diff --git a/lib/remote/core/core_client.dart b/lib/remote/core/core_client.dart index ca07da5..a291c99 100644 --- a/lib/remote/core/core_client.dart +++ b/lib/remote/core/core_client.dart @@ -18,7 +18,7 @@ class CoreClient { bool sendToken = true, }) async { final headers = { - 'Content-Type': 'application/json', + 'Content-Type': 'application/json; charset=utf-8', }; if (sendToken) { headers["Authorization"] = @@ -30,7 +30,8 @@ class CoreClient { body: json.encode(body), headers: headers, ); - print(response.body); + final responseBody = utf8.decode(response.bodyBytes); + print(responseBody); if (response.statusCode == 401 && sendToken) { final accessToken = await _refresh(); @@ -70,8 +71,8 @@ class CoreClient { Uri.parse(url), headers: headers, ); - - print(response.body); + final responseBody = utf8.decode(response.bodyBytes); + print(responseBody); if (response.statusCode == 401 && sendToken) { final accessToken = await _refresh(); diff --git a/lib/remote/night_study/night_study_data_source.dart b/lib/remote/night_study/night_study_data_source.dart index 9349a6b..e61ec46 100644 --- a/lib/remote/night_study/night_study_data_source.dart +++ b/lib/remote/night_study/night_study_data_source.dart @@ -8,33 +8,31 @@ import '../../feature/night_study/item/night_study_item.dart'; class NightStudyDataSource{ - Future> postNightStudy( - String title, - String reason, + Future postNightStudy( PlaceType place, String content, bool doNeedPhone, String reasonForPhone, DateTime startAt, - DateTime endAt) async { - return await CoreClient.post( - url: EasierDodamUrl.NIGHT_STUDY, - body: NightStudyRequest( - place: place, - content: content, - doNeedPhone: doNeedPhone, - reasonForPhone: reasonForPhone, - endAt: endAt, - startAt: startAt - ).toJson(), - decoder: NightStudyResponse.fromJson, - sendToken: true + DateTime endAt + ) async { + await CoreClient.post( + url: EasierDodamUrl.NIGHT_STUDY, + body: NightStudyRequest( + place: place.name.toString(), + content: content, + doNeedPhone: doNeedPhone, + reasonForPhone: reasonForPhone, + startAt: startAt, + endAt: endAt + ).toJson(), ); + return true; } Future> getMyNightStudies() async{ final response = await CoreClient.get>( - url: EasierDodamUrl.NIGHT_STUDY, + url: EasierDodamUrl.NIGHT_STUDY_MY, listDecoder: (data) { return data .map((item) => NightStudyResponse.fromJson(item as Map)) diff --git a/lib/remote/night_study/request/night_study_request.dart b/lib/remote/night_study/request/night_study_request.dart index ba6bcb9..5f3e54a 100644 --- a/lib/remote/night_study/request/night_study_request.dart +++ b/lib/remote/night_study/request/night_study_request.dart @@ -6,7 +6,7 @@ part 'night_study_request.g.dart'; @JsonSerializable() class NightStudyRequest{ - PlaceType place; + String place; String content; bool doNeedPhone; String reasonForPhone; diff --git a/lib/remote/night_study/request/night_study_request.g.dart b/lib/remote/night_study/request/night_study_request.g.dart index 96ad105..441c280 100644 --- a/lib/remote/night_study/request/night_study_request.g.dart +++ b/lib/remote/night_study/request/night_study_request.g.dart @@ -8,7 +8,7 @@ part of 'night_study_request.dart'; NightStudyRequest _$NightStudyRequestFromJson(Map json) => NightStudyRequest( - place: $enumDecode(_$PlaceTypeEnumMap, json['place']), + place: json['place'] as String, content: json['content'] as String, doNeedPhone: json['doNeedPhone'] as bool, reasonForPhone: json['reasonForPhone'] as String, @@ -18,16 +18,10 @@ NightStudyRequest _$NightStudyRequestFromJson(Map json) => Map _$NightStudyRequestToJson(NightStudyRequest instance) => { - 'place': _$PlaceTypeEnumMap[instance.place]!, + 'place': instance.place, 'content': instance.content, 'doNeedPhone': instance.doNeedPhone, 'reasonForPhone': instance.reasonForPhone, 'startAt': instance.startAt.toIso8601String(), 'endAt': instance.endAt.toIso8601String(), }; - -const _$PlaceTypeEnumMap = { - PlaceType.PROGRAMMING_1: 'PROGRAMMING_1', - PlaceType.PROGRAMMING_2: 'PROGRAMMING_2', - PlaceType.PROGRAMMING_3: 'PROGRAMMING_3', -}; diff --git a/lib/remote/night_study/response/night_study_response.dart b/lib/remote/night_study/response/night_study_response.dart index 604e7d7..9c74ca3 100644 --- a/lib/remote/night_study/response/night_study_response.dart +++ b/lib/remote/night_study/response/night_study_response.dart @@ -7,7 +7,7 @@ part 'night_study_response.g.dart'; enum Status { ALLOWED, PENDING, REJECTED } @JsonSerializable() -class NightStudyResponse extends BaseObject{ +class NightStudyResponse { int id; String content; Status allowCheck; @@ -39,10 +39,6 @@ class NightStudyResponse extends BaseObject{ factory NightStudyResponse.fromJson(Map json) => _$NightStudyResponseFromJson(json); - @override - NightStudyResponse fromJson(json) { - return NightStudyResponse.fromJson(json); - } - + Map toJson() => _$NightStudyResponseToJson(this); } \ No newline at end of file From 3677eefa40b70eb72426fd62a2c7368d4cd5ae58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Tue, 26 Nov 2024 09:43:36 +0900 Subject: [PATCH 11/15] =?UTF-8?q?chore:=20response=20=EC=84=9C=EB=B2=84?= =?UTF-8?q?=EB=9E=91=20response=20=EB=8B=A4=EB=A6=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/images/ic_splash.png | Bin 0 -> 3352 bytes .../night_study/item/night_study_item.dart | 37 ++++++- lib/feature/night_study/night_study.dart | 4 +- .../night_study/night_study_viewmodel.dart | 9 +- lib/main.dart | 95 ++++++++++++++---- .../response/night_study_response.dart | 19 ++-- .../response/night_study_response.g.dart | 20 ++-- .../student/reponse/student_response.dart | 3 +- .../student/reponse/student_response.g.dart | 2 + 9 files changed, 142 insertions(+), 47 deletions(-) create mode 100644 assets/images/ic_splash.png diff --git a/assets/images/ic_splash.png b/assets/images/ic_splash.png new file mode 100644 index 0000000000000000000000000000000000000000..67f41ebb76ff0996cb265a56db4fbf82bc8237d3 GIT binary patch literal 3352 zcmV+z4d?QSP)wl=-Xa>F()P1i+!Vo(_oAXDW_wZWDXc`V&2(G5yh<L(srYQbY|wgKAMGk`djC5{Y^=?L>##1VCBXI?kw19A;}9LFNpttt59ZNe<@kDNEl=34t)HY`2ydom<~9E@ zk2;izxiE&^FI_Sigd8?To_vW7~qv}+9$@9F!$rk^V)OEk6Ve3c{9hW@5gyVTFC`=g#@L>OiIt6vu|r=*)!4&P|BUWc7@ge;Vt_Vm~bX zth_I?@e)0zd` z=NHONYZ?27pg}RTKFvN!y`a2;COS2*Nu^Qxb=<{)%K?g#?M^7#&E?3A$xL2!-^Y(Y z(4ZJqRokt@mU-A6tsjPl3y zJA;V@@3-2HYoN#0y_oAK*2TyufI=GsP#&B3Sj3}wN6EU_Y?d!a965=yeLesH00000 z000000001h1ET2KPi~D0(&6mYMW@pK6CfGSq!m9AD2CSG2#Ca^8QoB>hSDI$n1D#U zF#mqQa=$v_9iiSAlp?COyCskppSQ~s5J@QLydBa3F9;!K!7S^cu{g{J7KEZ%3L1;U zd?@(Ol35BGi^F_qxEzvM--3n3VHR@;S~9DG#^NxGyCXF920O61NfwL4bhQ3KKs1|z z#^Nv?58qzW*%UMuhv{HJD4w)tjl4L_9s$rany?^zH|?2k=|0c=BhPzE+{-TPHrjdU zS(j&;Y}ix7Uz|T#9#cN);D>!KJnrwaWkGsh4wRLydl{b@d97Ou7Zjc@fTaGX+Ww(%b3s;!vvrfsneSym^d-@?IFTd1@?i&ziJd+S%@t z(DL`f|IfnK2E@jdAKe+Do6jKlW?jE|a>OZJ(7ZTo(Ir)R#Y)2El(+3*#8ad+HzMzd z5pXg3VKelF&|AbpHv%_?H`awTy|*0}hwF^VHP{-n>)29L^I49le#WV9zHJ`I4`g-l z$Ko);r5b2E2gQz#IHS4~`q~d{?>>smVT3z1(AW2`?693Ch&g2CbIG2ug2ka53&Log zU!DP#^J8jnC5P}69yx`JqUo(IV_(A(w)Hi5N-3wvnGdEkz^pIMQA%F0uQa5z*>+b|s@iHd5HUg6(Ujr7}Mcz!$O!VoT zn$B7bnt`BQgZ*YtT@px4c0tgt(ei$4wBH;jfS}!mt#eqD0hl%f?KW)>bv1DkHU&V? zPN7c;grp?9AZS-X5?G}TLA%U=z$z(?X&`9n{5|axSY^wG3;E@vO($?5_N*2yy^@=J zc8ChK5X-|P?Fk54I*L09ktDc3-7N*d7kWhFQa$N-bHXo1CK%Y7T~v zby9n>{ivMWOsA@d**!Fj;7N0zQQdw`3@B)b5d%W#bEDF<*(yc!b z(7sFQD_0urK+tJmz-EL`7v1;d2oQ8SG6bzE_Mx@@LJk2zr-1?WA&z}hLD0!yK)s_t z&`H35b`}Ua2@I%@p`MdNK+wsINe;UuF?MI*QauR-orI(Xp%yR%RjZGcWorupK_?+; zLFh>kvid z4MDFXZ9u)2n&8nRi544zUPoHDekH(%-o}H)_CHG4oen{-BduHi+?la@r{?PWOmF?~ zw#!pRsLV6C<7LZSfz9BKhMnqbpx3$fr{vlcSi3Dtjj0t}9dn}uEOZ=s3&Id-etjOa z9YTNh;AbDn9f6?ZNUh;;tb}s|JJr^>BiH`dL%Smo^eQq1t!gu#x=%`duzog=a6UkE z1cHtuwFa6qmy(Bn7R7G-)$b1x_Jg38$gY9b`ah~8aX)(x!iJzDq}M=m`+z#b!sdDr z&Oq(}1RWuMK)v0{Kc+epx*{X%W0$nn5cHBUiAP^i6Nn0-N?2b$F3D?7Xzi$eYE0-b~Ne4?@s&Vc0!y z+(J>Q%XQZSg02(cLh+{mA>0-|2UtuzE(M@A;2W+Nab z0aJf#y<(*y=sGj(-qJ}QLJ$e8MYR$PGyK{pzXh+K3|Ot$e!4Wc5pXbFM_%czLk!nPx{A!x8Xs25qnXPw^h1CU(MD0K~ z-ypEiWs%x?_gDz67lEM5g7L{ATrXm)`vm+wG<6{8@{9?Du(h7s)(Tb6gMpw+BW)H- z)v%}qYy*R!%i%AYCxSR$^_z7e=rX{6PUdIzi$e&y4ANWgR)v6XEeN_CV*;C`G=DiF zJ_KC`sk2zBrbU^}6c37mpv&PxAL%MkUe#GcWC{yYpAl>Og}Z{zu~zws#*~8 zz)Hn4NKAxo_5v6fClz)Ks^7OAF-%?^PKq^{4lBC ziT$0EKF5eSu#nl!5MY@t=CgsIi=r!vK`ZK*_g*JlglRok8JE+dQ1E>5MIu+qCv8N} z^J;>Jxiz8aJ@eDcNLvToo7sFr*l!8%sd>}EVxBjNK||2RsVe2IOGFUtm^6E%Pq%V6Rb}Df`!gYRW;CvL8rsk zdDy*)AIcWA-OWqc9hShMfd8CEusN3z7Fs^=pOZ+i&J28L`Sb{E(z4x}Hh`eTgBbKC z#?|=4y22Yk(9%H+dX>=C7^OW8K}!cQ=p`)X6jvhxf|gA6eJ&*7TQR4&8W9k*WUB6S zAqStlY%wzsv}|CZ+09@v=iKFvIJ9h { color: Colors.black.withOpacity(0.08), spreadRadius: 0, blurRadius: 4, - offset: const Offset(0, 4), // changes position of shadow + offset: const Offset(0, 4), ), ], ), @@ -328,7 +328,7 @@ class _NightStudyScreenState extends State { height: 12, ), NightStudyItem( - tagType: switch (item.allowCheck) { + tagType: switch (item.status) { Status.ALLOWED => TagType.APPROVE, Status.PENDING => TagType.PENDING, Status.REJECTED => TagType.REJECT, diff --git a/lib/feature/night_study/night_study_viewmodel.dart b/lib/feature/night_study/night_study_viewmodel.dart index 528f4a8..ac3e1cd 100644 --- a/lib/feature/night_study/night_study_viewmodel.dart +++ b/lib/feature/night_study/night_study_viewmodel.dart @@ -25,12 +25,14 @@ class NightStudyViewmodel with ChangeNotifier { NightStudyViewmodel() { _nightStudyDataSource = NightStudyDataSource(); + getMyNightStudies(); _getNightStudyEntities(); } void _getNightStudyEntities() async { final database = await DatabaseManager.getDatabase(); - _nightStudyStreamSubscription = database.nightStudyDao.findAllEntitiesWithStream().listen((data) { + _nightStudyStreamSubscription + = database.nightStudyDao.findAllEntitiesWithStream().listen((data) { _nightStudyEntities = data; notifyListeners(); }); @@ -67,8 +69,9 @@ class NightStudyViewmodel with ChangeNotifier { nightStudyEntity.startAt, nightStudyEntity.endAt ); - notifyListeners(); - return true; + + getMyNightStudies(); + return true; } void setIsLoading(bool isLoading) { diff --git a/lib/main.dart b/lib/main.dart index 8953581..f531c6e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -18,7 +18,11 @@ import 'feature/out/out_viewmodel.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - await FlutterConfig.loadEnvVariables(); + try { + await FlutterConfig.loadEnvVariables(); + } catch (e) { + debugPrint('Failed to load environment variables: $e'); + } runApp(const MyApp()); } @@ -28,29 +32,76 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - debugShowCheckedModeBanner: false, - theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - useMaterial3: true, - fontFamily: "Pretendard", - scaffoldBackgroundColor: EasierDodamColors.staticWhite, + return MultiProvider( + providers: [ + ChangeNotifierProvider(create: (_) => NightStudyViewmodel()), + ChangeNotifierProvider(create: (_) => OutViewModel()), + ], + child: MaterialApp( + title: 'Flutter Demo', + debugShowCheckedModeBanner: false, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + useMaterial3: true, + fontFamily: "Pretendard", + scaffoldBackgroundColor: EasierDodamColors.staticWhite, + ), + initialRoute: loginRoute, + routes: { + nightStudyRoute: (context) => NightStudyScreen(), + loginRoute: (context) => LoginScreen(), + outRoute: (context) => OutScreen(), + outCreateRoute: (context) => OutCreateScreen(), + nightStudyCreateRoute: (context) => NightStudyCreateScreen(), + }, + home: const SplashScreen(), ), - initialRoute: loginRoute, - routes: { - nightStudyRoute: (context) => ChangeNotifierProvider( - create: (_) => NightStudyViewmodel(), - child: NightStudyScreen(), + ); + } +} + +class SplashScreen extends StatelessWidget { + const SplashScreen({super.key}); + + @override + Widget build(BuildContext context) { + Future.delayed(const Duration(seconds: 2), () { + Navigator.pushReplacementNamed(context, loginRoute); + }); + + return Scaffold( + body: Container( + decoration: BoxDecoration( + color: EasierDodamColors.staticWhite, ), - loginRoute: (context) => LoginScreen(), - outRoute: (context) => ChangeNotifierProvider( - create: (_) => OutViewModel(), - child: OutScreen(), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/images/ic_splash.png', + width: 200, + ), + const SizedBox(height: 16), + Text( + "도담도담을 쉽게", + style: TextStyle( + color: EasierDodamColors.primary300, + ), + ), + const SizedBox(height: 16), + CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation( + EasierDodamColors.primary300, + ), + ), + ], + ), + ], ), - outCreateRoute: (context) => OutCreateScreen(), - nightStudyCreateRoute: (context) => NightStudyCreateScreen(), - }, + ), ); } -} +} \ No newline at end of file diff --git a/lib/remote/night_study/response/night_study_response.dart b/lib/remote/night_study/response/night_study_response.dart index 9c74ca3..de7746e 100644 --- a/lib/remote/night_study/response/night_study_response.dart +++ b/lib/remote/night_study/response/night_study_response.dart @@ -1,4 +1,3 @@ -import 'package:easier_dodam/remote/core/base_response.dart'; import 'package:easier_dodam/remote/student/reponse/student_response.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -10,29 +9,31 @@ enum Status { ALLOWED, PENDING, REJECTED } class NightStudyResponse { int id; String content; - Status allowCheck; - bool isPhone; - String reason; + Status status; + bool doNeedPhone; + String? reasonForPhone; StudentResponse student; + String? rejectReason; String place; DateTime startAt; DateTime endAt; DateTime createdAt; - DateTime? checkedAt; + DateTime? modifiedAt; NightStudyResponse( { required this.id, required this.content, - required this.allowCheck, - required this.isPhone, - required this.reason, + required this.status, + required this.doNeedPhone, + this.reasonForPhone, required this.student, + this.rejectReason, required this.place, required this.startAt, required this.endAt, required this.createdAt, - this.checkedAt + this.modifiedAt } ); diff --git a/lib/remote/night_study/response/night_study_response.g.dart b/lib/remote/night_study/response/night_study_response.g.dart index 914d866..7a520a1 100644 --- a/lib/remote/night_study/response/night_study_response.g.dart +++ b/lib/remote/night_study/response/night_study_response.g.dart @@ -10,33 +10,35 @@ NightStudyResponse _$NightStudyResponseFromJson(Map json) => NightStudyResponse( id: (json['id'] as num).toInt(), content: json['content'] as String, - allowCheck: $enumDecode(_$StatusEnumMap, json['allowCheck']), - isPhone: json['isPhone'] as bool, - reason: json['reason'] as String, + status: $enumDecode(_$StatusEnumMap, json['status']), + doNeedPhone: json['doNeedPhone'] as bool, + reasonForPhone: json['reasonForPhone'] as String?, student: StudentResponse.fromJson(json['student'] as Map), + rejectReason: json['rejectReason'] as String?, place: json['place'] as String, startAt: DateTime.parse(json['startAt'] as String), endAt: DateTime.parse(json['endAt'] as String), createdAt: DateTime.parse(json['createdAt'] as String), - checkedAt: json['checkedAt'] == null + modifiedAt: json['modifiedAt'] == null ? null - : DateTime.parse(json['checkedAt'] as String), + : DateTime.parse(json['modifiedAt'] as String), ); Map _$NightStudyResponseToJson(NightStudyResponse instance) => { 'id': instance.id, 'content': instance.content, - 'allowCheck': _$StatusEnumMap[instance.allowCheck]!, - 'isPhone': instance.isPhone, - 'reason': instance.reason, + 'status': _$StatusEnumMap[instance.status]!, + 'doNeedPhone': instance.doNeedPhone, + 'reasonForPhone': instance.reasonForPhone, 'student': instance.student, + 'rejectReason': instance.rejectReason, 'place': instance.place, 'startAt': instance.startAt.toIso8601String(), 'endAt': instance.endAt.toIso8601String(), 'createdAt': instance.createdAt.toIso8601String(), - 'checkedAt': instance.checkedAt?.toIso8601String(), + 'modifiedAt': instance.modifiedAt?.toIso8601String(), }; const _$StatusEnumMap = { diff --git a/lib/remote/student/reponse/student_response.dart b/lib/remote/student/reponse/student_response.dart index c5c5c85..d07b499 100644 --- a/lib/remote/student/reponse/student_response.dart +++ b/lib/remote/student/reponse/student_response.dart @@ -5,12 +5,13 @@ part 'student_response.g.dart'; @JsonSerializable() class StudentResponse extends BaseObject{ + int? id; String name; int grade; int room; int number; - StudentResponse({required this.name, required this.grade, required this.room, required this.number}); + StudentResponse({this.id, required this.name, required this.grade, required this.room, required this.number}); factory StudentResponse.fromJson(Map json) => _$StudentResponseFromJson(json); diff --git a/lib/remote/student/reponse/student_response.g.dart b/lib/remote/student/reponse/student_response.g.dart index 311246d..3b1e74e 100644 --- a/lib/remote/student/reponse/student_response.g.dart +++ b/lib/remote/student/reponse/student_response.g.dart @@ -8,6 +8,7 @@ part of 'student_response.dart'; StudentResponse _$StudentResponseFromJson(Map json) => StudentResponse( + id: (json['id'] as num?)?.toInt(), name: json['name'] as String, grade: (json['grade'] as num).toInt(), room: (json['room'] as num).toInt(), @@ -16,6 +17,7 @@ StudentResponse _$StudentResponseFromJson(Map json) => Map _$StudentResponseToJson(StudentResponse instance) => { + 'id': instance.id, 'name': instance.name, 'grade': instance.grade, 'room': instance.room, From fdb47731b0982ac5fa61ac7c4cef2088d39c4517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Tue, 26 Nov 2024 10:50:58 +0900 Subject: [PATCH 12/15] feat: add splash --- assets/images/ic_splash.png | Bin 3352 -> 0 bytes assets/images/ic_splash.svg | 7 +++++++ lib/main.dart | 4 ++-- 3 files changed, 9 insertions(+), 2 deletions(-) delete mode 100644 assets/images/ic_splash.png create mode 100644 assets/images/ic_splash.svg diff --git a/assets/images/ic_splash.png b/assets/images/ic_splash.png deleted file mode 100644 index 67f41ebb76ff0996cb265a56db4fbf82bc8237d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3352 zcmV+z4d?QSP)wl=-Xa>F()P1i+!Vo(_oAXDW_wZWDXc`V&2(G5yh<L(srYQbY|wgKAMGk`djC5{Y^=?L>##1VCBXI?kw19A;}9LFNpttt59ZNe<@kDNEl=34t)HY`2ydom<~9E@ zk2;izxiE&^FI_Sigd8?To_vW7~qv}+9$@9F!$rk^V)OEk6Ve3c{9hW@5gyVTFC`=g#@L>OiIt6vu|r=*)!4&P|BUWc7@ge;Vt_Vm~bX zth_I?@e)0zd` z=NHONYZ?27pg}RTKFvN!y`a2;COS2*Nu^Qxb=<{)%K?g#?M^7#&E?3A$xL2!-^Y(Y z(4ZJqRokt@mU-A6tsjPl3y zJA;V@@3-2HYoN#0y_oAK*2TyufI=GsP#&B3Sj3}wN6EU_Y?d!a965=yeLesH00000 z000000001h1ET2KPi~D0(&6mYMW@pK6CfGSq!m9AD2CSG2#Ca^8QoB>hSDI$n1D#U zF#mqQa=$v_9iiSAlp?COyCskppSQ~s5J@QLydBa3F9;!K!7S^cu{g{J7KEZ%3L1;U zd?@(Ol35BGi^F_qxEzvM--3n3VHR@;S~9DG#^NxGyCXF920O61NfwL4bhQ3KKs1|z z#^Nv?58qzW*%UMuhv{HJD4w)tjl4L_9s$rany?^zH|?2k=|0c=BhPzE+{-TPHrjdU zS(j&;Y}ix7Uz|T#9#cN);D>!KJnrwaWkGsh4wRLydl{b@d97Ou7Zjc@fTaGX+Ww(%b3s;!vvrfsneSym^d-@?IFTd1@?i&ziJd+S%@t z(DL`f|IfnK2E@jdAKe+Do6jKlW?jE|a>OZJ(7ZTo(Ir)R#Y)2El(+3*#8ad+HzMzd z5pXg3VKelF&|AbpHv%_?H`awTy|*0}hwF^VHP{-n>)29L^I49le#WV9zHJ`I4`g-l z$Ko);r5b2E2gQz#IHS4~`q~d{?>>smVT3z1(AW2`?693Ch&g2CbIG2ug2ka53&Log zU!DP#^J8jnC5P}69yx`JqUo(IV_(A(w)Hi5N-3wvnGdEkz^pIMQA%F0uQa5z*>+b|s@iHd5HUg6(Ujr7}Mcz!$O!VoT zn$B7bnt`BQgZ*YtT@px4c0tgt(ei$4wBH;jfS}!mt#eqD0hl%f?KW)>bv1DkHU&V? zPN7c;grp?9AZS-X5?G}TLA%U=z$z(?X&`9n{5|axSY^wG3;E@vO($?5_N*2yy^@=J zc8ChK5X-|P?Fk54I*L09ktDc3-7N*d7kWhFQa$N-bHXo1CK%Y7T~v zby9n>{ivMWOsA@d**!Fj;7N0zQQdw`3@B)b5d%W#bEDF<*(yc!b z(7sFQD_0urK+tJmz-EL`7v1;d2oQ8SG6bzE_Mx@@LJk2zr-1?WA&z}hLD0!yK)s_t z&`H35b`}Ua2@I%@p`MdNK+wsINe;UuF?MI*QauR-orI(Xp%yR%RjZGcWorupK_?+; zLFh>kvid z4MDFXZ9u)2n&8nRi544zUPoHDekH(%-o}H)_CHG4oen{-BduHi+?la@r{?PWOmF?~ zw#!pRsLV6C<7LZSfz9BKhMnqbpx3$fr{vlcSi3Dtjj0t}9dn}uEOZ=s3&Id-etjOa z9YTNh;AbDn9f6?ZNUh;;tb}s|JJr^>BiH`dL%Smo^eQq1t!gu#x=%`duzog=a6UkE z1cHtuwFa6qmy(Bn7R7G-)$b1x_Jg38$gY9b`ah~8aX)(x!iJzDq}M=m`+z#b!sdDr z&Oq(}1RWuMK)v0{Kc+epx*{X%W0$nn5cHBUiAP^i6Nn0-N?2b$F3D?7Xzi$eYE0-b~Ne4?@s&Vc0!y z+(J>Q%XQZSg02(cLh+{mA>0-|2UtuzE(M@A;2W+Nab z0aJf#y<(*y=sGj(-qJ}QLJ$e8MYR$PGyK{pzXh+K3|Ot$e!4Wc5pXbFM_%czLk!nPx{A!x8Xs25qnXPw^h1CU(MD0K~ z-ypEiWs%x?_gDz67lEM5g7L{ATrXm)`vm+wG<6{8@{9?Du(h7s)(Tb6gMpw+BW)H- z)v%}qYy*R!%i%AYCxSR$^_z7e=rX{6PUdIzi$e&y4ANWgR)v6XEeN_CV*;C`G=DiF zJ_KC`sk2zBrbU^}6c37mpv&PxAL%MkUe#GcWC{yYpAl>Og}Z{zu~zws#*~8 zz)Hn4NKAxo_5v6fClz)Ks^7OAF-%?^PKq^{4lBC ziT$0EKF5eSu#nl!5MY@t=CgsIi=r!vK`ZK*_g*JlglRok8JE+dQ1E>5MIu+qCv8N} z^J;>Jxiz8aJ@eDcNLvToo7sFr*l!8%sd>}EVxBjNK||2RsVe2IOGFUtm^6E%Pq%V6Rb}Df`!gYRW;CvL8rsk zdDy*)AIcWA-OWqc9hShMfd8CEusN3z7Fs^=pOZ+i&J28L`Sb{E(z4x}Hh`eTgBbKC z#?|=4y22Yk(9%H+dX>=C7^OW8K}!cQ=p`)X6jvhxf|gA6eJ&*7TQR4&8W9k*WUB6S zAqStlY%wzsv}|CZ+09@v=iKFvIJ9h + + + + + + diff --git a/lib/main.dart b/lib/main.dart index 2dd06b6..677f120 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -53,8 +53,9 @@ class MyApp extends StatelessWidget { fontFamily: "Pretendard", scaffoldBackgroundColor: EasierDodamColors.staticWhite, ), - initialRoute: loginRoute, + initialRoute: '', routes: { + 'splash': (context) => const SplashScreen(), nightStudyRoute: (context) => NightStudyScreen(), loginRoute: (context) => LoginScreen(), logoutRoute: (context) => ChangeNotifierProvider( @@ -73,7 +74,6 @@ class MyApp extends StatelessWidget { outCreateRoute: (context) => OutCreateScreen(), nightStudyCreateRoute: (context) => NightStudyCreateScreen(), }, - home: const SplashScreen(), ), ); } From 98da3a3b3ab92efa0ec5044534896f716fa8e84c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Tue, 26 Nov 2024 10:51:14 +0900 Subject: [PATCH 13/15] chore: png -> svg --- lib/component/bottom_navigation_bar.dart | 2 +- lib/component/modal_bottom_sheet_container.dart | 1 - lib/main.dart | 17 ++++++----------- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/lib/component/bottom_navigation_bar.dart b/lib/component/bottom_navigation_bar.dart index a8420c4..2611d27 100644 --- a/lib/component/bottom_navigation_bar.dart +++ b/lib/component/bottom_navigation_bar.dart @@ -46,7 +46,7 @@ class EasierDodamBottomNavigationBar extends StatelessWidget { ), _buildNavItem( context, - icon: 'assets/images/ic_door_open.svg', + icon: 'assets//imagesic_door_open.svg', label: '외출', index: 1, ), diff --git a/lib/component/modal_bottom_sheet_container.dart b/lib/component/modal_bottom_sheet_container.dart index 90b9cf6..5ff9b80 100644 --- a/lib/component/modal_bottom_sheet_container.dart +++ b/lib/component/modal_bottom_sheet_container.dart @@ -1,5 +1,4 @@ import 'package:easier_dodam/component/theme/color.dart'; -import 'package:easier_dodam/component/theme/style.dart'; import 'package:flutter/material.dart'; class ModalBottomSheetContainer extends StatelessWidget { diff --git a/lib/main.dart b/lib/main.dart index 677f120..59939a4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,5 @@ import 'package:easier_dodam/component/theme/color.dart'; +import 'package:easier_dodam/component/theme/style.dart'; import 'package:easier_dodam/feature/login/login_navigation.dart'; import 'package:easier_dodam/feature/night_study/night_study_viewmodel.dart'; import 'package:easier_dodam/feature/logout/logout.dart'; @@ -13,6 +14,7 @@ import 'package:easier_dodam/feature/out_sleeping/out_sleeping_viewmodel.dart'; import 'package:easier_dodam/feature/out_sleeping_create/out_sleeping_create.dart'; import 'package:flutter/material.dart'; import 'package:flutter_config/flutter_config.dart'; +import 'package:flutter_svg/svg.dart'; import 'package:provider/provider.dart'; import 'feature/login/login.dart'; @@ -53,7 +55,7 @@ class MyApp extends StatelessWidget { fontFamily: "Pretendard", scaffoldBackgroundColor: EasierDodamColors.staticWhite, ), - initialRoute: '', + initialRoute: 'splash', routes: { 'splash': (context) => const SplashScreen(), nightStudyRoute: (context) => NightStudyScreen(), @@ -99,23 +101,16 @@ class SplashScreen extends StatelessWidget { Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Image.asset( - 'assets/images/ic_splash.png', + SvgPicture.asset( + 'assets/images/ic_splash.svg', width: 200, ), const SizedBox(height: 16), Text( "도담도담을 쉽게", - style: TextStyle( - color: EasierDodamColors.primary300, - ), + style: EasierDodamStyles.title1.copyWith(fontSize: 30, color: EasierDodamColors.staticBlack), ), const SizedBox(height: 16), - CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - EasierDodamColors.primary300, - ), - ), ], ), ], From cfdf6810350ac5fc896d29e32a7d7bf251efe0d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Tue, 26 Nov 2024 11:15:25 +0900 Subject: [PATCH 14/15] chore: isToken? outSleepRoute : loginRoute --- lib/component/bottom_navigation_bar.dart | 2 +- lib/main.dart | 10 ++++++++-- lib/remote/core/core_client.dart | 5 +++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/component/bottom_navigation_bar.dart b/lib/component/bottom_navigation_bar.dart index 76a4ed5..8c3ba06 100644 --- a/lib/component/bottom_navigation_bar.dart +++ b/lib/component/bottom_navigation_bar.dart @@ -40,7 +40,7 @@ class EasierDodamBottomNavigationBar extends StatelessWidget { ), _buildNavItem( context, - icon: 'assets//imagesic_door_open.svg', + icon: 'assets/images/ic_door_open.svg', label: '외출', index: 1, ), diff --git a/lib/main.dart b/lib/main.dart index 4cbfa05..ec671c3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -12,6 +12,7 @@ import 'package:easier_dodam/feature/out_sleeping/out_sleeping.dart'; import 'package:easier_dodam/feature/out_sleeping/out_sleeping_navigation.dart'; import 'package:easier_dodam/feature/out_sleeping/out_sleeping_viewmodel.dart'; import 'package:easier_dodam/feature/out_sleeping_create/out_sleeping_create.dart'; +import 'package:easier_dodam/remote/core/core_client.dart'; import 'package:flutter/material.dart'; import 'package:flutter_config/flutter_config.dart'; import 'package:flutter_svg/svg.dart'; @@ -25,6 +26,7 @@ import 'feature/night_study_create/night_study_create_navigation.dart'; import 'feature/out/out_navigation.dart'; import 'feature/out/out_viewmodel.dart'; import 'feature/out_sleeping_create/out_sleeping_create_navigation.dart'; +import 'local/storage_manager.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -86,8 +88,12 @@ class SplashScreen extends StatelessWidget { @override Widget build(BuildContext context) { - Future.delayed(const Duration(seconds: 2), () { - Navigator.pushReplacementNamed(context, loginRoute); + Future.delayed(const Duration(seconds: 1), () async { + if (await CoreClient().hasToken()) { + Navigator.pushReplacementNamed(context, outSleepingRoute); + } else { + Navigator.pushReplacementNamed(context, loginRoute); + } }); return Scaffold( diff --git a/lib/remote/core/core_client.dart b/lib/remote/core/core_client.dart index a291c99..529d2a3 100644 --- a/lib/remote/core/core_client.dart +++ b/lib/remote/core/core_client.dart @@ -196,4 +196,9 @@ class CoreClient { _isRefresh = false; return baseResponse.data.accessToken; } + + Future hasToken() async { + final tokenDto = await StorageManager.getUserToken(); + return tokenDto.accessToken != null && tokenDto.accessToken!.isNotEmpty; + } } From 32fd6b14d79217927b524f93ed9c61b1f3b71a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Tue, 26 Nov 2024 11:41:04 +0900 Subject: [PATCH 15/15] chore: chage fun --- lib/local/storage_manager.dart | 5 +++++ lib/main.dart | 2 +- lib/remote/core/core_client.dart | 5 ----- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/local/storage_manager.dart b/lib/local/storage_manager.dart index 29bb478..bd1861a 100644 --- a/lib/local/storage_manager.dart +++ b/lib/local/storage_manager.dart @@ -43,6 +43,11 @@ class StorageManager { ); } + Future hasToken() async { + final tokenDto = await StorageManager.getUserToken(); + return tokenDto.accessToken != null && tokenDto.accessToken!.isNotEmpty; + } + static get _idKey => "id"; static get _pwKey => "pw"; static get _accessTokenKey => "accessToken"; diff --git a/lib/main.dart b/lib/main.dart index ec671c3..eaac5e4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -89,7 +89,7 @@ class SplashScreen extends StatelessWidget { @override Widget build(BuildContext context) { Future.delayed(const Duration(seconds: 1), () async { - if (await CoreClient().hasToken()) { + if (await StorageManager().hasToken()) { Navigator.pushReplacementNamed(context, outSleepingRoute); } else { Navigator.pushReplacementNamed(context, loginRoute); diff --git a/lib/remote/core/core_client.dart b/lib/remote/core/core_client.dart index 529d2a3..a291c99 100644 --- a/lib/remote/core/core_client.dart +++ b/lib/remote/core/core_client.dart @@ -196,9 +196,4 @@ class CoreClient { _isRefresh = false; return baseResponse.data.accessToken; } - - Future hasToken() async { - final tokenDto = await StorageManager.getUserToken(); - return tokenDto.accessToken != null && tokenDto.accessToken!.isNotEmpty; - } }