diff --git a/lib/new_ui/screens/attendance_screen/add_attendance.dart b/lib/new_ui/screens/attendance_screen/add_attendance.dart new file mode 100644 index 0000000..0d3f8a4 --- /dev/null +++ b/lib/new_ui/screens/attendance_screen/add_attendance.dart @@ -0,0 +1,251 @@ +import 'package:flutter/material.dart'; +import 'package:tsec_app/new_ui/colors.dart'; +import 'package:tsec_app/new_ui/screens/attendance_screen/widgets/attendanceservice.dart'; + +class AddAttendanceScreen extends StatefulWidget { + + int? index; + final bool isUpdate; + Map? updatedSubject; + List? attendanceList; + AddAttendanceScreen({required this.isUpdate, this.updatedSubject,this.index,this.attendanceList}); + + @override + State createState() => _AddAttendanceScreenState(); +} + +class _AddAttendanceScreenState extends State { + + late TextEditingController subjectController; + late TextEditingController totalLecturesController; + late TextEditingController attendedLecturesController; + + @override + void initState() { + super.initState(); + subjectController = TextEditingController(text: widget.isUpdate ? widget.updatedSubject!['subject_name']:""); + totalLecturesController = TextEditingController(text: widget.isUpdate ? widget.updatedSubject!['total'].toString():""); + attendedLecturesController = TextEditingController(text: widget.isUpdate ? widget.updatedSubject!['present'].toString():""); + } + + TextStyle inputTextFieldStyle = TextStyle(color: Colors.white,); + + @override + Widget build(BuildContext context) { + Size size = MediaQuery.of(context).size; + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + foregroundColor: Colors.white, + centerTitle: true, + actions: [ + if (widget.isUpdate) IconButton(onPressed: (){ + showDialog(context: context, builder: (context){ + return AlertDialog( + title: Text("Are you sure you want to delete?",), + actions: [ + InkWell( + onTap:(){ + Navigator.pop(context); + }, + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5), + width: size.width*0.3, + decoration: BoxDecoration( + color: commonbgL4ightblack, + borderRadius: BorderRadius.circular(5), + ), + child: Text("Cancel",style: TextStyle(color: Colors.white),), + ), + ), + InkWell( + onTap: () async{ + await AttendanceService.deleteSubject(widget.attendanceList!, widget.index!); + Navigator.pop(context); + Navigator.pop(context); + }, + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 5), + width: size.width*0.3, + decoration: BoxDecoration( + color: Colors.red, + borderRadius: BorderRadius.circular(5), + ), + child: Text("Delete",style: TextStyle(color: Colors.white),), + ), + ), + ], + ); + }); + }, icon: Icon(Icons.delete,color: Colors.red,),) else SizedBox(), + ], + ), + body: ListView( + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: Text("Add a Subject",style: TextStyle(color: Colors.white,fontSize: 23,fontWeight: FontWeight.bold),), + ), + + SizedBox( + height: size.height*0.04, + ), + + Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: Text("Subject Name: ",style: TextStyle(color: Colors.white,fontSize: 17,fontWeight: FontWeight.bold),), + ), + + SizedBox( + height: size.height*0.01, + ), + Container( + padding: EdgeInsets.symmetric(horizontal: 10), + decoration: BoxDecoration( + color: commonbgL4ightblack, + borderRadius: BorderRadius.circular(5) + ), + margin: EdgeInsets.symmetric(horizontal: 20), + child: TextField( + style: inputTextFieldStyle, + controller: subjectController, + decoration: InputDecoration( + border: InputBorder.none, + ), + ), + ), + + + SizedBox( + height: size.height*0.04, + ), + + Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: Text("Attended Lectures: ",style: TextStyle(color: Colors.white,fontSize: 17,fontWeight: FontWeight.bold),), + ), + + SizedBox( + height: size.height*0.01, + ), + Container( + padding: EdgeInsets.symmetric(horizontal: 10), + decoration: BoxDecoration( + color: commonbgL4ightblack, + borderRadius: BorderRadius.circular(5) + ), + margin: EdgeInsets.symmetric(horizontal: 20), + child: TextField( + style: inputTextFieldStyle, + keyboardType: TextInputType.number, + controller: attendedLecturesController, + decoration: InputDecoration( + border: InputBorder.none, + ), + ), + ), + + + SizedBox( + height: size.height*0.04, + ), + + Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: Text("Total Lectures: ",style: TextStyle(color: Colors.white,fontSize: 17,fontWeight: FontWeight.bold),), + ), + + SizedBox( + height: size.height*0.01, + ), + Container( + padding: EdgeInsets.symmetric(horizontal: 10), + decoration: BoxDecoration( + color: commonbgL4ightblack, + borderRadius: BorderRadius.circular(5) + ), + margin: EdgeInsets.symmetric(horizontal: 20), + child: TextField( + style: inputTextFieldStyle, + keyboardType: TextInputType.number, + controller: totalLecturesController, + decoration: InputDecoration( + border: InputBorder.none, + ), + ), + ), + + SizedBox( + height: size.height*0.325, + ), + + InkWell( + onTap: () async{ + bool isSubjectAdded = await addSubject(); + if(isSubjectAdded){ + Navigator.pop(context); + showSnackBarMessage("Subject Added Successfully", Colors.green); + } + }, + splashFactory: NoSplash.splashFactory, + child: Container( + alignment: Alignment.center, + height: 45, + width: size.width, + margin: EdgeInsets.symmetric(horizontal: 20), + decoration: BoxDecoration( + color: cardcolorblue, + borderRadius: BorderRadius.circular(5), + ), + child: Text("Send Mail",style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold),), + ), + ), + ], + ), + ); + } + + Future addSubject() async{ + if(totalLecturesController.text.isEmpty || attendedLecturesController.text.isEmpty || subjectController.text.isEmpty){ + showSnackBarMessage("Fields cannot be left blank", Colors.red); + return false; + } + else if(totalLecturesController.text.contains(',') || totalLecturesController.text.contains('.') || attendedLecturesController.text.contains(',') || attendedLecturesController.text.contains('.')){ + showSnackBarMessage("Attended and Total Lectures can only have Numeric Charachters", Colors.red); + return false; + } + String subjectName = subjectController.text; + int totalLectures = + int.parse(totalLecturesController.text); + int attendedLectures = + int.parse(attendedLecturesController.text); + + if(totalLectures.isNegative || attendedLectures.isNegative){ + showSnackBarMessage("Lectures cannot be Negative", Colors.red); + return false; + }else if(attendedLectures>totalLectures){ + showSnackBarMessage("Attended Lectures cannot be greater than Total Lectures", Colors.red); + return false; + } + else{ + Map updatedSubject = { + "subject_name": subjectName, + "total": totalLectures, + "present": attendedLectures + }; + if(widget.isUpdate){ + await AttendanceService.updateSubject(widget.attendanceList!, widget.index!, updatedSubject); + }else { + await AttendanceService.addSubject(updatedSubject); + } + return true; + } + + } + + showSnackBarMessage(String text,Color color){ + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(text,style: TextStyle(color: Colors.white),),backgroundColor: color,),); + } +} diff --git a/lib/new_ui/screens/attendance_screen/attendance_screen.dart b/lib/new_ui/screens/attendance_screen/attendance_screen.dart index dd13185..94ec4f3 100644 --- a/lib/new_ui/screens/attendance_screen/attendance_screen.dart +++ b/lib/new_ui/screens/attendance_screen/attendance_screen.dart @@ -11,6 +11,7 @@ import 'package:tsec_app/provider/auth_provider.dart'; import 'package:tsec_app/services/sharedprefsfordot.dart'; import '../../showcasekeys.dart'; +import 'add_attendance.dart'; class AttendanceScreen extends StatefulWidget { const AttendanceScreen({super.key}); @@ -183,11 +184,30 @@ class _AttendanceScreenState extends State { itemCount: attendanceList.length, itemBuilder: (context, index) { var attendanceInfo = attendanceList[index]; + print(attendanceInfo); return GestureDetector( onTap: () { // Show dialog with current values for modification - showDialog( + + Navigator.push(context, PageRouteBuilder( + pageBuilder: (context, animation, secondaryAnimation) => + AddAttendanceScreen(isUpdate: true,index: index,attendanceList: attendanceList,updatedSubject: attendanceInfo,), + transitionsBuilder: (context, animation, secondaryAnimation, child) { + const begin = Offset(0.0, 1.0); // Start from bottom + const end = Offset.zero; // Move to top (center) + const curve = Curves.easeInOut; + + var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve)); + var offsetAnimation = animation.drive(tween); + + return SlideTransition( + position: offsetAnimation, + child: child, + ); + }, + ),); + /* showDialog( context: context, builder: (BuildContext context) { TextEditingController subjectNameController = @@ -364,7 +384,8 @@ class _AttendanceScreenState extends State { } isEnabled = false; - /*DocumentSnapshot doc = await FirebaseFirestore.instance + */ + /*DocumentSnapshot doc = await FirebaseFirestore.instance .collection("Attendance") .doc(FirebaseAuth.instance.currentUser!.uid) .get(); @@ -390,6 +411,7 @@ class _AttendanceScreenState extends State { .update({'attendance': attendanceList}); } }*/ + /* }, child: Text('Update', style: TextStyle(color: Colors.blue)), @@ -399,7 +421,8 @@ class _AttendanceScreenState extends State { AttendanceService.deleteSubject( attendanceList, index); - /*DocumentSnapshot doc = await FirebaseFirestore.instance + */ + /*DocumentSnapshot doc = await FirebaseFirestore.instance .collection("Attendance") .doc(FirebaseAuth.instance.currentUser!.uid) .get(); @@ -417,6 +440,7 @@ class _AttendanceScreenState extends State { .update({'attendance': attendanceList}); } _fetchAndSetAttendance();*/ + /* Navigator.of(context).pop(); }, child: Text('Delete', @@ -432,7 +456,7 @@ class _AttendanceScreenState extends State { ], ); }, - ); + );*/ }, child: Card( child: Container( @@ -491,7 +515,7 @@ class _AttendanceScreenState extends State { height: 10, ), LinearProgressIndicator( - value: attendanceInfo['total'] + value: attendanceInfo['total'] != 0 ? attendanceInfo['present'] / attendanceInfo['total'] : 0, @@ -596,7 +620,7 @@ class _AttendanceScreenState extends State { descTextStyle: TextStyle(fontSize: 15), child: FloatingActionButton( onPressed: () { - showDialog( + /*showDialog( context: context, builder: (BuildContext context) { TextEditingController subjectNameController = @@ -740,7 +764,8 @@ class _AttendanceScreenState extends State { "present": attendedLectures }; AttendanceService.addSubject(updatedSubject); - /*FirebaseFirestore.instance + */ + /*FirebaseFirestore.instance .collection("Attendance") .doc(FirebaseAuth.instance.currentUser!.uid) .set({ @@ -751,6 +776,7 @@ class _AttendanceScreenState extends State { }]) }, SetOptions(merge: true)); _fetchAndSetAttendance();*/ + /* Navigator.of(context).pop(); } }, @@ -759,7 +785,25 @@ class _AttendanceScreenState extends State { ], ); }, - ); + );*/ + + Navigator.push(context, PageRouteBuilder( + pageBuilder: (context, animation, secondaryAnimation) => + AddAttendanceScreen(isUpdate: false,), + transitionsBuilder: (context, animation, secondaryAnimation, child) { + const begin = Offset(0.0, 1.0); // Start from bottom + const end = Offset.zero; // Move to top (center) + const curve = Curves.easeInOut; + + var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve)); + var offsetAnimation = animation.drive(tween); + + return SlideTransition( + position: offsetAnimation, + child: child, + ); + }, + ),); }, shape: CircleBorder( side: BorderSide( diff --git a/lib/new_ui/screens/attendance_screen/widgets/attendanceservice.dart b/lib/new_ui/screens/attendance_screen/widgets/attendanceservice.dart index 169861f..2979a09 100644 --- a/lib/new_ui/screens/attendance_screen/widgets/attendanceservice.dart +++ b/lib/new_ui/screens/attendance_screen/widgets/attendanceservice.dart @@ -27,7 +27,7 @@ class AttendanceService{ await firestore.doc(auth.currentUser!.uid).set({"attendance":attendanceList}); } - static addSubject(Map updatedSubject)async{ + static Future addSubject(Map updatedSubject)async{ List attendanceList; final get = await firestore.doc(auth.currentUser!.uid).get(); if(get.exists){ diff --git a/lib/new_ui/screens/login_screen/ResetPasswordScreen.dart b/lib/new_ui/screens/login_screen/ResetPasswordScreen.dart new file mode 100644 index 0000000..3743ab8 --- /dev/null +++ b/lib/new_ui/screens/login_screen/ResetPasswordScreen.dart @@ -0,0 +1,121 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:tsec_app/new_ui/colors.dart'; + +import '../../../provider/auth_provider.dart'; +import '../../../utils/custom_snackbar.dart'; + +class ResetPasswordScreen extends ConsumerStatefulWidget { + + @override + _ResetPasswordScreenState createState() => _ResetPasswordScreenState(); +} + +class _ResetPasswordScreenState extends ConsumerState { + String emailController = ""; + + @override + Widget build(BuildContext context) { + Size size = MediaQuery.of(context).size; + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + foregroundColor: Colors.white, + centerTitle: true, + ), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Text("Reset Password",style: TextStyle(color: Colors.white,fontSize: 23,fontWeight: FontWeight.bold),), + ), + SizedBox( + height: 20, + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Text("Forgot your password? No worries! Simply enter your email address below. We'll send a link to reset your password. Once you receive the link, follow the instructions to create a new password.",style: TextStyle(color: Colors.white,fontSize: 15),), + ), + + SizedBox( + height: 20, + ), + + Container( + alignment: Alignment.center, + height: 50, + margin: EdgeInsets.symmetric(horizontal: 20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5) + ), + padding: EdgeInsets.symmetric(horizontal: 10), + child: TextField( + onChanged: (val){ + setState(() { + emailController = val; + }); + }, + style: TextStyle(fontSize: 17), + decoration: InputDecoration( + border: InputBorder.none, + hintText: "Enter Email" + ), + ), + ), + + Spacer(), + + InkWell( + splashFactory: NoSplash.splashFactory, + onTap: emailController.isNotEmpty ? ()async{ + //Form Logic + await forgotPassword(emailController); + } : (){ + print("Please Enter Email"); + }, + child: Container( + alignment: Alignment.center, + height: 45, + width: size.width, + margin: EdgeInsets.symmetric(horizontal: 20), + decoration: BoxDecoration( + color: emailController.isNotEmpty ? cardcolorblue : Colors.grey.shade800, + borderRadius: BorderRadius.circular(5), + ), + child: Text("Send Mail",style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold),), + ), + ), + SizedBox( + height: 20, + ), + ], + ), + ); + } + + Future forgotPassword(String email) async { + if (email.trim() != "") { + try { + await ref + .watch(authProvider.notifier) + .resetPassword(email.trim(), context); + + showSnackBar(context, + 'Check your inbox and click on the link in password reset email'); + } on FirebaseAuthException catch (e) { + if (e.code == 'user-not-found') { + showSnackBar(context, 'No user found corresponding to that email.'); + } else + showSnackBar(context, e.message.toString()); + return null; + } + } else { + showSnackBar( + context, 'Enter the email to reset password of that account'); + } + } +} diff --git a/lib/new_ui/screens/login_screen/login_screen.dart b/lib/new_ui/screens/login_screen/login_screen.dart index 70838f3..979a143 100644 --- a/lib/new_ui/screens/login_screen/login_screen.dart +++ b/lib/new_ui/screens/login_screen/login_screen.dart @@ -6,6 +6,7 @@ import 'package:go_router/go_router.dart'; import 'package:tsec_app/models/notification_model/notification_model.dart'; import 'package:tsec_app/models/student_model/student_model.dart'; import 'package:tsec_app/models/user_model/user_model.dart'; +import 'package:tsec_app/new_ui/screens/login_screen/ResetPasswordScreen.dart'; import 'package:tsec_app/provider/auth_provider.dart'; import 'package:tsec_app/provider/firebase_provider.dart'; import 'package:tsec_app/provider/notification_provider.dart'; @@ -46,27 +47,7 @@ class _LoginScreenState extends ConsumerState { super.dispose(); } - Future forgotPassword() async { - if (_emailTextEditingController.text.trim() != "") { - try { - await ref - .watch(authProvider.notifier) - .resetPassword(_emailTextEditingController.text.trim(), context); - showSnackBar(context, - 'Check your inbox and click on the link in password reset email'); - } on FirebaseAuthException catch (e) { - if (e.code == 'user-not-found') { - showSnackBar(context, 'No user found corresponding to that email.'); - } else - showSnackBar(context, e.message.toString()); - return null; - } - } else { - showSnackBar( - context, 'Enter the email to reset password of that account'); - } - } Future login() async { if (_formKey.currentState!.validate()) { @@ -288,7 +269,8 @@ class _LoginScreenState extends ConsumerState { borderRadius: BorderRadius.circular( 30), // Set the desired border radius onTap: () async { - forgotPassword(); + //forgotPassword(); + Navigator.push(context, MaterialPageRoute(builder: (context)=> ResetPasswordScreen(),),); }, highlightShape: BoxShape.rectangle, // Custom shape diff --git a/lib/new_ui/screens/railway_screen/railwayform.dart b/lib/new_ui/screens/railway_screen/railwayform.dart index 2dc11ca..4ca4217 100644 --- a/lib/new_ui/screens/railway_screen/railwayform.dart +++ b/lib/new_ui/screens/railway_screen/railwayform.dart @@ -371,23 +371,23 @@ class _RailwayForm extends ConsumerState { statusMessage: "", ageMonths: int.parse(_ageMonths), ageYears: int.parse(_ageYears), - duration: duration ?? "Monthly", - branch: student.branch, - gender: gender ?? "Male", - firstName: firstNameController.text, - gradyear: student.gradyear, - middleName: middleNameController.text, - lastName: lastNameController.text, - idCardURL: idCardURL, - previousPassURL: previousPassURL, - from: homeStation, - to: toStation, + duration: duration?.toUpperCase() ?? "Monthly".toUpperCase(), + branch: student.branch.toUpperCase(), + gender: gender?.toUpperCase() ?? "Male".toUpperCase(), + firstName: firstNameController.text.toUpperCase(), + gradyear: student.gradyear.toUpperCase(), + middleName: middleNameController.text.toUpperCase(), + lastName: lastNameController.text.toUpperCase(), + idCardURL: idCardURL.toUpperCase(), + previousPassURL: previousPassURL.toUpperCase(), + from: homeStation.toUpperCase(), + to: toStation.toUpperCase(), lastPassIssued: null, - address: addressController.text, + address: addressController.text.toUpperCase(), dob: _selectedDate ?? DateTime.now(), phoneNum: int.parse(phoneNumController.text), - travelLane: travelLane ?? "Central", - type: travelClass ?? "I", + travelLane: travelLane?.toUpperCase() ?? "Central".toUpperCase(), + type: travelClass?.toUpperCase() ?? "I".toUpperCase(), ); if (_formKey.currentState!.validate() &&