From 5e66d88679ad4b48922dad3036b8f8fd61999c4e Mon Sep 17 00:00:00 2001 From: chayoosang Date: Sun, 3 Dec 2023 14:36:21 +0900 Subject: [PATCH] =?UTF-8?q?[PDA-44]=20feat:=20=EB=B9=84=ED=92=88=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=88=98=EC=A0=95=20=ED=9B=84?= =?UTF-8?q?=20=EB=B9=84=ED=92=88=20=ED=99=94=EB=A9=B4=20=EC=83=88=EB=A1=9C?= =?UTF-8?q?=20=EA=B3=A0=EC=B9=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Podfile.lock | 7 + lib/Model/network/api_manager.dart | 4 +- .../equipment/equipment_service.dart | 56 ++- .../equipment/component/equipment_cell.dart | 377 +--------------- .../screen/equipment_add_screen.dart | 80 +++- .../equipment/screen/equipment_screen.dart | 408 +++++++++++++++++- pubspec.lock | 70 ++- pubspec.yaml | 2 + 8 files changed, 605 insertions(+), 399 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 073ce45..e50f0d3 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -67,6 +67,9 @@ PODS: - nanopb/encode (= 2.30909.1) - nanopb/decode (2.30909.1) - nanopb/encode (2.30909.1) + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS - PromisesObjC (2.3.1) - Toast (4.0.0) - url_launcher_ios (0.0.1): @@ -80,6 +83,7 @@ DEPENDENCIES: - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) + - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) SPEC REPOS: @@ -110,6 +114,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/fluttertoast/ios" image_picker_ios: :path: ".symlinks/plugins/image_picker_ios/ios" + path_provider_foundation: + :path: ".symlinks/plugins/path_provider_foundation/darwin" url_launcher_ios: :path: ".symlinks/plugins/url_launcher_ios/ios" @@ -129,6 +135,7 @@ SPEC CHECKSUMS: GoogleUtilities: 202e7a9f5128accd11160fb9c19612de1911aa19 image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5 nanopb: d4d75c12cd1316f4a64e3c6963f879ecd4b5e0d5 + path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4 Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 url_launcher_ios: 68d46cc9766d0c41dbdc884310529557e3cd7a86 diff --git a/lib/Model/network/api_manager.dart b/lib/Model/network/api_manager.dart index 18e1893..2a0adb9 100644 --- a/lib/Model/network/api_manager.dart +++ b/lib/Model/network/api_manager.dart @@ -63,8 +63,8 @@ class APIManager { options: defaultOptions, queryParameters: queryParameters); } - // print('api + $response'); - // print('api + ${response.data}'); + print('api + $response'); + print('api + ${response.data}'); return response.data; } diff --git a/lib/Presenter/equipment/equipment_service.dart b/lib/Presenter/equipment/equipment_service.dart index 84c6473..c8530bb 100644 --- a/lib/Presenter/equipment/equipment_service.dart +++ b/lib/Presenter/equipment/equipment_service.dart @@ -7,7 +7,7 @@ import 'package:frontend/Model/model/general_model.dart'; import 'package:frontend/Model/network/api_manager.dart'; class EquipmentService { - final equipmentGetURL = '/equipments?cond='; + final equipmentGetURL = '/equipments?size=200&cond='; final equipmentPostURL = '/equipments'; final equipmentCategoryURL = "/equipments/categories"; final bukitURL = @@ -22,9 +22,9 @@ class EquipmentService { return _equipmentService; } - Future getEquipment() async { + Future getEquipment(String cond) async { final response = APIManager() - .request(RequestType.get, equipmentGetURL, null, null, null); + .request(RequestType.get, equipmentGetURL + cond, null, null, null); return response; } @@ -84,4 +84,54 @@ class EquipmentService { } } } + + Future editEquipment( + int equipmentId, + String category, + String? description, + String? imgKey, + String? location, + String name, + String quantity) async { + try { + final body = EquipmentAddRequest( + category: category, + description: description, + imgKey: imgKey, + location: location, + name: name, + quantity: quantity) + .toJson(); + + var response = APIManager().request(RequestType.patch, + "$equipmentPostURL/$equipmentId", null, null, body); + if (response != null) { + return true; + } + } on DioError catch (e) { + final response = e.response; + if (response != null) { + final error = + GeneralModel.fromJson(response.data as Map); + return error.message; + } + } + } + + Future deleteEquipment(int equipmentId) async { + try { + var response = APIManager().request(RequestType.delete, + "$equipmentPostURL/$equipmentId", null, null, null); + if (response != null) { + return true; + } + } on DioError catch (e) { + final response = e.response; + if (response != null) { + final error = + GeneralModel.fromJson(response.data as Map); + return error.message; + } + } + } } diff --git a/lib/View/equipment/component/equipment_cell.dart b/lib/View/equipment/component/equipment_cell.dart index 75a7462..b6898e1 100644 --- a/lib/View/equipment/component/equipment_cell.dart +++ b/lib/View/equipment/component/equipment_cell.dart @@ -1,7 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:fluttertoast/fluttertoast.dart'; import 'package:frontend/Model/model/equipment/equipment_list_model.dart'; +import 'package:frontend/Presenter/equipment/equipment_service.dart'; import 'package:frontend/View/colors.dart'; +import 'package:frontend/View/equipment/screen/equipment_add_screen.dart'; +import 'package:frontend/View/equipment/screen/equipment_screen.dart'; class EquipmentCell extends StatefulWidget { final EquipmentModel equipment; @@ -20,10 +24,7 @@ class _EquipmentCellState extends State { @override Widget build(BuildContext context) { - return GestureDetector( - onTap: showDetail, - child: equipmentCell(), - ); + return equipmentCell(); } Widget equipmentCell() { @@ -174,372 +175,4 @@ class _EquipmentCellState extends State { ], )); } - - void showDetail() { - showModalBottomSheet( - isScrollControlled: true, - context: context, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(15), - ), - builder: (BuildContext context) { - return Container( - width: MediaQuery.of(context).size.width, - height: MediaQuery.of(context).size.height * 0.7, - padding: const EdgeInsets.all(15), - decoration: const BoxDecoration( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(12), topRight: Radius.circular(12)), - color: Colors.white, - ), - child: Column( - children: [ - SizedBox( - width: double.infinity, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - IconButton( - onPressed: didTapCancelButton, - icon: SvgPicture.asset( - 'asset/image/cancel.svg', - width: 15, - height: 15, - )), - Row( - children: [ - TextButton( - onPressed: editEquipment, - child: const Text( - '수정', - style: TextStyle( - color: Color(0xFF640FAF), - fontSize: 12, - fontFamily: 'NanumSquare_ac', - fontWeight: FontWeight.w700, - letterSpacing: 0.08, - ), - )), - TextButton( - onPressed: showDeleteSheet, - child: const Text( - '삭제', - style: TextStyle( - color: Color(0xFF640FAF), - fontSize: 12, - fontFamily: 'NanumSquare_ac', - fontWeight: FontWeight.w700, - letterSpacing: 0.08, - ), - )) - ], - ) - ], - ), - ), - const SizedBox( - height: 12, - ), - SizedBox( - width: double.infinity, - height: 200, - child: (widget.equipment.imgUrl == null) - ? Image.asset('asset/image/pladi_icon.png') - : Image.network( - widget.equipment.imgUrl!, - fit: BoxFit.fill, - ), - ), - const SizedBox( - height: 14, - ), - Row( - children: [ - const SizedBox( - width: 51, - child: Text( - '카테고리', - style: TextStyle( - color: Color(0xFF717171), - fontSize: 14, - fontFamily: 'NanumSquare_ac', - fontWeight: FontWeight.w400, - ), - ), - ), - const SizedBox( - width: 18, - ), - Text( - widget.equipment.category, - style: const TextStyle( - color: Colors.black, - fontSize: 14, - fontFamily: 'NanumSquare_ac', - fontWeight: FontWeight.w400, - height: 0, - ), - ), - ], - ), - const SizedBox( - height: 12, - ), - Row( - children: [ - const SizedBox( - width: 51, - child: Text( - '비품명', - style: TextStyle( - color: Color(0xFF717171), - fontSize: 14, - fontFamily: 'NanumSquare_ac', - fontWeight: FontWeight.w400, - ), - ), - ), - const SizedBox( - width: 18, - ), - Text( - widget.equipment.name, - style: const TextStyle( - color: Colors.black, - fontSize: 14, - fontFamily: 'NanumSquare_ac', - fontWeight: FontWeight.w400, - height: 0, - ), - ), - ], - ), - const SizedBox( - height: 12, - ), - Row( - children: [ - const SizedBox( - width: 51, - child: Text( - '수량', - style: TextStyle( - color: Color(0xFF717171), - fontSize: 14, - fontFamily: 'NanumSquare_ac', - fontWeight: FontWeight.w400, - ), - ), - ), - const SizedBox( - width: 18, - ), - Text( - widget.equipment.quantity, - style: const TextStyle( - color: Colors.black, - fontSize: 14, - fontFamily: 'NanumSquare_ac', - fontWeight: FontWeight.w400, - height: 0, - ), - ), - ], - ), - const SizedBox( - height: 12, - ), - Row( - children: [ - const SizedBox( - width: 51, - child: Text( - '책임자', - style: TextStyle( - color: Color(0xFF717171), - fontSize: 14, - fontFamily: 'NanumSquare_ac', - fontWeight: FontWeight.w400, - ), - ), - ), - const SizedBox( - width: 18, - ), - Text( - "${widget.equipment.keeper}(${widget.equipment.contact})", - style: const TextStyle( - color: Colors.black, - fontSize: 14, - fontFamily: 'NanumSquare_ac', - fontWeight: FontWeight.w400, - height: 0, - ), - ), - ], - ), - const SizedBox( - height: 12, - ), - Row( - children: [ - const SizedBox( - width: 51, - child: Text( - '보관장소', - style: TextStyle( - color: Color(0xFF717171), - fontSize: 14, - fontFamily: 'NanumSquare_ac', - fontWeight: FontWeight.w400, - ), - ), - ), - const SizedBox( - width: 18, - ), - Text( - widget.equipment.location == null - ? "보관 장소" - : widget.equipment.location!, - style: const TextStyle( - color: Colors.black, - fontSize: 14, - fontFamily: 'NanumSquare_ac', - fontWeight: FontWeight.w400, - height: 0, - ), - ), - ], - ), - const SizedBox( - height: 12, - ), - Row( - children: [ - const SizedBox( - width: 51, - child: Text( - '설명', - style: TextStyle( - color: Color(0xFF717171), - fontSize: 14, - fontFamily: 'NanumSquare_ac', - fontWeight: FontWeight.w400, - ), - ), - ), - const SizedBox( - width: 18, - ), - SizedBox( - width: (MediaQuery.of(context).size.width - 100), - child: Text( - widget.equipment.description == null - ? "설명" - : widget.equipment.description!, - style: const TextStyle( - color: Colors.black, - fontSize: 14, - fontFamily: 'NanumSquare_ac', - fontWeight: FontWeight.w400, - ), - ), - ), - ], - ), - const SizedBox( - height: 12, - ), - ], - ), - ); - }); - } - - void showDeleteSheet() { - showModalBottomSheet( - context: context, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(15), - ), - builder: (BuildContext context) { - return Container( - height: 180, - decoration: const BoxDecoration( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(12), topRight: Radius.circular(12)), - color: Colors.white, - ), - child: Column( - children: [ - const SizedBox( - height: 30, - ), - const Text( - '비품을 삭제하시겠습니까?', - style: TextStyle(fontSize: 16, color: Color(0xFF656565)), - ), - const SizedBox( - height: 30, - ), - Container( - margin: const EdgeInsets.symmetric(horizontal: 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Expanded( - child: ElevatedButton( - onPressed: didTapCancelButton, - style: ElevatedButton.styleFrom( - elevation: 0, - backgroundColor: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(15), - side: const BorderSide( - color: Color(0xFFC9C9C9)))), - child: const Text( - '취소', - style: TextStyle( - fontSize: 14, color: Color(0xFF717171)), - ), - ), - ), - const SizedBox( - width: 10, - ), - Expanded( - child: ElevatedButton( - onPressed: deleteEquipment, - style: ElevatedButton.styleFrom( - elevation: 0, - backgroundColor: purple, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(15), - )), - child: const Text( - '확인', - style: TextStyle(fontSize: 14, color: Colors.white), - ), - ), - ), - ], - ), - ) - ], - ), - ); - }); - } - - void didTapCancelButton() { - Navigator.of(context).pop(); - } - - void editEquipment() {} - - void deleteEquipment() { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - } } diff --git a/lib/View/equipment/screen/equipment_add_screen.dart b/lib/View/equipment/screen/equipment_add_screen.dart index f8d46cb..9408884 100644 --- a/lib/View/equipment/screen/equipment_add_screen.dart +++ b/lib/View/equipment/screen/equipment_add_screen.dart @@ -1,18 +1,24 @@ import 'dart:io'; +import 'dart:math'; +import 'dart:typed_data'; -import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:frontend/Model/model/equipment/equipment_category_model.dart'; +import 'package:frontend/Model/model/equipment/equipment_list_model.dart'; import 'package:frontend/Model/model/equipment/image_url_model.dart'; import 'package:frontend/Presenter/equipment/equipment_service.dart'; import 'package:frontend/View/common/component/purple_bottom_button.dart'; import 'package:frontend/View/common/component/sub_app_bar.dart'; import 'package:frontend/View/equipment/screen/equipment_screen.dart'; +import 'package:http/http.dart' as http; import 'package:image_picker/image_picker.dart'; +import 'package:path_provider/path_provider.dart'; class EquipmentAddScreen extends StatefulWidget { - const EquipmentAddScreen({super.key}); + final EquipmentModel? equipment; + + const EquipmentAddScreen({super.key, this.equipment}); @override State createState() => _EquipmentAddScreen(); @@ -35,9 +41,43 @@ class _EquipmentAddScreen extends State { @override void initState() { + checkEdit(); super.initState(); } + void checkEdit() async { + if (widget.equipment != null) { + nameController.text = widget.equipment!.name; + quantityController.text = widget.equipment!.quantity; + + _selectedCategory = widget.equipment!.category; + + if (widget.equipment!.location != null) { + loacationController.text = widget.equipment!.location!; + } + if (widget.equipment!.description != null) { + descriptionController.text = widget.equipment!.description!; + } + + if (widget.equipment!.imgUrl != null) { + urlToFile(widget.equipment!.imgUrl!); + } + } + } + + void urlToFile(String imageUrl) async { + final http.Response responseData = await http.get(Uri.parse(imageUrl)); + Uint8List uint8list = responseData.bodyBytes; + var buffer = uint8list.buffer; + ByteData byteData = ByteData.view(buffer); + var tempDir = await getTemporaryDirectory(); + File file = await File('${tempDir.path}/jpeg').writeAsBytes( + buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes)); + setState(() { + userImage = file; + }); + } + @override void dispose() { nameFocusNode.dispose(); @@ -50,12 +90,12 @@ class _EquipmentAddScreen extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: const SubAppBar( - titleText: '신규 비품 추가', + appBar: SubAppBar( + titleText: widget.equipment == null ? '신규 비품 추가' : "비품 수정", ), body: futureBody(), bottomNavigationBar: PurpleBottomButton( - title: '추가', + title: widget.equipment == null ? '추가' : "수정", onPressed: checkEssential, ), ); @@ -486,17 +526,31 @@ class _EquipmentAddScreen extends State { loacationController.text == "" ? null : loacationController.text; var imgKey = imageKey != null ? "equipment/$imageKey" : null; - Future result = EquipmentService().addEquipment( - _selectedCategory!, description, imgKey, location, name, quantity); - result.then((value) => { - if (value == true) {moveToPop()} else {showAlert(value)} - }); + if (widget.equipment == null) { + Future result = EquipmentService().addEquipment( + _selectedCategory!, description, imgKey, location, name, quantity); + result.then((value) => { + if (value == true) {moveToPop()} else {showAlert(value)} + }); + } else { + Future result = EquipmentService().editEquipment( + widget.equipment!.equipmentId, + _selectedCategory!, + description, + imgKey, + location, + name, + quantity); + result.then((value) => { + if (value == true) + {Navigator.of(context).pop(), Navigator.of(context).pop()} + else + {showAlert(value)} + }); + } } void moveToPop() { - EquipmentScreenState? parent = - context.findAncestorStateOfType(); Navigator.of(context).pop(); - parent!.reloadData(); } } diff --git a/lib/View/equipment/screen/equipment_screen.dart b/lib/View/equipment/screen/equipment_screen.dart index 02f700c..d21299b 100644 --- a/lib/View/equipment/screen/equipment_screen.dart +++ b/lib/View/equipment/screen/equipment_screen.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:fluttertoast/fluttertoast.dart'; import 'package:frontend/Model/model/equipment/equipment_list_model.dart'; import 'package:frontend/Presenter/equipment/equipment_service.dart'; +import 'package:frontend/View/colors.dart'; import 'package:frontend/View/common/component/main_app_bar.dart'; import 'package:frontend/View/equipment/component/equipment_cell.dart'; import 'package:frontend/View/equipment/screen/equipment_add_screen.dart'; @@ -15,6 +17,7 @@ class EquipmentScreen extends StatefulWidget { class EquipmentScreenState extends State with SingleTickerProviderStateMixin { + String cond = ""; @override Widget build(BuildContext context) { return Scaffold( @@ -71,7 +74,10 @@ class EquipmentScreenState extends State scrollDirection: Axis.vertical, itemCount: equipmentList.length, itemBuilder: (BuildContext context, int index) { - return EquipmentCell(equipment: equipmentList[index]); + return GestureDetector( + onTap: () => showDetail(equipmentList[index]), + child: EquipmentCell(equipment: equipmentList[index]), + ); }, ); } @@ -102,19 +108,409 @@ class EquipmentScreenState extends State ); } + void showDetail(EquipmentModel equipment) { + showModalBottomSheet( + isScrollControlled: true, + context: context, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15), + ), + builder: (BuildContext context) { + return Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height * 0.7, + padding: const EdgeInsets.all(15), + decoration: const BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(12), topRight: Radius.circular(12)), + color: Colors.white, + ), + child: Column( + children: [ + SizedBox( + width: double.infinity, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + IconButton( + onPressed: didTapCancelButton, + icon: SvgPicture.asset( + 'asset/image/cancel.svg', + width: 15, + height: 15, + )), + Row( + children: [ + TextButton( + onPressed: () => editEquipment(equipment), + child: const Text( + '수정', + style: TextStyle( + color: Color(0xFF640FAF), + fontSize: 12, + fontFamily: 'NanumSquare_ac', + fontWeight: FontWeight.w700, + letterSpacing: 0.08, + ), + )), + TextButton( + onPressed: () => showDeleteSheet(equipment), + child: const Text( + '삭제', + style: TextStyle( + color: Color(0xFF640FAF), + fontSize: 12, + fontFamily: 'NanumSquare_ac', + fontWeight: FontWeight.w700, + letterSpacing: 0.08, + ), + )) + ], + ) + ], + ), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double.infinity, + height: 200, + child: (equipment.imgUrl == null) + ? Image.asset('asset/image/pladi_icon.png') + : Image.network( + equipment.imgUrl!, + fit: BoxFit.fill, + ), + ), + const SizedBox( + height: 14, + ), + Row( + children: [ + const SizedBox( + width: 51, + child: Text( + '카테고리', + style: TextStyle( + color: Color(0xFF717171), + fontSize: 14, + fontFamily: 'NanumSquare_ac', + fontWeight: FontWeight.w400, + ), + ), + ), + const SizedBox( + width: 18, + ), + Text( + equipment.category, + style: const TextStyle( + color: Colors.black, + fontSize: 14, + fontFamily: 'NanumSquare_ac', + fontWeight: FontWeight.w400, + height: 0, + ), + ), + ], + ), + const SizedBox( + height: 12, + ), + Row( + children: [ + const SizedBox( + width: 51, + child: Text( + '비품명', + style: TextStyle( + color: Color(0xFF717171), + fontSize: 14, + fontFamily: 'NanumSquare_ac', + fontWeight: FontWeight.w400, + ), + ), + ), + const SizedBox( + width: 18, + ), + Text( + equipment.name, + style: const TextStyle( + color: Colors.black, + fontSize: 14, + fontFamily: 'NanumSquare_ac', + fontWeight: FontWeight.w400, + height: 0, + ), + ), + ], + ), + const SizedBox( + height: 12, + ), + Row( + children: [ + const SizedBox( + width: 51, + child: Text( + '수량', + style: TextStyle( + color: Color(0xFF717171), + fontSize: 14, + fontFamily: 'NanumSquare_ac', + fontWeight: FontWeight.w400, + ), + ), + ), + const SizedBox( + width: 18, + ), + Text( + equipment.quantity, + style: const TextStyle( + color: Colors.black, + fontSize: 14, + fontFamily: 'NanumSquare_ac', + fontWeight: FontWeight.w400, + height: 0, + ), + ), + ], + ), + const SizedBox( + height: 12, + ), + Row( + children: [ + const SizedBox( + width: 51, + child: Text( + '책임자', + style: TextStyle( + color: Color(0xFF717171), + fontSize: 14, + fontFamily: 'NanumSquare_ac', + fontWeight: FontWeight.w400, + ), + ), + ), + const SizedBox( + width: 18, + ), + Text( + "${equipment.keeper}(${equipment.contact})", + style: const TextStyle( + color: Colors.black, + fontSize: 14, + fontFamily: 'NanumSquare_ac', + fontWeight: FontWeight.w400, + height: 0, + ), + ), + ], + ), + const SizedBox( + height: 12, + ), + Row( + children: [ + const SizedBox( + width: 51, + child: Text( + '보관장소', + style: TextStyle( + color: Color(0xFF717171), + fontSize: 14, + fontFamily: 'NanumSquare_ac', + fontWeight: FontWeight.w400, + ), + ), + ), + const SizedBox( + width: 18, + ), + Text( + equipment.location == null + ? "보관 장소" + : equipment.location!, + style: const TextStyle( + color: Colors.black, + fontSize: 14, + fontFamily: 'NanumSquare_ac', + fontWeight: FontWeight.w400, + height: 0, + ), + ), + ], + ), + const SizedBox( + height: 12, + ), + Row( + children: [ + const SizedBox( + width: 51, + child: Text( + '설명', + style: TextStyle( + color: Color(0xFF717171), + fontSize: 14, + fontFamily: 'NanumSquare_ac', + fontWeight: FontWeight.w400, + ), + ), + ), + const SizedBox( + width: 18, + ), + SizedBox( + width: (MediaQuery.of(context).size.width - 100), + child: Text( + equipment.description == null + ? "설명" + : equipment.description!, + style: const TextStyle( + color: Colors.black, + fontSize: 14, + fontFamily: 'NanumSquare_ac', + fontWeight: FontWeight.w400, + ), + ), + ), + ], + ), + const SizedBox( + height: 12, + ), + ], + ), + ); + }).then((value) { + setState(() {}); + }); + } + + void showDeleteSheet(EquipmentModel equipment) { + showModalBottomSheet( + context: context, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15), + ), + builder: (BuildContext context) { + return Container( + height: 180, + decoration: const BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(12), topRight: Radius.circular(12)), + color: Colors.white, + ), + child: Column( + children: [ + const SizedBox( + height: 30, + ), + const Text( + '비품을 삭제하시겠습니까?', + style: TextStyle(fontSize: 16, color: Color(0xFF656565)), + ), + const SizedBox( + height: 30, + ), + Container( + margin: const EdgeInsets.symmetric(horizontal: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + child: ElevatedButton( + onPressed: didTapCancelButton, + style: ElevatedButton.styleFrom( + elevation: 0, + backgroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15), + side: const BorderSide( + color: Color(0xFFC9C9C9)))), + child: const Text( + '취소', + style: TextStyle( + fontSize: 14, color: Color(0xFF717171)), + ), + ), + ), + const SizedBox( + width: 10, + ), + Expanded( + child: ElevatedButton( + onPressed: () => deleteEquipment(equipment), + style: ElevatedButton.styleFrom( + elevation: 0, + backgroundColor: purple, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15), + )), + child: const Text( + '확인', + style: TextStyle(fontSize: 14, color: Colors.white), + ), + ), + ), + ], + ), + ) + ], + ), + ); + }).then((value) { + setState(() {}); + }); + } + void moveToAddEquipment() { Navigator.of(context) - .push(MaterialPageRoute(builder: (_) => const EquipmentAddScreen())); + .push(MaterialPageRoute(builder: (_) => const EquipmentAddScreen())) + .then((value) { + setState(() {}); + }); } Future fetchData() async { - return EquipmentService().getEquipment(); + return EquipmentService().getEquipment(cond); } void reloadData() { - print(123); - setState(() { - fetchData(); + setState(() {}); + } + + void didTapCancelButton() { + Navigator.of(context).pop(); + } + + void editEquipment(EquipmentModel equipment) { + Navigator.of(context) + .push(MaterialPageRoute( + builder: (_) => EquipmentAddScreen(equipment: equipment))) + .then((value) { + setState(() {}); }); } + + void deleteEquipment(EquipmentModel equipment) { + Future result = + EquipmentService().deleteEquipment(equipment.equipmentId); + result.then((value) => { + if (value == true) + {Navigator.of(context).pop(), Navigator.of(context).pop()} + else + {Fluttertoast.showToast(msg: value)} + }); + } + + void popNavi() { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + } } diff --git a/pubspec.lock b/pubspec.lock index 8c206e5..5529f06 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -465,13 +465,13 @@ packages: source: hosted version: "2.3.1" http: - dependency: transitive + dependency: "direct main" description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "0.13.6" http_multi_server: dependency: transitive description: @@ -664,6 +664,54 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" + path_provider: + dependency: "direct main" + description: + name: path_provider + sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + url: "https://pub.dev" + source: hosted + version: "2.1.1" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + url: "https://pub.dev" + source: hosted + version: "2.3.1" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + url: "https://pub.dev" + source: hosted + version: "2.2.1" petitparser: dependency: transitive description: @@ -672,6 +720,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.4.0" + platform: + dependency: transitive + description: + name: platform + sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59" + url: "https://pub.dev" + source: hosted + version: "3.1.3" plugin_platform_interface: dependency: transitive description: @@ -957,6 +1013,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.0" + win32: + dependency: transitive + description: + name: win32 + sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574 + url: "https://pub.dev" + source: hosted + version: "5.1.1" xdg_directories: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 7813f0c..35fb711 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -21,6 +21,8 @@ dependencies: firebase_messaging: "^14.5.0" flutter_local_notifications: "^14.0.0+1" url_launcher: "^6.2.1" + http: ^0.13.4 + path_provider: ^2.1.1 dev_dependencies: flutter_test: sdk: flutter