0

I have a bookings collection in Firebase and I am trying to populate the events in TableCalendar using it, my listview Is successfully showing all bookings when I click on a date I I just need the markers to show for each date so the admin knows if there is a booking there or not

The booking model:

import 'package:cloud_firestore/cloud_firestore.dart';

    class Booking {
      final String serviceTitle;
      final DateTime bookingDate;
      final DateTime startTime;
      final DateTime endTime;
      final String userEmail; // Added field for user's email
    
      Booking({
        required this.serviceTitle,
        required this.bookingDate,
        required this.startTime,
        required this.endTime,
        required this.userEmail, // Included user's email
      });
    
      // Constructor to initialize from Firestore document
      Booking.fromFirestore(QueryDocumentSnapshot<Map<String, dynamic>> doc)
          : serviceTitle = doc['serviceTitle'],
            bookingDate = (doc['bookingDate'] as Timestamp).toDate(),
            startTime = (doc['startTime'] as Timestamp).toDate(),
            endTime = (doc['endTime'] as Timestamp).toDate(),
            userEmail = doc['userEmail']; // Initialize user's email field
    }

The Way I get data from Firebase in dbhandler class:

//Return all listing from all Users
  Future<List<Booking>> getAllBookings() async {
    List<Booking> allBookings = [];

    try {
      QuerySnapshot querySnapshot =
          await FirebaseFirestore.instance.collection('bookings').get();

      allBookings = querySnapshot.docs.map((doc) {
        Map<String, dynamic> bookingData = doc.data() as Map<String, dynamic>;
        return Booking(
          serviceTitle: bookingData['serviceTitle'],
          bookingDate: (bookingData['bookingDate'] as Timestamp).toDate(),
          startTime: (bookingData['startTime'] as Timestamp).toDate(),
          endTime: (bookingData['endTime'] as Timestamp).toDate(),
          userEmail: bookingData['userEmail'],
          // You can include other fields as needed
        );
      }).toList();
    } catch (e) {
      print('Error retrieving all bookings: $e');
    }

    return allBookings;
  }

The admin page:

import 'package:flutter/material.dart';
import 'package:mona/pages/models/booking.dart';
import 'package:mona/services/auth/db_handler.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:intl/intl.dart';

class AdminPage extends StatefulWidget {
  const AdminPage({super.key});

  @override
  State<AdminPage> createState() => _AdminPageState();
}

class _AdminPageState extends State<AdminPage> {
  CalendarFormat _calendarFormat = CalendarFormat.month;
  DateTime _focusedDay = DateTime.now();
  DateTime _selectedDay = DateTime.now();
  DBHandler dbhandler = DBHandler();
  List<Booking> allBookings = [];
  List<Booking> filteredBooking = [];

//now i neeed a selected events where it returns events for a certain day when clciked
  Map<DateTime, List<Booking>> _events = {};

  @override
  void initState() {
    super.initState();
    fetchAllBookings();
    //Starting off with Todays List
    filteredBooking = filterBookingsByDate(DateTime.now());
  }

  Future<void> fetchAllBookings() async {
    List<Booking> bookings = await dbhandler.getAllBookings();
    setState(() {
      allBookings = bookings;
      organizeBookings(allBookings);
      print(_events.toString());
    });
  }

  //organising bookings into events method
  void organizeBookings(List<Booking> allBookings) {
    for (var booking in allBookings) {
      DateTime date = booking.bookingDate;
      if (_events.containsKey(date)) {
        _events[date]!.add(booking);
      } else {
        _events[date] = [booking];
      }
    }
  }

  List<Booking> filterBookingsByDate(DateTime selectedDate) {
    List<Booking> filteredBookings = [];

    for (var booking in allBookings) {
      if (isSameDay(booking.bookingDate, selectedDate)) {
        filteredBookings.add(booking);
      }
    }

    return filteredBookings;
  }

  //need a method here to get bookings for a particular Date
  //I can interate thourhg the Bookings list trying to match the bookingDate to selectedDay

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Calendar'),
      ),
      body: Center(
        child: Column(
          children: [
            TableCalendar(
              firstDay: DateTime.utc(2010, 10, 16),
              lastDay: DateTime.utc(2030, 3, 14),
              focusedDay: DateTime.now(),
              calendarFormat: _calendarFormat,
              onFormatChanged: (format) {
                setState(() {
                  _calendarFormat = format;
                });
              },
              selectedDayPredicate: (day) {
                return isSameDay(_selectedDay, day);
              },
              onDaySelected: (selectedDay, focusedDay) {
                setState(() {
                  _selectedDay = selectedDay;
                  _focusedDay = focusedDay; // Update focused day as well
                  filteredBooking = filterBookingsByDate(selectedDay);

                  //use the Selected Day to get List of bookings below
                });
              },
              onPageChanged: (focusedDay) {
                _focusedDay = focusedDay;
              },
              eventLoader: (day) {
                return _events[day] ?? [];
              },
            ),
            const SizedBox(height: 16.0), // Add spacing
            Expanded(
              child: ListView.builder(
                itemCount: filteredBooking.length,
                itemBuilder: (context, index) {
                  Booking booking = filteredBooking[index];
                  return Container(
                    color: Colors.grey[200],
                    margin: EdgeInsets.all(10),
                    child: ListTile(
                      title: Text('Service: ${booking.serviceTitle}'),
                      subtitle: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                              'Date: ${DateFormat('dd-MM-yyyy').format(booking.bookingDate)}'),
                          Text(
                              'Start Time: ${DateFormat('HH:mm').format(booking.startTime)}'),
                          Text(
                              'End Time: ${DateFormat('HH:mm').format(booking.endTime)}'),
                          Text('User Email: ${booking.userEmail}'),
                        ],
                      ),
                    ),
                  );
                },
              ),
            ),
            const SizedBox(height: 8.0),

          ],
        ),
      ),
    );
  }
}

And this is what the bookings collection looks like:

bookingDate
August 15, 2023 at 1:36:18 PM UTC+1
(timestamp)
bookingId
"ExlESetu1qLXPBFn2q62"
endTime
August 15, 2023 at 12:00:00 PM UTC+1
serviceTitle
"Service A"
startTime
August 15, 2023 at 11:30:00 AM UTC+1
userEmail
"jondoe@gmail.com"
userId
"lQe76eOCCrYy14ahbmEh5p8HTnM2"
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807

0 Answers0