From 696c7e7dc9216e33fbc0c7738499971d2d422c56 Mon Sep 17 00:00:00 2001 From: Hardik Roongta Date: Sun, 16 Jul 2023 01:10:45 +0530 Subject: [PATCH] accept, reject and get owned room bookings routes --- lib/main.dart | 26 +- packages/irbs/lib/src/globals/colors.dart | 1 + packages/irbs/lib/src/globals/endpoints.dart | 3 + packages/irbs/lib/src/main.dart | 2 +- .../lib/src/models/owned_room_booking.dart | 37 ++ .../irbs/lib/src/screens/all_requests.dart | 46 +-- packages/irbs/lib/src/screens/home.dart | 304 +++++++------- .../lib/src/screens/room_booking_details.dart | 57 ++- packages/irbs/lib/src/services/api.dart | 68 +++ .../irbs/lib/src/widgets/home/drawer.dart | 390 +++++++++--------- .../irbs/lib/src/widgets/home/empty_sate.dart | 4 +- .../irbs/lib/src/widgets/home/request.dart | 35 +- .../lib/src/widgets/home/request_list.dart | 89 +++- .../lib/src/widgets/home/request_widget.dart | 2 +- .../lib/src/widgets/home/respond_dialog.dart | 86 ++-- .../roomBookingDetails/request_modal.dart | 18 +- 16 files changed, 678 insertions(+), 490 deletions(-) create mode 100644 packages/irbs/lib/src/models/owned_room_booking.dart diff --git a/lib/main.dart b/lib/main.dart index 56f942a..7470989 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -58,14 +58,26 @@ class HomePage extends StatelessWidget { // r.hardik@iitg.ac.in // eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiI2NGE5YmY5YWFjM2VhYjAxOTdiNWI2N2UiLCJpYXQiOjE2ODg5Njg4OTQsImV4cCI6MTY4OTgzMjg5NH0.W1UyMNO1gcWKHjCb5Et3_sd6I9Hi6ObfQVYdKYFQsgM - await user.setString("userInfo", jsonEncode({ - "_id": "64a9bf9aac3eab0197b5b67e", - "name": "Hareesh Nandigrama", - "outlookEmail": "h.nandigrama@iitg.ac.in", - "rollNo": "200101071", - "__v": 0 + // await user.setString("userInfo", jsonEncode({ + // "_id": "64a9bf9aac3eab0197b5b67e", + // "name": "Hareesh Nandigrama", + // "outlookEmail": "h.nandigrama@iitg.ac.in", + // "rollNo": "200101071", + // "__v": 0 + // })); + + await user.setString('userInfo', jsonEncode({ + '_id': '64a9bf9aac3eab0197b5b67e', + 'name': 'Hardik Roongta', + 'outlookEmail': 'r.hardik@iitg.ac.in', + 'roolNo': '210102036', + '__v': 0 })); - await user.setString("accessToken", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiI2NDlkOTk2NzA2MmNmOTBmYzljMjMwNjAiLCJpYXQiOjE2ODg4MDQ4OTQsImV4cCI6MTY4OTY2ODg5NH0.wfrq1RDzMbDOWKQzauZpbXyxg8u687pQPK054SyQdpM"); + + // Hardik + await user.setString("accessToken", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiI2NGE5YmY5YWFjM2VhYjAxOTdiNWI2N2UiLCJpYXQiOjE2ODg5Njg4OTQsImV4cCI6MTY4OTgzMjg5NH0.W1UyMNO1gcWKHjCb5Et3_sd6I9Hi6ObfQVYdKYFQsgM"); + + //await user.setString("accessToken", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiI2NDlkOTk2NzA2MmNmOTBmYzljMjMwNjAiLCJpYXQiOjE2ODg4MDQ4OTQsImV4cCI6MTY4OTY2ODg5NH0.wfrq1RDzMbDOWKQzauZpbXyxg8u687pQPK054SyQdpM"); Navigator.of(context).push( MaterialPageRoute( builder: (context) => const IRBS() diff --git a/packages/irbs/lib/src/globals/colors.dart b/packages/irbs/lib/src/globals/colors.dart index 82ea6c8..908be8b 100644 --- a/packages/irbs/lib/src/globals/colors.dart +++ b/packages/irbs/lib/src/globals/colors.dart @@ -22,4 +22,5 @@ class Themes{ static const dropDownColor = Color.fromRGBO(32, 40, 54, 1); static const myRoomsFormHeadingColor = Color.fromRGBO(253, 252, 255, 1); static const requestTile = Color.fromRGBO(35, 41, 52, 1); + static const disabledButtonBackground = Color.fromRGBO(62, 71, 88, 1); } \ No newline at end of file diff --git a/packages/irbs/lib/src/globals/endpoints.dart b/packages/irbs/lib/src/globals/endpoints.dart index c19bc3b..6496570 100644 --- a/packages/irbs/lib/src/globals/endpoints.dart +++ b/packages/irbs/lib/src/globals/endpoints.dart @@ -3,11 +3,14 @@ class Endpoints { static const apiSecurityKey = ''; static const getAllRooms = '/api/room'; static const getRoomBookings = '/api/booking'; + static const getOwnedRoomBookings = '/api/booking/rooms-owned'; static const getSpecificRoom = '/api/room'; static const getMyRooms = '/api/room/owned'; static const deleteBooking ='/api/booking'; static const createBooking = '/api/booking'; static const editRoom = '/api/room'; + static const rejectBooking = '/api/booking/reject'; + static const acceptBooking = '/api/booking/accept'; static getHeader() { return { 'Content-Type': 'application/json', diff --git a/packages/irbs/lib/src/main.dart b/packages/irbs/lib/src/main.dart index 90652d0..4c45d79 100644 --- a/packages/irbs/lib/src/main.dart +++ b/packages/irbs/lib/src/main.dart @@ -32,7 +32,7 @@ class _IRBSState extends State { debugShowCheckedModeBanner: false, initialRoute: '/irbs/home', routes: { - '/irbs/home': (context) => const Home(isAdmin: true), + '/irbs/home': (context) => const Home(), '/irbs/onboarding': (context) => const Onboarding(), '/irbs/roomList': (context) => const RoomList(), '/irbs/bookingHistory': (context) => const BookingHistory(), diff --git a/packages/irbs/lib/src/models/owned_room_booking.dart b/packages/irbs/lib/src/models/owned_room_booking.dart new file mode 100644 index 0000000..e5d44a9 --- /dev/null +++ b/packages/irbs/lib/src/models/owned_room_booking.dart @@ -0,0 +1,37 @@ +import 'package:irbs/src/models/booking_model.dart'; + +class OwnedRoomBooking{ + late String roomId; + late String user; + late String status; + late String inTime; + late String outTime; + late String bookingPurpose; + late String createdAt; + late String id; + late RoomDetailsModel roomDetails; + + OwnedRoomBooking({ + required this.roomId, + required this.user, + required this.status, + required this.inTime, + required this.outTime, + required this.bookingPurpose, + required this.createdAt, + required this.id, + required this.roomDetails + }); + + OwnedRoomBooking.fromJson(Map json){ + roomId = json['roomId']; + user = json['user']; + status = json['status']; + inTime = json['inTime']; + outTime = json['outTime']; + bookingPurpose = json['bookingPurpose']; + createdAt = json['createdAt']; + id = json['id']; + roomDetails = RoomDetailsModel.fromJson(json['roomDetails']); + } +} \ No newline at end of file diff --git a/packages/irbs/lib/src/screens/all_requests.dart b/packages/irbs/lib/src/screens/all_requests.dart index 6df1ed7..a65f89a 100644 --- a/packages/irbs/lib/src/screens/all_requests.dart +++ b/packages/irbs/lib/src/screens/all_requests.dart @@ -1,10 +1,12 @@ import 'package:flutter/material.dart'; +import 'package:irbs/src/services/api.dart'; import 'package:irbs/src/widgets/home/request.dart'; - +import 'package:irbs/src/models/owned_room_booking.dart'; import '../globals/colors.dart'; import '../globals/styles.dart'; class ViewAllRequests extends StatelessWidget { - const ViewAllRequests({Key? key}) : super(key: key); + final List requestedBookings; + const ViewAllRequests({required this.requestedBookings, super.key}); @override Widget build(BuildContext context) { @@ -28,39 +30,17 @@ class ViewAllRequests extends StatelessWidget { backgroundColor: Themes.kCommonBoxBackground, ), - body: const SafeArea( - child:SingleChildScrollView( + body: SafeArea( + child: SingleChildScrollView( + child: Center( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - - Padding( - padding: EdgeInsets.symmetric(horizontal: 32,vertical: 12), - child: Request(), - ), - Padding( - padding: EdgeInsets.symmetric(horizontal: 32,vertical: 12), - child: Request(), - ), - Padding( - padding: EdgeInsets.symmetric(horizontal: 32,vertical: 12), - child: Request(), - ), - Padding( - padding: EdgeInsets.symmetric(horizontal: 32,vertical: 12), - child: Request(), - ), - Padding( - padding: EdgeInsets.symmetric(horizontal: 32,vertical: 12), - child: Request(), - ), - Padding( - padding: EdgeInsets.symmetric(horizontal: 32,vertical: 12), - child: Request(), - ), - ], + children: requestedBookings.map((booking) => Padding( + padding: const EdgeInsets.symmetric(vertical: 12), + child: Request(bookingData: booking), + )).toList() ), - ) + ), + ), ), ); } diff --git a/packages/irbs/lib/src/screens/home.dart b/packages/irbs/lib/src/screens/home.dart index 5c0e261..8cc190b 100644 --- a/packages/irbs/lib/src/screens/home.dart +++ b/packages/irbs/lib/src/screens/home.dart @@ -2,27 +2,25 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:irbs/src/globals/colors.dart'; import 'package:irbs/src/globals/styles.dart'; +import 'package:irbs/src/services/api.dart'; import 'package:irbs/src/store/common_store.dart'; import 'package:irbs/src/store/data_store.dart'; import 'package:irbs/src/widgets/home/common_rooms.dart'; -import 'package:irbs/src/widgets/home/current_bookings_widget.dart'; import 'package:irbs/src/widgets/home/drawer.dart'; import 'package:irbs/src/widgets/home/request_list.dart'; import 'package:irbs/src/widgets/roomlist/list_display.dart'; import 'package:provider/provider.dart'; -import 'all_requests.dart'; - class Home extends StatefulWidget { - final bool isAdmin; - - const Home({required this.isAdmin, super.key}); + const Home({super.key}); @override State createState() => _HomeState(); } class _HomeState extends State { + bool isAdmin = false; + @override void initState() { // TODO: implement initState @@ -31,171 +29,155 @@ class _HomeState extends State { } @override Widget build(BuildContext context) { - final screenWidth = MediaQuery.of(context).size.width; var cs = context.read(); - return Scaffold( - backgroundColor: const Color.fromRGBO(28, 28, 30, 1), - endDrawer: (!widget.isAdmin) ? null : SideDrawer(), - appBar: AppBar( - centerTitle: true, - leading: GestureDetector( - onTap: () { - Navigator.of(context, rootNavigator: true).pop(); - }, - child: const Icon( - Icons.arrow_back_sharp, - color: Colors.white, - ), - ), - title: const Text( - "IRBS", - style: kAppBarTextStyle, - ), - actions: widget.isAdmin - ? [] - : [ - GestureDetector( - onTap: () { - Navigator.pushReplacementNamed( - context, '/irbs/onboarding'); - }, - child: Padding( - padding: const EdgeInsets.only(right:11.0), - child: Image.asset( - 'assets/question_circle.png', - package: 'irbs', - height: 24, - width: 24, - ), - )) - ], - backgroundColor: Themes.kCommonBoxBackground, - ), - body: Stack(fit: StackFit.expand, children: [ - SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (widget.isAdmin) - Padding( - padding: const EdgeInsets.only(top: 18, left: 16, bottom: 10), - child: Text( - 'Requests', - style: - kSubHeadingStyle.copyWith(fontWeight: FontWeight.w600), - ), + return FutureBuilder( + future: APIService().getMyRooms(), + builder: (context, snapshot) { + if(!snapshot.hasData){ + return const Center(child: CircularProgressIndicator(),); + }else if(snapshot.hasError){ + return Center(child: Text(snapshot.error.toString()),); + }else{ + if(snapshot.data!.isNotEmpty){ + isAdmin = true; + } + return Scaffold( + backgroundColor: const Color.fromRGBO(28, 28, 30, 1), + endDrawer: (!isAdmin) ? null : SideDrawer(), + appBar: AppBar( + centerTitle: true, + leading: GestureDetector( + onTap: () { + Navigator.of(context, rootNavigator: true).pop(); + }, + child: const Icon( + Icons.arrow_back_sharp, + color: Colors.white, ), - if (widget.isAdmin) - SizedBox( - height: 167 * screenWidth / 360, - child: const RequestList()), - if (widget.isAdmin) - GestureDetector( - child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 16, vertical: 12), - child: Container( - height: 40, - width: double.maxFinite, - decoration: BoxDecoration( - color: Themes.kCommonBoxBackground, - borderRadius: BorderRadius.circular(4)), - child: const Center( + ), + title: const Text( + "IRBS", + style: kAppBarTextStyle, + ), + actions: isAdmin + ? [] + : [ + GestureDetector( + onTap: () { + Navigator.pushReplacementNamed( + context, '/irbs/onboarding'); + }, + child: Padding( + padding: const EdgeInsets.only(right:11.0), + child: Image.asset( + 'assets/question_circle.png', + package: 'irbs', + height: 24, + width: 24, + ), + )) + ], + backgroundColor: Themes.kCommonBoxBackground, + ), + body: Stack(fit: StackFit.expand, children: [ + SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (isAdmin) + Padding( + padding: const EdgeInsets.only(top: 18, left: 16, bottom: 10), child: Text( - 'View all Requests', - style: kRequestedRoomStyle, + 'Requests', + style: + kSubHeadingStyle.copyWith(fontWeight: FontWeight.w600), ), ), - ), - ), - onTap: (){ - Navigator.of(context).push( - MaterialPageRoute(builder: (context)=> ViewAllRequests() - ) - ); - }, - ), - Padding( - padding: const EdgeInsets.only( - top: 10, left: 16, bottom: 7, right: 16), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - 'Current Bookings', - style: kSubHeadingStyle.copyWith( - fontWeight: FontWeight.w600), - ), - TextButton( - onPressed: () { - Navigator.pushNamed(context, '/irbs/bookingHistory'); - }, - child: const Text( - 'View History', - style: kTextButtonStyle, + if(isAdmin)const RequestList(), + Padding( + padding: const EdgeInsets.only( + top: 10, left: 16, bottom: 7, right: 16), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Current Bookings', + style: kSubHeadingStyle.copyWith( + fontWeight: FontWeight.w600), + ), + TextButton( + onPressed: () { + Navigator.pushNamed(context, '/irbs/bookingHistory'); + }, + child: const Text( + 'View History', + style: kTextButtonStyle, + ), + ), + ], ), ), + FutureBuilder( + future: cs.initialisePinnedRooms(), + builder: (context, snapshot){ + if(!snapshot.hasData){return SizedBox();} + return Observer( + builder: (context) { + return ListDisplay(roomList: cs.pinnedRooms.values.toList(), type: 'Pinned Rooms'); + } + ); + }), + const CommonRooms(), + const SizedBox( + height: 108, + ) ], ), ), - FutureBuilder( - future: cs.initialisePinnedRooms(), - builder: (context, snapshot){ - if(!snapshot.hasData){return SizedBox();} - return Observer( - builder: (context) { - return ListDisplay(roomList: cs.pinnedRooms.values.toList(), type: 'Pinned Rooms'); - } - ); - }), - const CommonRooms(), - const SizedBox( - height: 108, - ) - ], - ), - ), - Positioned( - left: 0, - right: 0, - bottom: 0, - child: Column(children: [ - Container( - height: 24, - decoration: const BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Color.fromRGBO(28, 28, 30, 0), - Color.fromRGBO(28, 28, 30, 1) - ])), - ), - Container( - color: const Color.fromRGBO(28, 28, 30, 1), - child: Container( - height: 52, - margin: const EdgeInsets.fromLTRB(17, 0, 16, 36), - decoration: const BoxDecoration( - color: Color.fromRGBO(118, 172, 255, 1), - borderRadius: BorderRadius.all(Radius.circular(4))), - child: InkWell( - onTap: () { - Navigator.pushNamed(context, '/irbs/roomList'); - }, - child: const Center( - child: Text( - 'Book a Room', - style: TextStyle( - fontFamily: 'Montserrat', - package: 'irbs', - fontSize: 16, - fontWeight: FontWeight.bold), - ))), - ), - ), - ])) - ]), + Positioned( + left: 0, + right: 0, + bottom: 0, + child: Column(children: [ + Container( + height: 24, + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Color.fromRGBO(28, 28, 30, 0), + Color.fromRGBO(28, 28, 30, 1) + ])), + ), + Container( + color: const Color.fromRGBO(28, 28, 30, 1), + child: Container( + height: 52, + margin: const EdgeInsets.fromLTRB(17, 0, 16, 36), + decoration: const BoxDecoration( + color: Color.fromRGBO(118, 172, 255, 1), + borderRadius: BorderRadius.all(Radius.circular(4))), + child: InkWell( + onTap: () { + Navigator.pushNamed(context, '/irbs/roomList'); + }, + child: const Center( + child: Text( + 'Book a Room', + style: TextStyle( + fontFamily: 'Montserrat', + package: 'irbs', + fontSize: 16, + fontWeight: FontWeight.bold), + ))), + ), + ), + ])) + ]), + ); + } + }, ); } } diff --git a/packages/irbs/lib/src/screens/room_booking_details.dart b/packages/irbs/lib/src/screens/room_booking_details.dart index fcb10e8..c4b1b2c 100644 --- a/packages/irbs/lib/src/screens/room_booking_details.dart +++ b/packages/irbs/lib/src/screens/room_booking_details.dart @@ -22,16 +22,36 @@ class RoomBookingDetails extends StatefulWidget { class _RoomBookingDetailsState extends State { CalendarView view = CalendarView.month; + late Future getRoomBookings; TextEditingController dateCtl = TextEditingController(); - _showModal(context) { - showModalBottomSheet( + _showModal(context)async { + await showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (BuildContext context) { return RequestModal(room: widget.room); }); + + setState(() { + getRoomBookings = APIService().getBookingsForCalendar( + roomId: widget.room.id, + month: DateTime.now().month, + year: DateTime.now().year.toString() + ); + }); + } + + @override + void initState() { + // TODO: implement initState + super.initState(); + getRoomBookings = APIService().getBookingsForCalendar( + roomId: widget.room.id, + month: DateTime.now().month, + year: DateTime.now().year.toString() + ); } @override @@ -83,12 +103,9 @@ class _RoomBookingDetailsState extends State { fit: BoxFit.contain, )), body: FutureBuilder( - future: APIService().getBookingsForCalendar( - roomId: widget.room.id, - month: DateTime.now().month, - year: DateTime.now().year.toString() - ), + future: getRoomBookings, builder: (context, snapshot) { + print('INSIDE BUILDER'); if(!snapshot.hasData){ return const Center(child: CircularProgressIndicator(),); } @@ -99,7 +116,8 @@ class _RoomBookingDetailsState extends State { allBookings = []; latestBookings = []; for(var booking in snapshot.data!){ - if(DateTime.parse(booking.outTime).toIso8601String().compareTo(DateTime.now().toLocal().toIso8601String()) == 1){ + if(DateTime.parse(booking.outTime).toIso8601String().compareTo( + DateTime.now().toLocal().toIso8601String()) == 1){ allBookings.add(booking); } } @@ -126,16 +144,19 @@ class _RoomBookingDetailsState extends State { style: roomheadingStyle, )), GestureDetector( - onTap: () { - Navigator.of(context).push(MaterialPageRoute(builder: (context) => RoomDetails(room: widget.room,))); - }, - child: const Padding( - padding: EdgeInsets.only(right: 16.0), - child: Icon( - Icons.more_vert, - color: Colors.white, - ), - )) + onTap: () { + Navigator.of(context).push( + MaterialPageRoute(builder: (context) => RoomDetails(room: widget.room,)), + ); + }, + child: const Padding( + padding: EdgeInsets.only(right: 16.0), + child: Icon( + Icons.more_vert, + color: Colors.white, + ), + ), + ), ], ), ), diff --git a/packages/irbs/lib/src/services/api.dart b/packages/irbs/lib/src/services/api.dart index 8e926e0..8ad6989 100644 --- a/packages/irbs/lib/src/services/api.dart +++ b/packages/irbs/lib/src/services/api.dart @@ -1,5 +1,6 @@ import 'package:dio/dio.dart'; import 'package:irbs/src/models/booking_model.dart'; +import 'package:irbs/src/models/owned_room_booking.dart'; import 'package:irbs/src/models/room_model.dart'; import '../functions/auth_helper_functions.dart'; import '../functions/snackbar.dart'; @@ -51,6 +52,29 @@ class APIService { })); } + Future> getOwnedRoomBookings()async{ + try { + Response res = await dio.get( + '${Endpoints.baseUrl}${Endpoints.getOwnedRoomBookings}', + queryParameters: { + 'status': 'requested' + } + ); + + if(res.statusCode == 200){ + List bookings = []; + for(var booking in res.data){ + bookings.add(OwnedRoomBooking.fromJson(booking)); + } + return bookings; + }else{ + throw Exception(res.statusMessage); + } + }catch(e){ + throw Exception(e.toString()); + } + } + Future>> getAllRooms() async { try { var response = await dio.get(Endpoints.getAllRooms); @@ -226,6 +250,47 @@ class APIService { throw Exception(e.toString()); } } + + Future rejectBooking(String bookingId, String rejectionReason)async{ + try { + Response res = await dio.post( + Endpoints.baseUrl+Endpoints.rejectBooking, + data: { + 'id': bookingId, + 'reasonRejection': rejectionReason + } + ); + + if(res.statusCode == 200){ + print('Booking rejected'); + }else{ + throw Exception(res.statusMessage); + } + }catch(e){ + throw Exception(e.toString()); + } + } + + Future acceptBooking(String bookingId, String instructions)async{ + try { + Response res = await dio.post( + Endpoints.baseUrl+Endpoints.acceptBooking, + data: { + 'id': bookingId, + 'acceptInstructions': instructions + } + ); + + if(res.statusCode == 200){ + print('Booking accepted'); + }else{ + throw Exception(res.statusMessage); + } + }catch(e){ + throw Exception(e.toString()); + } + } + Future>> getBookingHistory()async{ try{ Response res = await dio.get(Endpoints.getRoomBookings, queryParameters: { @@ -263,6 +328,7 @@ class APIService { throw Exception(e.toString()); } } + Future deleteBooking(String id) async { try { Response response = await dio.delete(Endpoints.deleteBooking, data: { @@ -280,6 +346,7 @@ class APIService { return "Failed"; } } + Future endBooking(String id) async{ try { Response response = await dio.patch('${Endpoints.deleteBooking}/$id', data: { @@ -295,6 +362,7 @@ class APIService { print('ERROR: $error'); } } + Future editRoomDetails(String roomId, String details) async { try { var response = diff --git a/packages/irbs/lib/src/widgets/home/drawer.dart b/packages/irbs/lib/src/widgets/home/drawer.dart index 11be68a..17df901 100644 --- a/packages/irbs/lib/src/widgets/home/drawer.dart +++ b/packages/irbs/lib/src/widgets/home/drawer.dart @@ -9,220 +9,220 @@ class SideDrawer extends StatelessWidget { SideDrawer({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return FutureBuilder( - future: DataStore().getMyRooms(), - builder: (context, snapshot) { - if (!snapshot.hasData) { - print(snapshot.data); - return const CircularProgressIndicator(); - } else if (snapshot.hasError) { - return const Text('Error'); - } - List? rooms = snapshot.data; - return SafeArea( - child: Container( - width: 240, - decoration: const BoxDecoration( - color: Color.fromRGBO(39, 49, 65, 1), - borderRadius: BorderRadius.only( - topLeft: Radius.circular(4), - bottomLeft: Radius.circular(4))), - child: Stack( - children: [ - Column( - children: [ - Container( + return SafeArea( + child: Container( + width: 240, + decoration: BoxDecoration( + color: const Color.fromRGBO(31, 39, 51, 1), + borderRadius: BorderRadius.circular(4) + ), + child: FutureBuilder( + future: DataStore().getMyRooms(), + builder: (context, snapshot) { + if (!snapshot.hasData) { + print(snapshot.data); + return const Center(child: CircularProgressIndicator()); + } else if (snapshot.hasError) { + return const Text('Error'); + } + List? rooms = snapshot.data; + return Stack( + children: [ + Column( + children: [ + Container( + width: 240, + decoration: BoxDecoration( + color: const Color.fromRGBO(31, 39, 51, 1), + borderRadius: BorderRadius.circular(4)), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox( + height: 24, + ), + SvgPicture.asset( + 'packages/irbs/assets/images/person.svg', + color: Colors.white, + ), + Text( + DataStore.userData["name"] ?? "Name", + style: sideDrawerStyle, + ), + Text( + DataStore.userData["rollNo"] ?? "RollNumber", + style: sideDrawerStyle, + ), + const SizedBox( + height: 28, + ), + ListView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: + const EdgeInsets.symmetric(horizontal: 20), + itemCount: rooms?.length, + itemBuilder: (BuildContext context, int index) { + String roomName = rooms![index].roomName; + return Column( + children: [ + const SizedBox( + height: 8, + ), + Container( + height: 0.5, + color: Colors.white.withOpacity(0.2), + ), + const SizedBox( + height: 8, + ), + Row( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Container( + width: 112, + child: Text( + roomName, + style: dialogCancelStyle.copyWith( + color: Colors.white + .withOpacity(0.5)), + ), + ), + const SizedBox( + width: 8, + ), + Container( + width: 80, + child: Text( + 'Admin', + style: + dialogCancelStyle.copyWith( + color: Colors.white + .withOpacity(0.5)), + )) + ], + ) + ], + ); + }, + ), + const SizedBox( + height: 12, + ), + ], + ), + ), + Expanded( + child: Container( width: 240, - decoration: BoxDecoration( - color: const Color.fromRGBO(31, 39, 51, 1), - borderRadius: BorderRadius.circular(4)), + padding: const EdgeInsets.symmetric(horizontal: 24), child: Column( - crossAxisAlignment: CrossAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox( - height: 24, - ), - SvgPicture.asset( - 'packages/irbs/assets/images/person.svg', - color: Colors.white, - ), - Text( - DataStore.userData["name"] ?? "Name", - style: sideDrawerStyle, + height: 16, ), Text( - DataStore.userData["rollNo"] ?? "RollNumber", - style: sideDrawerStyle, - ), - const SizedBox( - height: 28, + "My Rooms", + style: addmemberStyle.copyWith( + color: Colors.white.withOpacity(0.5)), ), + // SizedBox(height: 14,), ListView.builder( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, - padding: - const EdgeInsets.symmetric(horizontal: 20), itemCount: rooms?.length, - itemBuilder: (BuildContext context, int index) { - String roomName = rooms![index].roomName; - return Column( - children: [ - const SizedBox( - height: 8, - ), - Container( - height: 0.5, - color: Colors.white.withOpacity(0.2), - ), - const SizedBox( - height: 8, + itemBuilder: + (BuildContext context, int index) { + String? roomName = rooms?[index].roomName; + return InkWell( + child: Container( + margin: const EdgeInsets.symmetric( + vertical: 8), + padding: const EdgeInsets.symmetric( + vertical: 6), + child: Text( + roomName!, + style: sideDrawerRoomStyle, ), - Row( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Container( - width: 112, - child: Text( - roomName, - style: dialogCancelStyle.copyWith( - color: Colors.white - .withOpacity(0.5)), - ), - ), - const SizedBox( - width: 8, - ), - Container( - width: 80, - child: Text( - 'Admin', - style: - dialogCancelStyle.copyWith( - color: Colors.white - .withOpacity(0.5)), - )) - ], - ) - ], + ), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + RoomDetails(room: rooms![index],), + ), + ); + }, ); }, ), - const SizedBox( - height: 12, - ), ], ), ), - Expanded( - child: Container( - width: 240, - padding: const EdgeInsets.symmetric(horizontal: 24), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 16, - ), - Text( - "My Rooms", - style: addmemberStyle.copyWith( - color: Colors.white.withOpacity(0.5)), - ), -// SizedBox(height: 14,), - ListView.builder( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: rooms?.length, - itemBuilder: - (BuildContext context, int index) { - String? roomName = rooms?[index].roomName; - return InkWell( - child: Container( - margin: const EdgeInsets.symmetric( - vertical: 8), - padding: const EdgeInsets.symmetric( - vertical: 6), - child: Text( - roomName!, - style: sideDrawerRoomStyle, - ), - ), - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - RoomDetails(room: rooms![index],), - ), - ); - }, - ); - }, - ), - ], - ), - ), - ), - Align( - alignment: Alignment.bottomLeft, - child: Column( - children: [ - Container( - width: 200, - height: 0.5, - color: Colors.white.withOpacity(0.2), - ), - const SizedBox( - height: 16, - ), - Row( - children: [ - const SizedBox( - width: 24, - ), - Text( - "Need Help?", + ), + Align( + alignment: Alignment.bottomLeft, + child: Column( + children: [ + Container( + width: 200, + height: 0.5, + color: Colors.white.withOpacity(0.2), + ), + const SizedBox( + height: 16, + ), + Row( + children: [ + const SizedBox( + width: 24, + ), + Text( + "Need Help?", + style: cancelButtonStyle.copyWith( + color: Colors.white, height: 2), + ), + const SizedBox( + width: 8, + ), + GestureDetector( + onTap: () {}, + child: Text( + 'Contact Us', style: cancelButtonStyle.copyWith( - color: Colors.white, height: 2), - ), - const SizedBox( - width: 8, + color: Colors.white, + height: 2, + decoration: + TextDecoration.underline), ), - GestureDetector( - onTap: () {}, - child: Text( - 'Contact Us', - style: cancelButtonStyle.copyWith( - color: Colors.white, - height: 2, - decoration: - TextDecoration.underline), - ), - ) - ], - ), - const SizedBox( - height: 24, - ) - ], - )) - ], - ), - Positioned( - left: 16, - top: 16, - child: GestureDetector( - child: const Icon( - Icons.close, - color: Colors.white, - ), - onTap: () { - Navigator.pop(context); - }, - )), - ], - )), - ); - }); + ) + ], + ), + const SizedBox( + height: 24, + ) + ], + )) + ], + ), + Positioned( + left: 16, + top: 16, + child: GestureDetector( + child: const Icon( + Icons.close, + color: Colors.white, + ), + onTap: () { + Navigator.pop(context); + }, + )), + ], + ); + }), + ), + ); } } diff --git a/packages/irbs/lib/src/widgets/home/empty_sate.dart b/packages/irbs/lib/src/widgets/home/empty_sate.dart index a840e93..99e9426 100644 --- a/packages/irbs/lib/src/widgets/home/empty_sate.dart +++ b/packages/irbs/lib/src/widgets/home/empty_sate.dart @@ -12,7 +12,7 @@ class EmptyState extends StatelessWidget { margin: const EdgeInsets.symmetric(horizontal: 16), child: DottedBorder( borderType: BorderType.RRect, - color: Themes.white, + color: Themes.blueGrey, strokeWidth: 1.2, dashPattern: const [5.5], radius: const Radius.circular(4), @@ -21,7 +21,7 @@ class EmptyState extends StatelessWidget { height: 18, width: MediaQuery.of(context).size.width, child: Center(child: Text( text, - style: textStyle)), + style: subHeadingStyle)), ), ), ) diff --git a/packages/irbs/lib/src/widgets/home/request.dart b/packages/irbs/lib/src/widgets/home/request.dart index 612ec22..73cd70d 100644 --- a/packages/irbs/lib/src/widgets/home/request.dart +++ b/packages/irbs/lib/src/widgets/home/request.dart @@ -1,16 +1,14 @@ import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; import 'package:irbs/src/globals/colors.dart'; import 'package:irbs/src/globals/styles.dart'; import 'package:irbs/src/widgets/home/respond_dialog.dart'; +import 'package:irbs/src/models/owned_room_booking.dart'; -class Request extends StatefulWidget { - const Request({super.key}); +class Request extends StatelessWidget { + final OwnedRoomBooking bookingData; + const Request({required this.bookingData, super.key}); - @override - State createState() => _RequestState(); -} - -class _RequestState extends State { @override Widget build(BuildContext context) { final screenWidth = MediaQuery.of(context).size.width; @@ -31,7 +29,7 @@ class _RequestState extends State { alignment: Alignment.centerLeft, height: screenWidth*24/360, child: Text( - 'Coding Club Room', + bookingData.roomDetails.roomName, style: permanentTextStyle.copyWith(color: Colors.white, fontSize: 14*screenWidth/360), ), ), @@ -60,7 +58,7 @@ class _RequestState extends State { height: 12*screenWidth/360, alignment: Alignment.centerLeft, child: Text( - 'Aarya · Design Head', + bookingData.user, style: labelTextStyle.copyWith( fontSize: 10*screenWidth/360, color: Colors.white, height: 1 @@ -95,7 +93,7 @@ class _RequestState extends State { height: 12*screenWidth/360, alignment: Alignment.centerLeft, child: Text( - 'Club Meeting', + bookingData.bookingPurpose, style: labelTextStyle.copyWith( fontSize: 10*screenWidth/360, color: Colors.white, height: 1 @@ -130,7 +128,8 @@ class _RequestState extends State { height: 16*screenWidth/360, alignment: Alignment.centerLeft, child: Text( - '10:00 AM - 02:00 PM', + '${DateFormat('hh:mm a').format(DateTime.parse(bookingData.inTime))} - ${DateFormat('hh:mm a').format(DateTime.parse(bookingData.outTime))}', + // '10:00 AM - 02:00 PM', style: labelTextStyle.copyWith( fontSize: 10*screenWidth/360, color: Colors.white, height: 1 @@ -165,7 +164,7 @@ class _RequestState extends State { height: 16*screenWidth/360, alignment: Alignment.centerLeft, child: Text( - 'April 24, 2023', + DateFormat('MMMM dd, yyyy').format(DateTime.parse(bookingData.inTime)), style: labelTextStyle.copyWith( fontSize: 10*screenWidth/360, color: Colors.white, height: 1 @@ -187,16 +186,20 @@ class _RequestState extends State { showDialog( context: context, builder: (BuildContext context){ - return const AlertDialog( + return AlertDialog( contentPadding: EdgeInsets.zero, - insetPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 0), - content: RespondDialog(), + insetPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 0), + content: RespondDialog(bookingData: bookingData,), ); }, ); }, style: elevatedButtonStyle.copyWith( - shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(4))) + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(4) + ), + ), ), child: const Text('Respond') ), diff --git a/packages/irbs/lib/src/widgets/home/request_list.dart b/packages/irbs/lib/src/widgets/home/request_list.dart index 19691bd..7ca7c88 100644 --- a/packages/irbs/lib/src/widgets/home/request_list.dart +++ b/packages/irbs/lib/src/widgets/home/request_list.dart @@ -1,31 +1,84 @@ import 'package:flutter/material.dart'; import 'package:carousel_slider/carousel_slider.dart'; +import 'package:irbs/src/screens/all_requests.dart'; +import 'package:irbs/src/services/api.dart'; +import 'package:irbs/src/widgets/home/empty_sate.dart'; import 'package:irbs/src/widgets/home/request.dart'; +import 'package:irbs/src/globals/styles.dart'; +import 'package:irbs/src/globals/colors.dart'; class RequestList extends StatelessWidget { const RequestList({super.key}); @override Widget build(BuildContext context) { - return ListView( - physics: NeverScrollableScrollPhysics(), - children: [ - CarouselSlider( - items: const [ - Request(), - Request(), - Request(), - Request(), + double screenWidth = MediaQuery.of(context).size.width; + return FutureBuilder( + future: APIService().getOwnedRoomBookings(), + builder: (context, snapshot) { + if(!snapshot.hasData){ + return const Center(child: CircularProgressIndicator(),); + }else if(snapshot.hasError){ + return const Center(child: Text('Error'),); + } + else{ + if(snapshot.data!.isEmpty)return const EmptyState(text: 'No new requests'); + return Column( + children: [ + SizedBox( + height: 167 * screenWidth / 360, + child: ListView( + physics: const NeverScrollableScrollPhysics(), + children: [ + CarouselSlider( + items: snapshot.data!.map((booking) => Request(bookingData: booking)).toList(), + options: CarouselOptions( + height: (167 * MediaQuery.of(context).size.width) / 360, + padEnds: true, + enlargeCenterPage: false, + autoPlay: false, + enableInfiniteScroll: false, + viewportFraction: 0.9, + ), + ) + ], + ), + ), + GestureDetector( + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + child: Container( + height: 40, + width: double.maxFinite, + decoration: BoxDecoration( + color: snapshot.data!.isEmpty + ? Themes.disabledButtonBackground + : Themes.kCommonBoxBackground, + borderRadius: BorderRadius.circular(4)), + child: const Center( + child: Text( + 'View all Requests', + style: kRequestedRoomStyle, + ), + ), + ), + ), + onTap: (){ + if(snapshot.data!.isEmpty)return; + Navigator.of(context).push( + MaterialPageRoute( + builder: (context)=> ViewAllRequests( + requestedBookings: snapshot.data ?? [], + ), + ), + ); + }, + ), ], - options: CarouselOptions( - height: (167 * MediaQuery.of(context).size.width) / 360, - padEnds: true, - enlargeCenterPage: false, - autoPlay: false, - enableInfiniteScroll: false, - viewportFraction: 0.9, - )) - ], + ); + } + }, ); } } diff --git a/packages/irbs/lib/src/widgets/home/request_widget.dart b/packages/irbs/lib/src/widgets/home/request_widget.dart index 958b515..004ede9 100644 --- a/packages/irbs/lib/src/widgets/home/request_widget.dart +++ b/packages/irbs/lib/src/widgets/home/request_widget.dart @@ -140,7 +140,7 @@ class _RequestWidgetState extends State { return const AlertDialog( contentPadding: EdgeInsets.zero, insetPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 0), - content: RespondDialog(), + //content: RespondDialog(bookingData: ,), ); }, ); diff --git a/packages/irbs/lib/src/widgets/home/respond_dialog.dart b/packages/irbs/lib/src/widgets/home/respond_dialog.dart index 77ab785..5a665f2 100644 --- a/packages/irbs/lib/src/widgets/home/respond_dialog.dart +++ b/packages/irbs/lib/src/widgets/home/respond_dialog.dart @@ -1,17 +1,21 @@ import 'package:flutter/material.dart'; import 'package:irbs/src/globals/colors.dart'; import 'package:irbs/src/globals/styles.dart'; - +import 'package:irbs/src/models/owned_room_booking.dart'; +import 'package:irbs/src/services/api.dart'; import 'approved_dialog.dart'; +import 'package:intl/intl.dart'; class RespondDialog extends StatefulWidget { - const RespondDialog({Key? key}) : super(key: key); + final OwnedRoomBooking bookingData; + const RespondDialog({required this.bookingData, super.key}); @override State createState() => _RespondDialogState(); } class _RespondDialogState extends State { + final TextEditingController textEditingController = TextEditingController(); @override Widget build(BuildContext context) { return Container( @@ -30,7 +34,7 @@ class _RespondDialogState extends State { onTap: () { Navigator.pop(context); }, - child: Icon( + child: const Icon( Icons.clear, size: 20, color: Colors.white, @@ -57,14 +61,14 @@ class _RespondDialogState extends State { TextSpan(text: 'Requested by ', style: kHeading3Style), TextSpan(style: kHeading3DescStyle, children: [ TextSpan( - text: 'Aarya', - ), - TextSpan( - text: ' · ', + text: widget.bookingData.user, ), - TextSpan( - text: 'Design Head', - ) + // TextSpan( + // text: ' · ', + // ), + // TextSpan( + // text: 'Design Head', + // ) ]), ]), ), @@ -73,14 +77,17 @@ class _RespondDialogState extends State { maxLines: 1, text: TextSpan(children: [ TextSpan( - text: 'Exibition Hall', + text: widget.bookingData.roomDetails.roomName, style: kDialogRoomStyle, ), - TextSpan(text: ' ', style: kDialogRoomStyle), - TextSpan(text: 'Common Room', style: kDialogSubRoomStyle) + const TextSpan(text: ' ', style: kDialogRoomStyle), + TextSpan(text: widget.bookingData.roomDetails.roomType == 'club' + ? 'Club Room' + : widget.bookingData.roomDetails.roomName == 'board' ? 'Board Room' : 'Common Room', + style: kDialogSubRoomStyle) ])), GridView.count( - physics: NeverScrollableScrollPhysics(), + physics: const NeverScrollableScrollPhysics(), childAspectRatio: 5, shrinkWrap: true, // primary: false, @@ -92,8 +99,8 @@ class _RespondDialogState extends State { children: [ Row( children: [ - Padding( - padding: const EdgeInsets.only(right: 7.33), + const Padding( + padding: EdgeInsets.only(right: 7.33), child: Icon( Icons.access_time, color: Color.fromRGBO(162, 172, 192, 1), @@ -103,13 +110,13 @@ class _RespondDialogState extends State { RichText( text: TextSpan(style: kDialogTimeStyle, children: [ TextSpan( - text: '10:00 AM', + text: DateFormat('hh:mm a').format(DateTime.parse(widget.bookingData.inTime)), ), - TextSpan( + const TextSpan( text: ' - ', ), TextSpan( - text: '2:00 PM', + text: DateFormat('hh:mm a').format(DateTime.parse(widget.bookingData.outTime)), ) ]), ), @@ -117,8 +124,8 @@ class _RespondDialogState extends State { ), Row( children: [ - Padding( - padding: const EdgeInsets.only(right: 7.33), + const Padding( + padding: EdgeInsets.only(right: 7.33), child: Icon( Icons.calendar_today_outlined, color: Color.fromRGBO(162, 172, 192, 1), @@ -126,7 +133,7 @@ class _RespondDialogState extends State { ), ), Text( - 'Apr 24, 2023', + DateFormat('MMM dd, yyyy').format(DateTime.parse(widget.bookingData.inTime)), style: kDialogTimeStyle, ), ], @@ -135,12 +142,15 @@ class _RespondDialogState extends State { ), RichText( text: TextSpan(children: [ - TextSpan(text: 'Purpose - ', style: kDialogPurposeStyle), - TextSpan(text: 'Club Meeting', style: kDialogTimeStyle) + const TextSpan(text: 'Purpose - ', style: kDialogPurposeStyle), + TextSpan( + text: widget.bookingData.bookingPurpose, + style: kDialogTimeStyle + ), ]), ), - Padding( - padding: const EdgeInsets.only( + const Padding( + padding: EdgeInsets.only( top: 12, bottom: 8, left: 0, right: 0), child: Text( 'Instruction/Reason to reject -', @@ -155,6 +165,7 @@ class _RespondDialogState extends State { width: double.maxFinite, child: TextField( maxLines: 3, + controller: textEditingController, style: editRoomText, decoration: InputDecoration( hintText: 'Type Here...', @@ -175,7 +186,7 @@ class _RespondDialogState extends State { ), ), GridView.count( - physics: NeverScrollableScrollPhysics(), + physics: const NeverScrollableScrollPhysics(), childAspectRatio: 2.75, shrinkWrap: true, // primary: false, @@ -190,7 +201,7 @@ class _RespondDialogState extends State { height: 24, width: double.maxFinite, decoration: BoxDecoration( - color: Color.fromRGBO(62, 71, 88, 1), + color: const Color.fromRGBO(62, 71, 88, 1), borderRadius: BorderRadius.circular(4)), child: Center( child: Text( @@ -200,7 +211,10 @@ class _RespondDialogState extends State { ), ), ), - onTap: () {}, + onTap: ()async{ + Navigator.pop(context); + await APIService().rejectBooking(widget.bookingData.id, textEditingController.text); + }, ), ), Padding( @@ -210,26 +224,28 @@ class _RespondDialogState extends State { height: 24, width: double.maxFinite, decoration: BoxDecoration( - color: Color.fromRGBO(118, 172, 255, 1), + color: const Color.fromRGBO(118, 172, 255, 1), borderRadius: BorderRadius.circular(4)), - child: Center( + child: const Center( child: Text( 'Approve', style: kApproveStyle, ), ), ), - onTap: () { - Navigator.pop(context); - showDialog( + onTap: () async{ + // Navigator.pop(context); + await APIService().acceptBooking(widget.bookingData.id, textEditingController.text); + await showDialog( context: context, builder: (BuildContext context) { - return AlertDialog( + return const AlertDialog( contentPadding: EdgeInsets.zero, content: ApprovedDialog(), ); }, ); + Navigator.pop(context); }, ), ), diff --git a/packages/irbs/lib/src/widgets/roomBookingDetails/request_modal.dart b/packages/irbs/lib/src/widgets/roomBookingDetails/request_modal.dart index 5e603c3..6d60812 100644 --- a/packages/irbs/lib/src/widgets/roomBookingDetails/request_modal.dart +++ b/packages/irbs/lib/src/widgets/roomBookingDetails/request_modal.dart @@ -203,7 +203,7 @@ class _RequestModalState extends State builder: (context, child) => IRBSDatePicker( child: child, )); - if (pickedDate != Null) { + if (pickedDate != null) { print(pickedDate); print(pickedDate?.toIso8601String()); String formattedDate = @@ -348,9 +348,21 @@ class _RequestModalState extends State if (_formkey.currentState!.validate() == false) { print('invalid'); } else { - var inTime=new DateTime(pickedDate!.year,pickedDate!.month,pickedDate!.day,res!.hour,res!.minute); + var inTime= DateTime( + pickedDate!.year, + pickedDate!.month, + pickedDate!.day, + res!.hour, + res!.minute + ); print(inTime); - var outTime=new DateTime(pickedDate!.year,pickedDate!.month,pickedDate!.day,res1!.hour,res1!.minute); + var outTime= DateTime( + pickedDate!.year, + pickedDate!.month, + pickedDate!.day, + res1!.hour, + res1!.minute + ); print(outTime); print(nameCtl.text); print(dateCtl.text);