diff --git a/lib/cart/cart_screen.dart b/lib/cart/cart_screen.dart new file mode 100644 index 0000000..ec06f6d --- /dev/null +++ b/lib/cart/cart_screen.dart @@ -0,0 +1,74 @@ +import 'package:cart_sample/cart/widget/add_more_widget.dart'; +import 'package:cart_sample/cart/widget/billing_widget.dart'; +import 'package:cart_sample/cart/widget/menu_widget.dart'; +import 'package:cart_sample/cart/widget/store_name_widget.dart'; +import 'package:cart_sample/util/util.dart'; +import 'package:flutter/material.dart'; + +part 'widget/order_widget.dart'; + +class CartScreen extends StatefulWidget { + const CartScreen({Key? key}) : super(key: key); + + @override + State createState() => _CartScreenState(); +} + +class _CartScreenState extends State { + final Map _store = { + 'image': 'images/chickenCartoonImage.jpg', + 'title': '치킨 잠실점', + }; + + final Map _menu = { + 'name': '후라이드 치킨', + 'image': 'images/chicken.png', + 'description': '• 찜 & 리뷰 약속 : 참여. 서비스음료제공', + 'price': '18000', + }; + + final Map _billing = { + 'delivery price': '3000', + }; + + late final String _toBePaidPrice = _calculateToBePaidPrice(); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color.fromRGBO(246, 246, 246, 1.0), + appBar: AppBar( + leading: const BackButton(color: Colors.black), + title: const Text('장바구니', style: TextStyle(color: Colors.black)), + elevation: 0, + backgroundColor: Colors.white, + ), + body: ListView( + children: [ + SizedBox(height: 10), + StoreNameWidget(_store['image'], _store['title']), + SizedBox(height: 1), + MenuWidget( + _menu['name'], + _menu['image'], + _menu['description'], + _menu['price'], + ), + SizedBox(height: 1), + AddMoreWidget(), + BillingWidget( + _menu['price'], + _billing['delivery price'], + _toBePaidPrice, + ), + ], + ), + bottomNavigationBar: _OrderWidget(_toBePaidPrice), + ); + } + + String _calculateToBePaidPrice() { + return '${int.parse(_menu['price']) + + int.parse(_billing['delivery price'])}'; + } +} diff --git a/lib/cart/widget/add_more_widget.dart b/lib/cart/widget/add_more_widget.dart new file mode 100644 index 0000000..4975e11 --- /dev/null +++ b/lib/cart/widget/add_more_widget.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; + +class AddMoreWidget extends StatelessWidget { + const AddMoreWidget({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () { + debugPrint('GestureDetector'); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.white, + border: Border( + bottom: BorderSide(color: Colors.grey.withOpacity(0.3), width: 2), + ), + ), + height: 50, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.add), + Text('더 담으러 가기', style: TextStyle(fontSize: 17)), + ], + ), + ), + ); + } +} diff --git a/lib/cart/widget/billing_widget.dart b/lib/cart/widget/billing_widget.dart new file mode 100644 index 0000000..e2d61f4 --- /dev/null +++ b/lib/cart/widget/billing_widget.dart @@ -0,0 +1,80 @@ +import 'package:cart_sample/util/util.dart'; +import 'package:flutter/material.dart'; + +class BillingWidget extends StatelessWidget { + const BillingWidget( + this._totalPrice, + this._deliveryPrice, + this._toBePaidPrice, { + Key? key, + }) : super(key: key); + + final String _totalPrice; + final String _deliveryPrice; + final String _toBePaidPrice; + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + border: Border( + bottom: BorderSide(color: Colors.grey.withOpacity(0.3), width: 2), + ), + ), + child: Column( + children: [ + SizedBox(height: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Row( + children: [ + Text('총 주문금액'), + Spacer(), + Text('${NumberUtil.formatByDefaultCurrency(_totalPrice)}원'), + ], + ), + ), + SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Row( + children: [ + Text( + '배탈팁', + style: TextStyle(fontSize: 16), + ), + Spacer(), + Text( + '${NumberUtil.formatByDefaultCurrency(_deliveryPrice)}원', + style: TextStyle(fontSize: 16), + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.all(20), + child: Divider(color: Colors.grey), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Row( + children: [ + Text( + '결제예정금액', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + ), + Spacer(), + Text( + '${NumberUtil.formatByDefaultCurrency(_toBePaidPrice)}원', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + ), + ], + ), + ), + SizedBox(height: 20), + ], + ), + ); + } +} diff --git a/lib/cart/widget/menu_widget.dart b/lib/cart/widget/menu_widget.dart new file mode 100644 index 0000000..53cb907 --- /dev/null +++ b/lib/cart/widget/menu_widget.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; + +class MenuWidget extends StatelessWidget { + const MenuWidget( + this._name, + this._image, + this._description, + this._price, { + Key? key, + }) : super(key: key); + + final String _name; + final String _image; + final String _description; + final String _price; + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: Column( + children: [ + Row( + children: [ + SizedBox(width: 20), + Text( + _name, + style: TextStyle(fontSize: 17, fontWeight: FontWeight.bold), + ), + Spacer(), + IconButton( + icon: Icon(Icons.close, color: Colors.grey), + onPressed: () {}, + ), + ], + ), + Row( + children: [ + SizedBox(width: 20), + Container( + decoration: BoxDecoration( + border: Border.all( + color: Colors.grey.withOpacity(0.3), + width: 1, + ), + borderRadius: BorderRadius.circular(12), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(12), + child: Image.asset( + _image, + width: 70, + height: 70, + fit: BoxFit.cover, + ), + ), + ), + SizedBox(width: 10), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _description, + style: TextStyle(color: Color.fromRGBO(125, 125, 125, 1.0)), + ), + Text(_price), + ], + ), + ], + ), + SizedBox(height: 20), + ], + ), + ); + } +} diff --git a/lib/cart/widget/order_widget.dart b/lib/cart/widget/order_widget.dart new file mode 100644 index 0000000..044a5f1 --- /dev/null +++ b/lib/cart/widget/order_widget.dart @@ -0,0 +1,66 @@ +part of '../cart_screen.dart'; + +class _OrderWidget extends StatelessWidget { + const _OrderWidget( + this._toBePaidPrice, { + Key? key, + }) : super(key: key); + + final String _toBePaidPrice; + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: SafeArea( + child: Container( + height: 65, + padding: const EdgeInsets.symmetric( + horizontal: 20, + vertical: 10, + ), + child: ElevatedButton( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + width: 25, + height: 25, + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + ), + child: Center( + child: Text( + '1', + style: TextStyle( + color: Color.fromRGBO(44, 191, 188, 1.0), + fontWeight: FontWeight.bold, + ), + ), + ), + ), + SizedBox( + width: 7, + ), + Text( + '${NumberUtil.formatByDefaultCurrency(_toBePaidPrice)}원 ' + '배달 주문하기', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + ], + ), + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + Color.fromRGBO(44, 191, 188, 1.0), + ), + ), + onPressed: () { + debugPrint('ElevatedButton'); + }, + ), + ), + ), + ); + } +} diff --git a/lib/cart/widget/store_name_widget.dart b/lib/cart/widget/store_name_widget.dart new file mode 100644 index 0000000..4cd4b9d --- /dev/null +++ b/lib/cart/widget/store_name_widget.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; + +class StoreNameWidget extends StatelessWidget { + const StoreNameWidget( + this._image, + this._title, { + Key? key, + }) : super(key: key); + + final String _image; + final String _title; + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + height: 70, + child: Row( + children: [ + SizedBox(width: 20), + ClipRRect( + borderRadius: BorderRadius.circular(12), + child: Image.asset(_image, width: 35, height: 35), + ), + SizedBox(width: 10), + Text( + _title, + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + ) + ], + ), + ); + } +} diff --git a/lib/cart_screen.dart b/lib/cart_screen.dart deleted file mode 100644 index 5b6fb25..0000000 --- a/lib/cart_screen.dart +++ /dev/null @@ -1,316 +0,0 @@ -import 'package:flutter/material.dart'; - -class CartScreen extends StatefulWidget { - const CartScreen({Key? key}) : super(key: key); - - @override - State createState() => _CartScreenState(); -} - -class _CartScreenState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: const Color.fromRGBO(246, 246, 246, 1.0), - appBar: AppBar( - leading: const BackButton( - color: Colors.black, - ), - title: const Text( - '장바구니', - style: TextStyle( - color: Colors.black, - ), - ), - elevation: 0, - backgroundColor: Colors.white, - ), - body: ListView( - children: [ - SizedBox( - height: 10, - ), - _buildStoreName(), - SizedBox( - height: 1, - ), - _buildMenu(), - SizedBox( - height: 1, - ), - _buildAddMore(), - _buildBilling(), - ], - ), - bottomNavigationBar: Container( - color: Colors.white, - child: SafeArea( - child: Container( - height: 65, - padding: const EdgeInsets.symmetric( - horizontal: 20, - vertical: 10, - ), - child: ElevatedButton( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - width: 25, - height: 25, - decoration: BoxDecoration( - color: Colors.white, - shape: BoxShape.circle, - ), - child: Center( - child: Text( - '1', - style: TextStyle( - color: Color.fromRGBO(44, 191, 188, 1.0), - fontWeight: FontWeight.bold, - ), - ), - ), - ), - SizedBox( - width: 7, - ), - Text( - '21,000원 배달 주문하기', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - ], - ), - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( - Color.fromRGBO(44, 191, 188, 1.0), - ), - ), - onPressed: () {}, - ), - ), - ), - ), - ); - } - - Widget _buildStoreName() { - return Container( - color: Colors.white, - height: 70, - child: Row( - children: [ - SizedBox( - width: 20, - ), - ClipRRect( - borderRadius: BorderRadius.circular(12), - child: Image.asset( - 'images/chickenCartoonImage.jpg', - width: 35, - height: 35, - ), - ), - SizedBox( - width: 10, - ), - Text( - '치킨 잠실점', - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), - ) - ], - ), - ); - } - - Widget _buildMenu() { - return Container( - color: Colors.white, - child: Column( - children: [ - Row( - children: [ - SizedBox( - width: 20, - ), - Text( - '후라이드 치킨', - style: TextStyle( - fontSize: 17, - fontWeight: FontWeight.bold, - ), - ), - Spacer(), - IconButton( - icon: Icon( - Icons.close, - color: Colors.grey, - ), - onPressed: () {}, - ), - ], - ), - Row( - children: [ - SizedBox( - width: 20, - ), - Container( - decoration: BoxDecoration( - border: Border.all( - color: Colors.grey.withOpacity(0.3), - width: 1, - ), - borderRadius: BorderRadius.circular(12), - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(12), - child: Image.asset( - 'images/chicken.png', - width: 70, - height: 70, - fit: BoxFit.cover, - ), - ), - ), - SizedBox( - width: 10, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - '• 찜 & 리뷰 약속 : 참여. 서비스음료제공', - style: TextStyle( - color: Color.fromRGBO(125, 125, 125, 1.0), - ), - ), - Text('18,000원'), - ], - ), - ], - ), - SizedBox( - height: 20, - ), - ], - ), - ); - } - - Widget _buildAddMore() { - return GestureDetector( - onTap: () {}, - child: Container( - decoration: BoxDecoration( - color: Colors.white, - border: Border( - bottom: BorderSide( - color: Colors.grey.withOpacity(0.3), - width: 2, - ), - ), - ), - height: 50, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.add), - Text( - '더 담으러 가기', - style: TextStyle(fontSize: 17), - ), - ], - ), - ), - ); - } - - Widget _buildBilling() { - return Container( - decoration: BoxDecoration( - color: Colors.white, - border: Border( - bottom: BorderSide( - color: Colors.grey.withOpacity(0.3), - width: 2, - ), - ), - ), - child: Column( - children: [ - SizedBox( - height: 20, - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Row( - children: [ - Text('총 주문금액'), - Spacer(), - Text('18,000원'), - ], - ), - ), - SizedBox( - height: 10, - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Row( - children: [ - Text( - '배탈팁', - style: TextStyle( - fontSize: 16, - ), - ), - Spacer(), - Text( - '3,000원', - style: TextStyle( - fontSize: 16, - ), - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.all(20), - child: Divider( - color: Colors.grey, - ), - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Row( - children: [ - Text( - '결제예정금액', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - ), - ), - Spacer(), - Text( - '21,000원', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - ), - ), - ], - ), - ), - SizedBox( - height: 20, - ), - ], - ), - ); - } -} diff --git a/lib/main.dart b/lib/main.dart index e78ce53..e96e2dd 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,4 @@ -import 'package:cart_sample/cart_screen.dart'; +import 'package:cart_sample/cart/cart_screen.dart'; import 'package:flutter/material.dart'; void main() { diff --git a/lib/util/util.dart b/lib/util/util.dart new file mode 100644 index 0000000..f6930fb --- /dev/null +++ b/lib/util/util.dart @@ -0,0 +1,8 @@ +import 'package:intl/intl.dart'; + +class NumberUtil { + static String formatByDefaultCurrency(String number) { + final result = NumberFormat.currency(locale: 'ko_KR', symbol: ''); + return result.format(int.parse(number)); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index c6a0a39..e782a3d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,6 +35,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 + intl: ^0.17.0 dev_dependencies: