diff --git a/images/backbutton_appbar.png b/images/backbutton_appbar.png new file mode 100644 index 0000000..0d1c569 Binary files /dev/null and b/images/backbutton_appbar.png differ diff --git a/images/help_appbar.png b/images/help_appbar.png new file mode 100644 index 0000000..5a57af5 Binary files /dev/null and b/images/help_appbar.png differ diff --git a/images/search.png b/images/search.png new file mode 100644 index 0000000..85d4215 Binary files /dev/null and b/images/search.png differ diff --git a/lib/common/dashboard.dart b/lib/common/dashboard.dart index f9b5a49..427063a 100644 --- a/lib/common/dashboard.dart +++ b/lib/common/dashboard.dart @@ -1,11 +1,15 @@ import 'dart:convert'; import 'dart:io'; +import 'package:flutter/cupertino.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:image_picker/image_picker.dart'; import 'package:supplier_new/common/settings.dart'; import 'package:supplier_new/orders/all_orders.dart'; +import 'package:supplier_new/orders/order_requests.dart'; +import 'package:supplier_new/plans/all_plans.dart'; +import 'package:supplier_new/plans/plan_requests.dart'; import 'package:supplier_new/resources/fleet.dart'; import 'package:supplier_new/set_rates/set_rates.dart'; @@ -32,8 +36,8 @@ class _DashboardScreenState extends State { // Define a list of widgets for each screen final List _screens = [ HomeScreen(), - HomeScreen(), - HomeScreen(), + AllOrders(), + AllPlans(), FleetStep1Page(), HomeScreen(), ]; @@ -251,7 +255,7 @@ class _DashboardScreenState extends State { _scaffoldKey.currentState?.openEndDrawer(); return false; // Prevent the default back action (exit the app) } - else if (_currentIndex == 2) { + else if (_currentIndex == 0) { final shouldPop = await showDialog( context: context, builder: (context) { @@ -339,7 +343,7 @@ class _DashboardScreenState extends State { } else { setState(() { - _currentIndex = 2; + _currentIndex = 0; }); return false; } @@ -347,7 +351,7 @@ class _DashboardScreenState extends State { child: Scaffold( key: _scaffoldKey, backgroundColor: Colors.white, - appBar: AppBar( + appBar: _currentIndex==0?AppBar( backgroundColor: Colors.white, elevation: 0, scrolledUnderElevation: 0, @@ -392,7 +396,7 @@ class _DashboardScreenState extends State { _scaffoldKey.currentState?.openDrawer(); }, ), - ), + ):null, drawer: Drawer( width: MediaQuery.of(context).size.width, backgroundColor: Colors.white, @@ -566,7 +570,7 @@ class _DashboardScreenState extends State { style: fontTextStyle(20,Color(0XFF2A2A2A),FontWeight.w500), ), Visibility( - visible:AppSettings.loginType.toString().toLowerCase()=='user', + visible:true, child: Text( AppSettings.email, style: fontTextStyle(14,Color(0XFF2A2A2A),FontWeight.w400), @@ -809,19 +813,35 @@ class _HomeScreenState extends State { /// Requests Section Row( - children: const [ + children: [ Expanded( - child: RequestCard( - title: "Order Requests", - subtitle: "1 new request", + child: GestureDetector( + onTap: (){ + Navigator.push( + context, + new MaterialPageRoute( + builder: (__) => new OrderRequestsPage())); + }, + child: RequestCard( + title: "Order Requests", + subtitle: "1 new request", + ), ), ), SizedBox(width: 12), Expanded( - child: RequestCard( - title: "Plan Requests", - subtitle: "2 new request", - ), + child: GestureDetector( + onTap: (){ + Navigator.push( + context, + new MaterialPageRoute( + builder: (__) => new PlanRequestPage())); + }, + child: RequestCard( + title: "Plan Requests", + subtitle: "2 new request", + ), + ) ), ], ) diff --git a/lib/common/settings.dart b/lib/common/settings.dart index ffd3fc6..625156b 100644 --- a/lib/common/settings.dart +++ b/lib/common/settings.dart @@ -373,7 +373,7 @@ class AppSettings{ static Future saveAvailableReportAndLocationsInMemory( dynamic input) async { // save login name information - await saveData('username', input['simplydata']['username'], 'STRING'); + await saveData('username', input['simplydata']['suppliername'], 'STRING'); await saveData('logintype', input['simplydata']['loginType'], 'STRING'); await saveData('all_motor_access', input['simplydata']['all_motor_access'], 'STRING'); await saveData('buildingname', input['simplydata']['buildingName'], 'STRING'); diff --git a/lib/orders/all_orders.dart b/lib/orders/all_orders.dart index 649e854..465a4f6 100644 --- a/lib/orders/all_orders.dart +++ b/lib/orders/all_orders.dart @@ -52,6 +52,26 @@ class _AllOrdersState extends State { time: "09:30 PM, Yesterday", extraInfo: "Cancelled by user", ), + OrdersModel( + date: DateTime(2025, 8, 25), + imageAsset: "images/building.png",// sample image + status: "assigned", + title: "Lakeview Towers", + location: "Madhapur", + quantity: "8,000L - Tanker Water", + time: "09:30 PM, Yesterday", + extraInfo: "Assigned to Madhav", + ), + OrdersModel( + date: DateTime(2025, 8, 26), + imageAsset: "images/building.png",// sample image + status: "pending", + title: "Lakeview Towers", + location: "Madhapur", + quantity: "8,000L - Tanker Water", + time: "09:30 PM, Yesterday", + extraInfo: "", + ), ]; // ✅ Group orders by date @@ -266,11 +286,32 @@ class OrderCard extends StatelessWidget { Color _getStatusColor() { switch (order.status.toLowerCase()) { case "completed": - return Colors.green; + return Color(0XFFC4E8C3); case "in-progress": - return Colors.blue; + return Color(0XFFE8F2FF); case "cancelled": - return Colors.red; + return Color(0XFFFCEDEC); + case "assigned": + return Color(0XFFF9DBC6); + case "pending": + return Color(0XFFFDF3D3); + default: + return Colors.grey; + } + } + + Color _getTextStatusColor() { + switch (order.status.toLowerCase()) { + case "completed": + return Color(0XFF0A9E04); + case "in-progress": + return Color(0XFF1D7AFC); + case "cancelled": + return Color(0XFFE2483D); + case "assigned": + return Color(0XFFE56910); + case "pending": + return Color(0XFFD0AE3C); default: return Colors.grey; } @@ -279,6 +320,7 @@ class OrderCard extends StatelessWidget { @override Widget build(BuildContext context) { final statusColor = _getStatusColor(); + final textStatusColor = _getTextStatusColor(); return Padding(padding: EdgeInsets.fromLTRB(0, 8, 0, 0), child: Container( @@ -301,13 +343,13 @@ class OrderCard extends StatelessWidget { ClipRRect( borderRadius: const BorderRadius.only( topLeft: Radius.circular(12), - bottomLeft: Radius.circular(12), + bottomLeft: Radius.circular(0), ), child: order.imageAsset != null ? Image.asset( order.imageAsset!, - height: 100, - width: 100, + height: 145, + width: 145, fit: BoxFit.cover, ) : Image.network( @@ -332,63 +374,43 @@ class OrderCard extends StatelessWidget { vertical: 2, ), decoration: BoxDecoration( - color: statusColor.withOpacity(0.1), - borderRadius: BorderRadius.circular(8), + color: statusColor, + borderRadius: BorderRadius.circular(4), ), child: Text( order.status, - style: TextStyle( - fontSize: 11, - fontWeight: FontWeight.w600, - color: statusColor, - ), + style: fontTextStyle(10,textStatusColor,FontWeight.w400) ), ), const SizedBox(height: 6), Text( order.title, - style: const TextStyle( - fontSize: 15, - fontWeight: FontWeight.w600, - ), + style:fontTextStyle(16,Color(0XFF2D2E30),FontWeight.w600) ), Text( order.location, - style: TextStyle( - fontSize: 12, - color: Colors.grey.shade600, - ), + style: fontTextStyle(12,Color(0XFF646566),FontWeight.w400) ), const SizedBox(height: 4), Text( order.quantity, - style: const TextStyle( - fontSize: 13, - fontWeight: FontWeight.w500, - ), + style: fontTextStyle(14,Color(0XFF444444),FontWeight.w500) ), Text( order.time, - style: TextStyle( - fontSize: 12, - color: Colors.grey.shade600, - ), + style:fontTextStyle(12,Color(0XFF939495),FontWeight.w400) ), const SizedBox(height: 4), Text( order.extraInfo, - style: TextStyle( - fontSize: 12, - color: order.status == "in-progress" - ? Colors.blue - : Colors.grey.shade600, - fontWeight: order.status == "in-progress" - ? FontWeight.w600 - : FontWeight.w400, - ), + style:fontTextStyle(12, order.status == "in-progress" + ? Color(0XFF1D7AFC) + : Color(0XFF646566),FontWeight.w400) + + ), ], ), diff --git a/lib/orders/search_order_appbar.dart b/lib/orders/search_order_appbar.dart index d484bdd..c2eb385 100644 --- a/lib/orders/search_order_appbar.dart +++ b/lib/orders/search_order_appbar.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:supplier_new/common/settings.dart'; class SearchOrderAppBar extends StatelessWidget implements PreferredSizeWidget { final TextEditingController controller; @@ -16,36 +17,72 @@ class SearchOrderAppBar extends StatelessWidget implements PreferredSizeWidget { Widget build(BuildContext context) { return AppBar( backgroundColor: Colors.white, + scrolledUnderElevation: 0, elevation: 0, - leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), - onPressed: onBack, + leading: GestureDetector( + onTap: () { + Navigator.pop(context); + }, + child: Padding( + padding: const EdgeInsets.fromLTRB( + 8, 8, 8, 8), // Add padding if needed + child: Image.asset( + 'images/backbutton_appbar.png', + height: 24, + width: 24,// Replace with your image path + fit: BoxFit.contain, // Adjust the fit + ), + ), ), titleSpacing: 0, title: Container( height: 40, decoration: BoxDecoration( color: Colors.white, - borderRadius: BorderRadius.circular(24), - border: Border.all(color: Colors.grey.shade400), + borderRadius: BorderRadius.circular(22), + border: Border.all(color: Color(0XFF939495)), ), child: TextField( controller: controller, - decoration: const InputDecoration( + decoration: InputDecoration( hintText: "Search order", - hintStyle: TextStyle(fontSize: 14, color: Colors.grey), - prefixIcon: Icon(Icons.search, color: Colors.grey), + hintStyle: fontTextStyle(16, Color(0XFF646566), FontWeight.w400), + prefixIcon: SizedBox( + height: 20, + width: 20, + child: Padding( + padding: const EdgeInsets.all(8.0), // adjust spacing + child: Image.asset( + 'images/search.png', + fit: BoxFit.contain, + ), + ), + ), border: InputBorder.none, - contentPadding: EdgeInsets.symmetric(vertical: 10), + contentPadding: const EdgeInsets.symmetric(vertical: 0), + ), + style: fontTextStyle(16,Color(0XFF2A2A2A),FontWeight.w400), ), ), - actions: [ - IconButton( - icon: const Icon(Icons.help_outline, color: Colors.black), - onPressed: onHelp, - ), - const SizedBox(width: 8), + + actions: [ + Padding(padding: EdgeInsets.all(8), + child: + GestureDetector( + onTap: () { + }, + child: Padding( + padding: const EdgeInsets.fromLTRB( + 8, 8, 8, 8), // Add padding if needed + child: Image.asset( + 'images/help_appbar.png', + height: 24, + width: 24,// Replace with your image path + fit: BoxFit.contain, // Adjust the fit + ), + ), + ),) ], ); } diff --git a/lib/plans/all_plans.dart b/lib/plans/all_plans.dart new file mode 100644 index 0000000..95cca86 --- /dev/null +++ b/lib/plans/all_plans.dart @@ -0,0 +1,404 @@ +import 'package:flutter/material.dart'; +import 'package:supplier_new/common/settings.dart'; +import 'package:supplier_new/plans/plan_requests.dart'; +import 'package:supplier_new/plans/plans_model.dart'; +import 'package:supplier_new/plans/search_plan_appbar.dart'; + +class AllPlans extends StatefulWidget { + const AllPlans({super.key}); + + @override + State createState() => _AllPlansState(); +} + +class _AllPlansState extends State { + final TextEditingController searchController = TextEditingController(); + + @override + Widget build(BuildContext context) { + final List plans = [ + PlansModel( + status: "Active", + apartment: "Green Valley Apartments", + liters: "10,000 L - Drinking water", + price: "₹3,400", + advance: "10% Advance", + deliveries: "10/22 Deliveries", + frequency: "4/week", + ), + PlansModel( + status: "Active", + apartment: "Lakeview Towers", + liters: "8,000 L - Drinking water", + price: "₹2,900", + advance: "5% Advance", + deliveries: "8/20 Deliveries", + frequency: "3/week", + ), + PlansModel( + status: "Active", + apartment: "Hilltop Residency", + liters: "12,000 L - Drinking water", + price: "₹4,500", + advance: "15% Advance", + deliveries: "12/25 Deliveries", + frequency: "5/week", + ), + PlansModel( + status: "Inactive", + apartment: "Silver Oak Villas", + liters: "6,000 L - Drinking water", + price: "₹2,100", + advance: "0% Advance", + deliveries: "0/15 Deliveries", + frequency: "0/week", + ), + ]; + + return Scaffold( + backgroundColor: const Color(0XFFFFFFFF), + appBar: SearchPlanAppBar( + controller: searchController, + onBack: () => Navigator.pop(context), + onHelp: () { + print("Help tapped"); + }, + ), + body: SingleChildScrollView( + child: Column( + children: [ + /// 🔹 Grey top section + Container( + decoration: const BoxDecoration( + color: Color(0XFFF2F2F2), + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(24), + bottomRight: Radius.circular(24), + ), + ), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24), + child: Column( + children: [ + Text( + "05", + style: fontTextStyle(64, const Color(0XFF2D2E30), FontWeight.w700), + ), + Text( + "Active Plans", + style: fontTextStyle(24, const Color(0XFF2D2E30), FontWeight.w600), + ), + const SizedBox(height: 24), + + /// Bore Water + Drinking Water + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + PlanCategoryCard( + image: Image.asset( + 'images/bore-water.png', + fit: BoxFit.contain, + height: 40, + width: 40, + ), + value: "02", + label: "Bore Water", + ), + PlanCategoryCard( + image: Image.asset( + 'images/drinking-water.png', + height: 40, + width: 40, + fit: BoxFit.contain, + ), + value: "03", + label: "Drinking Water", + ), + ], + ), + const SizedBox(height: 24), + + /// Button + SizedBox( + width: double.infinity, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0XFF8270DB), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(32), + ), + padding: const EdgeInsets.symmetric( + horizontal: 16, vertical: 16), + ), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const PlanRequestPage()), + ); + }, + child: Text( + "View Plan Requests", + style: fontTextStyle( + 16, const Color(0XFFFFFFFF), FontWeight.w500), + ), + ), + ), + ], + ), + ), + + + + /// 🔹 White bottom section (filters + list) + Container( + color: Color(0XFFFFFFFF), + child: Column( + children: [ + const SizedBox(height: 12), + + /// Filters Row + SingleChildScrollView( + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.symmetric(horizontal: 12), + child: Row( + children: [ + FilterChipWidget(label: "Building"), + const SizedBox(width: 8), + FilterChipWidget(label: "Status"), + const SizedBox(width: 8), + FilterChipWidget(label: "Date"), + const SizedBox(width: 8), + FilterChipWidget(label: "Amount"), + ], + ), + ), + + const SizedBox(height: 20), + + /// Order List + ListView.builder( + padding: const EdgeInsets.all(12), + itemCount: plans.length, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + final delivery = plans[index]; + return PlansCard(delivery: delivery); + }, + ), + ], + ), + ), + ], + ), + ), + ); + } +} + +/// Curve clipper for smooth transition +class SmallCurveClipper extends CustomClipper { + @override + Path getClip(Size size) { + final path = Path(); + path.lineTo(0, 0); + path.lineTo(0, size.height); + + // Smooth downward curve + path.quadraticBezierTo( + size.width / 2, -20, // control point (curve depth) + size.width, size.height, + ); + + path.lineTo(size.width, 0); + path.close(); + return path; + } + + @override + bool shouldReclip(covariant CustomClipper oldClipper) => false; +} + +/// Category Card +class PlanCategoryCard extends StatelessWidget { + final Image image; + final String value; + final String label; + + const PlanCategoryCard({ + super.key, + required this.image, + required this.value, + required this.label, + }); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + SizedBox(width: 40, height: 40, child: image), + const SizedBox(height: 8), + Text( + value, + style: fontTextStyle(20, const Color(0XFF515253), FontWeight.w700), + ), + const SizedBox(height: 4), + Text( + label, + style: fontTextStyle(16, const Color(0XFF515253), FontWeight.w400), + ), + ], + ); + } +} + +/// Filter Chip +class FilterChipWidget extends StatelessWidget { + final String label; + const FilterChipWidget({super.key, required this.label}); + + @override + Widget build(BuildContext context) { + return ChoiceChip( + label: Text(label), + selected: false, + onSelected: (_) {}, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + backgroundColor: Colors.white, + side: BorderSide(color: Colors.grey.shade300), + ); + } +} + +/// Plan Card +class PlansCard extends StatelessWidget { + final PlansModel delivery; + + const PlansCard({super.key, required this.delivery}); + + @override + Widget build(BuildContext context) { + bool isActive = delivery.status == "Active"; + + return Container( + margin: const EdgeInsets.only(bottom: 12), + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: const Color(0xFFE5E5E5)), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.03), + blurRadius: 5, + offset: const Offset(0, 2), + ) + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Status Chip + Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), + decoration: BoxDecoration( + color: isActive ? const Color(0xFFE9F9EE) : const Color(0xFFF2F2F2), + borderRadius: BorderRadius.circular(6), + border: Border.all( + color: isActive ? const Color(0xFF3BB273) : Colors.grey.shade400, + ), + ), + child: Text( + delivery.status, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + color: isActive ? const Color(0xFF3BB273) : Colors.grey.shade600, + ), + ), + ), + const SizedBox(height: 8), + + // Apartment + Price Row + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + delivery.apartment, + style: const TextStyle( + fontSize: 15, + fontWeight: FontWeight.w600, + color: Color(0xFF2A2A2A), + ), + ), + Text( + delivery.price, + style: const TextStyle( + fontSize: 15, + fontWeight: FontWeight.w600, + color: Color(0xFF2A2A2A), + ), + ), + ], + ), + const SizedBox(height: 4), + + // Liters & Advance + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + delivery.liters, + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: Color(0xFF7B5AF4), + ), + ), + Text( + delivery.advance, + style: const TextStyle( + fontSize: 12, + color: Color(0xFF646566), + ), + ), + ], + ), + const SizedBox(height: 12), + + // Deliveries row with background + Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8), + decoration: BoxDecoration( + color: const Color(0xFFF8F6FF), + borderRadius: BorderRadius.circular(8), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + delivery.deliveries, + style: const TextStyle( + fontSize: 13, + fontWeight: FontWeight.w500, + color: Color(0xFF2A2A2A), + ), + ), + Text( + delivery.frequency, + style: const TextStyle( + fontSize: 13, + fontWeight: FontWeight.w500, + color: Color(0xFF7B5AF4), + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/plans/plan_requests.dart b/lib/plans/plan_requests.dart new file mode 100644 index 0000000..91745a1 --- /dev/null +++ b/lib/plans/plan_requests.dart @@ -0,0 +1,294 @@ +import 'package:flutter/material.dart'; + +class PlanRequestPage extends StatefulWidget { + const PlanRequestPage({super.key}); + + @override + State createState() => _PlanRequestPageState(); +} + +class _PlanRequestPageState extends State { + final TextEditingController searchController = TextEditingController(); + + // ✅ Sample orders list + final List allPlans = [ + PlanModel( + status: "New", + title: "Green Valley Apartments", + location: "Gachibowli", + description: "10,000 L - Drinking water", + price: "₹3,400", + ), + PlanModel( + status: "Expires in 15m", + title: "Lakeview Towers", + location: "Madhapur", + description: "8,000 L - Borewell water", + price: "₹2,700", + ), + PlanModel( + status: "Expired", + title: "Sunrise Residency", + location: "Kukatpally", + description: "12,000 L - Tanker water", + price: "₹4,000", + ), + PlanModel( + status: "Rejected", + title: "Skyline Apartments", + location: "Kompally", + description: "5,000 L - Drinking water", + price: "₹1,600", + ), + PlanModel( + status: "Pending", + title: "Skyline Apartments", + location: "Kompally", + description: "5,000 L - Drinking water", + price: "₹1,600", + ), + PlanModel( + status: "Rejected", + title: "Elite Towers", + location: "Hitech City", + description: "20,000 L - Borewell water", + price: "₹6,000", + ), + ]; + + @override + Widget build(BuildContext context) { + // ✅ Split orders into rejected and others + final rejectedPlans = + allPlans.where((o) => o.status.toLowerCase() == "rejected").toList(); + final otherPlans = + allPlans.where((o) => o.status.toLowerCase() != "rejected").toList(); + + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + backgroundColor: Colors.white, + elevation: 0, + leading: IconButton( + icon: const Icon(Icons.arrow_back, color: Colors.black), + onPressed: () => Navigator.pop(context), + ), + title: const Text( + "Plan Requests", + style: TextStyle( + color: Colors.black, + fontSize: 16, + fontWeight: FontWeight.w600, + ), + ), + centerTitle: false, + actions: [ + IconButton( + icon: const Icon(Icons.help_outline, color: Colors.black), + onPressed: () {}, + ), + const SizedBox(width: 8), + ], + ), + body: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + children: [ + /// Search bar + Row( + children: [ + Expanded( + child: Container( + height: 42, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), + border: Border.all(color: Colors.grey.shade300), + color: Colors.white, + ), + child: TextField( + controller: searchController, + decoration: const InputDecoration( + hintText: "Search", + prefixIcon: Icon(Icons.search, color: Colors.grey), + border: InputBorder.none, + contentPadding: EdgeInsets.symmetric(vertical: 10), + ), + ), + ), + ), + const SizedBox(width: 10), + Container( + height: 42, + width: 42, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.grey.shade300), + color: Colors.white, + ), + child: IconButton( + icon: const Icon(Icons.sort, size: 20, color: Colors.black), + onPressed: () {}, + ), + ), + ], + ), + + const SizedBox(height: 16), + + /// Orders List + Expanded( + child: ListView( + children: [ + // Active / Other Orders + ...otherPlans.map((o) => OrderCard(order: o)), + + // Rejected Orders Section + if (rejectedPlans.isNotEmpty) ...[ + const SizedBox(height: 12), + const Text( + "Rejected Requests", + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + color: Colors.black, + ), + ), + const SizedBox(height: 8), + ...rejectedPlans.map((o) => OrderCard(order: o)), + ], + ], + ), + ), + ], + ), + ), + ); + } +} + +/// Order Model +class PlanModel { + final String status; + final String title; + final String location; + final String description; + final String price; + + PlanModel({ + required this.status, + required this.title, + required this.location, + required this.description, + required this.price, + }); +} + +/// Order Card widget +class OrderCard extends StatelessWidget { + final PlanModel order; + + const OrderCard({super.key, required this.order}); + + Color _getStatusColor() { + switch (order.status.toLowerCase()) { + case "new": + return Colors.blue; + case "expires in 15m": + case "expires in 5m": + return Colors.orange; + case "expired": + return Colors.grey; + case "rejected": + return Colors.red; + default: + return Colors.black; + } + } + + @override + Widget build(BuildContext context) { + final statusColor = _getStatusColor(); + + return Container( + margin: const EdgeInsets.only(bottom: 12), + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.grey.shade300), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + /// Left content + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Status chip + Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + decoration: BoxDecoration( + color: statusColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + order.status, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: statusColor, + ), + ), + ), + const SizedBox(height: 6), + + // Title + Text( + order.title, + style: const TextStyle( + fontSize: 15, + fontWeight: FontWeight.w600, + ), + ), + + // Location + Text( + order.location, + style: TextStyle( + fontSize: 12, + color: Colors.grey.shade600, + ), + ), + + const SizedBox(height: 4), + + // Description + Text( + order.description, + style: const TextStyle( + fontSize: 12, + color: Colors.blue, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + ), + + /// Price + Text( + order.price, + style: const TextStyle( + fontSize: 15, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ); + } +} diff --git a/lib/plans/plans_model.dart b/lib/plans/plans_model.dart new file mode 100644 index 0000000..59c36a0 --- /dev/null +++ b/lib/plans/plans_model.dart @@ -0,0 +1,19 @@ +class PlansModel { + final String status; + final String apartment; + final String liters; + final String price; + final String advance; + final String deliveries; + final String frequency; + + PlansModel({ + required this.status, + required this.apartment, + required this.liters, + required this.price, + required this.advance, + required this.deliveries, + required this.frequency, + }); +} \ No newline at end of file diff --git a/lib/plans/search_plan_appbar.dart b/lib/plans/search_plan_appbar.dart new file mode 100644 index 0000000..6e7f823 --- /dev/null +++ b/lib/plans/search_plan_appbar.dart @@ -0,0 +1,92 @@ +import 'package:flutter/material.dart'; +import 'package:supplier_new/common/settings.dart'; + +class SearchPlanAppBar extends StatelessWidget implements PreferredSizeWidget { + final TextEditingController controller; + final VoidCallback onBack; + final VoidCallback onHelp; + + const SearchPlanAppBar({ + super.key, + required this.controller, + required this.onBack, + required this.onHelp, + }); + + @override + Widget build(BuildContext context) { + return AppBar( + backgroundColor: Colors.white, + scrolledUnderElevation: 0, + elevation: 0, + leading: GestureDetector( + onTap: () { + Navigator.pop(context); + }, + child: Padding( + padding: const EdgeInsets.fromLTRB( + 8, 8, 8, 8), // Add padding if needed + child: Image.asset( + 'images/backbutton_appbar.png', + height: 24, + width: 24,// Replace with your image path + fit: BoxFit.contain, // Adjust the fit + ), + ), + ), + titleSpacing: 0, + title: Container( + height: 40, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(22), + border: Border.all(color: Color(0XFF939495)), + ), + child: TextField( + controller: controller, + decoration: InputDecoration( + hintText: "Search Plan", + hintStyle: fontTextStyle(16, Color(0XFF646566), FontWeight.w400), + prefixIcon: SizedBox( + height: 20, + width: 20, + child: Padding( + padding: const EdgeInsets.all(8.0), // adjust spacing + child: Image.asset( + 'images/search.png', + fit: BoxFit.contain, + ), + ), + ), + border: InputBorder.none, + contentPadding: const EdgeInsets.symmetric(vertical: 0), + + ), + style: fontTextStyle(16,Color(0XFF2A2A2A),FontWeight.w400), + ), + ), + + actions: [ + Padding(padding: EdgeInsets.all(8), + child: + GestureDetector( + onTap: () { + }, + child: Padding( + padding: const EdgeInsets.fromLTRB( + 8, 8, 8, 8), // Add padding if needed + child: Image.asset( + 'images/help_appbar.png', + height: 24, + width: 24,// Replace with your image path + fit: BoxFit.contain, // Adjust the fit + ), + ), + ),) + ], + ); + } + + @override + Size get preferredSize => const Size.fromHeight(kToolbarHeight); +}