3
votes

I have been working on an appointment app where appointment slots start from 7 am to 8 pm from the current time to the next 2 days. Appointments slots are available every half an hour unless someone booked it. So if the user wants to book an appointment for today it'll disable already passed time and show available slots after 1hr from the current time. Now, where I got stuck is I created the function which lists all the available appointments after the current time but don't know how to get values to flutter widget. I'm getting null every time

 class GetAppointment with ChangeNotifier {
    final String appId, allotedCrew, allotedSlot, usedSlot, totalTimeSlots;
    final DateTime totalDurationinHr;
    dynamic availableTimeSlotsFm, currentDate;
    bool slotAvailable, dayAvailable;
    
    GetAppointment({
       this.appId,
       this.allotedCrew,
       this.allotedSlot,
       this.usedSlot,
       this.totalTimeSlots,
       this.totalDurationinHr,
       this.availableTimeSlotsFm,
       this.currentDate,
       this.slotAvailable: true,
       this.dayAvailable: true});
    }

    extension on DateTime {
        DateTime roundDown({Duration delta = const Duration(minutes: 30)}) {
        return DateTime.fromMillisecondsSinceEpoch(this.millisecondsSinceEpoch -
        this.millisecondsSinceEpoch % delta.inMilliseconds);
    }
}

class Appointments with ChangeNotifier {
    Map<String, GetAppointment> _appointmentList = {};

    Map<String, GetAppointment> get items {
        return {..._appointmentList};
    }
    
    generateBookingSlots() {
        final endTime = DateTime(now.year, now.month, now.day, 23, 60, now.second);
        final startTime = DateTime(now.year, now.month, now.day, 6, 60, now.second);
        var currentTime = DateTime.now();
        var availableTimeSlots = DateTime.now();
        var currentDate, availableTimeSlotsFm;
        final diff_dy = endTime.difference(startTime).inDays;
        final diff_hr = endTime.difference(startTime).inHours;
    
        //List available day from current day
        for (int i = 0; i <= 3; i++) {
            int a = 0;
            if ((diff_hr * 2) <= 0) {
               a = 1;
            }
            currentDate = DateTime.now().add(Duration(days: 1) * (i + a));
        } 
        
        // List numbers of hours in single day
        final listAllTime = List.generate(diff_hr * 2, (index) {
        final totalDuration = startTime.add(Duration(minutes: 30));
        final totalTimeSlots =
             DateFormat.jm().format(startTime.add(Duration(minutes: 30) * index));

        if (currentTime.difference(startTime).inHours > 0 &&
             currentTime.isBefore(endTime) &&
             availableTimeSlots.isBefore(endTime)) {
             availableTimeSlots = currentTime.add(Duration(minutes: 30) * index);
             availableTimeSlots.roundDown(delta: Duration(minutes: 30));
             availableTimeSlotsFm = DateFormat.jm()
                .format(availableTimeSlots.roundDown(delta: Duration(minutes: 30)));
             // availableTimeSlots.roundDown();
         }
         _appointmentList.putIfAbsent(
             index.toString(),
            () => GetAppointment(
                appId: index.toString(),
                allotedCrew: "2",
                allotedSlot: "2",
                usedSlot: "2",
                totalTimeSlots: totalTimeSlots,
                totalDurationinHr: totalDuration,
                availableTimeSlotsFm: availableTimeSlotsFm,
                currentDate: currentDate,
             ));
        return {
           'totalDurationinHr': totalDuration,
           'totalTimeSlotsFm': totalTimeSlots,
           'availableTimeSlotsFm': availableTimeSlotsFm,
           'currentDate': currentDate
        };
      });
     // notifyListeners();
  }

enter image description here

This is how it should look like, I can handle the UI part, just don't know how to get those timing in simple list format

1

1 Answers

2
votes

Instead of that Try doing this

List<Map<String, dynamic>> get generateBookingSlots {
    final endTime = DateTime(now.year, now.month, now.day, 23, 60, now.second);
    final startTime = DateTime(now.year, now.month, now.day, 6, 60, now.second);
    var currentTime = DateTime.now();
    var availableTimeSlots = DateTime.now();
    var currentDate, availableTimeSlotsFm;
    final diff_dy = endTime.difference(startTime).inDays;
    final diff_hr = endTime.difference(startTime).inHours;

    //List available day from current day
    for (int i = 0; i <= 3; i++) {
        int a = 0;
        if ((diff_hr * 2) <= 0) {
           a = 1;
        }
        currentDate = DateTime.now().add(Duration(days: 1) * (i + a));
    } 
    
    // List numbers of hours in single day
    final listAllTime = List.generate(diff_hr * 2, (index) {
    final totalDuration = startTime.add(Duration(minutes: 30));
    final totalTimeSlots =
         DateFormat.jm().format(startTime.add(Duration(minutes: 30) * index));

    if (currentTime.difference(startTime).inHours > 0 &&
         currentTime.isBefore(endTime) &&
         availableTimeSlots.isBefore(endTime)) {
         availableTimeSlots = currentTime.add(Duration(minutes: 30) * index);
         availableTimeSlots.roundDown(delta: Duration(minutes: 30));
         availableTimeSlotsFm = DateFormat.jm()
            .format(availableTimeSlots.roundDown(delta: Duration(minutes: 30)));
         // availableTimeSlots.roundDown();
     }

     return {
       'totalDurationinHr': totalDuration,
       'totalTimeSlotsFm': totalTimeSlots,
       'availableTimeSlotsFm': availableTimeSlotsFm,
       'currentDate': currentDate
     }
   });
   return listAlltime.toList();
}

Now you can easily get your data by calling generateBookingSlots If you need to get individual data then do this

List<Map<String, dynamic>> get totalDurationinHr{
    final totalDurationinHr = List.generate(generateBookingSlots.length, (index) {
          return {'totalDurationinHr' :generateBookingSlots[index]['totalDurationinHr'] }
    }

}