import ' dart:convert ' ;
import ' package:auto_size_text/auto_size_text.dart ' ;
import ' package:flutter/widgets.dart ' ;
import ' package:http/http.dart ' as http ;
import ' package:flutter/material.dart ' ;
import ' package:bookatanker/common/settings.dart ' ;
import ' package:table_calendar/table_calendar.dart ' ;
import ' package:intl/intl.dart ' ;
import ' package:bookatanker/models/supplier_tankers_model.dart ' ;
import ' package:bookatanker/supplier/cart_summary.dart ' ;
class SupplierScreenFromSearch extends StatefulWidget {
var details ;
SupplierScreenFromSearch ( { this . details } ) ;
@ override
State < SupplierScreenFromSearch > createState ( ) = > _SupplierScreenFromSearchState ( ) ;
}
class _SupplierScreenFromSearchState extends State < SupplierScreenFromSearch > {
DateTime _focusedDay = DateTime . now ( ) ;
DateTime ? _selectedDay ;
bool isTankerDataLoading = false ;
bool isCartDataLoading = false ;
List < SupplierTankersModel > tankersList = [ ] ;
bool isSereverIssue = false ;
List cart = [ ] ;
Map < String , int > localQuantities = { } ;
Map < String , int > localTotalPrices = { } ;
Future < void > getTankers ( ) async {
isTankerDataLoading = true ;
try {
var tankerResponse = await AppSettings . getAllTankers ( widget . details . supplier_id ) ;
setState ( ( ) {
tankersList =
( ( jsonDecode ( tankerResponse ) [ ' data ' ] ) as List ) . map ( ( dynamic model ) {
return SupplierTankersModel . fromJson ( model ) ;
} ) . toList ( ) ;
isTankerDataLoading = false ;
} ) ;
} catch ( e ) {
setState ( ( ) {
isTankerDataLoading = false ;
isSereverIssue = true ;
} ) ;
/ * AppSettings . longFailedToast ( ' There is an issue at server side please try after some time ' ) ;
Navigator . pop ( context ) ; * /
}
}
@ override
void initState ( ) {
super . initState ( ) ;
_selectedDay = _focusedDay ;
getTankers ( ) ;
}
@ override
Widget build ( BuildContext context ) {
return Scaffold (
backgroundColor: Color ( 0XFFFFFFFF ) ,
appBar: AppSettings . SupplierAppBar ( ' ' , context ) ,
body: Padding (
padding: EdgeInsets . fromLTRB ( 0 , 8 , 0 , 8 ) ,
child: Column (
children: [
// ✅ Fixed Content
Expanded (
flex: 0 ,
child: Column (
children: [
Padding ( padding: EdgeInsets . fromLTRB ( 12 , 0 , 12 , 0 ) ,
child: Column (
children: [
Padding (
padding: EdgeInsets . fromLTRB ( 8 , 8 , 8 , 8 ) ,
child: Column (
mainAxisAlignment: MainAxisAlignment . start ,
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
Visibility (
visible: true ,
child: Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
Row (
children: [
Visibility (
visible: widget . details . supplier_name ! = ' ' ,
child: Text (
widget . details . supplier_name . toString ( ) ,
style: fontTextStyle (
16 , Color ( 0XFF2D2E30 ) , FontWeight . w600 ) ,
) ,
) ,
SizedBox (
width:
MediaQuery . of ( context ) . size . width *
. 012 ,
) ,
widget . details . isFavorite ? Image . asset (
' images/heart_active.png ' ,
fit: BoxFit . cover ,
width:
16 , // Match the diameter of the CircleAvatar
height: 16 ,
) :
Image . asset (
' images/heart_outline.png ' ,
fit: BoxFit . cover ,
width:
16 , // Match the diameter of the CircleAvatar
height: 16 ,
) ,
] ,
) ,
Container (
decoration: BoxDecoration (
shape: BoxShape . rectangle ,
color: Color ( 0XFFFDF3D3 ) ,
border: Border . all (
width: 0 ,
color: Color ( 0XFFFDF3D3 ) ,
) ,
borderRadius:
BorderRadius . circular (
12 ,
) ) ,
child: Padding (
padding: EdgeInsets . fromLTRB ( 10 , 2 , 10 , 2 ) ,
child: Row (
mainAxisAlignment: MainAxisAlignment . center ,
crossAxisAlignment: CrossAxisAlignment . center ,
children: [
Image . asset (
' images/star.png ' ,
fit: BoxFit . cover ,
width:
16 , // Match the diameter of the CircleAvatar
height: 16 ,
) ,
Visibility (
visible: true ,
child: Text (
' 4.2 ' ,
style: fontTextStyle ( 11 ,
Color ( 0XFF232527 ) , FontWeight . w600 ) ,
) ,
) ,
] ,
) ,
) ,
)
] ,
) ,
) ,
Visibility (
visible: true ,
child: Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
Text (
widget . details . displayAddress +
' ' +
widget . details . distanceInMeters
. toString ( ) +
' Km ' ,
style: fontTextStyle ( 12 , Color ( 0XFF515253 ) ,
FontWeight . w400 ) ) ,
] ,
) ,
) ,
SizedBox ( height: MediaQuery . of ( context ) . size . height * . 004 , ) ,
Row (
children: [
Container (
padding: EdgeInsets . symmetric ( horizontal: 4 , vertical: 2 ) ,
decoration: BoxDecoration (
color: Color ( 0xFF8877DD ) ,
borderRadius: BorderRadius . circular ( 4 ) ,
border: Border . all (
width: 1 ,
color: Color ( 0xFF8877DD ) ,
) ,
) ,
child: AutoSizeText (
capitalizeFirst ( ' Bore Water ' ) ,
maxLines: 1 ,
overflow: TextOverflow . ellipsis ,
style: fontTextStyle ( 12 , Color ( 0xFFFFFFFF ) , FontWeight . w400 ) ,
) ,
) ,
SizedBox ( width: MediaQuery . of ( context ) . size . width * . 016 , ) ,
Container (
padding: EdgeInsets . symmetric ( horizontal: 4 , vertical: 2 ) ,
decoration: BoxDecoration (
color: Color ( 0xFFCA86B0 ) ,
borderRadius: BorderRadius . circular ( 4 ) ,
border: Border . all (
width: 1 ,
color: Color ( 0xFFCA86B0 ) ,
) ,
) ,
child: AutoSizeText (
capitalizeFirst ( ' Drinking Water ' ) ,
maxLines: 1 ,
overflow: TextOverflow . ellipsis ,
style: fontTextStyle ( 12 , Color ( 0xFFFFFFFF ) , FontWeight . w400 ) ,
) ,
) ,
] ,
) ,
SizedBox ( height: MediaQuery . of ( context ) . size . height * . 016 , ) ,
Row (
children: [
Container (
padding: EdgeInsets . symmetric ( horizontal: 4 , vertical: 2 ) ,
decoration: BoxDecoration (
color: Color ( 0xFFFFFFFF ) ,
borderRadius: BorderRadius . circular ( 12 ) ,
border: Border . all (
width: 1 ,
color: Color ( 0xFF1D7AFC ) ,
) ,
) ,
child: Row (
children: [
Image . asset (
' images/ring.png ' ,
fit: BoxFit . cover ,
width:
16 , // Match the diameter of the CircleAvatar
height: 16 ,
) ,
AutoSizeText (
capitalizeFirst ( ' Best water quality ' ) ,
maxLines: 1 ,
overflow: TextOverflow . ellipsis ,
style: fontTextStyle ( 10 , Color ( 0xFF2D2E30 ) , FontWeight . w400 ) ,
) ,
] ,
) ,
) ,
SizedBox ( width: MediaQuery . of ( context ) . size . width * . 016 , ) ,
Container (
padding: EdgeInsets . symmetric ( horizontal: 4 , vertical: 2 ) ,
decoration: BoxDecoration (
color: Color ( 0xFFFFFFFF ) ,
borderRadius: BorderRadius . circular ( 12 ) ,
border: Border . all (
width: 1 ,
color: Color ( 0xFF1D7AFC ) ,
) ,
) ,
child: Row (
children: [
Image . asset (
' images/ring.png ' ,
fit: BoxFit . cover ,
width:
16 , // Match the diameter of the CircleAvatar
height: 16 ,
) ,
AutoSizeText (
capitalizeFirst ( ' Steel casing tankers ' ) ,
maxLines: 1 ,
overflow: TextOverflow . ellipsis ,
style: fontTextStyle ( 10 , Color ( 0xFF2D2E30 ) , FontWeight . w400 ) ,
) ,
] ,
) ,
) ,
] ,
) ,
] ,
) ,
) ,
] ,
) ,
) ,
Padding (
padding: EdgeInsets . zero ,
child: Container (
width: double
. infinity , // makes it expand within the Card's width
decoration: BoxDecoration (
borderRadius: BorderRadius . vertical (
bottom: Radius . circular ( 0 ) ,
) , // match Card border
gradient: LinearGradient (
colors: [
Color ( 0xFFFFE8A3 ) ,
Color ( 0xFFFFF8DF ) ,
Color ( 0xFFFFFFFF ) ,
] ,
begin: Alignment . topLeft ,
end: Alignment . bottomRight ,
) ,
) ,
padding: EdgeInsets . symmetric ( vertical: 12 ) ,
alignment: Alignment . center ,
child: Padding (
padding: EdgeInsets . fromLTRB ( 12 , 0 , 12 , 0 ) ,
child: Column (
mainAxisAlignment: MainAxisAlignment . start ,
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
Text ( ' Start regular deliveries? ' ,
style: fontTextStyle (
16 ,
Color ( 0XFF2D2E30 ) ,
FontWeight . w600 ) ) ,
SizedBox ( height: MediaQuery . of ( context ) . size . height * . 012 ) ,
Row (
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
Expanded (
flex: 3 ,
child: Text (
' Want to get water regularly from this supplier? Send a plan request. ' ,
style: fontTextStyle ( 10 , Color ( 0XFF515253 ) , FontWeight . w400 ) ,
maxLines: 2 ,
overflow: TextOverflow . ellipsis ,
) ,
) ,
SizedBox ( width: MediaQuery . of ( context ) . size . width * . 036 ) ,
Expanded (
flex: 1 ,
child: GestureDetector (
onTap: ( ) { } ,
child: Container (
decoration: BoxDecoration (
color: Color ( 0XFFFFFFFF ) ,
border: Border . all ( width: 1 , color: Color ( 0XFF1D7AFC ) ) ,
borderRadius: BorderRadius . circular ( 24 ) ,
) ,
alignment: Alignment . center ,
padding: EdgeInsets . symmetric ( vertical: 10 , horizontal: 8 ) ,
child: Text (
' Request ' ,
style: fontTextStyle ( 12 , Color ( 0XFF1D7AFC ) , FontWeight . w600 ) ,
) ,
) ,
) ,
) ,
] ,
)
] ,
)
,
) ) ,
) ,
SizedBox ( height: MediaQuery . of ( context ) . size . height * . 016 ) ,
] ,
) ,
) ,
// ✅ Scrollable
Expanded (
child: SingleChildScrollView (
padding: EdgeInsets . fromLTRB ( 0 , 0 , 0 , 0 ) ,
child: Column (
children: [
Padding ( padding: EdgeInsets . fromLTRB ( 18 , 0 , 18 , 0 ) ,
child: Container (
width: double . infinity ,
padding:
EdgeInsets . symmetric ( horizontal: 8 , vertical: 4 ) ,
decoration: BoxDecoration (
color: Color ( 0XFFFCF0E7 ) ,
borderRadius: BorderRadius . circular ( 6 ) ,
border: Border . all
(
color: Color ( 0XFFEFA168 ) ) ,
) ,
child: Row (
crossAxisAlignment: CrossAxisAlignment . start ,
mainAxisAlignment: MainAxisAlignment . start ,
children: [
Image . asset (
' images/warning.png ' ,
fit: BoxFit . cover ,
width:
22 , // Match the diameter of the CircleAvatar
height: 22 ,
) ,
SizedBox ( width: MediaQuery . of ( context ) . size . width * . 020 ) ,
Expanded ( child: Text (
' The prices shown below are NOT inclusive of the transport charges. Transport charges are calculated based on the distance between the sourcing location and the delivery location. ' ,
style: fontTextStyle (
10 ,
Color ( 0XFF444444 ) ,
FontWeight . w400 ) ,
) , )
] ,
)
) , ) ,
SizedBox ( height: MediaQuery . of ( context ) . size . height * . 016 ) ,
Padding (
padding: EdgeInsets . fromLTRB ( 12 , 0 , 12 , 0 ) ,
child: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
Text (
' SOURCE LOCATIONS ' ,
style: fontTextStyle ( 12 , Color ( 0XFF646566 ) , FontWeight . w400 ) ,
) ,
SizedBox ( height: MediaQuery . of ( context ) . size . height * . 016 ) ,
Card (
elevation: 2 ,
shape: RoundedRectangleBorder ( borderRadius: BorderRadius . circular ( 8 ) ) ,
color: Color ( 0XFFFFFFFF ) ,
child: Padding (
padding: const EdgeInsets . all ( 12.0 ) ,
child: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
. . . [
{ ' name ' : ' Gandipet ' , ' type ' : ' Drinking water ' , ' km ' : ' 4.5 Km ' } ,
{ ' name ' : ' Nizampet ' , ' type ' : ' Drinking water ' , ' km ' : ' 7.3 Km ' } ,
{ ' name ' : ' Secunderabad ' , ' type ' : ' Bore water ' , ' km ' : ' 12.4 Km ' } ,
] . map ( ( location ) = > Padding (
padding: const EdgeInsets . only ( bottom: 12.0 ) ,
child: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
Text ( location [ ' name ' ] ! ,
style: fontTextStyle ( 12 , Color ( 0XFF2D2E30 ) , FontWeight . w500 ) ) ,
Text ( location [ ' km ' ] ! ,
style: fontTextStyle ( 10 , Color ( 0XFF2D2E30 ) , FontWeight . w500 ) ) ,
] ,
) ,
Text ( location [ ' type ' ] ! ,
style: fontTextStyle ( 10 , Color ( 0XFF515253 ) , FontWeight . w400 ) ) ,
] ,
) ,
) ) ,
] ,
) ,
) ,
) ,
// Tankers
SizedBox ( height: MediaQuery . of ( context ) . size . height * . 016 ) ,
Text (
' TANKERS ' ,
style: fontTextStyle ( 12 , Color ( 0XFF646566 ) , FontWeight . w400 ) ,
) ,
SizedBox ( height: MediaQuery . of ( context ) . size . height * . 016 ) ,
ListView . builder (
itemCount: tankersList . length ,
shrinkWrap: true ,
physics: NeverScrollableScrollPhysics ( ) ,
itemBuilder: ( context , index ) {
final tanker = tankersList [ index ] ;
final isAvailable = tanker . status = = ' Available ' ;
final isEnabled = tanker . enabled ;
return Card (
shape: RoundedRectangleBorder ( borderRadius: BorderRadius . circular ( 8 ) ) ,
elevation: 2 ,
color: Color ( 0XFFFFFFFF ) ,
child: Padding (
padding: const EdgeInsets . all ( 12 ) ,
child: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
Text (
' ${ tanker . capacity } Litres ' ,
style: fontTextStyle ( 14 , Color ( 0XFF2D2E30 ) , FontWeight . w500 ) ,
) ,
Text (
' \u20B9 ${ AppSettings . formDouble ( tanker . price ) } ' ,
style: fontTextStyle ( 10 , Color ( 0XFF515253 ) , FontWeight . w400 ) ,
) ,
] ,
) ,
SizedBox ( height: MediaQuery . of ( context ) . size . height * . 004 , ) ,
Container (
padding: EdgeInsets . symmetric ( horizontal: 4 , vertical: 2 ) ,
decoration: BoxDecoration (
color: tanker . type_of_water . toString ( ) . toLowerCase ( ) = = ' bore water ' ? Color ( 0xFF8877DD ) : Color ( 0xFFCA86B0 ) ,
borderRadius: BorderRadius . circular ( 4 ) ,
border: Border . all (
width: 1 ,
color: tanker . type_of_water . toString ( ) . toLowerCase ( ) = = ' bore water ' ? Color ( 0xFF8877DD ) : Color ( 0xFFCA86B0 ) ,
) ,
) ,
child: AutoSizeText (
capitalizeFirst ( tanker . type_of_water ) ,
maxLines: 1 ,
overflow: TextOverflow . ellipsis ,
style: fontTextStyle ( 12 , Color ( 0xFFFFFFFF ) , FontWeight . w400 ) ,
) ,
) ,
SizedBox ( height: MediaQuery . of ( context ) . size . height * . 008 , ) ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
Container (
padding: EdgeInsets . symmetric ( horizontal: 8 , vertical: 4 ) ,
decoration: BoxDecoration (
borderRadius: BorderRadius . circular ( 6 ) ,
border: Border . all (
color: isAvailable ? Color ( 0XFF098603 ) : Colors . grey ,
) ,
) ,
child: Text (
tanker . status ,
style: fontTextStyle (
12 ,
isAvailable ? Color ( 0XFF098603 ) : Colors . grey ,
FontWeight . w500 ,
) ,
) ,
) ,
/ * ElevatedButton (
onPressed: isEnabled
? ( ) async {
AppSettings . preLoaderDialog ( context ) ;
final productId = tanker . id ;
final name = tanker . tanker_name ;
final priceString = tanker . price ;
final unitPrice = int . parse ( priceString . replaceAll ( ' , ' , ' ' ) ) ;
int currentQuantity = localQuantities [ productId ] ? ? 0 ;
int newQuantity = currentQuantity + 1 ;
int totalPrice = unitPrice * newQuantity ;
final payload = {
" productId " : productId ,
" name " : name ,
" quantity " : newQuantity ,
" price " : unitPrice ,
} ;
try {
final response = await http . post (
Uri . parse ( ' ${ AppSettings . host } cart/ ${ AppSettings . customerId } /add ' ) ,
headers: await AppSettings . buildRequestHeaders ( ) ,
body: jsonEncode ( payload ) ,
) ;
Navigator . of ( context , rootNavigator: true ) . pop ( ) ;
if ( response . statusCode = = 200 | | response . statusCode = = 201 ) {
setState ( ( ) {
localQuantities [ productId ] = newQuantity ;
localTotalPrices [ productId ] = totalPrice ;
int existingIndex = cart . indexWhere ( ( item ) = > item [ ' productId ' ] = = productId ) ;
if ( existingIndex ! = - 1 ) {
cart [ existingIndex ] [ ' quantity ' ] = newQuantity ;
cart [ existingIndex ] [ ' price ' ] = unitPrice ;
cart [ existingIndex ] [ ' total ' ] = totalPrice ;
} else {
cart . add ( {
" productId " : productId ,
" name " : name ,
" quantity " : newQuantity ,
" price " : unitPrice ,
" total " : totalPrice ,
} ) ;
}
} ) ;
} else {
print ( ' Failed to add to cart: ${ response . body } ' ) ;
}
} catch ( e ) {
Navigator . of ( context , rootNavigator: true ) . pop ( ) ;
print ( ' Error adding to cart: $ e ' ) ;
}
}
: null ,
style: ElevatedButton . styleFrom (
backgroundColor: isEnabled ? primaryColor : Colors . grey [ 300 ] ,
foregroundColor: Colors . white ,
shape: RoundedRectangleBorder (
borderRadius: BorderRadius . circular ( 8 ) ,
) ,
minimumSize: Size ( 64 , 36 ) ,
padding: EdgeInsets . zero ,
) ,
child: Text (
' Add ' ,
style: fontTextStyle ( 12 , Colors . white , FontWeight . w400 ) ,
) ,
) , * /
] ,
)
] ,
) ,
) ,
) ;
} ,
) ,
] ,
) ,
)
] ,
) ,
) ,
) ,
] ,
)
) ,
bottomNavigationBar: cart . isNotEmpty
? Padding (
padding: EdgeInsets . all ( 0 ) ,
child: Container (
height: 56 ,
width: double . infinity ,
decoration: BoxDecoration (
color: Color ( 0XFFF5CD47 ) ,
borderRadius: BorderRadius . only (
topLeft: Radius . circular ( 12 ) ,
topRight: Radius . circular ( 12 ) ,
) ,
) ,
padding: EdgeInsets . symmetric ( horizontal: 24 ) ,
child: Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
Text (
" Order updated " ,
style: fontTextStyle ( 12 , Color ( 0XFF232527 ) , FontWeight . w500 ) ,
) ,
GestureDetector (
onTap: ( ) {
Navigator . push (
context ,
MaterialPageRoute (
builder: ( context ) = > CartSummary ( details: cart , supplierDetails: widget . details , ) ) ,
) ;
} ,
child: Row (
children: [
Text (
" View summary " ,
style: fontTextStyle ( 12 , Color ( 0XFF232527 ) , FontWeight . w500 ) ,
) ,
Image . asset (
' images/arrow-right.png ' ,
fit: BoxFit . cover ,
width:
20 , // Match the diameter of the CircleAvatar
height: 20 ,
color: Color ( 0XFF343637 ) ,
) ,
] ,
) ,
) ,
] ,
) ,
) ,
)
: null ,
) ;
}
}