diff --git a/lib/main.dart b/lib/main.dart index 6952895..5f44e50 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -26,6 +26,7 @@ class MyApp extends StatelessWidget { getPages: [ GetPage(name: '/product', page: () => ProductScreen()), GetPage(name: '/product/new', page: () => AddNewProductScreen()), + GetPage(name: '/orders', page: () => const OrderScreen()), ], ); } diff --git a/lib/model/model.dart b/lib/model/model.dart index 163178c..7b11c73 100644 --- a/lib/model/model.dart +++ b/lib/model/model.dart @@ -1 +1,2 @@ export 'product_model.dart'; +export 'order_model.dart'; diff --git a/lib/model/order_model.dart b/lib/model/order_model.dart new file mode 100644 index 0000000..ed7d343 --- /dev/null +++ b/lib/model/order_model.dart @@ -0,0 +1,134 @@ +import 'dart:convert'; + +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:equatable/equatable.dart'; + +class Order extends Equatable { + final int id; + final int customerId; + final List productIds; + final double deliveryFee; + final double subtotal; + final double total; + final bool isAccepted; + final bool isDelivered; + final bool isCancelled; + final DateTime createdAt; + + const Order({ + required this.id, + required this.customerId, + required this.productIds, + required this.deliveryFee, + required this.subtotal, + required this.total, + required this.isAccepted, + required this.isDelivered, + required this.isCancelled, + required this.createdAt, + }); + + Order copyWith({ + int? id, + int? customerId, + List? productIds, + double? deliveryFee, + double? subtotal, + double? total, + bool? isAccepted, + bool? isDelivered, + bool? isCancelled, + DateTime? createdAt, + }) { + return Order( + id: id ?? this.id, + customerId: customerId ?? this.customerId, + productIds: productIds ?? this.productIds, + deliveryFee: deliveryFee ?? this.deliveryFee, + subtotal: subtotal ?? this.subtotal, + total: total ?? this.total, + isAccepted: isAccepted ?? this.isAccepted, + isDelivered: isDelivered ?? this.isDelivered, + isCancelled: isCancelled ?? this.isCancelled, + createdAt: createdAt ?? this.createdAt, + ); + } + + Map toMap() { + return { + 'id': id, + 'customerId': customerId, + 'productIds': productIds, + 'deliveryFee': deliveryFee, + 'subtotal': subtotal, + 'total': total, + 'isAccepted': isAccepted, + 'isDelivered': isDelivered, + 'isCancelled': isCancelled, + 'createdAt': createdAt.millisecondsSinceEpoch, + }; + } + + factory Order.fromSnapshot(DocumentSnapshot snap) { + return Order( + id: snap['id'], + customerId: snap['customerId'], + productIds: List.from(snap['productIds']), + deliveryFee: snap['deliveryFee'], + subtotal: snap['subtotal'], + total: snap['total'], + isAccepted: snap['isAccepted'], + isDelivered: snap['isDelivered'], + isCancelled: snap['isCancelled'], + createdAt: snap['createdAt'].toDate(), + ); + } + + String toJson() => json.encode(toMap()); + + @override + bool get stringify => true; + + @override + List get props { + return [ + id, + customerId, + productIds, + deliveryFee, + subtotal, + total, + isAccepted, + isDelivered, + isCancelled, + createdAt, + ]; + } + + static List orders = [ + Order( + id: 1, + customerId: 2345, + productIds: const ['1', '2'], + deliveryFee: 10, + subtotal: 20, + total: 30, + isAccepted: false, + isDelivered: false, + isCancelled: false, + createdAt: DateTime.now(), + ), + Order( + id: 2, + customerId: 23, + productIds: const ['1', '3', '2'], + deliveryFee: 10, + subtotal: 30, + total: 30, + isAccepted: false, + isDelivered: false, + isCancelled: false, + createdAt: DateTime.now(), + ), + ]; +} diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index d0c1aca..4339ebd 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -31,7 +31,22 @@ class HomeScreen extends StatelessWidget { ), ), ), - ) + ), + Container( + height: 150, + width: double.infinity, + padding: const EdgeInsets.symmetric(horizontal: 20), + child: InkWell( + onTap: () { + Get.to(() => const OrderScreen()); + }, + child: const Card( + child: Center( + child: Text('Go To Orders'), + ), + ), + ), + ), ], ), ); diff --git a/lib/screens/order_screen.dart b/lib/screens/order_screen.dart new file mode 100644 index 0000000..72baccf --- /dev/null +++ b/lib/screens/order_screen.dart @@ -0,0 +1,205 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +import '../model/model.dart'; + +class OrderScreen extends StatelessWidget { + const OrderScreen({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Orders Screen'), + centerTitle: true, + backgroundColor: Colors.black, + ), + body: Column( + children: [ + Expanded( + child: ListView.builder( + itemCount: Order.orders.length, + itemBuilder: (context, index) { + return OrderCard( + order: Order.orders[index], + ); + }, + ), + ), + ], + ), + ); + } +} + +class OrderCard extends StatelessWidget { + final Order order; + const OrderCard({Key? key, required this.order}) : super(key: key); + + @override + Widget build(BuildContext context) { + var products = Product.products.where((product) { + return order.productIds.contains(product.id); + }).toList(); + + return Padding( + padding: const EdgeInsets.only( + left: 10, + right: 10, + top: 10, + ), + child: Card( + margin: EdgeInsets.zero, + child: Padding( + padding: const EdgeInsets.all(10.0), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Order ID: ${order.id}', + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + Text( + DateFormat('MMM dd, yyyy').format(order.createdAt), + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + const SizedBox(height: 10), + const SizedBox(height: 10), + ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: products.length, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.only(bottom: 10), + child: Row( + children: [ + SizedBox( + height: 50, + width: 50, + child: Image.network( + products[index].imageUrl, + fit: BoxFit.cover, + ), + ), + const SizedBox(width: 10), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + products[index].name, + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 5), + SizedBox( + width: 285, + child: Text( + products[index].description, + style: const TextStyle( + fontSize: 12, + ), + maxLines: 2, + overflow: TextOverflow.clip, + ), + ), + ], + ), + ], + ), + ); + }), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Column( + children: [ + const Text( + 'Delivery Fee', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 10), + Text( + '\$${order.deliveryFee}', + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + Column( + children: [ + const Text( + 'Total Fee', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 10), + Text( + '\$${order.total}', + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ], + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + primary: Colors.black, + minimumSize: const Size(150, 40), + ), + child: const Text( + 'Accept', + style: TextStyle( + fontSize: 12, + ), + ), + ), + ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + primary: Colors.black, + minimumSize: const Size(150, 40), + ), + child: const Text( + 'Cancel', + style: TextStyle( + fontSize: 12, + ), + ), + ), + ], + ) + ], + ), + ), + ), + ); + } +} diff --git a/lib/screens/screens.dart b/lib/screens/screens.dart index db0e8f9..e7c6ce6 100644 --- a/lib/screens/screens.dart +++ b/lib/screens/screens.dart @@ -1,3 +1,4 @@ export 'add_new_product_screen.dart'; export 'home_screen.dart'; export 'product_screen.dart'; +export 'order_screen.dart'; diff --git a/lib/services/services.dart b/lib/services/services.dart new file mode 100644 index 0000000..bfba48f --- /dev/null +++ b/lib/services/services.dart @@ -0,0 +1,2 @@ +export 'database_service.dart'; +export 'storage_service.dart'; diff --git a/pubspec.lock b/pubspec.lock index 3089e06..82dadb4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -234,7 +234,7 @@ packages: source: hosted version: "2.5.0" intl: - dependency: transitive + dependency: "direct main" description: name: intl url: "https://pub.dartlang.org" diff --git a/pubspec.yaml b/pubspec.yaml index 30f5abf..f05c7a8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -41,6 +41,7 @@ dependencies: cloud_firestore: ^3.1.18 firebase_storage: ^10.1.0 equatable: ^2.0.3 + intl: ^0.17.0 dev_dependencies: flutter_test: