I have managed to compile the code below but know that I can display the opening hours using a better method. I believe it can be done using Future Builder but I am not experienced as yet. The code below loads the items and then goes and find out the opening hours. Can anyone assist to optimize this code so It shows on first instance. I believe there are performance issues with the code below.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:intl/intl.dart';
import 'package:rapideats/global/global.dart';
import '../mainScreens/menus_screen.dart';
import '../models/sellers.dart';
class SellersDesignWidget extends StatefulWidget {
Sellers? model;
BuildContext? context;
SellersDesignWidget({this.model,this.context});
String status = "";
@override
State<SellersDesignWidget> createState() => _SellersDesignWidgetState();
}
class _SellersDesignWidgetState extends State<SellersDesignWidget> {
var status = "Closed";
getOpeningHours() async
{
var date = DateTime.now();
var from = "";
var to = "";
var TodaysDate = DateFormat('EEEE').format(date).substring(0,3).toLowerCase();
// prints mon,tue etc.
QuerySnapshot oh = await FirebaseFirestore.instance.collection("openingHours")
.where("sellerUID", isEqualTo:widget.model!.sellerUID!)
.get();
if(oh.docs.isNotEmpty)
{
for (int i=0; i < oh.docs.length; i++)
{
from = oh.docs[i][TodaysDate+"From"].toString();
to = oh.docs[i][TodaysDate+"To"].toString();
}
if(from == "00:00" && to == "00:00")
{
setState(() {
status = "Closed";
} );
}else
{
setState(() {
status = "Open Now: " + TodaysDate.toTitleCase() + " " + from + " - " + to + "Hrs";
} );
}
}
}
void initState(){
super.initState();
getOpeningHours();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child : Padding(
padding: const EdgeInsets.all(6.0),
child: Row(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(6.0),
child: Image.network(widget.model!.sellerAvatarUrl!,
height: 150,
width: 150,
fit:BoxFit.cover,
),
),
const SizedBox(width: 10.0,),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 20,
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Text(
widget.model!.sellerName!.toTitleCase(),
style: const TextStyle(
color:Colors.black,
fontSize: 24,
fontFamily:"Acme",
),
),
),
const SizedBox(
width: 10,
),
],
),
const SizedBox(
height: 20,
),
Row(
children: [
Text(
status,
style: TextStyle(
color: Colors.grey,
fontSize: 14,
),
),
],
),
const SizedBox(
height: 20,
),
Row(
children: [
Padding(
padding: const EdgeInsets.all(4.0),
child:
status == "Closed"
? const Text(
"",
)
: ElevatedButton(
child: const Text("Order Now"),
style: ElevatedButton.styleFrom(
backgroundColor:Colors.blueAccent,
),
onPressed: ()
{
Navigator.push(context, MaterialPageRoute(builder:(c)=> MenusScreen(model:widget.model)));
},
)
),
]
),
],
),
),
],
),
),
);
}
}
I recommend using a state management package to handle your UI states in an easier and cleaner way. As an example you can use Bloc or Provider (There's more packages)
But as an answer for your question, and to handle your state using FutureBuilder to optimize your UI Performance you can use this code
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:intl/intl.dart';
import 'package:rapideats/global/global.dart';
import '../mainScreens/menus_screen.dart';
import '../models/sellers.dart';
/// We Changed it to StatelessWidget as we don't need to rebuild the whole screen again
class SellersDesignWidget extends StatelessWidget {
final Sellers? model;
SellersDesignWidget({this.model});
/// We will use the same function with some modification to get the data and return the value to the FutureBuilder
Future<String> getOpeningHours() async
{
String status = "Closed";
DateTime date = DateTime.now();
String from = "";
String to = "";
String todaysDate = DateFormat('EEEE').format(date).substring(0, 3).toLowerCase();
// prints mon,tue etc.
QuerySnapshot oh = await FirebaseFirestore.instance.collection("openingHours")
.where("sellerUID", isEqualTo: model!.sellerUID!)
.get();
if (oh.docs.isNotEmpty) {
for (int i = 0; i < oh.docs.length; i++) {
from = oh.docs[i][todaysDate + "From"].toString();
to = oh.docs[i][todaysDate + "To"].toString();
}
if (from == "00:00" && to == "00:00") {
status = "Closed";
} else {
status = "Open Now: " + todaysDate.toTitleCase() + " " + from + " - " + to + "Hrs";
}
}
return status;
}
@override
Widget build(BuildContext context) {
/// As most of your UI doesn't depend on the data from Firebase so it can be shown directly
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Row(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(6.0),
child: Image.network(model!.sellerAvatarUrl!,
height: 150,
width: 150,
fit: BoxFit.cover,
),
),
const SizedBox(width: 10.0,),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 20,
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Text(
model!.sellerName!.toTitleCase(),
style: const TextStyle(
color: Colors.black,
fontSize: 24,
fontFamily: "Acme",
),
),
),
const SizedBox(
width: 10,
),
],
),
const SizedBox(
height: 20,
),
/// For the part needs the remote data we wrap it in future builder
FutureBuilder(
future: getOpeningHours(),
builder: (ctx, AsyncSnapshot<String?> status) {
/// When data is loading(status == null) we display a progress indicator and prevent the user from performing any actions
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
status.data == null ?
//Change SizedBox Size if needed
SizedBox(
width: 30, child: CircularProgressIndicator(),)
: Text(
status.data!,
style: TextStyle(
color: Colors.grey,
fontSize: 14,
),
),
],
),
const SizedBox(
height: 20,
),
Row(
children: [
Padding(
padding: const EdgeInsets.all(4.0),
child:
status.data == "Closed"
? const Text(
"",
)
: ElevatedButton(
child: status.data == null ?
//Change SizedBox Size if needed
SizedBox(
width: 30, child: CircularProgressIndicator(),) : Text("Order Now"),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blueAccent,
),
onPressed: () {
if (status.data != null) {
Navigator.push(context,
MaterialPageRoute(builder: (c) => MenusScreen(model: model)));
}
},
)
),
]
),
],
);
}),
],
),
),
],
),
),
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With