diff --git a/README.md b/README.md index aa48f389..c2acfc6a 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ Flutter: Use Stable Version *2.0* * `git checkout ` * Switches to the branch you just created -## To update your Project * `git fetch upstream` * Gets the new commits on the main repository diff --git a/android/build.gradle b/android/build.gradle index b3a325d5..881e7e55 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.6.10' + ext.kotlin_version = '1.8.21' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.2' + classpath 'com.android.tools.build:gradle:7.4.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -26,6 +26,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index cc5527d7..6b665338 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/clone.sh b/clone.sh deleted file mode 100644 index 3a3780c4..00000000 --- a/clone.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -#branches=("ac-1" "ac-2" "ac-3" "ac-4" "ac-5" "ps-1" "ps-2" "gad-1" "gad-2" "gad-3" "gad-4" "gad-5" "hr" "sa-1" "sa-2" "sa-3" "sa-4" "os-1" "os-2" "os-3" "os-4" "rspc") -branches=("ac") -for branch in "${branches[@]}" -do - echo "Creating $branch" - - git checkout -b "$branch" - git push origin "$branch" - - echo "Pushed new branch $branch to remote" -done \ No newline at end of file diff --git a/lib/Components/appBar2.dart b/lib/Components/appBar2.dart new file mode 100644 index 00000000..a1f63393 --- /dev/null +++ b/lib/Components/appBar2.dart @@ -0,0 +1,106 @@ +import 'package:flutter/material.dart'; +import 'package:fusion/constants.dart'; +import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/services/storage_service.dart'; + +class CustomAppBar extends StatefulWidget implements PreferredSizeWidget { + final String curr_desig; + final String headerTitle; + + final ValueChanged onDesignationChanged; + + const CustomAppBar({ + Key? key, + required this.curr_desig, + required this.headerTitle, + + required this.onDesignationChanged, + }) : super(key: key); + + @override + _CustomAppBarState createState() => _CustomAppBarState(); + + @override + Size get preferredSize => Size.fromHeight(kToolbarHeight); +} + +class _CustomAppBarState extends State { + late List designations; + late String current; + var service = locator(); + + @override + void initState() { + super.initState(); + designations = (service!.getFromDisk('designations') as List) + .map((dynamic item) => item.toString()) + .toList(); + + current = service!.getFromDisk( + 'Current_designation'); // Ensure designations is not null before accessing index 0 + } + + @override + Widget build(BuildContext context) { + return AppBar( + iconTheme: IconThemeData(color: Colors.white), + backgroundColor: kPrimaryColor, + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: Padding( + padding: EdgeInsets.only(right: 20.0), // Add some right padding to ensure space for the dropdown + child: Text( + widget.headerTitle, // Example of a long title + overflow: TextOverflow.ellipsis, // Prevents overflow by adding ellipsis + style: TextStyle( + color: Colors.white, + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + DropdownButtonHideUnderline( + child: DropdownButton( + padding: const EdgeInsets.all(15), + borderRadius: BorderRadius.circular(5), + value: current, + icon: Icon(Icons.arrow_drop_down, color: Colors.white), + iconSize: 24, + style: TextStyle(color: Colors.white, fontSize: 18), + dropdownColor: + kPrimaryColor, // Set the dropdown background color to orange + onChanged: (String? newValue) { + widget.onDesignationChanged(newValue!); + setState(() { + current = newValue!; + service!.saveToDisk('Current_designation', current); + }); + }, + items: designations.map>((String value) { + return DropdownMenuItem( + value: value, + child: Text( + value, + style: TextStyle( + color: Colors.white), // Set the text color to white + ), + ); + }).toList(), + onTap: () { + // Find the index of the selected value + int index = designations.indexOf(current); + // Scroll the dropdown to the selected value + Scrollable.ensureVisible(context, + alignment: 0.5, duration: Duration(milliseconds: 300)); + }, + ), + ), + ], + ), + actions: [], + ); + } +} \ No newline at end of file diff --git a/lib/Components/bottom_navigation_bar.dart b/lib/Components/bottom_navigation_bar.dart new file mode 100644 index 00000000..f95ad3c3 --- /dev/null +++ b/lib/Components/bottom_navigation_bar.dart @@ -0,0 +1,148 @@ +import 'package:flutter/material.dart'; + +class MyBottomNavigationBar extends StatefulWidget { + @override + _MyBottomNavigationBarState createState() => _MyBottomNavigationBarState(); +} + +class _MyBottomNavigationBarState extends State { + bool _notificationsBool = false; + bool _announcementsBool = false; + bool _newsBool = false; + bool _homeBool = false; + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 100.0, + child: Padding( + padding: EdgeInsets.only(bottom: 40), + child: Card( + color: Colors.deepOrangeAccent, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(17.0), + ), + child: Padding( + padding: const EdgeInsets.only( + left: 13.0, right: 10.0, top: 5.0, bottom: 5.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + GestureDetector( + onTap: () { + _notificationsBool = false; + _announcementsBool = false; + _newsBool = false; + _homeBool = true; + setState(() { + _notificationsBool = false; + _announcementsBool = false; + _newsBool = false; + _homeBool = true; + }); + Navigator.pushReplacementNamed(context, "/dashboard"); + + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon( + Icons.home_rounded, + color: Colors.white, + size: _homeBool ? 30.0 : 25.0, + ), + ], + ), + ), + GestureDetector( + onTap: () { + _newsBool = true; + _announcementsBool = false; + _notificationsBool = false; + _homeBool = false; + + setState(() { + _newsBool = true; + _announcementsBool = false; + _notificationsBool = false; + _homeBool = false; + }); + Navigator.pushReplacementNamed(context, "/news"); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon( + Icons.newspaper_rounded, + color: Colors.white, + size: _newsBool ? 30.0 : 25.0, + ), + ], + ), + ), + GestureDetector( + onTap: () { + _announcementsBool = false; + _newsBool = false; + _notificationsBool = true; + _homeBool = false; + + setState(() { + _announcementsBool = false; + _newsBool = false; + _notificationsBool = true; + _homeBool = false; + }); + Navigator.pushReplacementNamed(context, "/notification"); + }, + child: Padding( + padding: const EdgeInsets.only(right: 16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon( + Icons.notifications_active_rounded, + color: Colors.white, + size: _notificationsBool ? 30.0 : 25.0, + ), + ], + ), + ), + ), + GestureDetector( + onTap: () { + _announcementsBool = true; + _newsBool = false; + _notificationsBool = false; + _homeBool = false; + + setState(() { + _announcementsBool = true; + _newsBool = false; + _notificationsBool = false; + _homeBool = false; + }); + Navigator.pushReplacementNamed(context, "/announcement"); + }, + child: Padding( + padding: const EdgeInsets.only(right: 16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon( + Icons.campaign_rounded, + color: Colors.white, + size: _announcementsBool ? 30.0 : 25.0, + ), + ], + ), + ), + ), + ], + ), + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/Components/side_drawer.dart b/lib/Components/side_drawer.dart index be08db0e..264b2c16 100644 --- a/lib/Components/side_drawer.dart +++ b/lib/Components/side_drawer.dart @@ -13,6 +13,8 @@ class _SideDrawerState extends State { int count = 0; String? name; String? depttype; + + late String user; @override void initState() { super.initState(); @@ -23,6 +25,7 @@ class _SideDrawerState extends State { depttype = service.profileData.profile!['department']!['name'] + " " + service.profileData.profile!['user_type']; + user = service.profileData.profile!['user_type']; } @override @@ -124,6 +127,30 @@ class _SideDrawerState extends State { ModulesPadding( line: 'Gymkhana Module', pageMover: '/gymkhana_homepage'), + + user.toLowerCase().contains("student") + ? ModulesPadding( + line: 'Hostel', + pageMover: '/superadmin/hostel_admin', + // pageMover: '/caretaker/hostel_caretaker', + // pageMover: '/student/hostel_student', + isActive: true, + ) + : user.toLowerCase().contains('warden') + ? ModulesPadding( + line: 'Hostel', + pageMover: '/warden/hostel_warden', + isActive: true, + ) + : ModulesPadding( + line: 'Hostel', + // pageMover: '/warden/hostel_warden', + pageMover: '/caretaker/hostel_caretaker', + // pageMover: '/student/hostel_student', + // pageMover:'/superadmin/hostel_admin', + isActive: true, + ), + ModulesPadding( line: 'Establishment Module', pageMover: '/establishment'), diff --git a/lib/Components/side_drawer2.dart b/lib/Components/side_drawer2.dart new file mode 100644 index 00000000..557496cc --- /dev/null +++ b/lib/Components/side_drawer2.dart @@ -0,0 +1,312 @@ +import 'package:flutter/material.dart'; +import 'package:fusion/services/login_service.dart'; +import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/services/storage_service.dart'; + +class SideDrawer extends StatefulWidget { + final String curr_desig; + + const SideDrawer({ + Key? key, + required this.curr_desig, + }) : super(key: key); + + @override + _SideDrawerState createState() => _SideDrawerState(); +} + +class _SideDrawerState extends State { + bool _loading = false; + int count = 0; + late String name; + late String depttype; + late String type; + + @override + void initState() { + super.initState(); + var service = locator(); + print(service.profileData); + name = service.profileData.user!["first_name"] + + " " + + service.profileData.user!["last_name"]; + depttype = service.profileData.profile!['department']!['name']; + + type = service.profileData.profile!['user_type']; + + print(depttype); + } + + @override + Widget build(BuildContext context) { + return SafeArea( + child: Container( + margin: const EdgeInsets.only(right: 50.0), + height: MediaQuery.of(context).size.height, + color: Colors.white, + child: ListView( + shrinkWrap: true, + physics: ClampingScrollPhysics(), + children: [ + Column( + children: [ + Card( + elevation: 2.0, + margin: + + EdgeInsets.symmetric(horizontal: 12.0, vertical: 30.0), + + + // shadowColor: Colors.black, + color: Colors.white, + + child: Column( + children: [ + Container( + margin: EdgeInsets.only(top: 0.0), + width: 270.0, + height: 120.0, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/profile_pic.png'), + fit: BoxFit.contain, + ), + ), + ), + SizedBox( + height: 10.0, + ), + Text( + name, //Display name of User + style: TextStyle( + fontSize: 20.0, + color: Colors.black, + fontWeight: FontWeight.bold), + ), + SizedBox( + height: 10.0, + ), + Text( + depttype + + " " + + widget.curr_desig, // Display Type of User + style: TextStyle( + fontSize: 17.0, + color: Colors.black, + fontWeight: FontWeight.bold), + ), + SizedBox( + height: 10.0, + ), + ], + ), + ), + ], + ), + ModulesCard(cardLine: 'DashBoard', pageMover: '/dashboard'), + + + if ((type != "staff" || + widget.curr_desig == "acadmin" || + widget.curr_desig == "corelabcaretaker")) + + + ModulesCard( + cardLine: 'Academics Module', + pageMover: '/academic_home_page', + ), + + + if ((type == "student" || widget.curr_desig=="acadmin")) + + ModulesCard( + cardLine: 'Programme Curriculum', + pageMover: '/programme_curriculum_home', + ), + + if ((type == "student") || widget.curr_desig== "Dean_s" || widget.curr_desig== "DeanPnD" || widget.curr_desig== "dean_rspc" || widget.curr_desig== "dean_s" ) + ModulesCard( + cardLine: 'Gymkhana Module', + pageMover: '/gymkhana_homepage', + ), + + if ((type == "student" || widget.curr_desig== "mess_manager" || widget.curr_desig== "mess_warden")) + ModulesCard(cardLine: 'Central Mess Module',pageMover: '/central_mess_home'), + + + + ModulesCard( + cardLine: 'Health Center Module', + pageMover: '/health_center', + ), + + if ((type == "student" )) + ModulesCard(cardLine: 'Leave Module'), + + if ((type == "student" )) + ModulesCard(cardLine: 'Purchase and Store'), + + if ((type == "student" )) + ModulesCard(cardLine: 'Human Resource'), + + if(type == "student"|| widget.curr_desig=="placement chairman" || widget.curr_desig=="placement officer") + ModulesCard(cardLine: 'Placement Module'), + + ModulesCard(cardLine: 'Visitors Hostel Module',pageMover: '/visitor_hostel'), + + if(type != "student") + ModulesCard(cardLine: 'File Tracking Module',pageMover: '/compose_file'), + + + ModulesCard( + cardLine: 'Establishment Module', pageMover: '/establishment'), + + ModulesCard( + cardLine: 'Library Module', pageMover: '/library_homepage'), + + + if(type == "student" || widget.curr_desig== "spacsconvenor"|| widget.curr_desig== "spacsassistant") + ModulesCard(cardLine: 'Awards & Scholarship Module'), + + + ModulesCard(cardLine: 'Complaint Module', pageMover: '/complaint'), + + ModulesCard(cardLine: 'Research Module'), + + ModulesCard(cardLine: 'Counselling Cell'), + + if ((type == "faculty" || widget.curr_desig == "acadadmin")) + ModulesCard( + cardLine: 'Examination Module', + pageMover: '/examination', + ), + + if ((widget.curr_desig == "Executive Engineer (Civil)" || + widget.curr_desig == "EE" || + widget.curr_desig == "Admin IWD" || + widget.curr_desig == "Electrical_AE" || + widget.curr_desig == "mess_manager" || + widget.curr_desig == "Electrical_JE" || + widget.curr_desig == "Civil_AE" || + widget.curr_desig == "Civil_JE" || + widget.curr_desig == "Director" || + widget.curr_desig == "dean_s" || + widget.curr_desig == "Dean_s" || + widget.curr_desig == "DeanPnD")) + ModulesCard(cardLine: 'IWD', pageMover: '/iwd/home_page'), + + if (type == "student") + ModulesCard( + cardLine: 'Hostel', + pageMover: '/student/hostel_student', + ), + if (type == "warden") + ModulesCard( + cardLine: 'Hostel', + pageMover: '/warden/hostel_warden', + ), + if (type == "caretaker") + ModulesCard( + cardLine: 'Hostel', + pageMover: '/registered_courses', + ), + if (type == "Admin") + ModulesCard( + cardLine: 'Hostel', + pageMover: '/superadmin/hostel_admin', + ), + ModulesCard( + cardLine: 'HR Module', + pageMover: '/hr_homepage', + ), + + + + // ModulesCard( + // cardLine: 'Profile', + // icon: Icons.account_circle, + // pageMover: '/profile'), + + // ModulesCard(cardLine: 'Office Of Dean Students'), + // ModulesCard(cardLine: 'Office Of Dean Academics'), + // ModulesCard(cardLine: 'Director Office'), + // ModulesCard(cardLine: 'Office Of Purchase Officer'), + // ModulesCard(cardLine: 'Office Of Registrar'), + // ModulesCard(cardLine: 'Office Of P&D'), + // ModulesCard(cardLine: 'Office Of HOD (Branch)'), + // ModulesCard(cardLine: 'Finance & Accounts'), + // ModulesCard(cardLine: 'Meet Our Team'), + ModulesCard(cardLine: 'Log Out', icon: Icons.logout), + ], + ), + ), + ); + } + + + + String _getGymkhanaPage() { + // Determine the pageMover based on designation + print(1); + print(widget.curr_desig); + if (widget.curr_desig == 'co-ordinator') { + return '/gymkhana_coordinator'; + } else if (widget.curr_desig == 'Counsellor') { + return '/gymkhana_counsellor'; + } else if (widget.curr_desig == 'Convenor') { + return '/gymkhana_convenor'; + } else if (widget.curr_desig == 'Dean Academic') { + return '/gymkhana_dean'; + } else + return '/gymkhana_homepage'; + + + } +// ignore: must_be_immutable +} + +class ModulesCard extends StatelessWidget { + final String? cardLine; + final String? pageMover; + IconData? icon; + ModulesCard({this.cardLine, this.icon, this.pageMover}); + @override + Widget build(BuildContext context) { + return GestureDetector( + //behaviour to translucent to get Tap even on blank or empty space within container + behavior: HitTestBehavior.translucent, + child: Card( + color: Colors.white, + margin: const EdgeInsets.all(10.0), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + cardLine!, + style: TextStyle(fontSize: 16.0, color: Colors.black), + ), + Icon( + icon, + color: Colors.deepOrangeAccent, + ), + ], + ), + ), + ), + onTap: () async { + var _prefs = await StorageService.getInstance(); + String token = _prefs!.userInDB?.token ?? ""; + if (cardLine == 'Log Out') { + LoginService auth = LoginService(); + auth.logout(); + Navigator.pushReplacementNamed(context, "/landing"); + } + if (pageMover != null) + Navigator.pushReplacementNamed(context, pageMover!, arguments: token); + }, + ); + } + +} diff --git a/lib/DesignationProvider.dart b/lib/DesignationProvider.dart new file mode 100644 index 00000000..34031248 --- /dev/null +++ b/lib/DesignationProvider.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +class DesignationProvider extends ChangeNotifier { + late String _designation; + + String get designation => _designation; + + void updateDesignation(String newDesignation) { + _designation = newDesignation; + notifyListeners(); // Notify listeners about the change + } +} \ No newline at end of file diff --git a/lib/api.dart b/lib/api.dart index 802bee2d..1f76a52b 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -1,10 +1,11 @@ //Server and local links String klocalLink = "127.0.0.1:8000"; -String kserverLink = "172.27.16.215:80"; +String kserverLink = "172.27.16.214:8000"; //Login Service -String kAuthUrl = "172.27.16.215:80"; +String kAuthUrl = "172.27.16.214:8000"; String kAuthLogin = "/api/auth/login/"; +// String kAuthLogin = "/accounts/login"; //Profile Service String kProfile = "/api/profile/"; @@ -20,6 +21,7 @@ String kComplaintRemove = "/complaint/api/removecomplain/"; //Dashboard String kDashboard = "/api/dashboard/"; +String kNotification = "/api/notification/"; String kNotificationRead = "/api/notification/read/"; //Gymkhana diff --git a/lib/main.dart b/lib/main.dart index 9ca81ff8..3f9e9eab 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,15 +1,18 @@ import 'package:flutter/material.dart'; import 'dart:async'; import 'package:fusion/screens/Academic/Add_Drop_Courses/add_drop_courses.dart'; -import 'package:fusion/screens/Complaint/ComplaintHistory/complain_history.dart'; -import 'package:fusion/screens/Complaint/Feedback/feedback.dart'; -import 'package:fusion/screens/Complaint/LodgeComplaint/lodge_complaint.dart'; +// import 'package:fusion/screens/Complaint/ComplaintHistory/complain_history.dart'; +// import 'package:fusion/screens/Complaint/Feedback/feedback.dart'; +// import 'package:fusion/screens/Complaint/LodgeComplaint/lodge_complaint.dart'; import 'package:fusion/screens/Establishment/establishment_home_page.dart'; import 'package:fusion/screens/Library/Book_Search.dart'; -import 'package:fusion/screens/Library/dues.dart'; +// import 'package:fusion/screens/Library/dues.dart'; import 'package:fusion/screens/Library/issued_items.dart'; import 'package:fusion/screens/Library/lib_home_screen.dart'; +import 'package:fusion/screens/LoginandDashboard/DashboardComponents/news.dart'; import 'package:fusion/screens/LoginandDashboard/dashboard.dart'; +import 'package:fusion/screens/LoginandDashboard/DashboardComponents/notify.dart'; +import 'package:fusion/screens/LoginandDashboard/DashboardComponents/announcement.dart'; import 'package:fusion/screens/LoginandDashboard/login_page.dart'; import 'package:fusion/screens/Academic/academic_home_page.dart'; import 'package:fusion/screens/Academic/Current_Semester/current_semester_home_page.dart'; @@ -25,7 +28,7 @@ import 'package:fusion/screens/Gymkhana/Polls.dart'; import 'package:fusion/screens/Gymkhana/Apply.dart'; import 'package:fusion/screens/Gymkhana/Record.dart'; import 'package:fusion/screens/Gymkhana/Club.dart'; -import 'package:fusion/screens/Complaint/complaint.dart'; +// import 'package:fusion/screens/Complaint/complaint.dart'; import 'package:fusion/screens/Profile/profile.dart'; import 'package:fusion/screens/Programme_Curriculum/Batches/batches.dart'; import 'package:fusion/screens/Programme_Curriculum/Courses/courses.dart'; @@ -42,6 +45,11 @@ import 'package:fusion/screens/Healthcenter/viewschedule.dart'; import 'package:fusion/screens/Healthcenter/history.dart'; import 'package:fusion/screens/Healthcenter/HealthCenter.dart'; import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/screens/Hostel/caretaker/hostel_caretaker.dart'; +import 'package:fusion/screens/Hostel/student/hostel_student.dart'; +import 'package:fusion/screens/Hostel/warden/hostel_warden.dart'; +import 'package:fusion/screens/Hostel/superadmin/hostel_admin.dart'; + void main() { WidgetsFlutterBinding.ensureInitialized(); @@ -60,9 +68,13 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { MediaQueryData windowData = - MediaQueryData.fromWindow(WidgetsBinding.instance.window); + + + MediaQueryData.fromWindow(WidgetsBinding.instance.window); + windowData = windowData.copyWith( - textScaleFactor: 1, + + textScaler: TextScaler.linear(1), ); return MediaQuery( data: windowData, @@ -71,16 +83,19 @@ class MyApp extends StatelessWidget { title: 'Fusion', debugShowCheckedModeBanner: false, theme: ThemeData( - // primarySwatch: Colors.blueGrey, + // primarySwatch: Colors.blueGrey, // colorSchemeSeed: Color(0xFF2085D0), colorSchemeSeed: Color(0xFFF36C35), - fontFamily: 'Nunito', + fontFamily: 'Nunito', useMaterial3: true, ), initialRoute: '/landing', routes: { '/landing': (context) => LandingPage(), '/login_page': (context) => LoginPage(), + '/notification':(context)=>Notify(), + '/news':(context)=>News(), + '/announcement':(context)=>Announcement(), '/dashboard': (context) => Dashboard(), '/academic_home_page': (context) => AcademicHomePage( ModalRoute.of(context)!.settings.arguments.toString()), @@ -113,13 +128,13 @@ class MyApp extends StatelessWidget { '/library_homepage': (context) => LibraryHomeScreen(), '/library_homepage/book_search': (context) => BookSearch(), '/library_homepage/issued_items': (context) => IssuedItems(), - '/library_homepage/dues': (context) => LibraryDues(), - '/complaint': (context) => - Complaint(ModalRoute.of(context)!.settings.arguments.toString()), - '/complaint/lodge_complaint': (context) => LodgeComplaint( - ModalRoute.of(context)!.settings.arguments.toString()), - '/complaint/complaint_history': (context) => ComplainHistory(), - '/complaint/feedback': (context) => ComplaintFeedBack(), + // '/library_homepage/dues': (context) => LibraryDues(), + // '/complaint': (context) => + // Complaint(ModalRoute.of(context)!.settings.arguments.toString()), + // '/complaint/lodge_complaint': (context) => LodgeComplaint( + // ModalRoute.of(context)!.settings.arguments.toString()), + // '/complaint/complaint_history': (context) => ComplainHistory(), + // '/complaint/feedback': (context) => ComplaintFeedBack(), '/profile': (context) => Profile(), '/health_center': (context) => HealthCenterMod( ModalRoute.of(context)!.settings.arguments.toString()), @@ -127,8 +142,12 @@ class MyApp extends StatelessWidget { '/health_center/feedback': (context) => FeedBack(), '/health_center/viewschedule': (context) => ViewSchedule(), '/health_center/history': (context) => History(), + '/caretaker/hostel_caretaker': (context) => Hostelcaretaker(), + '/warden/hostel_warden': (context) => Hostelwarden(), + '/student/hostel_student': (context) => Hostelstudent(), + '/superadmin/hostel_admin': (context) => Hosteladmin(), }, ), ); } -} +} \ No newline at end of file diff --git a/lib/screens/Complaint/ComplaintHistory/complain_history.dart b/lib/screens/Academic/Complaint/ComplaintHistory/complain_history.dart similarity index 100% rename from lib/screens/Complaint/ComplaintHistory/complain_history.dart rename to lib/screens/Academic/Complaint/ComplaintHistory/complain_history.dart diff --git a/lib/screens/Complaint/ComplaintHistory/complaints_card.dart b/lib/screens/Academic/Complaint/ComplaintHistory/complaints_card.dart similarity index 100% rename from lib/screens/Complaint/ComplaintHistory/complaints_card.dart rename to lib/screens/Academic/Complaint/ComplaintHistory/complaints_card.dart diff --git a/lib/screens/Complaint/ComplaintHistory/declined_complaints.dart b/lib/screens/Academic/Complaint/ComplaintHistory/declined_complaints.dart similarity index 100% rename from lib/screens/Complaint/ComplaintHistory/declined_complaints.dart rename to lib/screens/Academic/Complaint/ComplaintHistory/declined_complaints.dart diff --git a/lib/screens/Complaint/ComplaintHistory/get_complaint_by_id.dart b/lib/screens/Academic/Complaint/ComplaintHistory/get_complaint_by_id.dart similarity index 100% rename from lib/screens/Complaint/ComplaintHistory/get_complaint_by_id.dart rename to lib/screens/Academic/Complaint/ComplaintHistory/get_complaint_by_id.dart diff --git a/lib/screens/Complaint/ComplaintHistory/on-hold_complaints.dart b/lib/screens/Academic/Complaint/ComplaintHistory/on-hold_complaints.dart similarity index 100% rename from lib/screens/Complaint/ComplaintHistory/on-hold_complaints.dart rename to lib/screens/Academic/Complaint/ComplaintHistory/on-hold_complaints.dart diff --git a/lib/screens/Complaint/ComplaintHistory/pending_complaints.dart b/lib/screens/Academic/Complaint/ComplaintHistory/pending_complaints.dart similarity index 100% rename from lib/screens/Complaint/ComplaintHistory/pending_complaints.dart rename to lib/screens/Academic/Complaint/ComplaintHistory/pending_complaints.dart diff --git a/lib/screens/Complaint/ComplaintHistory/resolved_complaints.dart b/lib/screens/Academic/Complaint/ComplaintHistory/resolved_complaints.dart similarity index 100% rename from lib/screens/Complaint/ComplaintHistory/resolved_complaints.dart rename to lib/screens/Academic/Complaint/ComplaintHistory/resolved_complaints.dart diff --git a/lib/screens/Complaint/ComplaintHistory/update_complaint.dart b/lib/screens/Academic/Complaint/ComplaintHistory/update_complaint.dart similarity index 99% rename from lib/screens/Complaint/ComplaintHistory/update_complaint.dart rename to lib/screens/Academic/Complaint/ComplaintHistory/update_complaint.dart index 8ea7af87..917de43c 100644 --- a/lib/screens/Complaint/ComplaintHistory/update_complaint.dart +++ b/lib/screens/Academic/Complaint/ComplaintHistory/update_complaint.dart @@ -172,8 +172,8 @@ class _UpdateComplaintState extends State { widget.id!, complaint_date, finishedDate, - complaint_type!, - location!, + complaint_type, + location, specific_location!, details!, status, diff --git a/lib/screens/Complaint/Constants/constants.dart b/lib/screens/Academic/Complaint/Constants/constants.dart similarity index 100% rename from lib/screens/Complaint/Constants/constants.dart rename to lib/screens/Academic/Complaint/Constants/constants.dart diff --git a/lib/screens/Complaint/Feedback/feedback.dart b/lib/screens/Academic/Complaint/Feedback/feedback.dart similarity index 100% rename from lib/screens/Complaint/Feedback/feedback.dart rename to lib/screens/Academic/Complaint/Feedback/feedback.dart diff --git a/lib/screens/Complaint/LodgeComplaint/lodge_complaint.dart b/lib/screens/Academic/Complaint/LodgeComplaint/lodge_complaint.dart similarity index 100% rename from lib/screens/Complaint/LodgeComplaint/lodge_complaint.dart rename to lib/screens/Academic/Complaint/LodgeComplaint/lodge_complaint.dart diff --git a/lib/screens/Complaint/complaint.dart b/lib/screens/Academic/Complaint/complaint.dart similarity index 98% rename from lib/screens/Complaint/complaint.dart rename to lib/screens/Academic/Complaint/complaint.dart index f1b5ed77..a7fc09ed 100644 --- a/lib/screens/Complaint/complaint.dart +++ b/lib/screens/Academic/Complaint/complaint.dart @@ -4,12 +4,9 @@ import 'package:fusion/Components/appBar.dart'; import 'package:fusion/models/profile.dart'; import 'package:fusion/services/profile_service.dart'; import 'package:http/http.dart'; -import 'ComplaintHistory/complain_history.dart'; import 'package:flutter/material.dart'; import 'package:fusion/Components/side_drawer.dart'; import 'dart:ui'; -import 'LodgeComplaint/lodge_complaint.dart'; -import 'Feedback/feedback.dart'; import 'package:provider/provider.dart'; class Complaint extends StatefulWidget { diff --git a/lib/screens/Academic/Registration/final_registration.dart b/lib/screens/Academic/Registration/final_registration.dart index 4ca4b245..dbcdae07 100644 --- a/lib/screens/Academic/Registration/final_registration.dart +++ b/lib/screens/Academic/Registration/final_registration.dart @@ -1,74 +1,74 @@ -import 'package:flutter/material.dart'; - -class FinalRegistration extends StatefulWidget { - final data; - const FinalRegistration({Key? key, this.data}) : super(key: key); - @override - _FinalRegistrationState createState() => _FinalRegistrationState(); -} - -class _FinalRegistrationState extends State { - getRows(List? map) { - List list = []; - map?.forEach((element) { - element.length > 0 - ? list.add(DataRow(cells: [ - DataCell(Text(element[0]['course_id']['id'].toString())), - DataCell(Text(element[0]['course_code'].toString())), - DataCell(Text(element[0]['course_id']['course_name'].toString())), - DataCell(Text(element[0]['credits'].toString())), - DataCell(Text(element[0]['sem'].toString())) - ])) - : true; - }); - return list; - } - - @override - Widget build(BuildContext context) { - List? finalData = widget.data?.final_registration_choices; - return Container( - child: Column( - children: [ - SizedBox(height: 10), - Text("Final Choices Of Courses"), - if (finalData != null && finalData[0].length > 0) - SingleChildScrollView( - scrollDirection: Axis.vertical, - child: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: DataTable(columns: [ - DataColumn( - label: Text("Course ID"), - numeric: false, - ), - DataColumn( - label: Text("Course Code"), - numeric: false, - ), - DataColumn( - label: Text("Course Name"), - numeric: false, - ), - DataColumn( - label: Text("Credits"), - numeric: false, - ), - DataColumn( - label: Text("Semester"), - numeric: false, - ) - ], rows: getRows(finalData)), - ), - ), - if (finalData == null || finalData[0].length == 0) - Expanded( - child: Center( - child: Text( - 'Final Registration Date is yet to come', - style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold), - ))) - ], - )); - } -} +// import 'package:flutter/material.dart'; +// +// class FinalRegistration extends StatefulWidget { +// final data; +// const FinalRegistration({Key? key, this.data}) : super(key: key); +// @override +// _FinalRegistrationState createState() => _FinalRegistrationState(); +// } +// +// class _FinalRegistrationState extends State { +// getRows(List? map) { +// List list = []; +// map?.forEach((element) { +// element.length > 0 +// ? list.add(DataRow(cells: [ +// DataCell(Text(element[0]['course_id']['id'].toString())), +// DataCell(Text(element[0]['course_code'].toString())), +// DataCell(Text(element[0]['course_id']['course_name'].toString())), +// DataCell(Text(element[0]['credits'].toString())), +// DataCell(Text(element[0]['sem'].toString())) +// ])) +// : true; +// }); +// return list; +// } +// +// @override +// Widget build(BuildContext context) { +// List? finalData = widget.data?.final_registration_choices; +// return Container( +// child: Column( +// children: [ +// SizedBox(height: 10), +// Text("Final Choices Of Courses"), +// if (finalData[0].length > 0) +// SingleChildScrollView( +// scrollDirection: Axis.vertical, +// child: SingleChildScrollView( +// scrollDirection: Axis.horizontal, +// child: DataTable(columns: [ +// DataColumn( +// label: Text("Course ID"), +// numeric: false, +// ), +// DataColumn( +// label: Text("Course Code"), +// numeric: false, +// ), +// DataColumn( +// label: Text("Course Name"), +// numeric: false, +// ), +// DataColumn( +// label: Text("Credits"), +// numeric: false, +// ), +// DataColumn( +// label: Text("Semester"), +// numeric: false, +// ) +// ], rows: getRows(finalData)), +// ), +// ), +// if (finalData[0].length == 0) +// Expanded( +// child: Center( +// child: Text( +// 'Final Registration Date is yet to come', +// style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold), +// ))) +// ], +// )); +// } +// } diff --git a/lib/screens/Academic/Registration/registration_home_page.dart b/lib/screens/Academic/Registration/registration_home_page.dart index 24dfac50..f6729e1e 100644 --- a/lib/screens/Academic/Registration/registration_home_page.dart +++ b/lib/screens/Academic/Registration/registration_home_page.dart @@ -73,7 +73,7 @@ class _RegistrationHomePageState extends State { children: [ Courses(data: data.currently_registered), PreRegistration(), - FinalRegistration(data: data) + // FinalRegistration(data: data) // FinalRegistration(data: data) ], ), diff --git a/lib/screens/Gymkhana/Record.dart b/lib/screens/Gymkhana/Record.dart index adcfacf2..0a5f8f05 100644 --- a/lib/screens/Gymkhana/Record.dart +++ b/lib/screens/Gymkhana/Record.dart @@ -123,10 +123,10 @@ class Srecord { late String Category; Srecord( - {this.Name: "default-name", - this.Rollno: "000000", - this.Club: "default-club", - this.Category: "default-category"}); + {this.Name = "default-name", + this.Rollno = "000000", + this.Club = "default-club", + this.Category = "default-category"}); } var Srecords = [ diff --git a/lib/screens/Hostel/caretaker/complaintregister.dart b/lib/screens/Hostel/caretaker/complaintregister.dart new file mode 100644 index 00000000..d1672a61 --- /dev/null +++ b/lib/screens/Hostel/caretaker/complaintregister.dart @@ -0,0 +1,97 @@ + +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:fusion/Components/side_drawer.dart'; + +class Complaintregister extends StatelessWidget { + const Complaintregister({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: SideDrawer(), + appBar: AppBar( + title: const Text('Complaint Register'), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + body: Padding( + padding: const EdgeInsets.fromLTRB(20, 30, 20, 0), // Add padding to the body + child: GridView.count( + crossAxisCount: 2, + childAspectRatio: 1.5, // Adjust the aspect ratio to make the cards horizontally rectangular + children: List.generate( + roomNumbers.length, + (index) => InkWell( + onTap: () { + // Navigate to a new screen when the card is tapped + Navigator.push( + context, + MaterialPageRoute(builder: (context) => DetailScreen(roomNumber: roomNumbers[index])), + ); + }, + child: Card( + color: Color.fromARGB(255, 245, 103, 47), + child: Padding( + padding: const EdgeInsets.all(8.0), // Add padding to make the cards compact + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + roomNumbers[index], + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.white, // Set the text color to white + ), + ), + Icon(Icons.arrow_forward, color: Colors.white), // Set the arrow color to white + ], + ), + ), + ), + ), + ), + ), + ), + ), + ); + } +} + +class DetailScreen extends StatelessWidget { + final String roomNumber; + + const DetailScreen({Key? key, required this.roomNumber}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Room $roomNumber Details'), + ), + body: Center( + child: Text( + 'Room $roomNumber Details', + style: TextStyle( + color: Colors.white, // Set the text color to white + ), + ), + ), + ); + } +} + +List roomNumbers = [ + '101', + '102', + '103', + '104', + '105', + '106', + '107', + '108', + '109', + '110', +]; \ No newline at end of file diff --git a/lib/screens/Hostel/caretaker/guestroom.dart b/lib/screens/Hostel/caretaker/guestroom.dart new file mode 100644 index 00000000..a070486c --- /dev/null +++ b/lib/screens/Hostel/caretaker/guestroom.dart @@ -0,0 +1,227 @@ + +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:fusion/Components/side_drawer.dart'; +class Guestroom extends StatelessWidget { + const Guestroom({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: SideDrawer(), + appBar: AppBar( + title: const Text('Guest Room'), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + body: Container( + child: Padding( + padding: const EdgeInsets.fromLTRB(20, 40, 20, 20), + child: Container( + width: double.infinity, // Prevent horizontal scrolling + child: Expanded( + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + alignment: Alignment.topLeft, + child: const Text( + 'Status', + style: TextStyle( + fontSize: 23, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.left, + ), + ), + Container( + width: MediaQuery.of(context).size.width - 40, + height: 250, + decoration: BoxDecoration( + color: Color.fromARGB( + 255, 245, 103, 47), // Change to orange color + borderRadius: BorderRadius.circular(8), + ), + padding: const EdgeInsets.all(8), + margin: const EdgeInsets.symmetric(vertical: 4), + child: const Text( + '', + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ), + Container( + alignment: Alignment.topLeft, + padding: const EdgeInsets.only(top: 30, bottom: 10), + child: const Text( + 'Guest Room 1', + style: TextStyle( + fontSize: 23, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.left, + ), + ), + Container( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment + .center, // Align vertically center + children: [ + Column( + children: [ + Container( + width: MediaQuery.of(context).size.width - 40, + height: 70, // Set the height to 30px + padding: const EdgeInsets.only(top: 10, bottom: 10), + child: ElevatedButton( + onPressed: () { + // View Documents + }, + child: const Text('View Documents', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: Color.fromARGB(255, 245, 103, 47), // Add background color + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), // Set border radius to 5px + ), + + ), + ), + ), + Container( + child: Row( + children: [ + ElevatedButton.icon( + onPressed: () { + // Approve + }, + icon: Icon(Icons.check, color: Colors.white), + label: const Text('Approve', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.green, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), // Set border radius to 5px + ), + ), + ), + SizedBox(width: 10), + ElevatedButton.icon( + onPressed: () { + // Cancel + }, + icon: Icon(Icons.close, color: Colors.white), + label: const Text('Cancel', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), // Set border radius to 5px + ), + ), + ), + ], + ), + ), + ], + ), + ], + ), + ), + ), + Container( + alignment: Alignment.topLeft, + padding: const EdgeInsets.only(top: 30, bottom: 10), + child: const Text( + 'Guest Room 2', + style: TextStyle( + fontSize: 23, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.left, + ), + ), + Container( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment + .center, // Align vertically center + children: [ + Column( + children: [ + Container( + width: MediaQuery.of(context).size.width - 40, + height: 70, // Set the height to 30px + padding: const EdgeInsets.only(top: 10, bottom: 10), + child: ElevatedButton( + onPressed: () { + // View Documents + }, + child: const Text('View Documents', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: Color.fromARGB(255, 245, 103, 47), // Add background color + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), // Set border radius to 5px + ), + + ), + ), + ), + Container( + child: Row( + children: [ + ElevatedButton.icon( + onPressed: () { + // Approve + }, + icon: Icon(Icons.check, color: Colors.white), + label: const Text('Approve', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.green, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), // Set border radius to 5px + ), + ), + ), + SizedBox(width: 10), + ElevatedButton.icon( + onPressed: () { + // Cancel + }, + icon: Icon(Icons.close, color: Colors.white), + label: const Text('Cancel', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), // Set border radius to 5px + ), + ), + ), + ], + ), + ), + ], + ), + ], + ), + ), + ), + ], + ), + ), + ], + ), + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/screens/Hostel/caretaker/hostel_caretaker.dart b/lib/screens/Hostel/caretaker/hostel_caretaker.dart new file mode 100644 index 00000000..0a26fc2f --- /dev/null +++ b/lib/screens/Hostel/caretaker/hostel_caretaker.dart @@ -0,0 +1,365 @@ +import 'package:flutter/material.dart'; +import 'package:fusion/screens/Hostel/caretaker/guestroom.dart'; +import 'package:fusion/screens/Hostel/caretaker/inventory.dart'; +import 'package:fusion/screens/Hostel/caretaker/managefines.dart'; +import 'package:fusion/screens/Hostel/caretaker/managerooms.dart'; +import 'package:fusion/screens/Hostel/caretaker/leaveapplication.dart'; +import 'package:fusion/screens/Hostel/caretaker/staffinfo.dart'; +import 'package:fusion/screens/Hostel/caretaker/managestudent.dart'; +import 'package:fusion/screens/Hostel/caretaker/noticeboard.dart'; +import 'package:fusion/screens/Hostel/caretaker/report.dart'; +import 'package:fusion/screens/Hostel/caretaker/complaintregister.dart'; + +import 'package:fusion/Components/appBar2.dart'; +import 'package:fusion/Components/side_drawer2.dart'; +import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/services/storage_service.dart'; +import 'package:fusion/Components/bottom_navigation_bar.dart'; + +class Hostelcaretaker extends StatefulWidget { + const Hostelcaretaker({Key? key}) : super(key: key); + @override + _HostelcaretakerState createState() => _HostelcaretakerState(); +} + +class _HostelcaretakerState extends State { + late String curr_desig; + + @override + void initState() { + super.initState(); + var service = locator(); + curr_desig = service.getFromDisk("Current_designation") ?? ""; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CustomAppBar( + curr_desig: curr_desig, + headerTitle: "Central Mess", + onDesignationChanged: (newValue) { + setState(() { + curr_desig = newValue; + }); + }, + ), + drawer: SideDrawer(curr_desig: curr_desig), + bottomNavigationBar: MyBottomNavigationBar(), + body: Container( + padding: const EdgeInsets.all(20.0), + child: Container( + child: GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + childAspectRatio: 1.0, + mainAxisSpacing: 5.0, + crossAxisSpacing: 5.0, + ), + children: [ + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Guestroom()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.add_home, + color: Colors.white, + size: 30, + ), + Text( + 'Guest Room', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Staffinfo()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.person, + color: Colors.white, + size: 30, + ), + Text( + 'Staff Info', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Managerooms()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.home, + color: Colors.white, + size: 30, + ), + Text( + 'Manage Rooms', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Managefines()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.monetization_on, + color: Colors.white, + size: 30, + ), + Text( + 'Manage Fines', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Report()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.report, + color: Colors.white, + size: 30, + ), + Text( + 'Report', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => Leaveapplication()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.card_travel, + color: Colors.white, + size: 30, + ), + Text( + 'Leave', + style: TextStyle(color: Colors.white, fontSize: 15), + ), + Text( + 'Application', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => Complaintregister()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.report_problem_rounded, + color: Colors.white, + size: 30, + ), + Text( + 'Complaint', + style: TextStyle(color: Colors.white, fontSize: 15), + ), + Text( + 'Register', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Managestudent()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.school, + color: Colors.white, + size: 30, + ), + Text( + 'Manage', + style: TextStyle(color: Colors.white, fontSize: 15), + ), + Text( + 'Student', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Noticeboard()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.dashboard, + color: Colors.white, + size: 30, + ), + Text( + 'Notice Board', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Inventory()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.inventory, + color: Colors.white, + size: 30, + ), + Text( + 'Inventory', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + ]), + ), + ), + ); + } +} diff --git a/lib/screens/Hostel/caretaker/inventory.dart b/lib/screens/Hostel/caretaker/inventory.dart new file mode 100644 index 00000000..8d09770f --- /dev/null +++ b/lib/screens/Hostel/caretaker/inventory.dart @@ -0,0 +1,72 @@ + +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:fusion/Components/side_drawer.dart'; + +class Inventory extends StatelessWidget { + const Inventory({ Key? key }) : super(key: key); + + @override + Widget build(BuildContext context){ + return Scaffold( + drawer: SideDrawer(), + appBar: AppBar( + title: const Text('Inventory'), + backgroundColor: Color.fromARGB(255, 245, 103, 47), // Set the background color to orange + foregroundColor: Colors.white, + ), + body: Padding( + padding: const EdgeInsets.only(top: 30, left: 20, right: 20, bottom: 30), + child: Column( + children: [ + Text( + 'Inventory Amount: \$1000', // Replace with actual inventory amount + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold, color: Color.fromARGB(255, 245, 103, 47)), + ), + SizedBox(height: 16), + Text( + 'Expense History:', // Replace with actual expense history + style: TextStyle(fontSize: 18), + ), + Expanded( + child: ListView( + children: [ + ListTile( + title: Text('Expense 1'), // Replace with actual expense details + ), + ListTile( + title: Text('Expense 2'), // Replace with actual expense details + ), + // Add more ListTiles for additional expenses + ], + ), + ), + Padding( + padding: const EdgeInsets.only(top: 10), + child: ElevatedButton( + onPressed: () { + // Add logic to create a new expense + }, + style: ElevatedButton.styleFrom( + foregroundColor: Colors.white, + backgroundColor: Color.fromARGB(255, 245, 103, 47), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), + side: BorderSide( + color: Color.fromARGB(255, 245, 103, 47), + width: 2, + ), + ), + ), + child: Text( + 'Create New Expense', + style: TextStyle(fontWeight: FontWeight.bold), + ), + ), + ), + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/screens/Hostel/caretaker/leaveapplication.dart b/lib/screens/Hostel/caretaker/leaveapplication.dart new file mode 100644 index 00000000..e5849cc1 --- /dev/null +++ b/lib/screens/Hostel/caretaker/leaveapplication.dart @@ -0,0 +1,228 @@ + +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:fusion/Components/side_drawer.dart'; + +class Leaveapplication extends StatelessWidget { + const Leaveapplication({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: SideDrawer(), + appBar: AppBar( + title: const Text('Leave Application'), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + body: Container( + child: Padding( + padding: const EdgeInsets.fromLTRB(20, 40, 20, 20), + child: Container( + width: double.infinity, // Prevent horizontal scrolling + child: Expanded( + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + alignment: Alignment.topLeft, + child: const Text( + 'Status', + style: TextStyle( + fontSize: 23, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.left, + ), + ), + Container( + width: MediaQuery.of(context).size.width - 40, + height: 250, + decoration: BoxDecoration( + color: Color.fromARGB( + 255, 245, 103, 47), // Change to orange color + borderRadius: BorderRadius.circular(8), + ), + padding: const EdgeInsets.all(8), + margin: const EdgeInsets.symmetric(vertical: 4), + child: const Text( + '', + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ), + Container( + alignment: Alignment.topLeft, + padding: const EdgeInsets.only(top: 30, bottom: 10), + child: const Text( + '21bcs198', + style: TextStyle( + fontSize: 23, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.left, + ), + ), + Container( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment + .center, // Align vertically center + children: [ + Column( + children: [ + Container( + width: MediaQuery.of(context).size.width - 40, + height: 70, // Set the height to 30px + padding: const EdgeInsets.only(top: 10, bottom: 10), + child: ElevatedButton( + onPressed: () { + // Leave Form + }, + child: const Text('Leave Form', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: Color.fromARGB(255, 245, 103, 47), // Add background color + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), // Set border radius to 5px + ), + + ), + ), + ), + Container( + child: Row( + children: [ + ElevatedButton.icon( + onPressed: () { + // Approve + }, + icon: Icon(Icons.check, color: Colors.white), + label: const Text('Approve', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.green, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), // Set border radius to 5px + ), + ), + ), + SizedBox(width: 10), + ElevatedButton.icon( + onPressed: () { + // Cancel + }, + icon: Icon(Icons.close, color: Colors.white), + label: const Text('Cancel', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), // Set border radius to 5px + ), + ), + ), + ], + ), + ), + ], + ), + ], + ), + ), + ), + Container( + alignment: Alignment.topLeft, + padding: const EdgeInsets.only(top: 30, bottom: 10), + child: const Text( + '21bcs199', + style: TextStyle( + fontSize: 23, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.left, + ), + ), + Container( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment + .center, // Align vertically center + children: [ + Column( + children: [ + Container( + width: MediaQuery.of(context).size.width - 40, + height: 70, // Set the height to 30px + padding: const EdgeInsets.only(top: 10, bottom: 10), + child: ElevatedButton( + onPressed: () { + // Leave Form + }, + child: const Text('Leave Form', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: Color.fromARGB(255, 245, 103, 47), // Add background color + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), // Set border radius to 5px + ), + + ), + ), + ), + Container( + child: Row( + children: [ + ElevatedButton.icon( + onPressed: () { + // Approve + }, + icon: Icon(Icons.check, color: Colors.white), + label: const Text('Approve', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.green, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), // Set border radius to 5px + ), + ), + ), + SizedBox(width: 10), + ElevatedButton.icon( + onPressed: () { + // Cancel + }, + icon: Icon(Icons.close, color: Colors.white), + label: const Text('Cancel', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), // Set border radius to 5px + ), + ), + ), + ], + ), + ), + ], + ), + ], + ), + ), + ), + ], + ), + ), + ], + ), + ), + ), + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/screens/Hostel/caretaker/managefines.dart b/lib/screens/Hostel/caretaker/managefines.dart new file mode 100644 index 00000000..3adad987 --- /dev/null +++ b/lib/screens/Hostel/caretaker/managefines.dart @@ -0,0 +1,441 @@ + +import 'dart:convert'; +import 'package:flutter/material.dart'; + +class Student { + late final String name; + late final String rollNo; + late final double fineAmount; + late final String reason; + late final String description; + + Student({ + required this.name, + required this.rollNo, + required this.fineAmount, + required this.reason, + required this.description, + }); +} + +class Managefines extends StatefulWidget { + const Managefines({Key? key}) : super(key: key); + + @override + _ManagefinesState createState() => _ManagefinesState(); +} + +class _ManagefinesState extends State { + List students = []; + List filteredStudents = []; + + @override + void initState() { + super.initState(); + _fetchFines(); + } + + Future _fetchFines() async { + // Simulating API call to fetch fines + final String finesData = ''' + [ + {"name": "Raju", "rollNo": "21bcs001", "fineAmount": 50.0, "reason": "Late Entry", "description": "Late by 15 minutes"}, + {"name": "Keerthan", "rollNo": "21bme002", "fineAmount": 30.0, "reason": "Hostel Damage", "description": "Broken window glass"}, + {"name": "Aravind", "rollNo": "21bcs003", "fineAmount": 20.0, "reason": "Misbehaviour", "description": "Argument with warden"} + ] + '''; + final List finesList = json.decode(finesData); + setState(() { + students = finesList.map((fine) => Student( + name: fine['name'], + rollNo: fine['rollNo'], + fineAmount: fine['fineAmount'], + reason: fine['reason'], + description: fine['description'], + )).toList(); + filteredStudents = List.from(students); + }); + } + + Future _editFineDetails(Student student) async { + // Display dialog to edit fine details + showDialog( + context: context, + builder: (BuildContext context) { + double fineAmount = student.fineAmount; + String reason = student.reason; + String description = student.description; + + return AlertDialog( + title: Text('Edit Fine Details'), + content: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextField( + decoration: InputDecoration(labelText: 'Fine Amount'), + controller: TextEditingController(text: fineAmount.toString()), + onChanged: (value) { + fineAmount = double.tryParse(value) ?? 0.0; + }, + ), + Text('Reason'), + DropdownButtonFormField( + value: reason, + onChanged: (value) { + setState(() { + reason = value!; + }); + }, + items: ['Late Entry', 'Hostel Damage', 'Misbehaviour', 'Others'] + .map>( + (String value) => DropdownMenuItem( + value: value, + child: Text(value), + ), + ) + .toList(), + ), + TextField( + decoration: InputDecoration(labelText: 'Description'), + controller: TextEditingController(text: description), + onChanged: (value) { + description = value; + }, + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + // Perform the edit operation here + setState(() { + // Find the index of the student in the list + int index = students.indexWhere((s) => s.rollNo == student.rollNo); + if (index != -1) { + // Update the properties of the student object directly + students[index].fineAmount = fineAmount; + students[index].reason = reason; + students[index].description = description; + // Update the filteredStudents list as well + int filteredIndex = filteredStudents.indexWhere((s) => s.rollNo == student.rollNo); + if (filteredIndex != -1) { + filteredStudents[filteredIndex].fineAmount = fineAmount; + filteredStudents[filteredIndex].reason = reason; + filteredStudents[filteredIndex].description = description; + } + } + }); + // Simulate PUT API call to update fine details + // _updateFineDetails(student); + Navigator.of(context).pop(); + }, + child: Text('Submit'), + ), + ], + ); + }, + ); + } + + + Future _deleteFineDetails(Student student) async { + // Show confirmation dialog before deleting the fine + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Confirm Deletion'), + content: Text('Are you sure you want to delete this fine?'), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + // Delete the fine + _deleteFine(student); + Navigator.of(context).pop(); + }, + child: Text('Delete'), + ), + ], + ); + }, + ); + } + + void _deleteFine(Student student) { + setState(() { + students.remove(student); + filteredStudents.remove(student); + }); + // Simulate DELETE API call to delete fine details + // _invokeDeleteAPI(student.rollNo); + } + + Future _showAddDialog() async { + String name = ''; + String rollNo = ''; + double fineAmount = 0.0; + String reason = 'Late Entry'; + String description = ''; + + await showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Add New Fine'), + content: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextField( + decoration: InputDecoration(labelText: 'Name'), + onChanged: (value) { + name = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Roll No'), + onChanged: (value) { + rollNo = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Fine Amount'), + onChanged: (value) { + fineAmount = double.tryParse(value) ?? 0.0; + }, + ), + DropdownButtonFormField( + value: reason, + onChanged: (value) { + setState(() { + reason = value!; + }); + }, + items: ['Late Entry', 'Hostel Damage', 'Misbehaviour', 'Others'] + .map>( + (String value) => DropdownMenuItem( + value: value, + child: Text(value), + ), + ) + .toList(), + ), + TextField( + decoration: InputDecoration(labelText: 'Description'), + onChanged: (value) { + description = value; + }, + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + // Perform the add operation here + setState(() { + final newFine = Student( + name: name, + rollNo: rollNo, + fineAmount: fineAmount, + reason: reason, + description: description, + ); + students.add(newFine); + filteredStudents.add(newFine); + }); + // Simulate POST API call to add new fine details + // _addFineDetails(name, rollNo, fineAmount, reason, description); + Navigator.of(context).pop(); + }, + child: Text('Submit'), + ), + ], + ); + }, + ); + } + + void _searchFines(String query) { + setState(() { + if (query.isNotEmpty) { + filteredStudents = students.where((student) { + return student.name.toLowerCase().contains(query.toLowerCase()) || + student.rollNo.toLowerCase().contains(query.toLowerCase()); + }).toList(); + } else { + filteredStudents = List.from(students); + } + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Manage Fines'), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + actions: [ + IconButton( + icon: Icon(Icons.search), + onPressed: () async { + final String? result = await showSearch( + context: context, + delegate: FineSearchDelegate(students: students), + ); + if (result != null) { + _searchFines(result); + } + }, + ), + ], + ), + body: SingleChildScrollView( + child: DataTable( + columns: const [ + DataColumn(label: Text('Name')), + DataColumn(label: Text('Roll No')), + DataColumn(label: Text('Fine Amount')), + DataColumn(label: Text('Reason')), + DataColumn(label: Text('Description')), + DataColumn(label: Text('Edit')), + DataColumn(label: Text('Remove')), + ], + rows: List.generate( + filteredStudents.length, + (index) => DataRow( + cells: [ + DataCell(Text(filteredStudents[index].name)), + DataCell(Text(filteredStudents[index].rollNo)), + DataCell(Text('₹${filteredStudents[index].fineAmount.toString()}')), + DataCell(Text(filteredStudents[index].reason)), + DataCell(Text(filteredStudents[index].description)), + DataCell( + IconButton( + icon: Icon(Icons.edit), + onPressed: () { + _editFineDetails(filteredStudents[index]); + }, + ), + + ), + DataCell( + IconButton( + icon: Icon(Icons.delete), + onPressed: () { + _deleteFineDetails(filteredStudents[index]); + }, + ), + ), + + ], + ), + ), + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: _showAddDialog, + child: Icon(Icons.add), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + ), + ); + } +} + +class FineSearchDelegate extends SearchDelegate { + final List students; + + FineSearchDelegate({required this.students}); + + @override + ThemeData appBarTheme(BuildContext context) { + final ThemeData theme = Theme.of(context); + return theme.copyWith( + appBarTheme: AppBarTheme( + backgroundColor: theme.scaffoldBackgroundColor, // Match with screen's UI theme + iconTheme: IconThemeData(color: theme.primaryColor), // Match with screen's UI theme + ), + ); + } + + @override + List buildActions(BuildContext context) { + return [ + + IconButton( + icon: Icon(Icons.clear), + onPressed: () { + query = ''; + }, + ), + ]; + } + + @override + Widget buildLeading(BuildContext context) { + return IconButton( + icon: Icon(Icons.arrow_back), + onPressed: () { + close(context, ''); // Pass an empty string as a result to indicate closing the search screen + }, + ); + } + + @override + Widget buildResults(BuildContext context) { + return _buildSearchResults(context); + } + + @override + Widget buildSuggestions(BuildContext context) { + return _buildSearchResults(context); + } + + Widget _buildSearchResults(BuildContext context) { + final List filteredStudents = students.where((student) { + final String lowercaseQuery = query.toLowerCase(); + return student.name.toLowerCase().contains(lowercaseQuery) || + student.rollNo.toLowerCase().contains(lowercaseQuery); + }).toList(); + return ListView.builder( + itemCount: filteredStudents.length, + itemBuilder: (context, index) { + return ListTile( + title: Text(filteredStudents[index].name), + subtitle: Text(filteredStudents[index].rollNo), + onTap: () { + close(context, filteredStudents[index].rollNo); + }, + ); + }, + ); + } + +} + +void main() { + runApp(MaterialApp( + home: Managefines(), + )); +} + diff --git a/lib/screens/Hostel/caretaker/managerooms.dart b/lib/screens/Hostel/caretaker/managerooms.dart new file mode 100644 index 00000000..e6ac8386 --- /dev/null +++ b/lib/screens/Hostel/caretaker/managerooms.dart @@ -0,0 +1,557 @@ + +import 'dart:convert'; +import 'package:flutter/material.dart'; + +class Room { + final int roomNumber; + final int capacity; + + late int currentOccupancy; + late String status; + List studentNames; + List studentRollNumbers; + + + Room({ + required this.roomNumber, + required this.capacity, + required this.currentOccupancy, + required this.status, + required this.studentNames, + + required this.studentRollNumbers, + + }); +} + +class Managerooms extends StatefulWidget { + const Managerooms({Key? key}) : super(key: key); + + @override + _ManageroomsState createState() => _ManageroomsState(); +} + +class _ManageroomsState extends State { + List rooms = []; + List filteredRooms = []; + + @override + void initState() { + super.initState(); + _fetchRoomDetails(); + } + + Future _fetchRoomDetails() async { + // Simulating GET API call to fetch room details + final String roomData = ''' + [ + {"roomNumber": 101, "capacity": 2, "currentOccupancy": 1, "status": "Partially Allotted", "studentNames": ["Raman"], "studentRollNumbers": ["21bcs200"]}, + {"roomNumber": 102, "capacity": 3, "currentOccupancy": 2, "status": "Partially Allotted", "studentNames": ["Naman", "Ramu"], "studentRollNumbers": ["22bme041", "22bsm045"]}, + {"roomNumber": 103, "capacity": 3, "currentOccupancy": 3, "status": "Fully Allotted", "studentNames": ["Surya", "Divyanshu", "Raju"], "studentRollNumbers": ["21bcs101", "21bcs102", "21bcs103"]}, + {"roomNumber": 104, "capacity": 4, "currentOccupancy": 0, "status": "Unallotted", "studentNames": [], "studentRollNumbers": []}, + {"roomNumber": 105, "capacity": 2, "currentOccupancy": 2, "status": "Fully Allotted", "studentNames": ["John", "Doe"], "studentRollNumbers": ["22bcs001", "22bcs002"]} + ] + '''; + final List roomList = json.decode(roomData); + setState(() { + rooms = roomList.map((room) => + Room( + roomNumber: room['roomNumber'] as int, + capacity: room['capacity'] as int, + currentOccupancy: room['currentOccupancy'] as int, + status: room['status'] as String, + studentNames: List.from( + room['studentNames'] as List), + studentRollNumbers: List.from( + room['studentRollNumbers'] as List), + )).toList(); + filteredRooms = List.from(rooms); + }); + } + + Future _editStudentDetails(Room room) async { + List updatedNames = List.from(room.studentNames); + List updatedRollNumbers = List.from(room.studentRollNumbers); + + await showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Edit Student Details'), + content: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + for (int i = 0; i < room.currentOccupancy; i++) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Student-${i + 1}:'), + TextField( + controller: TextEditingController( + text: room.studentNames[i]), + onChanged: (value) { + updatedNames[i] = value; + }, + ), + Text('Roll.No-${i + 1}:'), + TextField( + controller: TextEditingController( + text: room.studentRollNumbers[i]), + onChanged: (value) { + updatedRollNumbers[i] = value; + }, + ), + ], + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + bool valid = true; + for (int i = 0; i < updatedNames.length; i++) { + if ((updatedNames[i].isNotEmpty && + updatedRollNumbers[i].isEmpty) || + (updatedRollNumbers[i].isNotEmpty && + updatedNames[i].isEmpty)) { + valid = false; + break; + } + } + if (valid) { + setState(() { + room.studentNames = updatedNames.toList(); + room.studentRollNumbers = updatedRollNumbers.toList(); + room.currentOccupancy = room.studentNames.length; + room.status = room.currentOccupancy == room.capacity + ? "Fully Allotted" + : "Partially Allotted"; + }); + Navigator.of(context).pop(); + } else { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Error'), + content: Text( + 'Please fill in both Student and Roll.No fields for each student.'), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('OK'), + ), + ], + ); + }, + ); + } + }, + child: Text('Submit'), + ), + ], + ); + }, + ); + } + + Future _deleteStudentDetails(Room room) async { + List studentNames = List.from(room.studentNames); + List studentRollNumbers = List.from(room.studentRollNumbers); + + if (studentNames.isEmpty) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('No Students Found'), + content: Text('There are no students in this room to delete.'), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('OK'), + ), + ], + ); + }, + ); + return; + } + + String? selectedStudent; + await showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Select Student to Delete'), + content: Column( + mainAxisSize: MainAxisSize.min, + children: List.generate(studentNames.length, (index) { + return RadioListTile( + title: Text('${studentNames[index]} (${studentRollNumbers[index]})'), + value: studentNames[index], + groupValue: selectedStudent, + onChanged: (value) { + setState(() { + selectedStudent = value; + }); + }, + ); + }), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + if (selectedStudent != null) { + setState(() { + int index = room.studentNames.indexOf(selectedStudent!); + room.studentNames.removeAt(index); + room.studentRollNumbers.removeAt(index); + room.currentOccupancy--; + room.status = room.currentOccupancy == 0 + ? "Unallotted" + : "Partially Allotted"; + }); + Navigator.of(context).pop(); + } else { + // Handle the case when selectedStudent is null + print('No student selected to delete.'); + } + }, + child: Text('Delete'), + ), + ], + ); + }, + ); + } + + + Future _showAddDialog(Room room) async { + if (room.status == "Unallotted" || room.status == "Partially Allotted") { + String studentName = ''; + String studentRollNumber = ''; + + await showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Add Student'), + content: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + onChanged: (value) { + studentName = value; + }, + decoration: InputDecoration( + labelText: 'Student Name', + ), + ), + TextField( + onChanged: (value) { + studentRollNumber = value; + }, + decoration: InputDecoration( + labelText: 'Student Roll.No', + ), + ), + ], + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + setState(() { + room.studentNames.add(studentName); + room.studentRollNumbers.add(studentRollNumber); + room.currentOccupancy++; + room.status = room.currentOccupancy == room.capacity ? "Fully Allotted" : "Partially Allotted"; + }); + Navigator.of(context).pop(); + }, + child: Text('Add'), + ), + ], + ); + }, + ); + } else { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Alert'), + content: Text('You can only add students to "Unallotted" or "Partially Allotted" rooms only.'), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('OK'), + ), + ], + ); + }, + ); + } + } + + void _searchRooms(String query) { + setState(() { + filteredRooms = rooms.where((room) { + final roomNumberMatches = room.roomNumber.toString().contains(query); + final statusMatches = room.status.toLowerCase().contains(query.toLowerCase()); + final nameMatches = room.studentNames.any((name) => name.toLowerCase().contains(query.toLowerCase())); + final rollMatches = room.studentRollNumbers.any((roll) => roll.toLowerCase().contains(query.toLowerCase())); + return roomNumberMatches || statusMatches || nameMatches || rollMatches; + }).toList(); + + // Sort the filtered rooms based on relevance to the search query + filteredRooms.sort((a, b) { + final aRoomNumberMatches = a.roomNumber.toString().contains(query); + final bRoomNumberMatches = b.roomNumber.toString().contains(query); + final aStatusMatches = a.status.toLowerCase().contains(query.toLowerCase()); + final bStatusMatches = b.status.toLowerCase().contains(query.toLowerCase()); + final aNameMatches = a.studentNames.any((name) => name.toLowerCase().contains(query.toLowerCase())); + final bNameMatches = b.studentNames.any((name) => name.toLowerCase().contains(query.toLowerCase())); + final aRollMatches = a.studentRollNumbers.any((roll) => roll.toLowerCase().contains(query.toLowerCase())); + final bRollMatches = b.studentRollNumbers.any((roll) => roll.toLowerCase().contains(query.toLowerCase())); + + if (aRoomNumberMatches && !bRoomNumberMatches) { + return -1; + } else if (!aRoomNumberMatches && bRoomNumberMatches) { + return 1; + } else if (aStatusMatches && !bStatusMatches) { + return -1; + } else if (!aStatusMatches && bStatusMatches) { + return 1; + } else if (aNameMatches && !bNameMatches) { + return -1; + } else if (!aNameMatches && bNameMatches) { + return 1; + } else if (aRollMatches && !bRollMatches) { + return -1; + } else if (!aRollMatches && bRollMatches) { + return 1; + } else { + return 0; + } + }); + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Manage Rooms'), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + actions: [ + IconButton( + icon: Icon(Icons.search), + onPressed: () async { + final String? result = await showSearch( + context: context, + delegate: RoomSearchDelegate(rooms: rooms), + ); + if (result != null) { + _searchRooms(result); + } + }, + ), + ], + ), + body: SingleChildScrollView( + child: DataTable( + columns: const [ + DataColumn(label: Text('Room No')), + DataColumn(label: Text('Room Capacity')), + DataColumn(label: Text('Current Occupancy')), + DataColumn(label: Text('Current Status')), + DataColumn(label: Text('Student Names')), + DataColumn(label: Text('Roll.No of Students')), + DataColumn(label: Text('Edit')), + DataColumn(label: Text('Add')), + DataColumn(label: Text('Delete')), + ], + rows: filteredRooms.map((room) { + return DataRow(cells: [ + DataCell(Text(room.roomNumber.toString())), + DataCell(Text(room.capacity.toString())), + DataCell(Text(room.currentOccupancy.toString())), + DataCell(Text(room.status)), + DataCell(Text(room.studentNames.join(', '))), + DataCell(Text(room.studentRollNumbers.join(', '))), + DataCell( + IconButton( + icon: Icon(Icons.edit), + onPressed: () { + if (room.status != "Unallotted") { + _editStudentDetails(room); + } else { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Alert'), + content: Text('You can edit students in "Partially Allotted" or "Fully Allotted" rooms only.'), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('OK'), + ), + ], + ); + }, + ); + } + }, + ), + ), + DataCell( + IconButton( + icon: Icon(Icons.add), + onPressed: () { + _showAddDialog(room); + }, + ), + ), + DataCell( + IconButton( + icon: Icon(Icons.delete), + onPressed: () { + _deleteStudentDetails(room); + }, + ), + ), + ]); + + }).toList(), + ), + ), + ); + } +} + + +class RoomSearchDelegate extends SearchDelegate { + final List rooms; + + RoomSearchDelegate({required this.rooms}); + + @override + ThemeData appBarTheme(BuildContext context) { + final ThemeData theme = Theme.of(context); + return theme.copyWith( + appBarTheme: AppBarTheme( + backgroundColor: theme.scaffoldBackgroundColor, // Match with screen's UI theme + iconTheme: IconThemeData(color: theme.primaryColor), // Match with screen's UI theme + ), + ); + } + + @override + + + List buildActions(BuildContext context) { + return [ + IconButton( + icon: Icon(Icons.clear), + onPressed: () { + query = ''; + }, + ), + ]; + } + + @override + Widget buildLeading(BuildContext context) { + return IconButton( + icon: Icon(Icons.arrow_back), + onPressed: () { + close(context, null); + }, + ); + } + + @override + Widget buildResults(BuildContext context) { + return _buildSearchResults(context); + } + + @override + Widget buildSuggestions(BuildContext context) { + return _buildSearchResults(context); + } + + Widget _buildSearchResults(BuildContext context) { + + final List suggestionList = query.isEmpty + ? rooms + : rooms.where((room) { + final roomNumberMatches = room.roomNumber.toString().contains(query); + final statusMatches = room.status.toLowerCase().contains( + query.toLowerCase()); + final nameMatches = room.studentNames.any((name) => + name.toLowerCase().contains(query.toLowerCase())); + final rollMatches = room.studentRollNumbers.any((roll) => + roll.toLowerCase().contains(query.toLowerCase())); + return roomNumberMatches || statusMatches || nameMatches || rollMatches; + }).toList(); + + return ListView.builder( + itemCount: suggestionList.length, + itemBuilder: (context, index) { + final Room room = suggestionList[index]; + return ListTile( + title: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Room No: ${room.roomNumber}'), + Text('Status: ${room.status}'), + Text('Students: ${room.studentNames.join(", ")}'), + Text('Roll Numbers: ${room.studentRollNumbers.join(", ")}'), + ], + ), + onTap: () { + close(context, suggestionList[index].roomNumber.toString()); + + }, + ); + }, + ); + } +} + +void main() { + runApp(MaterialApp( + home: Managerooms(), + )); +} diff --git a/lib/screens/Hostel/caretaker/managestudent.dart b/lib/screens/Hostel/caretaker/managestudent.dart new file mode 100644 index 00000000..9d35e924 --- /dev/null +++ b/lib/screens/Hostel/caretaker/managestudent.dart @@ -0,0 +1,510 @@ + +import 'dart:convert'; +import 'package:flutter/material.dart'; + + + +class Student { + final String rollNo; + String name; + int batch; + String program; + String specialization; + String hallNo; + String roomNo; + String contactNo; + String address; + + Student({ + required this.rollNo, + required this.name, + required this.batch, + required this.program, + required this.specialization, + required this.hallNo, + required this.roomNo, + required this.contactNo, + required this.address, + }); +} + +class Managestudent extends StatefulWidget { + const Managestudent({Key? key}) : super(key: key); + + @override + _ManagestudentState createState() => _ManagestudentState(); +} + +class _ManagestudentState extends State { + List students = []; + List filteredStudents = []; + + @override + void initState() { + super.initState(); + _fetchStudentDetails(); + } + + Future _fetchStudentDetails() async { + // Simulating GET API call to fetch student details + final String studentData = ''' + [ + {"rollNo": "21bcs001", "name": "Rahul", "batch": 2021, "program": "B.Tech", "specialization": "CSE", "hallNo": "Hall-4", "roomNo": "G-31", "contactNo": "+911234567890", "address": "Address 1, City 1, State 1, Country 1"}, + {"rollNo": "21bme002", "name": "Kiran", "batch": 2021, "program": "B.Tech", "specialization": "MEE", "hallNo": "Hall-4", "roomNo": "F-24", "contactNo": "+919876543210", "address": "Address 2, City 2, State 2, Country 2"}, + {"rollNo": "21bcs003", "name": "Amit", "batch": 2021, "program": "B.Tech", "specialization": "CSE", "hallNo": "Hall-4", "roomNo": "S-12", "contactNo": "+914561237890", "address": "Address 3, City 3, State 3, Country 3"}, + {"rollNo": "21sm004", "name": "Kunal", "batch": 2021, "program": "B.Tech", "specialization": "SM", "hallNo": "Hall-4", "roomNo": "G-31", "contactNo": "+911234567890", "address": "Address 4, City 4, State 4, Country 4"}, + {"rollNo": "21bcs005", "name": "Vishal", "batch": 2021, "program": "B.Tech", "specialization": "CSE", "hallNo": "Hall-4", "roomNo": "F-24", "contactNo": "+919876543210", "address": "Address 5, City 5, State 5, Country 5"}, + {"rollNo": "23me116", "name": "Divyanshu", "batch": 2023, "program": "B.Tech", "specialization": "ME", "hallNo": "Hall-4", "roomNo": "S-12", "contactNo": "+914561237890", "address": "Address 6, City 6, State 6, Country 6"}, + {"rollNo": "23bec117", "name": "Raj", "batch": 2023, "program": "B.Tech", "specialization": "ECE", "hallNo": "Hall-4", "roomNo": "G-31", "contactNo": "+911234567890", "address": "Address 7, City 7, State 7, Country 7"}, + {"rollNo": "23bds118", "name": "Anurag", "batch": 2023, "program": "B.Des", "specialization": "DS", "hallNo": "Hall-4", "roomNo": "F-24", "contactNo": "+919876543210", "address": "Address 8, City 8, State 8, Country 8"} + ] + '''; + final List studentList = json.decode(studentData); + setState(() { + students = studentList.map((student) => Student( + rollNo: student['rollNo'], + name: student['name'], + batch: student['batch'], + program: student['program'], + specialization: student['specialization'], + hallNo: student['hallNo'], + roomNo: student['roomNo'], + contactNo: student['contactNo'], + address: student['address'], + )).toList(); + filteredStudents = List.from(students); + }); + } + + Future _editStudentDetails(Student student) async { + // Display dialog to edit student details + showDialog( + context: context, + builder: (BuildContext context) { + String name = student.name; + int batch = student.batch; + String program = student.program; + String specialization = student.specialization; + String hallNo = student.hallNo; + String roomNo = student.roomNo; + String contactNo = student.contactNo; + String address = student.address; + + return AlertDialog( + title: Text('Edit Student Details'), + content: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextField( + decoration: InputDecoration(labelText: 'Name'), + controller: TextEditingController(text: name), + onChanged: (value) { + name = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Batch'), + controller: TextEditingController(text: batch.toString()), + onChanged: (value) { + batch = int.tryParse(value) ?? 0; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Program'), + controller: TextEditingController(text: program), + onChanged: (value) { + program = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Specialization'), + controller: TextEditingController(text: specialization), + onChanged: (value) { + specialization = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Hall No'), + controller: TextEditingController(text: hallNo), + onChanged: (value) { + hallNo = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Room No'), + controller: TextEditingController(text: roomNo), + onChanged: (value) { + roomNo = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Contact No'), + controller: TextEditingController(text: contactNo), + onChanged: (value) { + contactNo = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Address'), + controller: TextEditingController(text: address), + onChanged: (value) { + address = value; + }, + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + // Perform the edit operation here + setState(() { + student.name = name; + student.batch = batch; + student.program = program; + student.specialization = specialization; + student.hallNo = hallNo; + student.roomNo = roomNo; + student.contactNo = contactNo; + student.address = address; + }); + // Simulate POST API call to update student details + // _updateStudentDetails(student); + Navigator.of(context).pop(); + }, + child: Text('Submit'), + ), + ], + ); + }, + ); + } + + Future _deleteStudentDetails(Student student) async { + // Show confirmation dialog before deleting the student + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Confirm Deletion'), + content: Text('Are you sure you want to delete this student?'), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + // Delete the student + _deleteStudent(student); + Navigator.of(context).pop(); + }, + child: Text('Delete'), + ), + ], + ); + }, + ); + } + + void _deleteStudent(Student student) { + setState(() { + students.remove(student); + filteredStudents.remove(student); + }); + // Simulate DELETE API call to delete student details + // _invokeDeleteAPI(student.rollNo); + } + + Future _showAddDialog() async { + String rollNo = ''; + String name = ''; + int batch = 0; + String program = ''; + String specialization = ''; + String hallNo = ''; + String roomNo = ''; + String contactNo = ''; + String address = ''; + + await showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Add New Student'), + content: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextField( + decoration: InputDecoration(labelText: 'Roll No'), + onChanged: (value) { + rollNo = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Name'), + onChanged: (value) { + name = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Batch'), + onChanged: (value) { + batch = int.tryParse(value) ?? 0; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Program'), + onChanged: (value) { + program = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Specialization'), + onChanged: (value) { + specialization = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Hall No'), + onChanged: (value) { + hallNo = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Room No'), + onChanged: (value) { + roomNo = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Contact No'), + onChanged: (value) { + contactNo = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Address'), + onChanged: (value) { + address = value; + }, + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + // Perform the add operation here + setState(() { + final newStudent = Student( + rollNo: rollNo, + name: name, + batch: batch, + program: program, + specialization: specialization, + hallNo: hallNo, + roomNo: roomNo, + contactNo: contactNo, + address: address, + ); + students.add(newStudent); + filteredStudents.add(newStudent); + }); + // Simulate POST API call to add new student details + // _addStudentDetails(rollNo, name, batch, program, specialization, hallNo, roomNo, contactNo, address); + Navigator.of(context).pop(); + }, + child: Text('Submit'), + ), + ], + ); + }, + ); + } + + void _searchStudents(String query) { + setState(() { + if (query.isNotEmpty) { + filteredStudents = students.where((student) { + return student.rollNo.contains(query) || student.name.contains(query); + }).toList(); + } else { + filteredStudents = List.from(students); + } + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + + appBar: AppBar( + title: Text('Manage Students'), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + actions: [ + IconButton( + icon: Icon(Icons.search), + onPressed: () async { + final String? result = await showSearch( + context: context, + delegate: StudentSearchDelegate(students: students), + ); + if (result != null) { + _searchStudents(result); + } + }, + ), + ], + ), + body: SingleChildScrollView( + child: DataTable( + columns: const [ + DataColumn(label: Text('Roll No')), + DataColumn(label: Text('Name')), + DataColumn(label: Text('Batch')), + DataColumn(label: Text('Program')), + DataColumn(label: Text('Specialization')), + DataColumn(label: Text('Hall No')), + DataColumn(label: Text('Room No')), + DataColumn(label: Text('Contact No')), + DataColumn(label: Text('Address')), + DataColumn(label: Text('Edit')), + DataColumn(label: Text('Remove')), + ], + rows: List.generate( + filteredStudents.length, + (index) => DataRow( + cells: [ + DataCell(Text(filteredStudents[index].rollNo)), + DataCell(Text(filteredStudents[index].name)), + DataCell(Text(filteredStudents[index].batch.toString())), + DataCell(Text(filteredStudents[index].program)), + DataCell(Text(filteredStudents[index].specialization)), + DataCell(Text(filteredStudents[index].hallNo)), + DataCell(Text(filteredStudents[index].roomNo)), + DataCell(Text(filteredStudents[index].contactNo)), + DataCell(Text(filteredStudents[index].address)), + DataCell( + IconButton( + icon: Icon(Icons.edit), + onPressed: () { + _editStudentDetails(filteredStudents[index]); + }, + ), + ), + DataCell( + IconButton( + icon: Icon(Icons.delete), + onPressed: () { + _deleteStudentDetails(filteredStudents[index]); + }, + ), + ), + ], + ), + ), + ), + + ), + floatingActionButton: FloatingActionButton( + onPressed: _showAddDialog, + child: Icon(Icons.add), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + ), + ); + } +} + +class StudentSearchDelegate extends SearchDelegate { + final List students; + + StudentSearchDelegate({required this.students}); + + @override + ThemeData appBarTheme(BuildContext context) { + final ThemeData theme = Theme.of(context); + return theme.copyWith( + appBarTheme: AppBarTheme( + backgroundColor: theme.scaffoldBackgroundColor, // Match with screen's UI theme + iconTheme: IconThemeData(color: theme.primaryColor), // Match with screen's UI theme + ), + ); + } + + @override + List buildActions(BuildContext context) { + return [ + IconButton( + icon: Icon(Icons.clear), + onPressed: () { + query = ''; + }, + ), + ]; + } + + @override + Widget buildLeading(BuildContext context) { + return IconButton( + icon: Icon(Icons.arrow_back), + onPressed: () { + close(context, null); + }, + ); + } + + @override + Widget buildResults(BuildContext context) { + return _buildSearchResults(context); + } + + @override + Widget buildSuggestions(BuildContext context) { + return _buildSearchResults(context); + } + + Widget _buildSearchResults(BuildContext context) { + final List filteredStudents = students.where((student) { + final String lowercaseQuery = query.toLowerCase(); + return student.rollNo.toLowerCase().contains(lowercaseQuery) || student.name.toLowerCase().contains(lowercaseQuery); + }).toList(); + return ListView.builder( + itemCount: filteredStudents.length, + itemBuilder: (context, index) { + return ListTile( + title: Text(filteredStudents[index].name), + subtitle: Text(filteredStudents[index].rollNo), + onTap: () { + close(context, filteredStudents[index].rollNo); + }, + ); + }, + ); + } +} + + + +void main() { + runApp(MaterialApp( + home: Managestudent(), + )); +} + diff --git a/lib/screens/Hostel/caretaker/noticeboard.dart b/lib/screens/Hostel/caretaker/noticeboard.dart new file mode 100644 index 00000000..c3ead8f5 --- /dev/null +++ b/lib/screens/Hostel/caretaker/noticeboard.dart @@ -0,0 +1,220 @@ + + +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:fusion/Components/side_drawer.dart'; + + +class Notice { + final String headline; + final String description; + final DateTime date; + + Notice(this.headline, this.description, this.date); +} + +class Noticeboard extends StatefulWidget { + const Noticeboard({Key? key}) : super(key: key); + + @override + _NoticeboardState createState() => _NoticeboardState(); +} + +class _NoticeboardState extends State { + + List notices = []; // Define the 'notices' list + + @override + void initState() { + super.initState(); + // Populate with sample notice boards + _populateNoticeBoards(); + } + + // Method to populate sample notice boards + void _populateNoticeBoards() { + // Sample notice board 1 + notices.add( + Notice( + 'Important Announcement', + 'All students are hereby informed that using Alcohol,Cigaretts andElectical Items are prohibited in hostels.If found heavy fine will be imposed.', + DateTime(2024, 4, 22), + ), + ); + + // Sample notice board 2 + notices.add( + Notice( + 'Republic Day 2k24', + 'As you all are aware today is Republic day,so interested students can attend the flag hosting infront of hostel which will be starting at 8:00am.', + DateTime(2024, 1, 26), + ), + ); + + // Notify the UI about the changes + setState(() {}); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: SideDrawer(), + appBar: AppBar( + title: const Text('Notice Board'), + + backgroundColor: const Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + body: Padding( + padding: EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Expanded( + child: ListView.builder( + itemCount: notices.length, + itemBuilder: (context, index) { + return Card( + margin: EdgeInsets.only(bottom: 20), + color: Color.fromARGB(255, 255, 229, 218), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: BorderSide( + color: Color.fromARGB(255, 245, 103, 47), + width: 2.0, + ), + ), + child: Padding( + padding: EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + notices[index].headline, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + Text( + '${notices[index].date.day}/${notices[index].date.month}/${notices[index].date.year}', + style: TextStyle(fontSize: 16), + ), + ], + ), + SizedBox(height: 10), + Text( + notices[index].description, + style: TextStyle(fontSize: 18), + ), + SizedBox(height: 20), + ElevatedButton( + onPressed: () { + // Handle file upload logic here + }, + child: Text('View Uploaded File'), + ), + SizedBox(height: 10), + Align( + alignment: Alignment.bottomRight, + child: ElevatedButton( + onPressed: () { + // Remove notice board logic here + setState(() { + notices.removeAt(index); + }); + }, + child: Text('Remove Notice'), + ), + ), + ], + ), + ), + ); + }, + ), + ), + ], + + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: () { + + // Display dialog to add a new notice + showDialog( + context: context, + builder: (BuildContext context) { + String headline = ''; + String description = ''; + + return AlertDialog( + title: Text('Add New Notice'), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextField( + decoration: InputDecoration( + labelText: 'Headline', + ), + onChanged: (value) { + headline = value; + }, + ), + SizedBox(height: 10), + TextField( + decoration: InputDecoration( + labelText: 'Description', + ), + onChanged: (value) { + description = value; + }, + ), + SizedBox(height: 10), + ElevatedButton( + onPressed: () { + // Handle file upload logic here + }, + child: Text('Upload File'), + ), + ], + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + // Add new notice logic here + setState(() { + notices.add(Notice(headline, description, DateTime.now())); + }); + // Invoke sample POST API + // _invokePostAPI(headline, description, file); + Navigator.of(context).pop(); + }, + child: Text('Add'), + ), + ], + ); + }, + ); + }, + child: const Icon(Icons.add), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + ); + } + + // Method to invoke a POST API + void _invokePostAPI(String headline, String description, String file) { + // Your implementation to invoke POST API + // Example: http.post(url, body: {'headline': headline, 'description': description, 'file': file}); + } + +} diff --git a/lib/screens/Hostel/caretaker/report.dart b/lib/screens/Hostel/caretaker/report.dart new file mode 100644 index 00000000..1406925d --- /dev/null +++ b/lib/screens/Hostel/caretaker/report.dart @@ -0,0 +1,226 @@ + +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:fusion/Components/side_drawer.dart'; + +class Student { + final String name; + final int rollNumber; + bool isPresent; + + Student({ + required this.name, + required this.rollNumber, + this.isPresent = false, + }); +} + +class Report extends StatefulWidget { + const Report({Key? key}) : super(key: key); + + @override + _ReportState createState() => _ReportState(); +} + +class _ReportState extends State { + late DateTime selectedDate; + late List students; + late List filteredStudents; + + @override + void initState() { + super.initState(); + selectedDate = DateTime.now(); + _fetchStudentDetails(); + } + + Future _fetchStudentDetails() async { + // Simulating fetching student data from an API + final String studentData = ''' + [ + {"name": "John Doe", "rollNumber": 101}, + {"name": "Alice Smith", "rollNumber": 102}, + {"name": "Bob Johnson", "rollNumber": 103} + ] + '''; + final List studentList = json.decode(studentData); + setState(() { + students = studentList.map((student) => Student( + name: student['name'], + rollNumber: student['rollNumber'], + )).toList(); + filteredStudents = List.from(students); + }); + } + + void _searchStudents(String query) { + setState(() { + if (query.isEmpty) { + filteredStudents = List.from(students); + } else { + filteredStudents = students + .where((student) => + student.name.toLowerCase().contains(query.toLowerCase()) || + student.rollNumber.toString().contains(query)) + .toList(); + } + }); + } + + Future _selectDate(BuildContext context) async { + final DateTime? picked = await showDatePicker( + context: context, + initialDate: selectedDate, + firstDate: DateTime(2000), + lastDate: DateTime.now(), + selectableDayPredicate: (DateTime date) { + // Allow only past dates to be selected + return date.isBefore(DateTime.now()); + }, + ); + if (picked != null && picked != selectedDate) { + setState(() { + selectedDate = picked; + }); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: SideDrawer(), + appBar: AppBar( + title: const Text('Report'), + ), + body: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + Expanded( + child: TextButton( + onPressed: () => _selectDate(context), + child: Text( + 'Selected Date: ${selectedDate.year}-${selectedDate.month}-${selectedDate.day}', + style: TextStyle(fontSize: 16), + ), + ), + ), + IconButton( + icon: Icon(Icons.search), + onPressed: () { + showSearch( + context: context, + delegate: StudentSearchDelegate(students: students), + ); + }, + ), + ], + ), + ), + Expanded( + child: ListView.builder( + itemCount: filteredStudents.length, + itemBuilder: (context, index) { + return ListTile( + title: Text( + filteredStudents[index].name, + style: TextStyle(fontSize: 18), + ), + subtitle: Text( + 'Roll No: ${filteredStudents[index].rollNumber}', + style: TextStyle(fontSize: 14), + ), + trailing: IconButton( + icon: filteredStudents[index].isPresent + ? Icon(Icons.check_circle, color: Colors.green) + : Icon(Icons.cancel, color: Colors.red), + onPressed: () { + setState(() { + filteredStudents[index].isPresent = + !filteredStudents[index].isPresent; + }); + }, + ), + ); + }, + ), + ), + ], + ), + ); + } +} + +class StudentSearchDelegate extends SearchDelegate { + final List students; + + StudentSearchDelegate({required this.students}); + + @override + ThemeData appBarTheme(BuildContext context) { + final ThemeData theme = Theme.of(context); + return theme.copyWith( + appBarTheme: AppBarTheme( + backgroundColor: theme.scaffoldBackgroundColor, + iconTheme: IconThemeData(color: theme.primaryColor), + ), + ); + } + + @override + List buildActions(BuildContext context) { + return [ + IconButton( + icon: Icon(Icons.clear), + onPressed: () { + query = ''; + }, + ), + ]; + } + + @override + Widget buildLeading(BuildContext context) { + return IconButton( + icon: Icon(Icons.arrow_back), + onPressed: () { + close(context, null); + }, + ); + } + + @override + Widget buildResults(BuildContext context) { + return _buildSearchResults(context); + } + + @override + Widget buildSuggestions(BuildContext context) { + return _buildSearchResults(context); + } + + Widget _buildSearchResults(BuildContext context) { + return ListView.builder( + itemCount: students.length, + itemBuilder: (context, index) { + return ListTile( + title: Text(students[index].name), + subtitle: Text('Roll No: ${students[index].rollNumber}'), + onTap: () { + close(context, students[index]); + }, + ); + }, + ); + } +} + +void main() { + runApp(MaterialApp( + home: Report(), + )); + +} diff --git a/lib/screens/Hostel/caretaker/staffinfo.dart b/lib/screens/Hostel/caretaker/staffinfo.dart new file mode 100644 index 00000000..6dfbce50 --- /dev/null +++ b/lib/screens/Hostel/caretaker/staffinfo.dart @@ -0,0 +1,274 @@ + +import 'dart:convert'; + +import 'package:flutter/material.dart'; + +void main() { + runApp(MyApp()); +} + +class Worker { + final String workerId; + final String name; + final String monthYear; + final String today; + final int workingDays; + final int totalAbsent; + final String remark; + + Worker({ + required this.workerId, + required this.name, + required this.monthYear, + required this.today, + required this.workingDays, + required this.totalAbsent, + required this.remark, + }); + + factory Worker.fromJson(Map json) { + return Worker( + workerId: json['workerId'], + name: json['name'], + monthYear: json['monthYear'], + today: json['today'], + workingDays: json['workingDays'], + totalAbsent: json['totalAbsent'], + remark: json['remark'], + ); + } +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Staff Info', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Staffinfo(), + ); + } +} + +class Staffinfo extends StatefulWidget { + const Staffinfo({Key? key}) : super(key: key); + + @override + _StaffInfoState createState() => _StaffInfoState(); +} + +class _StaffInfoState extends State { + late Map> halls; + String? selectedHall; + + Future _loadHallData() async { + String jsonString = ''' + { + "halls": { + "hall1": [ + { + "workerId": "001", + "name": "Rajesh Sharma", + "monthYear": "April/2024", + "today": "2024-04-22", + "workingDays": 20, + "totalAbsent": 2, + "remark": "Good performance overall." + }, + { + "workerId": "004", + "name": "Anita Singh", + "monthYear": "April/2024", + "today": "2024-04-22", + "workingDays": 19, + "totalAbsent": 1, + "remark": "Consistently good attendance." + } + ], + "hall2": [ + { + "workerId": "002", + "name": "Vikram Patel", + "monthYear": "April/2024", + "today": "2024-04-22", + "workingDays": 18, + "totalAbsent": 4, + "remark": "Needs improvement in attendance." + }, + { + "workerId": "005", + "name": "Deepa Gupta", + "monthYear": "April/2024", + "today": "2024-04-22", + "workingDays": 21, + "totalAbsent": 3, + "remark": "Average attendance, some improvement needed." + } + ], + "hall3": [ + { + "workerId": "003", + "name": "Arun Kumar", + "monthYear": "April/2024", + "today": "2024-04-22", + "workingDays": 22, + "totalAbsent": 1, + "remark": "Excellent attendance record." + }, + { + "workerId": "006", + "name": "Preeti Verma", + "monthYear": "April/2024", + "today": "2024-04-22", + "workingDays": 20, + "totalAbsent": 2, + "remark": "Good performance overall." + } + ] + } + } + '''; + + Map data = json.decode(jsonString); + Map hallsData = data['halls']; + setState(() { + halls = hallsData.map((key, value) => + MapEntry(key, (value as List).map((e) => Worker.fromJson(e)).toList())); + selectedHall = halls.keys.first; + }); + } + + @override + void initState() { + super.initState(); + _loadHallData(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Staff Info'), + ), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DropdownButton( + items: halls.keys.map((String hall) { + return DropdownMenuItem( + value: hall, + child: Text(hall), + ); + }).toList(), + value: selectedHall, + onChanged: (String? newValue) { + setState(() { + selectedHall = newValue; + }); + }, + ), + const SizedBox(height: 20), + if (selectedHall != null && halls[selectedHall!] != null) + Expanded( + child: ListView.builder( + itemCount: halls[selectedHall!]!.length, + itemBuilder: (BuildContext context, int index) { + Worker worker = halls[selectedHall!]![index]; + return Card( + elevation: 3, + margin: const EdgeInsets.symmetric(vertical: 8), + child: ListTile( + title: Text(worker.name), + subtitle: Text('Working days: ${worker.workingDays}, Absent: ${worker.totalAbsent}'), + trailing: PopupMenuButton( + itemBuilder: (context) => [ + PopupMenuItem( + value: 'edit', + child: Text('Edit'), + ), + PopupMenuItem( + value: 'delete', + child: Text('Delete'), + ), + ], + onSelected: (value) { + if (value == 'edit') { + // Implement edit logic + _showEditDialog(worker); + } else if (value == 'delete') { + // Implement delete logic + _showDeleteDialog(worker); + } + }, + ), + ), + ); + }, + ), + ), + ], + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: () { + // Implement add logic + }, + child: Icon(Icons.add), + ), + ); + } + + void _showEditDialog(Worker worker) { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text('Edit Worker'), + content: Text('You selected ${worker.name} for editing.'), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: Text('Cancel'), + ), + TextButton( + onPressed: () { + // Implement edit logic + Navigator.pop(context); + }, + child: Text('Edit'), + ), + ], + ), + ); + } + + void _showDeleteDialog(Worker worker) { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text('Delete Worker'), + content: Text('Are you sure you want to delete ${worker.name}?'), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: Text('Cancel'), + ), + TextButton( + onPressed: () { + // Implement delete logic + Navigator.pop(context); + }, + child: Text('Delete'), + ), + ], + ), + ); + } +} diff --git a/lib/screens/Hostel/student/allottedrooms.dart b/lib/screens/Hostel/student/allottedrooms.dart new file mode 100644 index 00000000..5cc22b76 --- /dev/null +++ b/lib/screens/Hostel/student/allottedrooms.dart @@ -0,0 +1,152 @@ +import 'dart:convert'; +import 'package:flutter/material.dart'; + +// Updated JSON data representing hostel details with room numbers +const String hostelData = ''' +[ + { + "hostelNumber": 1, + "students": [ + {"name": "Student 1", "rollNumber": "21bcs01", "program": "BTECH", "room": "F101"}, + {"name": "Student 2", "rollNumber": "21bcs02", "program": "BTECH", "room": "F101"}, + {"name": "Student 3", "rollNumber": "21bcs03", "program": "BTECH", "room": "F102"}, + {"name": "Student 4", "rollNumber": "21bcs04", "program": "BTECH", "room": "F102"}, + {"name": "Student 5", "rollNumber": "21bcs05", "program": "BTECH", "room": "S102"}, + {"name": "Student 6", "rollNumber": "21bcs06", "program": "BTECH", "room": "S102"}, + {"name": "Student 7", "rollNumber": "21bcs07", "program": "BTECH", "room": "S103"}, + {"name": "Student 8", "rollNumber": "21bcs08", "program": "BTECH", "room": "S103"}, + {"name": "Student 9", "rollNumber": "21bcs09", "program": "BTECH", "room": "F103"}, + {"name": "Student 10", "rollNumber": "21bcs10", "program": "BTECH", "room": "F103"} + ] + }, + { + "hostelNumber": 2, + "students": [ + {"name": "Student 11", "rollNumber": "22bcs01", "program": "BTECH", "room": "F201"}, + {"name": "Student 12", "rollNumber": "22bcs02", "program": "BTECH", "room": "F201"}, + {"name": "Student 13", "rollNumber": "22bcs03", "program": "BTECH", "room": "F202"}, + {"name": "Student 14", "rollNumber": "22bcs04", "program": "BTECH", "room": "F202"}, + {"name": "Student 15", "rollNumber": "22bcs05", "program": "BTECH", "room": "S202"}, + {"name": "Student 16", "rollNumber": "22bcs06", "program": "BTECH", "room": "S202"}, + {"name": "Student 17", "rollNumber": "22bcs07", "program": "BTECH", "room": "S203"}, + {"name": "Student 18", "rollNumber": "22bcs08", "program": "BTECH", "room": "S203"}, + {"name": "Student 19", "rollNumber": "22bcs09", "program": "BTECH", "room": "F203"}, + {"name": "Student 20", "rollNumber": "22bcs10", "program": "BTECH", "room": "F203"} + ] + }, + { + "hostelNumber": 3, + "students": [ + {"name": "Student 21", "rollNumber": "23bcs01", "program": "BTECH", "room": "F301"}, + {"name": "Student 22", "rollNumber": "23bcs02", "program": "BTECH", "room": "F301"}, + {"name": "Student 23", "rollNumber": "23bcs03", "program": "BTECH", "room": "F302"}, + {"name": "Student 24", "rollNumber": "23bcs04", "program": "BTECH", "room": "F302"}, + {"name": "Student 25", "rollNumber": "23bcs05", "program": "BTECH", "room": "S302"}, + {"name": "Student 26", "rollNumber": "23bcs06", "program": "BTECH", "room": "S302"}, + {"name": "Student 27", "rollNumber": "23bcs07", "program": "BTECH", "room": "S303"}, + {"name": "Student 28", "rollNumber": "23bcs08", "program": "BTECH", "room": "S303"}, + {"name": "Student 29", "rollNumber": "23bcs09", "program": "BTECH", "room": "F303"}, + {"name": "Student 30", "rollNumber": "23bcs10", "program": "BTECH", "room": "F303"} + ] + }, + { + "hostelNumber": 4, + "students": [ + {"name": "Student 31", "rollNumber": "24bcs01", "program": "BTECH", "room": "F401"}, + {"name": "Student 32", "rollNumber": "24bcs02", "program": "BTECH", "room": "F401"}, + {"name": "Student 33", "rollNumber": "24bcs03", "program": "BTECH", "room": "F402"}, + {"name": "Student 34", "rollNumber": "24bcs04", "program": "BTECH", "room": "F402"}, + {"name": "Student 35", "rollNumber": "24bcs05", "program": "BTECH", "room": "S402"}, + {"name": "Student 36", "rollNumber": "24bcs06", "program": "BTECH", "room": "S402"}, + {"name": "Student 37", "rollNumber": "24bcs07", "program": "BTECH", "room": "S403"}, + {"name": "Student 38", "rollNumber": "24bcs08", "program": "BTECH", "room": "S403"}, + {"name": "Student 39", "rollNumber": "24bcs09", "program": "BTECH", "room": "F403"}, + {"name": "Student 40", "rollNumber": "24bcs10", "program": "BTECH", "room": "F403"} + ] + } +] +'''; + +class Allottedrooms extends StatefulWidget { + @override + _AllottedroomsState createState() => _AllottedroomsState(); +} + +class _AllottedroomsState extends State { + final List> hostels = + (json.decode(hostelData) as List) + .map((i) => i as Map) + .toList(); + String? selectedHostel; + + @override + void initState() { + super.initState(); + selectedHostel = hostels[0]['hostelNumber'].toString(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Allotted Rooms'), + backgroundColor: const Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + body: Column( + children: [ + DropdownButton( + value: selectedHostel, + onChanged: (String? newValue) { + setState(() { + selectedHostel = newValue; + }); + }, + items: hostels.map>((hostel) { + return DropdownMenuItem( + value: hostel['hostelNumber'].toString(), + child: Text( + 'Hostel ${hostel['hostelNumber']}', + style: TextStyle(color: Colors.black), + ), + ); + }).toList(), + ), + Expanded( + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: DataTable( + columns: const [ + DataColumn(label: Text('Name')), + DataColumn(label: Text('Roll Number')), + DataColumn(label: Text('Program')), + DataColumn(label: Text('Room')), + ], + rows: (hostels.firstWhere( + (hostel) => + hostel['hostelNumber'].toString() == + selectedHostel)['students'] as List) + .map((student) { + return DataRow( + cells: [ + DataCell(Text(student['name'])), + DataCell(Text(student['rollNumber'])), + DataCell(Text(student['program'])), + DataCell(Text(student['room'])), + ], + ); + }).toList(), + ), + ), + ), + ], + ), + ); + } +} + +void main() { + runApp(MaterialApp( + home: Allottedrooms(), + )); +} diff --git a/lib/screens/Hostel/student/fines.dart b/lib/screens/Hostel/student/fines.dart new file mode 100644 index 00000000..4e6d8a51 --- /dev/null +++ b/lib/screens/Hostel/student/fines.dart @@ -0,0 +1,112 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:fusion/Components/side_drawer.dart'; + +class Fines extends StatelessWidget { + const Fines({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + // JSON data representing fines + const String fineData = ''' + { + "MyFine": [ + { + "hall": "4", + "amount": 200, + "status": "paid", + "reason": "Hall fee payment", + "action": "done" + }, + { + "hall": "4", + "amount": 50, + "status": "unpaid", + "reason": "Using unauthorized appliance (fan)", + "action": "pay" + }, + { + "hall": "4", + "amount": 500, + "status": "unpaid", + "reason": "Damage to hall property", + "action": "pay" + }, + { + "hall": "4", + "amount": 100, + "status": "unpaid", + "reason": "Violation of hall rules", + "action": "pay" + } + ] + } + '''; + + final Map fines = json.decode(fineData); + + return Scaffold( + drawer: SideDrawer(), + appBar: AppBar( + title: const Text('Fines'), + backgroundColor: const Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + body: Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'My Fines', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + SizedBox(height: 10), + Expanded( + child: ListView.builder( + itemCount: fines['MyFine'].length, + itemBuilder: (context, index) { + var fine = fines['MyFine'][index]; + return Card( + margin: const EdgeInsets.only(bottom: 10), + child: Padding( + padding: const EdgeInsets.all(10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Hall: ${fine['hall']}'), + Text('Amount: \$${fine['amount']}'), + Text( + 'Status: ${fine['status'].toString().toUpperCase()}', + style: TextStyle( + color: fine['status'] == 'unpaid' + ? Colors.red + : Colors.green, + ), + ), + Text('Reason: ${fine['reason']}'), + if (fine['status'] == 'unpaid') + ElevatedButton( + onPressed: () { + // Implement action for unpaid fine + }, + child: Text(fine['action'].toString()), + ), + ], + ), + ), + ); + }, + ), + ), + ], + ), + ), + ); + } +} + +void main() { + runApp(MaterialApp(home: Fines())); +} \ No newline at end of file diff --git a/lib/screens/Hostel/student/guestroom.dart b/lib/screens/Hostel/student/guestroom.dart new file mode 100644 index 00000000..a77b15c1 --- /dev/null +++ b/lib/screens/Hostel/student/guestroom.dart @@ -0,0 +1,320 @@ +import 'package:flutter/material.dart'; + +void main() { + runApp(MaterialApp( + home: Guestroom(), + )); +} + +class Guestroom extends StatefulWidget { + const Guestroom({Key? key}) : super(key: key); + + @override + _GuestroomState createState() => _GuestroomState(); +} + +class _GuestroomState extends State { + String? selectedHall; + DateTime? arrivalDate; + DateTime? departureDate; + TimeOfDay? arrivalTime; + TimeOfDay? departureTime; + int? numOfGuests; + String? nationality; + int? numOfRooms; + String? roomType; + String? guestName; + String? guestAddress; + String? guestEmail; + String? guestPhoneNumber; + bool availableRoom = false; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Guest Room'), + backgroundColor: const Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + body: SingleChildScrollView( + padding: const EdgeInsets.fromLTRB(20.0, 40.0, 20.0, 20.0), + child: Card( + elevation: 4, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15.0), + ), + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Book Guest Room', + style: TextStyle( + fontSize: 23.0, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 20.0), + DropdownButtonFormField( + value: selectedHall, + onChanged: (String? newValue) { + setState(() { + selectedHall = newValue; + }); + }, + items: ['1', '2', '3', '4'].map((String value) { + return DropdownMenuItem( + value: value, + child: Text('Hall $value'), + ); + }).toList(), + decoration: InputDecoration( + labelText: 'Hall', + border: OutlineInputBorder(), + ), + ), + const SizedBox(height: 10.0), + TextFormField( + decoration: InputDecoration( + labelText: 'Arrival Date', + border: OutlineInputBorder(), + ), + onTap: () async { + final DateTime? picked = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime.now(), + lastDate: DateTime(2101), + ); + if (picked != null && picked != arrivalDate) { + setState(() { + arrivalDate = picked; + }); + } + }, + controller: TextEditingController( + text: arrivalDate != null + ? "${arrivalDate!.day}/${arrivalDate!.month}/${arrivalDate!.year}" + : "", + ), + ), + const SizedBox(height: 10.0), + TextFormField( + decoration: InputDecoration( + labelText: 'Departure Date', + border: OutlineInputBorder(), + ), + onTap: () async { + final DateTime? picked = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime.now(), + lastDate: DateTime(2101), + ); + if (picked != null && picked != departureDate) { + setState(() { + departureDate = picked; + }); + } + }, + controller: TextEditingController( + text: departureDate != null + ? "${departureDate!.day}/${departureDate!.month}/${departureDate!.year}" + : "", + ), + ), + const SizedBox(height: 10.0), + TextFormField( + decoration: InputDecoration( + labelText: 'Arrival Time', + border: OutlineInputBorder(), + ), + onTap: () async { + final TimeOfDay? picked = await showTimePicker( + context: context, + initialTime: TimeOfDay.now(), + ); + if (picked != null && picked != arrivalTime) { + setState(() { + arrivalTime = picked; + }); + } + }, + controller: TextEditingController( + text: arrivalTime != null + ? "${arrivalTime!.hour}:${arrivalTime!.minute}" + : "", + ), + ), + const SizedBox(height: 10.0), + TextFormField( + decoration: InputDecoration( + labelText: 'Departure Time', + border: OutlineInputBorder(), + ), + onTap: () async { + final TimeOfDay? picked = await showTimePicker( + context: context, + initialTime: TimeOfDay.now(), + ); + if (picked != null && picked != departureTime) { + setState(() { + departureTime = picked; + }); + } + }, + controller: TextEditingController( + text: departureTime != null + ? "${departureTime!.hour}:${departureTime!.minute}" + : "", + ), + ), + const SizedBox(height: 10.0), + TextFormField( + decoration: InputDecoration( + labelText: 'Number of Guests', + border: OutlineInputBorder(), + ), + keyboardType: TextInputType.number, + onChanged: (value) { + // Parse and set the number of guests + setState(() { + numOfGuests = int.tryParse(value); + }); + }, + ), + const SizedBox(height: 10.0), + TextFormField( + decoration: InputDecoration( + labelText: 'Nationality', + border: OutlineInputBorder(), + ), + onChanged: (value) { + setState(() { + nationality = value; + }); + }, + ), + const SizedBox(height: 10.0), + TextFormField( + decoration: InputDecoration( + labelText: 'Number of Rooms', + border: OutlineInputBorder(), + ), + keyboardType: TextInputType.number, + onChanged: (value) { + // Parse and set the number of rooms + setState(() { + numOfRooms = int.tryParse(value); + }); + }, + ), + const SizedBox(height: 10.0), + TextFormField( + decoration: InputDecoration( + labelText: 'Room Type', + border: OutlineInputBorder(), + ), + onChanged: (value) { + setState(() { + roomType = value; + }); + }, + ), + const SizedBox(height: 10.0), + SwitchListTile( + title: Text("Available Room"), + value: availableRoom, + onChanged: (newValue) { + setState(() { + availableRoom = newValue; + }); + }, + ), + const SizedBox(height: 10.0), + TextFormField( + decoration: InputDecoration( + labelText: 'Name of Guest', + border: OutlineInputBorder(), + ), + onChanged: (value) { + setState(() { + guestName = value; + }); + }, + ), + const SizedBox(height: 10.0), + TextFormField( + decoration: InputDecoration( + labelText: 'Guest Address', + border: OutlineInputBorder(), + ), + onChanged: (value) { + setState(() { + guestAddress = value; + }); + }, + ), + const SizedBox(height: 10.0), + TextFormField( + decoration: InputDecoration( + labelText: 'Guest Email', + border: OutlineInputBorder(), + ), + onChanged: (value) { + setState(() { + guestEmail = value; + }); + }, + ), + const SizedBox(height: 10.0), + TextFormField( + decoration: InputDecoration( + labelText: 'Guest Phone Number', + border: OutlineInputBorder(), + ), + keyboardType: TextInputType.phone, + onChanged: (value) { + setState(() { + guestPhoneNumber = value; + }); + }, + ), + const SizedBox(height: 20.0), + ElevatedButton.icon( + onPressed: () { + // Handle booking logic + }, + icon: const Icon(Icons.add, color: Colors.white), + label: const Text('Book New', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.green, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5.0), + ), + ), + ), + const SizedBox(height: 10.0), + ElevatedButton.icon( + onPressed: () { + // Handle cancel logic + }, + icon: const Icon(Icons.close, color: Colors.white), + label: const Text('Cancel', style: TextStyle(color: Colors.white)), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5.0), + ), + ), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/screens/Hostel/student/hostel_student.dart b/lib/screens/Hostel/student/hostel_student.dart new file mode 100644 index 00000000..6e77eb82 --- /dev/null +++ b/lib/screens/Hostel/student/hostel_student.dart @@ -0,0 +1,215 @@ +import 'package:flutter/material.dart'; +import 'package:fusion/screens/Hostel/student/allottedrooms.dart'; +import 'package:fusion/screens/Hostel/student/fines.dart'; +import 'package:fusion/screens/Hostel/student/guestroom.dart'; +import 'package:fusion/screens/Hostel/student/leaveapplication.dart'; +import 'package:fusion/screens/Hostel/student/noticeboard.dart'; +import 'package:fusion/Components/appBar2.dart'; +import 'package:fusion/Components/side_drawer2.dart'; +import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/services/storage_service.dart'; +import 'package:fusion/Components/bottom_navigation_bar.dart'; + +class Hostelstudent extends StatefulWidget { + const Hostelstudent({Key? key}) : super(key: key); + + @override + _HostelstudentState createState() => _HostelstudentState(); +} + + +class _HostelstudentState extends State { + late String curr_desig; + + @override + void initState() { + super.initState(); + var service = locator(); + curr_desig = service.getFromDisk("Current_designation") ?? ""; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CustomAppBar( + curr_desig: curr_desig, + headerTitle: "Central Mess", + onDesignationChanged: (newValue) { + setState(() { + curr_desig = newValue; + }); + }, + ), + drawer: SideDrawer(curr_desig: curr_desig), + bottomNavigationBar: MyBottomNavigationBar(), + body: Container( + padding: const EdgeInsets.all(20.0), + child: GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + childAspectRatio: 1.0, + mainAxisSpacing: 5.0, + crossAxisSpacing: 5.0, + ), + children: [ + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Guestroom()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.add_home, + color: Colors.white, + size: 30, + ), + Text( + 'Guest Room', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Allottedrooms()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.home, + color: Colors.white, + size: 30, + ), + Text( + 'Alloted rooms', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Fines()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.monetization_on, + color: Colors.white, + size: 30, + ), + Text( + 'Manage Fines', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + ), + + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => Leaveapplication()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.card_travel, + color: Colors.white, + size: 30, + ), + Text( + 'Leave', + style: TextStyle(color: Colors.white, fontSize: 15), + ), + Text( + 'Application', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Noticeboard()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.dashboard, + color: Colors.white, + size: 30, + ), + Text( + 'Notice Board', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + + ]), + ), + ); + + } +} diff --git a/lib/screens/Hostel/student/leaveapplication.dart b/lib/screens/Hostel/student/leaveapplication.dart new file mode 100644 index 00000000..0cfc81cd --- /dev/null +++ b/lib/screens/Hostel/student/leaveapplication.dart @@ -0,0 +1,124 @@ +import 'package:flutter/material.dart'; + +class Leaveapplication extends StatefulWidget { + const Leaveapplication({Key? key}) : super(key: key); + + @override + _LeaveapplicationState createState() => _LeaveapplicationState(); +} + +class _LeaveapplicationState extends State { + final GlobalKey _formKey = GlobalKey(); + String? studentName; + String? rollNumber; + String? phoneNumber; + String? reason; + DateTime? startDate; + DateTime? endDate; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Leave Application'), + backgroundColor: const Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + body: Padding( + padding: const EdgeInsets.all(20), + child: Card( + elevation: 4, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15.0), + ), + child: Padding( + padding: const EdgeInsets.all(20), + child: Form( + key: _formKey, + child: ListView( + children: [ + TextFormField( + decoration: const InputDecoration(labelText: 'Student Name'), + onSaved: (String? value) { + studentName = value; + }, + ), + TextFormField( + decoration: const InputDecoration(labelText: 'Roll Number'), + onSaved: (String? value) { + rollNumber = value; + }, + ), + TextFormField( + decoration: const InputDecoration(labelText: 'Phone Number'), + onSaved: (String? value) { + phoneNumber = value; + }, + ), + TextFormField( + decoration: const InputDecoration(labelText: 'Reason'), + onSaved: (String? value) { + reason = value; + }, + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () async { + final DateTime? picked = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime.now(), + lastDate: DateTime(2101), + ); + if (picked != null) { + setState(() { + startDate = picked; + }); + } + }, + child: Text( + startDate != null + ? 'Start Date: ${startDate!.day}/${startDate!.month}/${startDate!.year}' + : 'Select Start Date', + ), + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () async { + final DateTime? picked = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime.now(), + lastDate: DateTime(2101), + ); + if (picked != null) { + setState(() { + endDate = picked; + }); + } + }, + child: Text( + endDate != null + ? 'End Date: ${endDate!.day}/${endDate!.month}/${endDate!.year}' + : 'Select End Date', + ), + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + _formKey.currentState!.save(); + // TODO: Implement submit functionality + } + }, + child: const Text('Submit'), + ), + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/screens/Hostel/student/noticeboard.dart b/lib/screens/Hostel/student/noticeboard.dart new file mode 100644 index 00000000..07175ac4 --- /dev/null +++ b/lib/screens/Hostel/student/noticeboard.dart @@ -0,0 +1,192 @@ +import 'package:flutter/material.dart'; +import 'package:fusion/Components/side_drawer.dart'; + +class Noticeboard extends StatelessWidget { + final List> notices = [ + { + "hall": "4", + "heading": "Annual Sports Meet", + "madeBy": { + "name": "John Doe", + "rollNo": "21bcs001" + }, + "description": "Get ready for an action-packed day of sports!", + "content": [ + "Date: April 25, 2024", + "Venue: Sports Ground", + "Events: Football, Cricket, Badminton, and more" + ] + }, + { + + + "hall": "3", + "heading": "Guest Lecture on AI", + "madeBy": { + "name": "Jane Smith", + "rollNo": "21bcs002" + }, + "description": "Learn about the latest advancements in Artificial Intelligence.", + "content": [ + "Speaker: Dr. Michael Johnson", + "Date: May 5, 2024", + "Time: 10:00 AM - 12:00 PM", + "Venue: Lecture Hall 1" + ] + }, + { + "hall": "2", + "heading": "Web Development Workshop", + "madeBy": { + "name": "Alice Lee", + "rollNo": "21bcs003" + }, + "description": "Enhance your web development skills with hands-on sessions.", + "content": [ + "Date: May 15, 2024", + "Time: 9:00 AM - 5:00 PM", + "Venue: Computer Lab 3", + "Topics: HTML, CSS, JavaScript" + ] + }, + { + "hall": "1", + "heading": "Cultural Night", + "madeBy": { + "name": "David Brown", + "rollNo": "21bcs004" + }, + "description": "Join us for an evening of music, dance, and fun!", + "content": [ + "Date: June 10, 2024", + "Time: 6:00 PM onwards", + "Venue: Auditorium", + "Performances: Music bands, Dance groups, Comedy acts" + ] + }, + { + "hall": "5", + "heading": "Congratulations to Toppers", + "madeBy": { + "name": "Emily Taylor", + "rollNo": "21bcs005" + }, + "description": "Celebrating the academic excellence of our top performers!", + "content": [ + "Top Scorers: John Smith, Alice Johnson, Michael Lee", + "Subject Toppers: Mathematics, Physics, Computer Science", + "Prize Distribution Ceremony: June 5, 2024" + ] + } + ]; + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: SideDrawer(), + appBar: AppBar( + title: const Text('Notice Board'), + backgroundColor: const Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + body: ListView.builder( + itemCount: notices.length, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Card( + elevation: 4, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + child: InkWell( + onTap: () { + _showNoticeDetails(context, notices[index]); + }, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + notices[index]['heading'], + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ), + Text( + 'Made By: ${notices[index]['madeBy']['name']} - ${notices[index]['madeBy']['rollNo']}', + style: TextStyle( + color: Colors.grey[700], + ), + ), + ], + ), + SizedBox(height: 8), + Text( + notices[index]['description'], + style: TextStyle( + color: Colors.grey[700], + ), + ), + ], + ), + ), + ), + ), + ); + }, + ), + ); + } + + void _showNoticeDetails(BuildContext context, Map notice) { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text(notice['heading']), + content: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + 'Description: ${notice['description']}', + style: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + SizedBox(height: 8), + ...List.from(notice['content'] + .map((content) => Text(content))), + SizedBox(height: 8), + Text( + 'Made By: ${notice['madeBy']['name']} - ${notice['madeBy']['rollNo']}', + ), + ], + ), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: const Text('Close'), + ), + ], + ); + }, + ); + } +} + +void main() { + runApp(MaterialApp( + home: Noticeboard(), + )); +} diff --git a/lib/screens/Hostel/superadmin/add_hostel.dart b/lib/screens/Hostel/superadmin/add_hostel.dart new file mode 100644 index 00000000..b6d6da55 --- /dev/null +++ b/lib/screens/Hostel/superadmin/add_hostel.dart @@ -0,0 +1,135 @@ +import 'package:flutter/material.dart'; +import 'package:fusion/Components/side_drawer.dart'; + +class AddHostelScreen extends StatefulWidget { + const AddHostelScreen({Key? key}) : super(key: key); + + @override + _AddHostelScreenState createState() => _AddHostelScreenState(); +} + +class _AddHostelScreenState extends State { + final _formKey = GlobalKey(); + + String? _selectedSeater; + + final List _seaterTypes = ['Single', 'Double', 'Triple']; + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: SideDrawer(), + appBar: AppBar( + title: const Text('Add Hostel'), + backgroundColor: const Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + body: Padding( + padding: const EdgeInsets.all(20), + child: Card( + elevation: 5, + child: Padding( + padding: const EdgeInsets.all(20), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Add Hostel', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + SizedBox(height: 20), + TextFormField( + decoration: InputDecoration( + labelText: 'Hall ID', + border: OutlineInputBorder(), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter Hall ID'; + } + return null; + }, + ), + SizedBox(height: 20), + TextFormField( + decoration: InputDecoration( + labelText: 'Max Accommodation', + border: OutlineInputBorder(), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter Max Accommodation'; + } + return null; + }, + ), + SizedBox(height: 20), + TextFormField( + decoration: InputDecoration( + labelText: 'Assigned Batch', + border: OutlineInputBorder(), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter Assigned Batch'; + } + return null; + }, + ), + SizedBox(height: 20), + DropdownButtonFormField( + decoration: InputDecoration( + labelText: 'Type of Seater', + border: OutlineInputBorder(), + ), + value: _selectedSeater, + items: _seaterTypes.map((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(), + onChanged: (value) { + setState(() { + _selectedSeater = value; + }); + }, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please select Type of Seater'; + } + return null; + }, + ), + SizedBox(height: 20), + ElevatedButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + _showSuccessSnackBar(); + } + }, + child: Text('Add Hostel'), + style: ElevatedButton.styleFrom( + primary: const Color.fromARGB(255, 245, 103, 47), + padding: EdgeInsets.symmetric(vertical: 15, horizontal: 50), + ), + ), + ], + ), + ), + ), + ), + ), + ); + } + + void _showSuccessSnackBar() { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Hall successfully added'), + ), + ); + } +} diff --git a/lib/screens/Hostel/superadmin/assign_batch.dart b/lib/screens/Hostel/superadmin/assign_batch.dart new file mode 100644 index 00000000..9bfb50be --- /dev/null +++ b/lib/screens/Hostel/superadmin/assign_batch.dart @@ -0,0 +1,120 @@ +import 'package:flutter/material.dart'; + +class AssignBatchScreen extends StatefulWidget { + const AssignBatchScreen({Key? key}) : super(key: key); + + @override + _AssignBatchScreenState createState() => _AssignBatchScreenState(); +} + +class _AssignBatchScreenState extends State { + final _formKey = GlobalKey(); + + String? _selectedHall; + String? _batchID; + + final List _hallList = ['Hall 1', 'Hall 2', 'Hall 3', 'Hall 4', 'Hall 5']; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Assign Batch'), + backgroundColor: Color.fromARGB(255, 245, 103, 47), // Background color + foregroundColor: Colors.white, // Foreground color (for back button and title) + ), + body: Padding( + padding: const EdgeInsets.all(20), + child: Card( + elevation: 5, + child: Padding( + padding: const EdgeInsets.all(20), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Assign Batch', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + SizedBox(height: 20), + DropdownButtonFormField( + decoration: InputDecoration( + labelText: 'Select Hall', + border: OutlineInputBorder(), + ), + value: _selectedHall, + items: _hallList.map((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(), + onChanged: (value) { + setState(() { + _selectedHall = value; + }); + }, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please select a hall'; + } + return null; + }, + ), + SizedBox(height: 20), + TextFormField( + decoration: InputDecoration( + labelText: 'Batch ID', + border: OutlineInputBorder(), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter Batch ID'; + } + return null; + }, + onChanged: (value) { + setState(() { + _batchID = value; + }); + }, + ), + SizedBox(height: 20), + ElevatedButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + _assignBatch(); + } + }, + child: Text('Assign'), + style: ElevatedButton.styleFrom( + primary: Color.fromARGB(255, 245, 103, 47), + padding: EdgeInsets.symmetric(vertical: 15, horizontal: 50), + ), + ), + ], + ), + ), + ), + ), + ), + ); + } + + void _assignBatch() { + // Simulate assigning batch logic + // Replace this with actual logic to assign batch + String message = 'Batch successfully assigned to $_selectedHall'; + _showSuccessSnackBar(message); + } + + void _showSuccessSnackBar(String message) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(message), + ), + ); + } +} diff --git a/lib/screens/Hostel/superadmin/assign_caretaker.dart b/lib/screens/Hostel/superadmin/assign_caretaker.dart new file mode 100644 index 00000000..5df0ad41 --- /dev/null +++ b/lib/screens/Hostel/superadmin/assign_caretaker.dart @@ -0,0 +1,122 @@ +import 'package:flutter/material.dart'; +import 'package:fusion/Components/side_drawer.dart'; + +class AssignCaretakerScreen extends StatefulWidget { + const AssignCaretakerScreen({Key? key}) : super(key: key); + + @override + _AssignCaretakerScreenState createState() => _AssignCaretakerScreenState(); +} + +class _AssignCaretakerScreenState extends State { + final _formKey = GlobalKey(); + + String? _selectedHall; + String? _caretakerUsername; + + final List _hallList = ['1', '2', '3', '4']; + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: SideDrawer(), + appBar: AppBar( + title: const Text('Assign Caretaker'), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + body: Padding( + padding: const EdgeInsets.all(20), + child: Card( + elevation: 5, + child: Padding( + padding: const EdgeInsets.all(20), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Assign Caretaker', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + SizedBox(height: 20), + DropdownButtonFormField( + decoration: InputDecoration( + labelText: 'Select Hall', + border: OutlineInputBorder(), + ), + value: _selectedHall, + items: _hallList.map((String value) { + return DropdownMenuItem( + value: value, + child: Text('Hall $value'), + ); + }).toList(), + onChanged: (value) { + setState(() { + _selectedHall = value; + }); + }, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please select a hall'; + } + return null; + }, + ), + SizedBox(height: 20), + TextFormField( + decoration: InputDecoration( + labelText: 'Caretaker Username', + border: OutlineInputBorder(), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter caretaker username'; + } + return null; + }, + onChanged: (value) { + setState(() { + _caretakerUsername = value; + }); + }, + ), + SizedBox(height: 20), + ElevatedButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + _assignCaretaker(); + } + }, + child: Text('Assign'), + style: ElevatedButton.styleFrom( + primary: Color.fromARGB(255, 245, 103, 47), + padding: EdgeInsets.symmetric(vertical: 15, horizontal: 50), + ), + ), + ], + ), + ), + ), + ), + ), + ); + } + + void _assignCaretaker() { + // Simulate assigning caretaker logic + // Replace this with actual logic to assign caretaker + String message = 'Caretaker successfully assigned to Hall $_selectedHall'; + _showSuccessSnackBar(message); + } + + void _showSuccessSnackBar(String message) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(message), + ), + ); + } +} diff --git a/lib/screens/Hostel/superadmin/assign_warden.dart b/lib/screens/Hostel/superadmin/assign_warden.dart new file mode 100644 index 00000000..5e76f0eb --- /dev/null +++ b/lib/screens/Hostel/superadmin/assign_warden.dart @@ -0,0 +1,123 @@ +// assign_warden.dart +import 'package:flutter/material.dart'; +import 'package:fusion/Components/side_drawer.dart'; + +class AssignWardenScreen extends StatefulWidget { + const AssignWardenScreen({Key? key}) : super(key: key); + + @override + _AssignWardenScreenState createState() => _AssignWardenScreenState(); +} + +class _AssignWardenScreenState extends State { + final _formKey = GlobalKey(); + + String? _selectedHall; + String? _wardenID; + + final List _hallList = ['Hall 1', 'Hall 2', 'Hall 3', 'Hall 4', 'Hall 5']; + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: SideDrawer(), + appBar: AppBar( + title: const Text('Assign Warden'), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + body: Padding( + padding: const EdgeInsets.all(20), + child: Card( + elevation: 5, + child: Padding( + padding: const EdgeInsets.all(20), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Assign Warden', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + SizedBox(height: 20), + DropdownButtonFormField( + decoration: InputDecoration( + labelText: 'Select Hall', + border: OutlineInputBorder(), + ), + value: _selectedHall, + items: _hallList.map((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(), + onChanged: (value) { + setState(() { + _selectedHall = value; + }); + }, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please select a hall'; + } + return null; + }, + ), + SizedBox(height: 20), + TextFormField( + decoration: InputDecoration( + labelText: 'Warden ID', + border: OutlineInputBorder(), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter Warden ID'; + } + return null; + }, + onChanged: (value) { + setState(() { + _wardenID = value; + }); + }, + ), + SizedBox(height: 20), + ElevatedButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + _assignWarden(); + } + }, + child: Text('Assign'), + style: ElevatedButton.styleFrom( + primary: Color.fromARGB(255, 245, 103, 47), + padding: EdgeInsets.symmetric(vertical: 15, horizontal: 50), + ), + ), + ], + ), + ), + ), + ), + ), + ); + } + + void _assignWarden() { + // Simulate assigning warden logic + // Replace this with actual logic to assign warden + String message = 'Warden successfully assigned to $_selectedHall'; + _showSuccessSnackBar(message); + } + + void _showSuccessSnackBar(String message) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(message), + ), + ); + } +} diff --git a/lib/screens/Hostel/superadmin/hostel_admin.dart b/lib/screens/Hostel/superadmin/hostel_admin.dart new file mode 100644 index 00000000..7cc4a627 --- /dev/null +++ b/lib/screens/Hostel/superadmin/hostel_admin.dart @@ -0,0 +1,139 @@ +import 'package:flutter/material.dart'; +import 'package:fusion/screens/Hostel/superadmin/add_hostel.dart'; +import 'package:fusion/screens/Hostel/superadmin/assign_warden.dart'; +import 'package:fusion/screens/Hostel/superadmin/assign_batch.dart'; +import 'package:fusion/screens/Hostel/superadmin/assign_caretaker.dart'; +import 'package:fusion/screens/Hostel/superadmin/view_hostel_history.dart'; +import 'package:fusion/screens/Hostel/superadmin/view_hostel.dart'; +// import 'package:fusion/Components/side_drawer.dart'; + +import 'package:fusion/Components/appBar2.dart'; +import 'package:fusion/Components/side_drawer2.dart'; +import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/services/storage_service.dart'; +import 'package:fusion/Components/bottom_navigation_bar.dart'; + +class Hosteladmin extends StatefulWidget { + const Hosteladmin({Key? key}) : super(key: key); +@override + _Hosteladminstate createState() => _Hosteladminstate(); +} +class _Hosteladminstate extends State { + late String curr_desig; + + @override + void initState() { + super.initState(); + var service = locator(); + curr_desig = service.getFromDisk("Current_designation") ?? ""; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CustomAppBar( + curr_desig: curr_desig, + headerTitle: "Central Mess", + onDesignationChanged: (newValue) { + setState(() { + curr_desig = newValue; + }); + }, + ), + drawer: SideDrawer(curr_desig: curr_desig), + bottomNavigationBar: MyBottomNavigationBar(), + body: Container( + padding: const EdgeInsets.all(20.0), + child: Container( + child: GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + childAspectRatio: 1.0, + mainAxisSpacing: 5.0, + crossAxisSpacing: 5.0, + ), + children: [ + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AddHostelScreen()), + ); + }, + child: buildCard(Icons.add, 'Add Hostel', context), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AssignWardenScreen()), + ); + }, + child: buildCard(Icons.person_add_alt_1, 'Assign Warden', context), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AssignBatchScreen()), + ); + }, + child: buildCard(Icons.batch_prediction, 'Assign Batch', context), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AssignCaretakerScreen()), + ); + }, + child: buildCard(Icons.person_add, 'Assign Caretaker', context), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => ViewHostelHistoryScreen()), + ); + }, + child: buildCard(Icons.history, 'View Hostel History', context), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => ViewHostelScreen()), + ); + }, + child: buildCard(Icons.home, 'View Hostel', context), + ), + ], + ), + ), + ), + ); + } + + Widget buildCard(IconData icon, String title, BuildContext context) { + return Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + icon, + color: Colors.white, + size: 30, + ), + Text( + title, + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ); + } +} diff --git a/lib/screens/Hostel/superadmin/view_hostel.dart b/lib/screens/Hostel/superadmin/view_hostel.dart new file mode 100644 index 00000000..773ed7a7 --- /dev/null +++ b/lib/screens/Hostel/superadmin/view_hostel.dart @@ -0,0 +1,109 @@ +import 'package:flutter/material.dart'; +import 'package:fusion/Components/side_drawer.dart'; + +class ViewHostelScreen extends StatelessWidget { + const ViewHostelScreen({Key? key}) : super(key: key); + + // Define the hostel data + static const List> hostelData = [ + { + "hostels": [ + { + "hallId": "1", + "hallName": "Hall 1", + "seaterType": "single", + "maxAccommodation": 400, + "occupied": 400, + "vacantSeats": 0, + "assignedBatch": "2019", + "assignedCaretaker": "None", + "assignedWardenID": "None" + }, + { + "hallId": "2", + "hallName": "Hall 2", + "seaterType": "single", + "maxAccommodation": 500, + "occupied": 400, + "vacantSeats": 100, + "assignedBatch": "2021", + "assignedCaretaker": "shyam", + "assignedWardenID": "GD" + }, + { + "hallId": "3", + "hallName": "Hall 3", + "seaterType": "single", + "maxAccommodation": 400, + "occupied": 380, + "vacantSeats": 20, + "assignedBatch": "2019", + "assignedCaretaker": "pankaj", + "assignedWardenID": "None" + } + ] +} + + ]; + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: SideDrawer(), + appBar: AppBar( + title: const Text('View Hostel'), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Card( + elevation: 5, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + 'Hostel List', + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + ), + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: DataTable( + columns: const [ + DataColumn(label: Text('Hall ID')), + DataColumn(label: Text('Hall Name')), + DataColumn(label: Text('Seater Type')), + DataColumn(label: Text('Max Accommodation')), + DataColumn(label: Text('Occupied')), + DataColumn(label: Text('Vacant Seats')), + DataColumn(label: Text('Assigned Batch')), + DataColumn(label: Text('Assigned Caretaker')), + DataColumn(label: Text('Assigned Warden ID')), + ], + rows: hostelData.map((data) { + return DataRow( + cells: [ + DataCell(Text(data['hallId'])), + DataCell(Text(data['hallName'])), + DataCell(Text(data['seaterType'])), + DataCell(Text(data['maxAccommodation'].toString())), + DataCell(Text(data['occupied'].toString())), + DataCell(Text(data['vacantSeats'].toString())), + DataCell(Text(data['assignedBatch'])), + DataCell(Text(data['assignedCaretaker'])), + DataCell(Text(data['assignedWardenID'])), + ], + ); + }).toList(), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/screens/Hostel/superadmin/view_hostel_history.dart b/lib/screens/Hostel/superadmin/view_hostel_history.dart new file mode 100644 index 00000000..75258a7e --- /dev/null +++ b/lib/screens/Hostel/superadmin/view_hostel_history.dart @@ -0,0 +1,146 @@ +import 'package:flutter/material.dart'; +import 'package:fusion/Components/side_drawer.dart'; + +class ViewHostelHistoryScreen extends StatefulWidget { + const ViewHostelHistoryScreen({Key? key}) : super(key: key); + + @override + _ViewHostelHistoryScreenState createState() => _ViewHostelHistoryScreenState(); +} + +class _ViewHostelHistoryScreenState extends State { + String _selectedHall = 'Hall 1'; // Default selected hall + static const Map? hostelHistoryData = { + "Hall 1": [ + { + "hall": "Hall 1", + "batch": "2019", + "caretaker": "Pankaj", + "warden": "None", + "date": "2024-04-18" + }, + { + "hall": "Hall 1", + "batch": "2020", + "caretaker": "Pankaj", + "warden": "None", + "date": "2024-04-18" + } + ], + "Hall 2": [ + { + "hall": "Hall 2", + "batch": "2019", + "caretaker": "Anita", + "warden": "None", + "date": "2024-04-18" + }, + { + "hall": "Hall 2", + "batch": "2020", + "caretaker": "Anita", + "warden": "None", + "date": "2024-04-18" + } + ], + // Add more hostel histories as needed + }; + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: SideDrawer(), + appBar: AppBar( + title: Text('View Hostel History - $_selectedHall'), // Display selected hall + backgroundColor: Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + body: Column( + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: DropdownButton( + value: _selectedHall, + onChanged: (newValue) { + setState(() { + _selectedHall = newValue!; + }); + }, + items: hostelHistoryData?.keys.map((hall) { + return DropdownMenuItem( + value: hall, + child: Text(hall), + ); + }).toList(), + ), + ), + Card( + elevation: 3, + margin: EdgeInsets.all(16.0), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Table( + border: TableBorder.all(color: Colors.grey), + columnWidths: { + 0: FlexColumnWidth(1), + 1: FlexColumnWidth(1), + 2: FlexColumnWidth(1), + 3: FlexColumnWidth(1), + 4: FlexColumnWidth(1), + }, + children: [ + _buildTableRow('Hall', 'Batch', 'Caretaker', 'Warden', 'Date'), + ..._buildRows(), + ], + ), + ), + ), + ], + ), + ); + } + + List _buildRows() { + List rows = []; + hostelHistoryData?[_selectedHall]?.forEach((history) { + rows.add( + TableRow( + children: [ + _buildTableCell(history['hall']), + _buildTableCell(history['batch']), + _buildTableCell(history['caretaker']), + _buildTableCell(history['warden']), + _buildTableCell(history['date']), + ], + ), + ); + }); + return rows; + } + + Widget _buildTableCell(String value) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Text(value), + ); + } + + TableRow _buildTableRow(String hall, String batch, String caretaker, String warden, String date) { + return TableRow( + decoration: BoxDecoration(color: Colors.grey[300]), + children: [ + _buildTableCell(hall), + _buildTableCell(batch), + _buildTableCell(caretaker), + _buildTableCell(warden), + _buildTableCell(date), + ], + ); + } +} + +void main() { + runApp(MaterialApp( + home: ViewHostelHistoryScreen(), + )); +} diff --git a/lib/screens/Hostel/warden/hostel_warden.dart b/lib/screens/Hostel/warden/hostel_warden.dart new file mode 100644 index 00000000..1a86b210 --- /dev/null +++ b/lib/screens/Hostel/warden/hostel_warden.dart @@ -0,0 +1,212 @@ + +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; + +import 'package:fusion/screens/Hostel/warden/managerooms.dart'; +import 'package:fusion/screens/Hostel/warden/managestudent.dart'; +import 'package:fusion/screens/Hostel/warden/noticeboard.dart'; +import 'package:fusion/screens/Hostel/warden/report.dart'; +import 'package:fusion/screens/Hostel/warden/staffinfo.dart'; +import 'package:fusion/Components/appBar2.dart'; +import 'package:fusion/Components/side_drawer2.dart'; +import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/services/storage_service.dart'; +import 'package:fusion/Components/bottom_navigation_bar.dart'; + + +class Hostelwarden extends StatefulWidget { + const Hostelwarden({Key? key}) : super(key: key); +@override + _Hostelwardenstate createState() => _Hostelwardenstate(); +} +class _Hostelwardenstate extends State { + late String curr_desig; + + @override + void initState() { + super.initState(); + var service = locator(); + curr_desig = service.getFromDisk("Current_designation") ?? ""; + } + + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CustomAppBar( + curr_desig: curr_desig, + headerTitle: "Central Mess", + onDesignationChanged: (newValue) { + setState(() { + curr_desig = newValue; + }); + }, + ), + drawer: SideDrawer(curr_desig: curr_desig), + bottomNavigationBar: MyBottomNavigationBar(), + body: Container( + padding: const EdgeInsets.all(20.0), + child: Container( + child: GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + childAspectRatio: 1.0, + mainAxisSpacing: 5.0, + crossAxisSpacing: 5.0, + ), + children: [ + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => StaffInfo()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.person, + color: Colors.white, + size: 30, + ), + Text( + 'Staff Info', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Managerooms()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.person, + color: Colors.white, + size: 30, + ), + Text( + 'ManageRooms', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Report()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.report, + color: Colors.white, + size: 30, + ), + Text( + 'Report', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Managestudent()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.school, + color: Colors.white, + size: 30, + ), + Text( + 'Manage', + style: TextStyle(color: Colors.white, fontSize: 15), + ), + Text( + 'Student', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Noticeboard()), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Color.fromARGB(255, 245, 103, 47), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.dashboard, + color: Colors.white, + size: 30, + ), + Text( + 'Notice Board', + style: TextStyle(color: Colors.white, fontSize: 15), + ) + ], + ), + ), + ), + + ]), + ), + ), + ); + } +} + diff --git a/lib/screens/Hostel/warden/managerooms.dart b/lib/screens/Hostel/warden/managerooms.dart new file mode 100644 index 00000000..54e7bd71 --- /dev/null +++ b/lib/screens/Hostel/warden/managerooms.dart @@ -0,0 +1,557 @@ + +import 'dart:convert'; +import 'package:flutter/material.dart'; + +class Room { + final int roomNumber; + final int capacity; + + final int currentOccupancy; + final String status; + final List studentNames; + final int numberOfStudents; + + Room({ + required this.roomNumber, + required this.capacity, + required this.currentOccupancy, + required this.status, + required this.studentNames, + required this.numberOfStudents, + }); +} + + +class Managerooms extends StatefulWidget { + const Managerooms({Key? key}) : super(key: key); + + @override + _ManageroomsState createState() => _ManageroomsState(); +} + + +class _ManageroomsState extends State { + List rooms = []; + List filteredRooms = []; + + @override + void initState() { + super.initState(); + _fetchRoomDetails(); + } + + Future _fetchRoomDetails() async { + // Simulating GET API call to fetch room details + final String roomData = ''' + [ + {"roomNumber": 101, "capacity": 2, "currentOccupancy": 1, "status": "Partially Allotted", "studentNames": ["Raman"], "studentRollNumbers": ["21bcs200"]}, + {"roomNumber": 102, "capacity": 3, "currentOccupancy": 2, "status": "Partially Allotted", "studentNames": ["Naman", "Ramu"], "studentRollNumbers": ["22bme041", "22bsm045"]}, + {"roomNumber": 103, "capacity": 3, "currentOccupancy": 3, "status": "Fully Allotted", "studentNames": ["Surya", "Divyanshu", "Raju"], "studentRollNumbers": ["21bcs101", "21bcs102", "21bcs103"]}, + {"roomNumber": 104, "capacity": 4, "currentOccupancy": 0, "status": "Unallotted", "studentNames": [], "studentRollNumbers": []}, + {"roomNumber": 105, "capacity": 2, "currentOccupancy": 2, "status": "Fully Allotted", "studentNames": ["John", "Doe"], "studentRollNumbers": ["22bcs001", "22bcs002"]} + ] + '''; + final List roomList = json.decode(roomData); + setState(() { + rooms = roomList.map((room) => + Room( + roomNumber: room['roomNumber'] as int, + capacity: room['capacity'] as int, + currentOccupancy: room['currentOccupancy'] as int, + status: room['status'] as String, + studentNames: List.from( + room['studentNames'] as List), + studentRollNumbers: List.from( + room['studentRollNumbers'] as List), + )).toList(); + filteredRooms = List.from(rooms); + }); + } + + Future _editStudentDetails(Room room) async { + List updatedNames = List.from(room.studentNames); + List updatedRollNumbers = List.from(room.studentRollNumbers); + + await showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Edit Student Details'), + content: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + for (int i = 0; i < room.currentOccupancy; i++) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Student-${i + 1}:'), + TextField( + controller: TextEditingController( + text: room.studentNames[i]), + onChanged: (value) { + updatedNames[i] = value; + }, + ), + Text('Roll.No-${i + 1}:'), + TextField( + controller: TextEditingController( + text: room.studentRollNumbers[i]), + onChanged: (value) { + updatedRollNumbers[i] = value; + }, + ), + ], + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + bool valid = true; + for (int i = 0; i < updatedNames.length; i++) { + if ((updatedNames[i].isNotEmpty && + updatedRollNumbers[i].isEmpty) || + (updatedRollNumbers[i].isNotEmpty && + updatedNames[i].isEmpty)) { + valid = false; + break; + } + } + if (valid) { + setState(() { + room.studentNames = updatedNames.toList(); + room.studentRollNumbers = updatedRollNumbers.toList(); + room.currentOccupancy = room.studentNames.length; + room.status = room.currentOccupancy == room.capacity + ? "Fully Allotted" + : "Partially Allotted"; + }); + Navigator.of(context).pop(); + } else { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Error'), + content: Text( + 'Please fill in both Student and Roll.No fields for each student.'), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('OK'), + ), + ], + ); + }, + ); + } + }, + child: Text('Submit'), + ), + ], + ); + }, + ); + } + + Future _deleteStudentDetails(Room room) async { + List studentNames = List.from(room.studentNames); + List studentRollNumbers = List.from(room.studentRollNumbers); + + if (studentNames.isEmpty) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('No Students Found'), + content: Text('There are no students in this room to delete.'), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('OK'), + ), + ], + ); + }, + ); + return; + } + + String? selectedStudent; + await showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Select Student to Delete'), + content: Column( + mainAxisSize: MainAxisSize.min, + children: List.generate(studentNames.length, (index) { + return RadioListTile( + title: Text('${studentNames[index]} (${studentRollNumbers[index]})'), + value: studentNames[index], + groupValue: selectedStudent, + onChanged: (value) { + setState(() { + selectedStudent = value; + }); + }, + ); + }), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + if (selectedStudent != null) { + setState(() { + int index = room.studentNames.indexOf(selectedStudent!); + room.studentNames.removeAt(index); + room.studentRollNumbers.removeAt(index); + room.currentOccupancy--; + room.status = room.currentOccupancy == 0 + ? "Unallotted" + : "Partially Allotted"; + }); + Navigator.of(context).pop(); + } else { + // Handle the case when selectedStudent is null + print('No student selected to delete.'); + } + }, + child: Text('Delete'), + ), + ], + ); + }, + ); + } + + + Future _showAddDialog(Room room) async { + if (room.status == "Unallotted" || room.status == "Partially Allotted") { + String studentName = ''; + String studentRollNumber = ''; + + await showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Add Student'), + content: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + onChanged: (value) { + studentName = value; + }, + decoration: InputDecoration( + labelText: 'Student Name', + ), + ), + TextField( + onChanged: (value) { + studentRollNumber = value; + }, + decoration: InputDecoration( + labelText: 'Student Roll.No', + ), + ), + ], + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + setState(() { + room.studentNames.add(studentName); + room.studentRollNumbers.add(studentRollNumber); + room.currentOccupancy++; + room.status = room.currentOccupancy == room.capacity ? "Fully Allotted" : "Partially Allotted"; + }); + Navigator.of(context).pop(); + }, + child: Text('Add'), + ), + ], + ); + }, + ); + } else { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Alert'), + content: Text('You can only add students to "Unallotted" or "Partially Allotted" rooms only.'), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('OK'), + ), + ], + ); + }, + ); + } + } + + void _searchRooms(String query) { + setState(() { + filteredRooms = rooms.where((room) { + final roomNumberMatches = room.roomNumber.toString().contains(query); + final statusMatches = room.status.toLowerCase().contains(query.toLowerCase()); + final nameMatches = room.studentNames.any((name) => name.toLowerCase().contains(query.toLowerCase())); + final rollMatches = room.studentRollNumbers.any((roll) => roll.toLowerCase().contains(query.toLowerCase())); + return roomNumberMatches || statusMatches || nameMatches || rollMatches; + }).toList(); + + // Sort the filtered rooms based on relevance to the search query + filteredRooms.sort((a, b) { + final aRoomNumberMatches = a.roomNumber.toString().contains(query); + final bRoomNumberMatches = b.roomNumber.toString().contains(query); + final aStatusMatches = a.status.toLowerCase().contains(query.toLowerCase()); + final bStatusMatches = b.status.toLowerCase().contains(query.toLowerCase()); + final aNameMatches = a.studentNames.any((name) => name.toLowerCase().contains(query.toLowerCase())); + final bNameMatches = b.studentNames.any((name) => name.toLowerCase().contains(query.toLowerCase())); + final aRollMatches = a.studentRollNumbers.any((roll) => roll.toLowerCase().contains(query.toLowerCase())); + final bRollMatches = b.studentRollNumbers.any((roll) => roll.toLowerCase().contains(query.toLowerCase())); + + if (aRoomNumberMatches && !bRoomNumberMatches) { + return -1; + } else if (!aRoomNumberMatches && bRoomNumberMatches) { + return 1; + } else if (aStatusMatches && !bStatusMatches) { + return -1; + } else if (!aStatusMatches && bStatusMatches) { + return 1; + } else if (aNameMatches && !bNameMatches) { + return -1; + } else if (!aNameMatches && bNameMatches) { + return 1; + } else if (aRollMatches && !bRollMatches) { + return -1; + } else if (!aRollMatches && bRollMatches) { + return 1; + } else { + return 0; + } + }); + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Manage Rooms'), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + actions: [ + IconButton( + icon: Icon(Icons.search), + onPressed: () async { + final String? result = await showSearch( + context: context, + delegate: RoomSearchDelegate(rooms: rooms), + ); + if (result != null) { + _searchRooms(result); + } + }, + ), + ], + ), + body: SingleChildScrollView( + child: DataTable( + columns: const [ + DataColumn(label: Text('Room No')), + DataColumn(label: Text('Room Capacity')), + DataColumn(label: Text('Current Occupancy')), + DataColumn(label: Text('Current Status')), + DataColumn(label: Text('Student Names')), + DataColumn(label: Text('Roll.No of Students')), + DataColumn(label: Text('Edit')), + DataColumn(label: Text('Add')), + DataColumn(label: Text('Delete')), + ], + rows: filteredRooms.map((room) { + return DataRow(cells: [ + DataCell(Text(room.roomNumber.toString())), + DataCell(Text(room.capacity.toString())), + DataCell(Text(room.currentOccupancy.toString())), + DataCell(Text(room.status)), + DataCell(Text(room.studentNames.join(', '))), + DataCell(Text(room.studentRollNumbers.join(', '))), + DataCell( + IconButton( + icon: Icon(Icons.edit), + onPressed: () { + if (room.status != "Unallotted") { + _editStudentDetails(room); + } else { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Alert'), + content: Text('You can edit students in "Partially Allotted" or "Fully Allotted" rooms only.'), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('OK'), + ), + ], + ); + }, + ); + } + }, + ), + ), + DataCell( + IconButton( + icon: Icon(Icons.add), + onPressed: () { + _showAddDialog(room); + }, + ), + ), + DataCell( + IconButton( + icon: Icon(Icons.delete), + onPressed: () { + _deleteStudentDetails(room); + }, + ), + ), + ]); + + }).toList(), + ), + ), + ); + } +} + + +class RoomSearchDelegate extends SearchDelegate { + + final List rooms; + + RoomSearchDelegate({required this.rooms}); + + @override + ThemeData appBarTheme(BuildContext context) { + final ThemeData theme = Theme.of(context); + return theme.copyWith( + appBarTheme: AppBarTheme( + + backgroundColor: theme.scaffoldBackgroundColor, // Match with screen's UI theme + iconTheme: IconThemeData(color: theme.primaryColor), // Match with screen's UI theme + + ), + ); + } + + @override + List buildActions(BuildContext context) { + return [ + IconButton( + icon: Icon(Icons.clear), + onPressed: () { + query = ''; + }, + ), + ]; + } + + + @override + Widget buildLeading(BuildContext context) { + return IconButton( + icon: Icon(Icons.arrow_back), + onPressed: () { + close(context, null); + }, + ); + } + + @override + Widget buildResults(BuildContext context) { + return _buildSearchResults(context); + } + + @override + Widget buildSuggestions(BuildContext context) { + return _buildSearchResults(context); + } + + Widget _buildSearchResults(BuildContext context) { + final List suggestionList = query.isEmpty + ? rooms + : rooms.where((room) { + final roomNumberMatches = room.roomNumber.toString().contains(query); + final statusMatches = room.status.toLowerCase().contains( + query.toLowerCase()); + final nameMatches = room.studentNames.any((name) => + name.toLowerCase().contains(query.toLowerCase())); + final rollMatches = room.studentRollNumbers.any((roll) => + roll.toLowerCase().contains(query.toLowerCase())); + return roomNumberMatches || statusMatches || nameMatches || rollMatches; + }).toList(); + + return ListView.builder( + itemCount: suggestionList.length, + itemBuilder: (context, index) { + final Room room = suggestionList[index]; + return ListTile( + title: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Room No: ${room.roomNumber}'), + Text('Status: ${room.status}'), + Text('Students: ${room.studentNames.join(", ")}'), + Text('Roll Numbers: ${room.studentRollNumbers.join(", ")}'), + ], + ), + onTap: () { + close(context, suggestionList[index].roomNumber.toString()); + }, + ); + }, + ); + } +} + + +void main() { + runApp(MaterialApp( + home: Managerooms(), + )); +} diff --git a/lib/screens/Hostel/warden/managestudent.dart b/lib/screens/Hostel/warden/managestudent.dart new file mode 100644 index 00000000..7d455be0 --- /dev/null +++ b/lib/screens/Hostel/warden/managestudent.dart @@ -0,0 +1,549 @@ + +import 'dart:convert'; +import 'package:flutter/material.dart'; + + + +class Student { + final String rollNo; + String name; + int batch; + String program; + String specialization; + String hallNo; + String roomNo; + String contactNo; + String address; + + Student({ + required this.rollNo, + required this.name, + required this.batch, + required this.program, + required this.specialization, + required this.hallNo, + required this.roomNo, + required this.contactNo, + required this.address, + }); +} + +class Managestudent extends StatefulWidget { + const Managestudent({Key? key}) : super(key: key); + + @override + _ManagestudentState createState() => _ManagestudentState(); +} + +class _ManagestudentState extends State { + List students = []; + List filteredStudents = []; + + @override + void initState() { + super.initState(); + _fetchStudentDetails(); + } + + Future _fetchStudentDetails() async { + // Simulating GET API call to fetch student details + final String studentData = ''' + [ + {"rollNo": "21bcs001", "name": "Rahul", "batch": 2021, "program": "B.Tech", "specialization": "CSE", "hallNo": "Hall-4", "roomNo": "G-31", "contactNo": "+911234567890", "address": "Address 1, City 1, State 1, Country 1"}, + {"rollNo": "21bme002", "name": "Kiran", "batch": 2021, "program": "B.Tech", "specialization": "MEE", "hallNo": "Hall-4", "roomNo": "F-24", "contactNo": "+919876543210", "address": "Address 2, City 2, State 2, Country 2"}, + {"rollNo": "21bcs003", "name": "Amit", "batch": 2021, "program": "B.Tech", "specialization": "CSE", "hallNo": "Hall-4", "roomNo": "S-12", "contactNo": "+914561237890", "address": "Address 3, City 3, State 3, Country 3"}, + {"rollNo": "21sm004", "name": "Kunal", "batch": 2021, "program": "B.Tech", "specialization": "SM", "hallNo": "Hall-4", "roomNo": "G-31", "contactNo": "+911234567890", "address": "Address 4, City 4, State 4, Country 4"}, + {"rollNo": "21bcs005", "name": "Vishal", "batch": 2021, "program": "B.Tech", "specialization": "CSE", "hallNo": "Hall-4", "roomNo": "F-24", "contactNo": "+919876543210", "address": "Address 5, City 5, State 5, Country 5"}, + {"rollNo": "23me116", "name": "Divyanshu", "batch": 2023, "program": "B.Tech", "specialization": "ME", "hallNo": "Hall-4", "roomNo": "S-12", "contactNo": "+914561237890", "address": "Address 6, City 6, State 6, Country 6"}, + {"rollNo": "23bec117", "name": "Raj", "batch": 2023, "program": "B.Tech", "specialization": "ECE", "hallNo": "Hall-4", "roomNo": "G-31", "contactNo": "+911234567890", "address": "Address 7, City 7, State 7, Country 7"}, + {"rollNo": "23bds118", "name": "Anurag", "batch": 2023, "program": "B.Des", "specialization": "DS", "hallNo": "Hall-4", "roomNo": "F-24", "contactNo": "+919876543210", "address": "Address 8, City 8, State 8, Country 8"} + ] + '''; + final List studentList = json.decode(studentData); + setState(() { + students = studentList.map((student) => Student( + rollNo: student['rollNo'], + name: student['name'], + batch: student['batch'], + program: student['program'], + specialization: student['specialization'], + hallNo: student['hallNo'], + roomNo: student['roomNo'], + contactNo: student['contactNo'], + address: student['address'], + )).toList(); + filteredStudents = List.from(students); + }); + } + + Future _editStudentDetails(Student student) async { + // Display dialog to edit student details + showDialog( + context: context, + builder: (BuildContext context) { + String name = student.name; + int batch = student.batch; + String program = student.program; + String specialization = student.specialization; + String hallNo = student.hallNo; + String roomNo = student.roomNo; + String contactNo = student.contactNo; + String address = student.address; + + return AlertDialog( + title: Text('Edit Student Details'), + content: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextField( + decoration: InputDecoration(labelText: 'Name'), + controller: TextEditingController(text: name), + onChanged: (value) { + name = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Batch'), + controller: TextEditingController(text: batch.toString()), + onChanged: (value) { + batch = int.tryParse(value) ?? 0; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Program'), + controller: TextEditingController(text: program), + onChanged: (value) { + program = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Specialization'), + controller: TextEditingController(text: specialization), + onChanged: (value) { + specialization = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Hall No'), + controller: TextEditingController(text: hallNo), + onChanged: (value) { + hallNo = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Room No'), + controller: TextEditingController(text: roomNo), + onChanged: (value) { + roomNo = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Contact No'), + controller: TextEditingController(text: contactNo), + onChanged: (value) { + contactNo = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Address'), + controller: TextEditingController(text: address), + onChanged: (value) { + address = value; + }, + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + // Perform the edit operation here + setState(() { + student.name = name; + student.batch = batch; + student.program = program; + student.specialization = specialization; + student.hallNo = hallNo; + student.roomNo = roomNo; + student.contactNo = contactNo; + student.address = address; + }); + // Simulate POST API call to update student details + // _updateStudentDetails(student); + Navigator.of(context).pop(); + }, + child: Text('Submit'), + ), + ], + ); + }, + ); + } + + Future _deleteStudentDetails(Student student) async { + // Show confirmation dialog before deleting the student + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Confirm Deletion'), + content: Text('Are you sure you want to delete this student?'), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + // Delete the student + _deleteStudent(student); + Navigator.of(context).pop(); + }, + child: Text('Delete'), + ), + ], + ); + }, + ); + } + + void _deleteStudent(Student student) { + setState(() { + students.remove(student); + filteredStudents.remove(student); + }); + // Simulate DELETE API call to delete student details + // _invokeDeleteAPI(student.rollNo); + } + + Future _showAddDialog() async { + String rollNo = ''; + String name = ''; + int batch = 0; + String program = ''; + String specialization = ''; + String hallNo = ''; + String roomNo = ''; + String contactNo = ''; + String address = ''; + + await showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Add New Student'), + content: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextField( + decoration: InputDecoration(labelText: 'Roll No'), + onChanged: (value) { + rollNo = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Name'), + onChanged: (value) { + name = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Batch'), + onChanged: (value) { + batch = int.tryParse(value) ?? 0; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Program'), + onChanged: (value) { + program = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Specialization'), + onChanged: (value) { + specialization = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Hall No'), + onChanged: (value) { + hallNo = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Room No'), + onChanged: (value) { + roomNo = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Contact No'), + onChanged: (value) { + contactNo = value; + }, + ), + TextField( + decoration: InputDecoration(labelText: 'Address'), + onChanged: (value) { + address = value; + }, + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + // Perform the add operation here + setState(() { + final newStudent = Student( + rollNo: rollNo, + name: name, + batch: batch, + program: program, + specialization: specialization, + hallNo: hallNo, + roomNo: roomNo, + contactNo: contactNo, + address: address, + ); + students.add(newStudent); + filteredStudents.add(newStudent); + }); + // Simulate POST API call to add new student details + // _addStudentDetails(rollNo, name, batch, program, specialization, hallNo, roomNo, contactNo, address); + Navigator.of(context).pop(); + }, + child: Text('Submit'), + ), + ], + ); + }, + ); + } + + void _searchStudents(String query) { + setState(() { + if (query.isNotEmpty) { + filteredStudents = students.where((student) { + return student.rollNo.contains(query) || student.name.contains(query); + }).toList(); + } else { + filteredStudents = List.from(students); + } + }); + } + + + @override + Widget build(BuildContext context) { + return Scaffold( + + appBar: AppBar( + title: Text('Manage Students'), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + actions: [ + IconButton( + icon: Icon(Icons.search), + onPressed: () async { + final String? result = await showSearch( + context: context, + delegate: StudentSearchDelegate(students: students), + ); + if (result != null) { + _searchStudents(result); + } + }, + ), + ], + ), + body: SingleChildScrollView( + child: DataTable( + columns: const [ + DataColumn(label: Text('Roll No')), + DataColumn(label: Text('Name')), + DataColumn(label: Text('Batch')), + DataColumn(label: Text('Program')), + DataColumn(label: Text('Specialization')), + DataColumn(label: Text('Hall No')), + DataColumn(label: Text('Room No')), + DataColumn(label: Text('Contact No')), + DataColumn(label: Text('Address')), + DataColumn(label: Text('Edit')), + DataColumn(label: Text('Remove')), + ], + rows: List.generate( + filteredStudents.length, + (index) => DataRow( + cells: [ + DataCell(Text(filteredStudents[index].rollNo)), + DataCell(Text(filteredStudents[index].name)), + DataCell(Text(filteredStudents[index].batch.toString())), + DataCell(Text(filteredStudents[index].program)), + DataCell(Text(filteredStudents[index].specialization)), + DataCell(Text(filteredStudents[index].hallNo)), + DataCell(Text(filteredStudents[index].roomNo)), + DataCell(Text(filteredStudents[index].contactNo)), + DataCell(Text(filteredStudents[index].address)), + DataCell( + IconButton( + icon: Icon(Icons.edit), + onPressed: () { + _editStudentDetails(filteredStudents[index]); + }, + ), + ), + DataCell( + IconButton( + icon: Icon(Icons.delete), + onPressed: () { + _deleteStudentDetails(filteredStudents[index]); + }, + ), + ), + ], + ), + ), + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: _showAddDialog, + child: Icon(Icons.add), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + ), + ); + } +} + +class StudentSearchDelegate extends SearchDelegate { + final List students; + + StudentSearchDelegate({required this.students}); + + @override + ThemeData appBarTheme(BuildContext context) { + final ThemeData theme = Theme.of(context); + return theme.copyWith( + appBarTheme: AppBarTheme( + backgroundColor: theme.scaffoldBackgroundColor, // Match with screen's UI theme + iconTheme: IconThemeData(color: theme.primaryColor), // Match with screen's UI theme + ), + ); + } + + @override + List buildActions(BuildContext context) { + return [ + IconButton( + icon: Icon(Icons.clear), + onPressed: () { + query = ''; + }, + ), + ]; + } + + @override + Widget buildLeading(BuildContext context) { + return IconButton( + icon: Icon(Icons.arrow_back), + onPressed: () { + close(context, null); + }, + + ); + } + + @override + Widget buildResults(BuildContext context) { + return _buildSearchResults(context); + } + + @override + Widget buildSuggestions(BuildContext context) { + return _buildSearchResults(context); + } + + Widget _buildSearchResults(BuildContext context) { + final List filteredStudents = students.where((student) { + final String lowercaseQuery = query.toLowerCase(); + return student.rollNo.toLowerCase().contains(lowercaseQuery) || student.name.toLowerCase().contains(lowercaseQuery); + }).toList(); + return ListView.builder( + itemCount: filteredStudents.length, + itemBuilder: (context, index) { + return ListTile( + title: Text(filteredStudents[index].name), + subtitle: Text(filteredStudents[index].rollNo), + onTap: () { + close(context, filteredStudents[index].rollNo); + }, + ); + }, + + ); + } + + @override + Widget buildResults(BuildContext context) { + return _buildSearchResults(context); + } + + @override + Widget buildSuggestions(BuildContext context) { + return _buildSearchResults(context); + } + + Widget _buildSearchResults(BuildContext context) { + final List filteredStudents = students.where((student) { + final String lowercaseQuery = query.toLowerCase(); + return student.rollNo.toLowerCase().contains(lowercaseQuery) || student.name.toLowerCase().contains(lowercaseQuery); + }).toList(); + return ListView.builder( + itemCount: filteredStudents.length, + itemBuilder: (context, index) { + return ListTile( + title: Text(filteredStudents[index].name), + subtitle: Text(filteredStudents[index].rollNo), + onTap: () { + close(context, filteredStudents[index].rollNo); + }, + ); + }, + ); + } +} + + + +void main() { + runApp(MaterialApp( + home: Managestudent(), + )); +} + + + +void main() { + runApp(MaterialApp( + home: Managestudent(), + )); + +} diff --git a/lib/screens/Hostel/warden/noticeboard.dart b/lib/screens/Hostel/warden/noticeboard.dart new file mode 100644 index 00000000..e05527b4 --- /dev/null +++ b/lib/screens/Hostel/warden/noticeboard.dart @@ -0,0 +1,220 @@ + + +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:fusion/Components/side_drawer.dart'; + +class Notice { + final String headline; + final String description; + final DateTime date; + + Notice(this.headline, this.description, this.date); +} + +class Noticeboard extends StatefulWidget { + const Noticeboard({Key? key}) : super(key: key); + + @override + _NoticeboardState createState() => _NoticeboardState(); +} + +class _NoticeboardState extends State { + + List notices = []; // Define the 'notices' list + + @override + void initState() { + super.initState(); + // Populate with sample notice boards + _populateNoticeBoards(); + } + + // Method to populate sample notice boards + void _populateNoticeBoards() { + // Sample notice board 1 + notices.add( + Notice( + 'Important Announcement', + 'All students are hereby informed that using Alcohol,Cigaretts andElectical Items are prohibited in hostels.If found heavy fine will be imposed.', + DateTime(2024, 4, 22), + ), + ); + + // Sample notice board 2 + notices.add( + Notice( + 'Republic Day 2k24', + 'As you all are aware today is Republic day,so interested students can attend the flag hosting infront of hostel which will be starting at 8:00am.', + DateTime(2024, 1, 26), + ), + ); + + // Notify the UI about the changes + setState(() {}); + } + + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: SideDrawer(), + appBar: AppBar( + title: const Text('Notice Board'), + + backgroundColor: const Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + body: Padding( + padding: EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Expanded( + child: ListView.builder( + itemCount: notices.length, + itemBuilder: (context, index) { + return Card( + margin: EdgeInsets.only(bottom: 20), + color: Color.fromARGB(255, 255, 229, 218), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: BorderSide( + color: Color.fromARGB(255, 245, 103, 47), + width: 2.0, + ), + ), + child: Padding( + padding: EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + notices[index].headline, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + Text( + '${notices[index].date.day}/${notices[index].date.month}/${notices[index].date.year}', + style: TextStyle(fontSize: 16), + ), + ], + ), + SizedBox(height: 10), + Text( + notices[index].description, + style: TextStyle(fontSize: 18), + ), + SizedBox(height: 20), + ElevatedButton( + onPressed: () { + // Handle file upload logic here + }, + child: Text('View Uploaded File'), + ), + SizedBox(height: 10), + Align( + alignment: Alignment.bottomRight, + child: ElevatedButton( + onPressed: () { + // Remove notice board logic here + setState(() { + notices.removeAt(index); + }); + }, + child: Text('Remove Notice'), + ), + ), + ], + ), + ), + ); + }, + ), + ), + ], + + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: () { + + // Display dialog to add a new notice + showDialog( + context: context, + builder: (BuildContext context) { + String headline = ''; + String description = ''; + + return AlertDialog( + title: Text('Add New Notice'), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextField( + decoration: InputDecoration( + labelText: 'Headline', + ), + onChanged: (value) { + headline = value; + }, + ), + SizedBox(height: 10), + TextField( + decoration: InputDecoration( + labelText: 'Description', + ), + onChanged: (value) { + description = value; + }, + ), + SizedBox(height: 10), + ElevatedButton( + onPressed: () { + // Handle file upload logic here + }, + child: Text('Upload File'), + ), + ], + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + // Add new notice logic here + setState(() { + notices.add(Notice(headline, description, DateTime.now())); + }); + // Invoke sample POST API + // _invokePostAPI(headline, description, file); + Navigator.of(context).pop(); + }, + child: Text('Add'), + ), + ], + ); + }, + ); + }, + child: const Icon(Icons.add), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + ); + } + + // Method to invoke a POST API + void _invokePostAPI(String headline, String description, String file) { + // Your implementation to invoke POST API + // Example: http.post(url, body: {'headline': headline, 'description': description, 'file': file}); + } + +} diff --git a/lib/screens/Hostel/warden/report.dart b/lib/screens/Hostel/warden/report.dart new file mode 100644 index 00000000..1b651159 --- /dev/null +++ b/lib/screens/Hostel/warden/report.dart @@ -0,0 +1,20 @@ + +import 'package:flutter/material.dart'; +import 'package:fusion/Components/side_drawer.dart'; +class Report extends StatelessWidget { +const Report ({Key?key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer:SideDrawer(), + appBar: AppBar( + title: const Text('Report'), + backgroundColor: Color.fromARGB(255, 245, 103, 47), + foregroundColor: Colors.white, + ), + ); + } +} + + diff --git a/lib/screens/Hostel/warden/staffinfo.dart b/lib/screens/Hostel/warden/staffinfo.dart new file mode 100644 index 00000000..10abbb6f --- /dev/null +++ b/lib/screens/Hostel/warden/staffinfo.dart @@ -0,0 +1,275 @@ + +import 'dart:convert'; + +import 'package:flutter/material.dart'; + +void main() { + runApp(MyApp()); +} + +class Worker { + final String workerId; + final String name; + final String monthYear; + final String today; + final int workingDays; + final int totalAbsent; + final String remark; + + Worker({ + required this.workerId, + required this.name, + required this.monthYear, + required this.today, + required this.workingDays, + required this.totalAbsent, + required this.remark, + }); + + factory Worker.fromJson(Map json) { + return Worker( + workerId: json['workerId'], + name: json['name'], + monthYear: json['monthYear'], + today: json['today'], + workingDays: json['workingDays'], + totalAbsent: json['totalAbsent'], + remark: json['remark'], + ); + } +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Staff Info', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: StaffInfo(), + ); + } +} + +class StaffInfo extends StatefulWidget { + const StaffInfo({Key? key}) : super(key: key); + + @override + _StaffInfoState createState() => _StaffInfoState(); +} + +class _StaffInfoState extends State { + late Map> halls; + String? selectedHall; + + Future _loadHallData() async { + String jsonString = ''' + { + "halls": { + "hall1": [ + { + "workerId": "001", + "name": "Rajesh Sharma", + "monthYear": "April/2024", + "today": "2024-04-22", + "workingDays": 20, + "totalAbsent": 2, + "remark": "Good performance overall." + }, + { + "workerId": "004", + "name": "Anita Singh", + "monthYear": "April/2024", + "today": "2024-04-22", + "workingDays": 19, + "totalAbsent": 1, + "remark": "Consistently good attendance." + } + ], + "hall2": [ + { + "workerId": "002", + "name": "Vikram Patel", + "monthYear": "April/2024", + "today": "2024-04-22", + "workingDays": 18, + "totalAbsent": 4, + "remark": "Needs improvement in attendance." + }, + { + "workerId": "005", + "name": "Deepa Gupta", + "monthYear": "April/2024", + "today": "2024-04-22", + "workingDays": 21, + "totalAbsent": 3, + "remark": "Average attendance, some improvement needed." + } + ], + "hall3": [ + { + "workerId": "003", + "name": "Arun Kumar", + "monthYear": "April/2024", + "today": "2024-04-22", + "workingDays": 22, + "totalAbsent": 1, + "remark": "Excellent attendance record." + }, + { + "workerId": "006", + "name": "Preeti Verma", + "monthYear": "April/2024", + "today": "2024-04-22", + "workingDays": 20, + "totalAbsent": 2, + "remark": "Good performance overall." + } + ] + } + } + '''; + + Map data = json.decode(jsonString); + Map hallsData = data['halls']; + setState(() { + halls = hallsData.map((key, value) => + MapEntry(key, (value as List).map((e) => Worker.fromJson(e)).toList())); + selectedHall = halls.keys.first; + }); + } + + @override + void initState() { + super.initState(); + _loadHallData(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Staff Info'), + ), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DropdownButton( + items: halls.keys.map((String hall) { + return DropdownMenuItem( + value: hall, + child: Text(hall), + ); + }).toList(), + value: selectedHall, + onChanged: (String? newValue) { + setState(() { + selectedHall = newValue; + }); + }, + ), + const SizedBox(height: 20), + if (selectedHall != null && halls[selectedHall!] != null) + Expanded( + child: ListView.builder( + itemCount: halls[selectedHall!]!.length, + itemBuilder: (BuildContext context, int index) { + Worker worker = halls[selectedHall!]![index]; + return Card( + elevation: 3, + margin: const EdgeInsets.symmetric(vertical: 8), + child: ListTile( + title: Text(worker.name), + subtitle: Text('Working days: ${worker.workingDays}, Absent: ${worker.totalAbsent}'), + trailing: PopupMenuButton( + itemBuilder: (context) => [ + PopupMenuItem( + value: 'edit', + child: Text('Edit'), + ), + PopupMenuItem( + value: 'delete', + child: Text('Delete'), + ), + ], + onSelected: (value) { + if (value == 'edit') { + // Implement edit logic + _showEditDialog(worker); + } else if (value == 'delete') { + // Implement delete logic + _showDeleteDialog(worker); + } + }, + ), + ), + ); + }, + ), + ), + ], + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: () { + // Implement add logic + }, + child: Icon(Icons.add), + ), + ); + } + + void _showEditDialog(Worker worker) { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text('Edit Worker'), + content: Text('You selected ${worker.name} for editing.'), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: Text('Cancel'), + ), + TextButton( + onPressed: () { + // Implement edit logic + Navigator.pop(context); + }, + child: Text('Edit'), + ), + ], + ), + ); + } + + void _showDeleteDialog(Worker worker) { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text('Delete Worker'), + content: Text('Are you sure you want to delete ${worker.name}?'), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: Text('Cancel'), + ), + TextButton( + onPressed: () { + // Implement delete logic + Navigator.pop(context); + }, + child: Text('Delete'), + ), + ], + ), + ); + } +} + diff --git a/lib/screens/LoginandDashboard/DashboardComponents/announcement.dart b/lib/screens/LoginandDashboard/DashboardComponents/announcement.dart new file mode 100644 index 00000000..c0db276f --- /dev/null +++ b/lib/screens/LoginandDashboard/DashboardComponents/announcement.dart @@ -0,0 +1,200 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:fusion/models/profile.dart'; +import 'package:fusion/services/profile_service.dart'; +import 'package:flutter/material.dart'; +import 'package:fusion/Components/appBar2.dart'; +import 'package:fusion/Components/side_drawer2.dart'; +import 'package:fusion/models/dashboard.dart'; +import 'package:fusion/screens/LoginandDashboard/DashboardComponents/cardItems.dart'; +import 'package:fusion/services/dashboard_service.dart'; +import 'package:http/http.dart'; +import 'package:fusion/Components/bottom_navigation_bar.dart'; +import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/services/storage_service.dart'; + +class Announcement extends StatefulWidget { + static String tag = 'home-page'; + @override + _AnnouncementState createState() => _AnnouncementState(); +} + +class _AnnouncementState extends State { + bool _notificationsBool = false; + bool _newsBool = false; + bool _announcementsBool = true; + bool _homeBool = false; + + bool _loading = true; + late String name; + late String studentType; + // Stream Controller for API + late StreamController _dashboardController; + late DashboardService dashboardService; + late DashboardData data; + late StreamController _profileController; + late ProfileService profileService; + late ProfileData data2; + var service = locator(); + late String curr_desig = service.getFromDisk("Current_designation"); + @override + void initState() { + super.initState(); + _dashboardController = StreamController(); + dashboardService = DashboardService(); + _profileController = StreamController(); + profileService = ProfileService(); + getData(); + } + + getData() async { + try { + print("gfsgsgd"); + Response response = await dashboardService.getDashboard(); + print("1"); + Response response2 = await profileService.getProfile(); + print("2"); + print(response); + print(response2); + + setState(() { + data = DashboardData.fromJson(jsonDecode(response.body)); + data2 = ProfileData.fromJson(jsonDecode(response2.body)); + _loading = false; + }); + name = data2.user!['first_name'] + ' ' + data2.user!['last_name']; + studentType = data2.profile!['department']!['name'] + + ' ' + + data2.profile!['user_type']; + } catch (e) { + print(e); + } + } + + loadData() async { + getData().then((res) { + _dashboardController.add(res); + _profileController.add(res); + }); + } + + final GlobalKey scaffoldKey = new GlobalKey(); + showSnack() { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('New Content Loaded'), + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CustomAppBar( + curr_desig: curr_desig, + headerTitle: "Announcement", + + onDesignationChanged: (newValue) { + setState(() { + curr_desig = newValue; + }); + }, + ), + bottomNavigationBar: MyBottomNavigationBar(), + drawer: SideDrawer(curr_desig: curr_desig), + body: _loading == true + ? Center(child: CircularProgressIndicator()) + : StreamBuilder( + stream: _dashboardController.stream, + builder: (context, AsyncSnapshot snapshot) { + return Stack(children: [ + Positioned( + left: 0, + child: Column( + children: [ + Card( + elevation: 0, + margin: EdgeInsets.symmetric( + horizontal: 10.0, vertical: 10.0), + color: Colors.transparent, + child: Padding( + padding: const EdgeInsets.only( + top: 10.0, + bottom: 10.0, + left: 13.0, + right: 10.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + GestureDetector( + onTap: () { + _notificationsBool = true; + _announcementsBool = false; + _newsBool = false; + setState(() { + _notificationsBool = true; + _announcementsBool = false; + _newsBool = false; + }); + Navigator.pushReplacementNamed( + context, "/notification"); + }, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () { + // Only handle navigation when the icon is clicked + _notificationsBool = false; + _announcementsBool = true; + _newsBool = false; + setState(() { + _notificationsBool = false; + _announcementsBool = true; + _newsBool = false; + }); + Navigator.pushReplacementNamed( + context, "/landing"); + }, + child: Icon( + Icons.navigate_before_rounded, + color: Colors.black, + size: 25.0, + ), + ), + SizedBox(width: 20.0), + Text( + 'Announcement', + style: TextStyle( + fontSize: 22.0, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + SizedBox(width: 170.0), + ], + ), + ), + ], + ), + ), + ), + + + ], + ), + ), + ]); + }, + ), + ); + } + + @override + void dispose() { + _dashboardController.close(); + super.dispose(); + } +} \ No newline at end of file diff --git a/lib/screens/LoginandDashboard/DashboardComponents/cardItems.dart b/lib/screens/LoginandDashboard/DashboardComponents/cardItems.dart index fffcde98..63afcdd9 100644 --- a/lib/screens/LoginandDashboard/DashboardComponents/cardItems.dart +++ b/lib/screens/LoginandDashboard/DashboardComponents/cardItems.dart @@ -1,36 +1,34 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; import 'package:fusion/models/notification.dart' as notif; import 'package:fusion/services/dashboard_service.dart'; class NotificationCard extends StatelessWidget { final List? notifications; - const NotificationCard({Key? key, required this.notifications}) - : super(key: key); + const NotificationCard({Key? key, required this.notifications}) : super(key: key); @override Widget build(BuildContext context) { return Card( elevation: 2.0, - margin: EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0), + margin: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0), shadowColor: Colors.black, - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: getCards(), + child: SingleChildScrollView( // Added to allow scrolling + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: getCards(), + ), ), ); } - getCards() { - List cards = []; - for (int i = 0; i < notifications!.length; i++) { - cards.add(InfoCard( - notification: notifications![i], - )); - } - return cards; + List getCards() { + // Transforming the notifications into InfoCard widgets + return notifications!.map((notif.Notification notification) { + return InfoCard( + notification: notification, + ); + }).toList(); } } @@ -38,19 +36,20 @@ class NewsCard extends StatelessWidget { @override Widget build(BuildContext context) { return Card( - elevation: 2.0, - margin: EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0), + elevation: 0, + margin: EdgeInsets.symmetric( + horizontal: 10.0, vertical: 10.0), shadowColor: Colors.black, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Card( elevation: 3.0, - margin: EdgeInsets.symmetric(horizontal: 15.0, vertical: 20.0), + margin: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 20.0), shadowColor: Colors.black, - child: Center( + child: const Center( child: Padding( - padding: const EdgeInsets.all(18.0), + padding: EdgeInsets.all(18.0), child: Text('Work in progress'), ), ), @@ -64,9 +63,10 @@ class NewsCard extends StatelessWidget { class InfoCard extends StatefulWidget { final notif.Notification notification; - InfoCard({ + const InfoCard({ + Key? key, required this.notification, - }); + }) : super(key: key); @override _InfoCardState createState() => _InfoCardState(); @@ -77,46 +77,38 @@ class _InfoCardState extends State { Widget build(BuildContext context) { return Card( elevation: 3.0, - margin: EdgeInsets.symmetric(horizontal: 15.0, vertical: 20.0), + margin: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 20.0), shadowColor: Colors.black, child: Column( children: [ - SizedBox( - height: 10.0, - ), + const SizedBox(height: 10.0), Text( widget.notification.data!["module"], textAlign: TextAlign.left, - style: TextStyle( + style: const TextStyle( fontSize: 20.0, color: Colors.deepOrangeAccent, fontWeight: FontWeight.bold, ), ), - SizedBox( - height: 10.0, - ), + const SizedBox(height: 10.0), Padding( padding: const EdgeInsets.all(8.0), child: Text( widget.notification.verb!, - style: TextStyle(fontSize: 15.0, color: Colors.black), + style: const TextStyle(fontSize: 15.0, color: Colors.black), ), ), - SizedBox( - height: 10.0, - ), + const SizedBox(height: 10.0), ElevatedButton( - child: widget.notification.unread! - ? Text('Mark As Read') - : Text('Mark As Unread'), + child: Text(widget.notification.unread! ? 'Mark As Read' : 'Mark As Unread'), onPressed: () { // Respond to button press DashboardService service = DashboardService(); setState(() { try { service.markRead(widget.notification.id!.toString()); - }catch(e){ + } catch (e) { print(e); } }); @@ -124,10 +116,8 @@ class _InfoCardState extends State { style: ButtonStyle( backgroundColor: MaterialStateProperty.resolveWith( (Set states) { - if (states.contains(MaterialState.pressed)) - return Colors.deepOrange; - return Colors - .deepOrangeAccent; // Use the component's default. + if (states.contains(MaterialState.pressed)) return Colors.deepOrange; + return Colors.deepOrangeAccent; // Default Color }, ), ), diff --git a/lib/screens/LoginandDashboard/DashboardComponents/news.dart b/lib/screens/LoginandDashboard/DashboardComponents/news.dart new file mode 100644 index 00000000..268ae36a --- /dev/null +++ b/lib/screens/LoginandDashboard/DashboardComponents/news.dart @@ -0,0 +1,201 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:fusion/models/profile.dart'; +import 'package:fusion/services/profile_service.dart'; +import 'package:flutter/material.dart'; +import 'package:fusion/Components/appBar2.dart'; +import 'package:fusion/Components/side_drawer2.dart'; +import 'package:fusion/models/dashboard.dart'; +import 'package:fusion/screens/LoginandDashboard/DashboardComponents/cardItems.dart'; +import 'package:fusion/services/dashboard_service.dart'; +import 'package:http/http.dart'; +import 'package:fusion/Components/bottom_navigation_bar.dart'; +import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/services/storage_service.dart'; + +class News extends StatefulWidget { + static String tag = 'home-page'; + @override + _NewsState createState() => _NewsState(); +} + +class _NewsState extends State { + bool _notificationsBool = false; + bool _newsBool = true; + bool _announcementsBool = false; + bool _homeBool = false; + + bool _loading = true; + late String name; + late String studentType; + // Stream Controller for API + late StreamController _dashboardController; + late DashboardService dashboardService; + late DashboardData data; + late StreamController _profileController; + late ProfileService profileService; + late ProfileData data2; + var service = locator(); + late String curr_desig = service.getFromDisk("Current_designation"); + + @override + void initState() { + super.initState(); + _dashboardController = StreamController(); + dashboardService = DashboardService(); + _profileController = StreamController(); + profileService = ProfileService(); + getData(); + } + + getData() async { + try { + print("gfsgsgd"); + Response response = await dashboardService.getDashboard(); + print("1"); + Response response2 = await profileService.getProfile(); + print("2"); + print(response); + print(response2); + + setState(() { + data = DashboardData.fromJson(jsonDecode(response.body)); + data2 = ProfileData.fromJson(jsonDecode(response2.body)); + _loading = false; + }); + name = data2.user!['first_name'] + ' ' + data2.user!['last_name']; + studentType = data2.profile!['department']!['name'] + + ' ' + + data2.profile!['user_type']; + } catch (e) { + print(e); + } + } + + loadData() async { + getData().then((res) { + _dashboardController.add(res); + _profileController.add(res); + }); + } + + final GlobalKey scaffoldKey = new GlobalKey(); + showSnack() { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('New Content Loaded'), + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CustomAppBar( + curr_desig: curr_desig, + headerTitle: "News", + + onDesignationChanged: (newValue) { + setState(() { + curr_desig = newValue; + }); + }, + ), + drawer: SideDrawer(curr_desig: curr_desig), + bottomNavigationBar: MyBottomNavigationBar(), + body: _loading == true + ? Center(child: CircularProgressIndicator()) + : StreamBuilder( + stream: _dashboardController.stream, + builder: (context, AsyncSnapshot snapshot) { + return Stack(children: [ + Positioned( + left: 0, + child: Column( + children: [ + Card( + elevation: 0, + margin: EdgeInsets.symmetric( + horizontal: 10.0, vertical: 10.0), + color: Colors.transparent, + child: Padding( + padding: const EdgeInsets.only( + top: 10.0, + bottom: 10.0, + left: 13.0, + right: 10.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + GestureDetector( + onTap: () { + _notificationsBool = true; + _announcementsBool = false; + _newsBool = false; + setState(() { + _notificationsBool = true; + _announcementsBool = false; + _newsBool = false; + }); + Navigator.pushReplacementNamed( + context, "/notification"); + }, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () { + // Only handle navigation when the icon is clicked + _notificationsBool = true; + _announcementsBool = false; + _newsBool = false; + setState(() { + _notificationsBool = true; + _announcementsBool = false; + _newsBool = false; + }); + Navigator.pushReplacementNamed( + context, "/landing"); + }, + child: Icon( + Icons.navigate_before_rounded, + color: Colors.black, + size: 25.0, + ), + ), + SizedBox(width: 20.0), + Text( + 'News', + style: TextStyle( + fontSize: 22.0, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + SizedBox(width: 170.0), + ], + ), + ), + ], + ), + ), + ), + + + ], + ), + ), + ]); + }, + ), + ); + } + + @override + void dispose() { + _dashboardController.close(); + super.dispose(); + } +} \ No newline at end of file diff --git a/lib/screens/LoginandDashboard/DashboardComponents/notify.dart b/lib/screens/LoginandDashboard/DashboardComponents/notify.dart new file mode 100644 index 00000000..198820b5 --- /dev/null +++ b/lib/screens/LoginandDashboard/DashboardComponents/notify.dart @@ -0,0 +1,152 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:fusion/models/profile.dart'; +import 'package:fusion/services/profile_service.dart'; +import 'package:flutter/material.dart'; +import 'package:fusion/Components/appBar2.dart'; +import 'package:fusion/Components/side_drawer2.dart'; +import 'package:fusion/models/dashboard.dart'; +import 'package:fusion/screens/LoginandDashboard/DashboardComponents/cardItems.dart'; +import 'package:fusion/services/dashboard_service.dart'; +import 'package:http/http.dart'; +import 'package:fusion/Components/bottom_navigation_bar.dart'; +import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/services/storage_service.dart'; +import 'package:fusion/models/notification.dart' as notif; +import 'package:intl/intl.dart'; + +class Notify extends StatefulWidget { + static String tag = 'home-page'; + @override + _NotifyState createState() => _NotifyState(); +} + +class _NotifyState extends State { + List _notifications = []; + bool _loading = true; + late String name; + late String studentType; + + // Stream Controller for API + late StreamController _dashboardController; + late DashboardService dashboardService; + late DashboardData data; + late StreamController _profileController; + late ProfileService profileService; + late ProfileData data2; + var service = locator(); + late String curr_desig = service.getFromDisk("Current_designation"); + @override + void initState() { + super.initState(); + _dashboardController = StreamController(); + dashboardService = DashboardService(); + _profileController = StreamController(); + profileService = ProfileService(); + getData(); + } + + getData() async { + try { + print("gfsgsgd"); + Response response = await dashboardService.getNotification(); + print("1"); + Response response2 = await profileService.getProfile(); + print("2"); + print(response); + print(response2); + + setState(() { + data = DashboardData.fromJson(jsonDecode(response.body)); + _notifications = notif.Notification.fromListJson(jsonDecode(response.body)['notifications']); + data2 = ProfileData.fromJson(jsonDecode(response2.body)); + _loading = false; + }); + name = data2.user!['first_name'] + ' ' + data2.user!['last_name']; + studentType = data2.profile!['department']!['name'] + + ' ' + + data2.profile!['user_type']; + } catch (e) { + print(e); + } + } + + loadData() async { + getData().then((res) { + _dashboardController.add(res); + _profileController.add(res); + }); + } + + final GlobalKey scaffoldKey = new GlobalKey(); + showSnack() { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('New Content Loaded'), + ), + ); + } + + @override +Widget build(BuildContext context) { + return Scaffold( + appBar: CustomAppBar( + curr_desig: curr_desig, + headerTitle: "Notifications", + + onDesignationChanged: (newValue) { + setState(() { + curr_desig = newValue; + }); + }, + ), // This is default app bar used in all modules + drawer: SideDrawer(curr_desig: curr_desig), + bottomNavigationBar: + MyBottomNavigationBar(), // This is sideDrawer used in all modules + body: _loading + ? Center(child: CircularProgressIndicator()) + : ListView.builder( + itemCount: _notifications.length, + padding: EdgeInsets.all(8.0), // Add padding around the list for better spacing + itemBuilder: (context, index) { + final notification = _notifications[index]; + final formattedDate = notification.timestamp != null + ? DateFormat('yyyy-MM-dd – kk:mm').format(notification.timestamp!) + : "No Date"; + + return Card( + elevation: 4.0, // Adjust the shadow's elevation + margin: EdgeInsets.symmetric(vertical: 4.0, horizontal: 0), // Spacing between cards + child: ListTile( + leading: Icon(notification.unread ?? false ? Icons.notifications_active : Icons.notifications_off), + title: Text(notification.verb ?? "No Title"), + subtitle: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + notification.description ?? "No Description", + overflow: TextOverflow.ellipsis, + ), + ), + Text(formattedDate, textAlign: TextAlign.right), + ], + ), + onTap: () { + // Handle tap + }, + ), + ); + }, + ), + + + ); + } + + @override + void dispose() { + _dashboardController.close(); + super.dispose(); + } +} \ No newline at end of file diff --git a/lib/screens/LoginandDashboard/dashboard.dart b/lib/screens/LoginandDashboard/dashboard.dart index 80c2719f..24f372d5 100644 --- a/lib/screens/LoginandDashboard/dashboard.dart +++ b/lib/screens/LoginandDashboard/dashboard.dart @@ -2,15 +2,17 @@ import 'dart:async'; import 'dart:convert'; import 'package:fusion/models/profile.dart'; import 'package:fusion/services/profile_service.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; -import 'package:fusion/Components/appBar.dart'; -import 'package:fusion/Components/side_drawer.dart'; +import 'package:fusion/Components/appBar2.dart'; +import 'package:fusion/Components/side_drawer2.dart'; import 'package:fusion/models/dashboard.dart'; import 'package:fusion/screens/LoginandDashboard/DashboardComponents/cardItems.dart'; import 'package:fusion/services/dashboard_service.dart'; import 'package:http/http.dart'; +import 'package:fusion/services/appBar_services.dart'; +import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/services/storage_service.dart'; +import 'package:fusion/Components/bottom_navigation_bar.dart'; class Dashboard extends StatefulWidget { static String tag = 'home-page'; @@ -20,9 +22,11 @@ class Dashboard extends StatefulWidget { } class _DashboardState extends State { - bool _notificationsBool = true; + bool _notificationsBool = false; bool _newsBool = false; bool _announcementsBool = false; + bool _homeBool = true; + bool _loading = true; late String name; late String studentType; @@ -33,6 +37,12 @@ class _DashboardState extends State { late StreamController _profileController; late ProfileService profileService; late ProfileData data2; + late List designationsArray; + var service = locator(); + late String curr_desig = service.getFromDisk("Current_designation"); + bool isStudent = false; + + final appBarServices _appBarServices = appBarServices(); @override void initState() { super.initState(); @@ -45,17 +55,28 @@ class _DashboardState extends State { getData() async { try { + print("gfsgsgd"); Response response = await dashboardService.getDashboard(); + print("1"); Response response2 = await profileService.getProfile(); + print("2"); + print(response); + print(response2); + setState(() { data = DashboardData.fromJson(jsonDecode(response.body)); data2 = ProfileData.fromJson(jsonDecode(response2.body)); _loading = false; }); + print(data2.user!); + print( + '-----------------------------------=---------------------------------------'); name = data2.user!['first_name'] + ' ' + data2.user!['last_name']; - studentType = data2.profile!['department']!['name'] + - ' ' + - data2.profile!['user_type']; + studentType = data2.profile!['department']!['name']; + + if (data2.profile!['user_type'] == 'student') { + isStudent = true; + } } catch (e) { print(e); } @@ -68,6 +89,15 @@ class _DashboardState extends State { }); } + fetchDesignations() async { + try { + designationsArray = await _appBarServices.getDesignations(); + } catch (e) { + print("Error fetching designations: $e"); + return null; + } + } + final GlobalKey scaffoldKey = new GlobalKey(); showSnack() { ScaffoldMessenger.of(context).showSnackBar( @@ -80,174 +110,221 @@ class _DashboardState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: DefaultAppBar() - .buildAppBar(), // This is default app bar used in all modules - drawer: SideDrawer(), // This is sideDrawer used in all modules - body: _loading == true - ? Center(child: CircularProgressIndicator()) - : StreamBuilder( - stream: _dashboardController.stream, - builder: (context, AsyncSnapshot snapshot) { - return ListView( - shrinkWrap: true, - physics: ClampingScrollPhysics(), - children: [ - Card( - elevation: 2.0, - margin: EdgeInsets.symmetric( - horizontal: 50.0, vertical: 20.0), - shadowColor: Colors.black, - child: Column( + appBar: CustomAppBar( + curr_desig: curr_desig, + headerTitle: "Dashboard", + onDesignationChanged: (newValue) { + setState(() { + curr_desig = newValue; + }); + }, + ), // This is default app bar used in all modules + drawer: SideDrawer(curr_desig: curr_desig), + bottomNavigationBar: + MyBottomNavigationBar(), // This is sideDrawer used in all modules + body: Column( + children: [ + Expanded( + child: _loading == true + ? Center(child: CircularProgressIndicator()) + : StreamBuilder( + stream: _dashboardController.stream, + builder: (context, AsyncSnapshot snapshot) { + return ListView( + shrinkWrap: true, + physics: ClampingScrollPhysics(), children: [ - Container( - margin: EdgeInsets.only(top: 20.0), - width: 170.0, - height: 170.0, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage('assets/profile_pic.png'), - fit: BoxFit.cover, - ), - ), - ), - SizedBox( - height: 10.0, - ), - Text( - name, //Display name of User - style: - TextStyle(fontSize: 20.0, color: Colors.black), - ), - SizedBox( - height: 10.0, - ), - Text( - studentType, // Display Type of User - style: - TextStyle(fontSize: 15.0, color: Colors.black), - ), - SizedBox( - height: 10.0, - ), - ], - ), - ), - Card( - color: Colors.black, - child: Padding( - padding: const EdgeInsets.all(10.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - GestureDetector( - onTap: () { - _notificationsBool = true; - _announcementsBool = false; - _newsBool = false; - setState(() { - _notificationsBool = true; - _announcementsBool = false; - _newsBool = false; - }); - }, - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Text( - 'Notifications', - style: TextStyle( - fontSize: 16.0, - color: Colors.white, + Card( + elevation: 2.0, + margin: EdgeInsets.symmetric( + horizontal: 20.0, vertical: 30.0), + // shadowColor: Colors.black, + color: Colors.white, + + child: Column( + children: [ + Container( + margin: EdgeInsets.only(top: 20.0), + width: 170.0, + height: 190.0, + decoration: BoxDecoration( + image: DecorationImage( + image: + AssetImage('assets/profile_pic.png'), + fit: BoxFit.cover, ), ), - Icon( - Icons.notifications_active_rounded, - color: _notificationsBool - ? Colors.deepOrangeAccent - : Colors.white, - ), - ], - ), + ), + SizedBox( + height: 10.0, + ), + Text( + name, //Display name of User + style: TextStyle( + fontSize: 20.0, + color: Colors.black, + fontWeight: FontWeight.bold), + ), + SizedBox( + height: 10.0, + ), + Text( + studentType + + " " + + curr_desig, // Display Type of User + style: TextStyle( + fontSize: 17.0, + color: Colors.black, + fontWeight: FontWeight.bold), + ), + SizedBox( + height: 10.0, + ), + ], ), - GestureDetector( - onTap: () { - _newsBool = true; - _announcementsBool = false; - _notificationsBool = false; - setState(() { - _newsBool = true; - _announcementsBool = false; - _notificationsBool = false; - }); - }, + ), + + Card( + margin: EdgeInsets.symmetric( + horizontal: 20.0, vertical: 10.0), + color: Colors.deepOrangeAccent, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + 50.0), // Set the border radius here + ), + child: Padding( + padding: const EdgeInsets.only( + top: 10.0, + bottom: 10.0, + left: 13.0, + right: 10.0), child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment + .spaceEvenly, // Align the children along the main axis with space between them + crossAxisAlignment: CrossAxisAlignment + .center, // Align the children along the cross axis (vertically by default) + // mainAxisSize: MainAxisSize.max, children: [ - Text( - 'News', - style: TextStyle( - fontSize: 16.0, - color: Colors.white, + GestureDetector( + onTap: () { + _notificationsBool = true; + _announcementsBool = false; + _newsBool = false; + setState(() { + _notificationsBool = true; + _announcementsBool = false; + _newsBool = false; + }); + Navigator.pushReplacementNamed( + context, "/profile"); + }, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Icon( + Icons.account_circle, + color: Colors.white, + size: 30.0, + ), + SizedBox(width: 40.0), + Text( + 'Professsional Profile', + style: TextStyle( + fontSize: 20.0, + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + SizedBox(width: 40.0), + Icon( + Icons.arrow_forward_ios_rounded, + color: Colors.white, + ), + ], ), ), - Icon( - Icons.email, - color: _newsBool - ? Colors.deepOrangeAccent - : Colors.white, - ), ], ), ), - GestureDetector( - onTap: () { - _announcementsBool = true; - _newsBool = false; - _notificationsBool = false; - setState(() { - _announcementsBool = true; - _newsBool = false; - _notificationsBool = false; - }); - }, + ), + + if (!isStudent) + Card( + margin: EdgeInsets.symmetric( + horizontal: 20.0, vertical: 10.0), + color: Colors.deepOrangeAccent, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + 50.0), // Set the border radius here + ), child: Padding( - padding: const EdgeInsets.only(right: 16.0), + padding: const EdgeInsets.only( + top: 10.0, + bottom: 10.0, + left: 13.0, + right: 10.0), child: Row( mainAxisAlignment: - MainAxisAlignment.spaceBetween, + MainAxisAlignment.spaceEvenly, children: [ - Text( - 'Announcements', - style: TextStyle( - fontSize: 16.0, - color: Colors.white, + GestureDetector( + onTap: () { + _notificationsBool = true; + _announcementsBool = false; + _newsBool = false; + setState(() { + _notificationsBool = true; + _announcementsBool = false; + _newsBool = false; + }); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment + .spaceEvenly, // Align the children along the main axis with space between them + crossAxisAlignment: CrossAxisAlignment + .center, // Align the children along the cross axis (vertically by default) + mainAxisSize: MainAxisSize.max, + children: [ + Icon( + Icons.notifications_active_rounded, + color: Colors.white, + ), + SizedBox(width: 40.0), + Text( + 'Admistrative Profile', + style: TextStyle( + fontSize: 20.0, + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + SizedBox(width: 40.0), + Icon( + Icons.arrow_forward_ios_rounded, + color: Colors.white, + ), + ], ), ), - Icon( - Icons.announcement, - color: _announcementsBool - ? Colors.deepOrangeAccent - : Colors.white, - ), ], ), ), ), - ], - ), - ), - ), - _notificationsBool - ? NotificationCard( - notifications: data.notifications, - ) - : NewsCard(), - ], - ); - }, - ), + + // _notificationsBool + // ? NotificationCard( + // notifications: data.notifications, + // ) + // : NewsCard(), + ], + ); + }, + ), + ), + // Place the BottomNavigationBar here + ], + ), ); } @@ -256,4 +333,4 @@ class _DashboardState extends State { _dashboardController.close(); super.dispose(); } -} +} \ No newline at end of file diff --git a/lib/screens/LoginandDashboard/login_page.dart b/lib/screens/LoginandDashboard/login_page.dart index ca09fee2..aff38280 100644 --- a/lib/screens/LoginandDashboard/login_page.dart +++ b/lib/screens/LoginandDashboard/login_page.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:fusion/constants.dart'; @@ -10,7 +9,9 @@ class LoginPage extends StatefulWidget { _LoginPageState createState() => _LoginPageState(); } -bool checkBoxValue = false; +bool _focused = false; +bool _focused2 = false; +double bottom =10; class _LoginPageState extends State { final GlobalKey _formKey = GlobalKey(); @@ -23,21 +24,45 @@ class _LoginPageState extends State { final Widget logoWidget = CircleAvatar( backgroundColor: Colors.transparent, - radius: 54.0, - child: Image.asset('assets/logo.jpg'), + radius: (_focused || _focused2) ? 110.0 : 150.0, + child:Container( + + child: Image.asset('assets/logo.jpg'), + ), ); - final Widget emailFormField = TextFormField( + final Widget emailFormField = Focus( + onFocusChange: (focus) { + setState(() { + _focused = focus; + if (focus==true){ + bottom=400; + } + + }); + }, + child:TextFormField( keyboardType: TextInputType.emailAddress, autofocus: false, decoration: InputDecoration( label: Text('Username', style: TextStyle( - fontSize: 12.0, + fontSize: 18.0, ),), contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), - border: OutlineInputBorder( - // borderRadius: BorderRadius.circular(32.0), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(width: 0, color: Color(0xFFf4f4f4)), + borderRadius: BorderRadius.circular(20.0), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(width: 0, color: Color(0xFFf4f4f4)), + borderRadius: BorderRadius.circular(20.0), ), + // enabledBorder: InputBorder.none, + fillColor: Color(0xFFf4f4f4), // Green color + filled: true, + floatingLabelBehavior: FloatingLabelBehavior.never, ), + cursorColor: Colors.black, + onChanged: (input) { username = input; }, @@ -48,23 +73,45 @@ class _LoginPageState extends State { else if (value?.contains('@') == true) { return 'Please enter username only'; } + return null; }, autofillHints: [AutofillHints.username], - ); + )); + + final Widget passwordFormField = Focus( + onFocusChange: (focus) { + setState(() { + _focused2 = focus; + if (focus==true){ + bottom=400; + } - final Widget passwordFormField = TextFormField( + }); + }, + child: TextFormField( autofocus: false, obscureText: true, decoration: InputDecoration( label: Text('Password', style: TextStyle( - fontSize: 12.0, + fontSize: 18.0, ),), contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), - border: OutlineInputBorder( - // borderRadius: BorderRadius.circular(32.0), + + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(width: 0, color: Color(0xFFf4f4f4)), + borderRadius: BorderRadius.circular(20.0), ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(width: 0, color: Color(0xFFf4f4f4)), + borderRadius: BorderRadius.circular(20.0), + ), + // enabledBorder: InputBorder.none, + fillColor: Color(0xFFf4f4f4), // Green color + filled: true, + floatingLabelBehavior: FloatingLabelBehavior.never, ), + cursorColor: Colors.black, onChanged: (input) { pass = input; }, @@ -74,12 +121,13 @@ class _LoginPageState extends State { } else if (value.length < 6) { return 'Password must be at least 6 characters'; } + return null; }, autofillHints: [AutofillHints.password], - ); + )); final loginButton = Padding( - padding: EdgeInsets.symmetric(vertical: 16.0), + padding: EdgeInsets.only(top: 16.0), child: ElevatedButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all(kPrimaryColor), @@ -102,7 +150,8 @@ class _LoginPageState extends State { style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, - fontSize: 14.0, + fontSize: 22.0, + ), ), ), @@ -124,13 +173,16 @@ class _LoginPageState extends State { key: _formKey, child: ListView( shrinkWrap: true, - padding: EdgeInsets.only(left: 24.0, right: 24.0), + padding: EdgeInsets.only(top:8.0,left: 24.0, right: 24.0), children: [ - logoWidget, + Padding( + padding: const EdgeInsets.only(top: 0.0), // Change the top padding here + child: logoWidget, + ), Padding( padding: const EdgeInsets.only(bottom: 30.0), child: Text( - 'Fusion Login', + 'Fusion', style: TextStyle( color: kPrimaryColor, fontWeight: FontWeight.bold, @@ -141,14 +193,21 @@ class _LoginPageState extends State { ), Padding( padding: EdgeInsets.only(bottom: 15), - child: emailFormField, + child: emailFormField, ), Padding( padding: EdgeInsets.only(bottom: 15), child: passwordFormField, ), - loginButton, - forgotLabel, + Padding( + padding: EdgeInsets.only(bottom: 0.0), + child: loginButton, + ), + Padding( + padding: EdgeInsets.only(top:0.0,bottom: bottom), + child: forgotLabel, + ), + ], ), ), @@ -157,29 +216,29 @@ class _LoginPageState extends State { ); } - // void _showDialog() { - // // flutter defined function - // showDialog( - // context: context, - // builder: (BuildContext context) { - // // return object of type Dialog - // return AlertDialog( - // title: Text("Invalid Username/Password"), - // content: Text("Please enter correct Username or Password"), - // actions: [ - // // usually buttons at the bottom of the dialog - // new TextButton( - // child: new Text( - // "Close", - // style: TextStyle(color: Colors.deepOrangeAccent), - // ), - // onPressed: () { - // Navigator.of(context).pop(); - // }, - // ), - // ], - // ); - // }, - // ); - // } -} +// void _showDialog() { +// // flutter defined function +// showDialog( +// context: context, +// builder: (BuildContext context) { +// // return object of type Dialog +// return AlertDialog( +// title: Text("Invalid Username/Password"), +// content: Text("Please enter correct Username or Password"), +// actions: [ +// // usually buttons at the bottom of the dialog +// new TextButton( +// child: new Text( +// "Close", +// style: TextStyle(color: Colors.deepOrangeAccent), +// ), +// onPressed: () { +// Navigator.of(context).pop(); +// }, +// ), +// ], +// ); +// }, +// ); +// } +} \ No newline at end of file diff --git a/lib/service_locator.dart b/lib/service_locator.dart new file mode 100644 index 00000000..6f6aa35e --- /dev/null +++ b/lib/service_locator.dart @@ -0,0 +1,9 @@ +import 'package:fusion/services/storage_service.dart'; +import 'package:get_it/get_it.dart'; + +GetIt locator = GetIt.instance; + +void setupLocator() async { + var instance = await StorageService.getInstance(); + locator.registerSingleton(instance!); +} diff --git a/lib/services/appBar_services.dart b/lib/services/appBar_services.dart new file mode 100644 index 00000000..bc7ba3c0 --- /dev/null +++ b/lib/services/appBar_services.dart @@ -0,0 +1,14 @@ +import 'package:fusion/services/storage_service.dart'; + +class appBarServices { + getDesignations() async { + try { + var storageService = await StorageService.getInstance(); + List? designations = storageService!.getFromDisk('designations'); + + return designations; + } catch (e) { + rethrow; + } + } +} \ No newline at end of file diff --git a/lib/services/dashboard_service.dart b/lib/services/dashboard_service.dart index 8e4520a9..ef348125 100644 --- a/lib/services/dashboard_service.dart +++ b/lib/services/dashboard_service.dart @@ -7,12 +7,12 @@ import 'package:http/http.dart' as http; class DashboardService { getDashboard() async { try { - var storage_service = locator(); - if (storage_service.userInDB?.token == null) + var storageService = locator(); + if (storageService.userInDB?.token == null) throw Exception('Token Error'); Map headers = { - 'Authorization': 'Token ' + (storage_service.userInDB?.token ?? "") + 'Authorization': 'Token ' + (storageService.userInDB?.token ?? "") }; var client = http.Client(); http.Response response = await client.get( @@ -24,6 +24,43 @@ class DashboardService { ); if (response.statusCode == 200) { print("success"); + print(response); + return response; + } + throw Exception('Can\'t load'); + } catch (e) { + rethrow; + } + } + + + getNotification() async { + try { + print("gett"); + var storageService = locator(); + if (storageService.userInDB?.token == null) + throw Exception('Token Error'); + + + Map headers = { + 'Authorization': 'Token ' + (storageService.userInDB?.token ?? "") + }; + print("gett2"); + + var client = http.Client(); + http.Response response = await client.get( + Uri.http( + getLink(), + kNotification, // constant dashboard path + ), + headers: headers, + ); + + print("gett3"); + + if (response.statusCode == 200) { + print("success"); + print(response); return response; } throw Exception('Can\'t load'); @@ -34,12 +71,12 @@ class DashboardService { markRead(String id) async { try { - StorageService? storage_service = await StorageService.getInstance(); + StorageService? storageService = await StorageService.getInstance(); - if (storage_service?.userInDB?.token == null) + if (storageService?.userInDB?.token == null) throw Exception('Token Error'); - String token = storage_service?.userInDB?.token ?? ""; + String token = storageService?.userInDB?.token ?? ""; Map headers = {'Authorization': 'Token ' + token}; Map body = {"id": id}; var client = http.Client(); @@ -60,4 +97,4 @@ class DashboardService { rethrow; } } -} +} \ No newline at end of file diff --git a/lib/services/login_service.dart b/lib/services/login_service.dart index 17d79b42..97277ffc 100644 --- a/lib/services/login_service.dart +++ b/lib/services/login_service.dart @@ -1,6 +1,5 @@ import 'dart:convert'; -import 'package:fusion/constants.dart'; import 'package:fusion/api.dart'; import 'package:fusion/models/user.dart'; import 'package:fusion/services/storage_service.dart'; @@ -25,8 +24,15 @@ class LoginService { var prefs = await StorageService.getInstance(); print("response.body: ${response.body}"); - var storage_service = await StorageService.getInstance(); - storage_service!.saveUserInDB(User((jsonDecode(response.body))["token"])); + var storageService = await StorageService.getInstance(); + storageService!.saveUserInDB(User((jsonDecode(response.body))["token"])); + storageService.saveToDisk>( + 'designations', + (jsonDecode(response.body)["designations"] as List) + .map((dynamic item) => item.toString()) + .toList(), + ); + storageService.saveStringToDisk("Current_designation",jsonDecode(response.body)["designations"][0]); return true; } catch (e) { rethrow; @@ -35,8 +41,8 @@ class LoginService { void logout() async { try { - var storage_service = await StorageService.getInstance(); - storage_service!.deleteKey("user"); + var storageService = await StorageService.getInstance(); + storageService!.deleteKey("user"); } catch (e) { rethrow; } diff --git a/lib/services/storage_service.dart b/lib/services/storage_service.dart index 94d39ea4..9d118326 100644 --- a/lib/services/storage_service.dart +++ b/lib/services/storage_service.dart @@ -13,19 +13,19 @@ class StorageService with ChangeNotifier { static const String ProfileKey = "ProfileKey"; User? get userInDB { - var userJson = _getFromDisk(UserKey); + var userJson = getFromDisk(UserKey); return userJson == null ? null : User.fromJson(jsonDecode(userJson)); } ProfileData get profileData { - var profileJson = _getFromDisk(ProfileKey); + var profileJson = getFromDisk(ProfileKey); // print(jsonDecode(profileJson)); return ProfileData.fromJson(jsonDecode(profileJson)); } AcademicData get academicData { - var profileJson = _getFromDisk(ProfileKey); + var profileJson = getFromDisk(ProfileKey); // print(jsonDecode(profileJson)); return AcademicData.fromJson(jsonDecode(profileJson)); } @@ -49,9 +49,9 @@ class StorageService with ChangeNotifier { return _instance; } - dynamic _getFromDisk(String key) { + dynamic getFromDisk(String key) { var value = _sharedPreferences?.get(key); - // print('(TRACE) LocalStorageService:_getFromDisk. key: $key value: $value'); + // print('(TRACE) LocalStorageService:getFromDisk. key: $key value: $value'); return value; } @@ -62,7 +62,7 @@ class StorageService with ChangeNotifier { void deleteKey(String key) { print( - '(TRACE) StorageService: deleteKey. key: $key value: ${_getFromDisk(key)}'); + '(TRACE) StorageService: deleteKey. key: $key value: ${getFromDisk(key)}'); _sharedPreferences!.remove(key); } @@ -84,4 +84,4 @@ class StorageService with ChangeNotifier { _sharedPreferences!.setStringList(key, content); } } -} +} \ No newline at end of file diff --git a/lib/storage_service.dart b/lib/storage_service.dart new file mode 100644 index 00000000..9d118326 --- /dev/null +++ b/lib/storage_service.dart @@ -0,0 +1,87 @@ +import 'dart:convert'; +import 'package:flutter/cupertino.dart'; +import 'package:fusion/models/profile.dart'; +import 'package:fusion/models/academic.dart'; +import 'package:fusion/models/user.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class StorageService with ChangeNotifier { + static StorageService? _instance; + static SharedPreferences? _sharedPreferences; + //This is the database key, do not change this + static const String UserKey = "user"; + static const String ProfileKey = "ProfileKey"; + + User? get userInDB { + var userJson = getFromDisk(UserKey); + + return userJson == null ? null : User.fromJson(jsonDecode(userJson)); + } + + ProfileData get profileData { + var profileJson = getFromDisk(ProfileKey); + // print(jsonDecode(profileJson)); + return ProfileData.fromJson(jsonDecode(profileJson)); + } + + AcademicData get academicData { + var profileJson = getFromDisk(ProfileKey); + // print(jsonDecode(profileJson)); + return AcademicData.fromJson(jsonDecode(profileJson)); + } + + void saveUserInDB(User userToSave) { + saveStringToDisk(UserKey, json.encode(userToSave.toJson())); + notifyListeners(); + } + + void saveProfileInDB(ProfileData data) { + saveStringToDisk(ProfileKey, jsonEncode(data.toJson())); + } + + static Future getInstance() async { + if (_instance == null) { + _instance = StorageService(); + } + if (_sharedPreferences == null) { + _sharedPreferences = await SharedPreferences.getInstance(); + } + return _instance; + } + + dynamic getFromDisk(String key) { + var value = _sharedPreferences?.get(key); + // print('(TRACE) LocalStorageService:getFromDisk. key: $key value: $value'); + return value; + } + + void saveStringToDisk(String key, String content) { + print('(TRACE) StorageService:_saveStringToDisk. key: $key'); + _sharedPreferences!.setString(key, content); + } + + void deleteKey(String key) { + print( + '(TRACE) StorageService: deleteKey. key: $key value: ${getFromDisk(key)}'); + _sharedPreferences!.remove(key); + } + + void saveToDisk(String key, T content) { + print('(TRACE) StorageService:_saveStringToDisk. key: $key'); + if (content is String) { + _sharedPreferences!.setString(key, content); + } + if (content is bool) { + _sharedPreferences!.setBool(key, content); + } + if (content is int) { + _sharedPreferences!.setInt(key, content); + } + if (content is double) { + _sharedPreferences!.setDouble(key, content); + } + if (content is List) { + _sharedPreferences!.setStringList(key, content); + } + } +} \ No newline at end of file diff --git a/scripts/clone.sh b/scripts/clone.sh new file mode 100644 index 00000000..20bf0276 --- /dev/null +++ b/scripts/clone.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +branches=("ac" "ac-1" "ac-2" "ac-3" "ac-4" "ac-5" "ps-1" "ps-2" "gad-1" "gad-2" "gad-3" "gad-4" "gad-5" "hr" "sa-1" "sa-2" "sa-3" "sa-4" "os-1" "os-2" "os-3" "os-4" "rspc") + +for branch in "${branches[@]}" +do + echo "Creating $branch..." + + git checkout -b "$branch" + git push origin "$branch" + + echo "Pushed new branch $branch to remote" +done \ No newline at end of file