Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Method to Display opening hours using optimized code

Tags:

flutter

dart

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)));
                        },
                         )
                        ),
                      ]
                  ),
                ],
              ),
            ),
          ],
        ),
        ),
    );
  }
}
like image 368
ivias Avatar asked Feb 20 '26 21:02

ivias


1 Answers

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)));
                                          }
                                        },
                                      )
                                  ),
                                ]
                            ),
                          ],
                        );
                      }),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

like image 86
Hesham Erfan Avatar answered Feb 23 '26 12:02

Hesham Erfan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!