Migrate from BitBucket

This commit is contained in:
2024-10-28 18:52:54 +00:00
commit 7a3db5d671
46 changed files with 6052 additions and 0 deletions
@@ -0,0 +1,51 @@
import 'package:flutter/material.dart';
import 'package:school_management_system/components/default_values.dart';
import 'package:school_management_system/screens/welcome/welcome_screen.dart';
late Future<bool> _checkToken;
class AttendanceScreen extends StatefulWidget {
const AttendanceScreen({super.key});
@override
State<AttendanceScreen> createState() => _AttendanceScreenState();
}
class _AttendanceScreenState extends State<AttendanceScreen> {
@override
void initState() {
_checkToken = checkTokenValidity();
super.initState();
}
@override
Widget build(BuildContext context) {
_checkToken.then(
(value) {
if (!value) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const WelcomeScreen();
},
),
);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Session Time Out / Sign Back In'),
),
);
}
},
);
return const Center(
child: Text(
'Attendance Page',
style: TextStyle(fontWeight: FontWeight.w800),
),
);
}
}
+222
View File
@@ -0,0 +1,222 @@
import 'package:flutter/material.dart';
import 'package:school_management_system/api/calender_requests.dart';
import 'package:school_management_system/components/default_values.dart';
import 'package:school_management_system/screens/welcome/welcome_screen.dart';
import 'package:syncfusion_flutter_calendar/calendar.dart';
late Future<Calendar> _studentData;
late Future<Calendar> _schoolData;
late Future<bool> _checkToken;
class SchoolCalender extends StatefulWidget {
const SchoolCalender({super.key});
@override
State<SchoolCalender> createState() => _SchoolCalenderState();
}
class _SchoolCalenderState extends State<SchoolCalender> {
List<Calenderrdetail> calendar = [];
@override
void initState() {
_checkToken = checkTokenValidity();
super.initState();
_studentData = getStudentCalender(loginId, session, semester);
_schoolData = getSchoolCalender('HOLIDAY', session, semester);
}
@override
Widget build(BuildContext context) {
_checkToken.then(
(value) {;
if (!value) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const WelcomeScreen();
},
),
);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Session Time Out / Sign Back In'),
),
);
}
},
);
return FutureBuilder<List<Calendar>>(
future: Future.wait([_schoolData, _studentData]),
builder: (context, snapshot) {
List<Widget> children;
if (snapshot.hasData) {
calendar = [];
var levelOne = 0;
while (levelOne < snapshot.data!.length) {
var levelTwo = 0;
while (levelTwo <
snapshot.data![levelOne].calenderrdetails!.length) {
calendar
.add(snapshot.data![levelOne].calenderrdetails![levelTwo]);
levelTwo++;
}
levelOne++;
}
children = [
const SizedBox(height: 20),
Expanded(
child: SfCalendar(
view: CalendarView.month,
showDatePickerButton: true,
showTodayButton: true,
dataSource: MeetingDataSource(_getDataSource()),
monthViewSettings: const MonthViewSettings(
showAgenda: true,
appointmentDisplayMode:
MonthAppointmentDisplayMode.appointment),
),
),
];
} else if (snapshot.hasError) {
calendar = [];
children = [
const Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: ${snapshot.error}'),
),
];
} else {
calendar = [];
children = const [
SizedBox(
width: 60,
height: 60,
child: CircularProgressIndicator(),
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Loading Data...'),
),
];
}
return Container(
padding: const EdgeInsets.all(20),
color: Colors.white,
child: Column(
children: children,
),
);
});
}
List<Meeting> _getDataSource() {
List<Meeting> meetings = <Meeting>[];
var calendarCount = 0;
if (calendar.isNotEmpty) {
while (calendarCount < calendar.length) {
bool? allday = calendar[calendarCount].allday;
DateTime? sdate = calendar[calendarCount].startdate;
String? stime = calendar[calendarCount].starttime;
DateTime? starttime = DateTime(
sdate!.year,
sdate.month,
sdate.day,
int.parse(stime!.split(':')[0]),
int.parse(stime.split(':')[1]),
int.parse(stime.split(':')[2]));
DateTime? edate = calendar[calendarCount].enddate;
String? etime = calendar[calendarCount].endtime;
DateTime? endtime = DateTime(
edate!.year,
edate.month,
edate.day,
int.parse(etime!.split(':')[0]),
int.parse(etime.split(':')[1]),
int.parse(etime.split(':')[2]));
// DateTime? enddate = calendar[initVal].enddate;
String? event = calendar[calendarCount].event;
// String? recurrenceRule = calendar[initVal].occurence;
meetings.add(Meeting(
event!, starttime, endtime, primaryColor, allday!, ""));
calendarCount++;
}
}
// // final DateTime today = DateTime.now();
// final DateTime startTime = DateTime(2024, 03, 16, 9, 0, 0);
// // DateTime(today.year, today.month, today.day, 9, 0, 0);
// final DateTime endTime = startTime.add(const Duration(hours: 2));
// meetings.add(Meeting(
// 'Birthday', startTime, endTime, const Color(0xFF0F8644), false));
return meetings;
}
}
class MeetingDataSource extends CalendarDataSource {
MeetingDataSource(this.source);
List<Meeting> source;
@override
List<dynamic> get appointments => source;
@override
DateTime getStartTime(int index) {
return source[index].from;
}
@override
DateTime getEndTime(int index) {
return source[index].to;
}
@override
String getSubject(int index) {
return source[index].eventName;
}
@override
Color getColor(int index) {
return source[index].background;
}
@override
bool isAllDay(int index) {
return source[index].isAllDay;
}
@override
String getRecurrenceRule(int index) {
return appointments[index].recurrenceRule;
}
}
class Meeting {
Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay,
this.recurrenceRule);
String eventName;
DateTime from;
DateTime to;
Color background;
bool isAllDay;
String recurrenceRule;
}
+53
View File
@@ -0,0 +1,53 @@
import 'package:flutter/material.dart';
import 'package:school_management_system/components/default_values.dart';
import 'package:school_management_system/screens/welcome/welcome_screen.dart';
late Future<bool> _checkToken;
class FinanceScreen extends StatefulWidget {
const FinanceScreen({super.key});
@override
State<FinanceScreen> createState() => _FinanceScreenState();
}
class _FinanceScreenState extends State<FinanceScreen> {
@override
void initState() {
_checkToken = checkTokenValidity();
super.initState();
}
@override
Widget build(BuildContext context) {
_checkToken.then(
(value) {
if (!value) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const WelcomeScreen();
},
),
);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Session Time Out / Sign Back In'),
),
);
}
},
);
return const Center(
child: Text(
'Finance Page',
style: TextStyle(fontWeight: FontWeight.w800),
),
);
}
}
+95
View File
@@ -0,0 +1,95 @@
import 'package:flutter/material.dart';
import 'package:school_management_system/components/default_values.dart';
import 'package:school_management_system/screens/welcome/welcome_screen.dart';
import 'package:webview_flutter/webview_flutter.dart';
late Future<bool> _checkToken;
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
late final WebViewController controller;
var loadingPercentage = 0;
// String? message;
// setMessage(String javascriptMessage) {
// if (mounted) {
// setState(() {
// message = javascriptMessage;
// });
// }
// }
@override
void initState() {
_checkToken = checkTokenValidity();
super.initState();
controller = WebViewController()
..loadRequest(
Uri.parse('https://www.tees.ac.uk/sections/stud/news.cfm'),
)
// ..addJavaScriptChannel("myChannel",
// onMessageReceived: (JavaScriptMessage message) {
// // setMessage(message.message);
// })
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(NavigationDelegate(
onPageStarted: (url) {
setState(() {
loadingPercentage = 0;
});
},
onProgress: (progress) {
setState(() {
loadingPercentage = progress;
});
},
onPageFinished: (url) {
setState(() {
loadingPercentage = 100;
});
},
));
}
@override
Widget build(BuildContext context) {
_checkToken.then(
(value) {
if (!value) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const WelcomeScreen();
},
),
);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Session Time Out / Sign Back In'),
),
);
}
},
);
return Stack(
children: [
WebViewWidget(
controller: controller,
),
if (loadingPercentage < 100)
LinearProgressIndicator(
value: loadingPercentage / 100.0,
),
],
);
}
}
@@ -0,0 +1,132 @@
import 'package:flutter/material.dart';
import 'package:school_management_system/api/auth_requests.dart';
import 'package:school_management_system/components/default_values.dart';
import 'package:school_management_system/screens/main/main_screen.dart';
class LoginForm extends StatefulWidget {
const LoginForm({
super.key,
});
@override
State<LoginForm> createState() => _LoginFormState();
}
class _LoginFormState extends State<LoginForm> {
var usernameController = TextEditingController();
var passwordController = TextEditingController();
var checked = false;
var obscureText = true;
//var authService = AuthoriseService();
@override
Widget build(BuildContext context) {
return Column(
// mainAxisAlignment: MainAxisAlignment.start,
children: [
TextField(
controller: usernameController,
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.next,
cursorColor: primaryColor,
onSubmitted: (username) {
setState(() {
usernameController.text = username;
});
},
decoration: const InputDecoration(
hintText: "Username",
prefixIcon: Padding(
padding: EdgeInsets.all(defaultPadding),
child: Icon(Icons.person),
),
),
),
const SizedBox(height: 10),
TextField(
controller: passwordController,
keyboardType: TextInputType.visiblePassword,
textInputAction: TextInputAction.done,
obscureText: obscureText,
onSubmitted: (paswword) {
setState(() {
passwordController.text = paswword;
});
},
cursorColor: primaryColor,
decoration: InputDecoration(
hintText: "Password",
prefixIcon: const Padding(
padding: EdgeInsets.all(defaultPadding),
child: Icon(Icons.lock),
),
suffixIcon: IconButton(
icon: Icon(
obscureText ? Icons.visibility : Icons.visibility_off),
onPressed: () {
setState(
() {
obscureText = !obscureText;
},
);
},
)),
),
const SizedBox(),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Checkbox(
value: checked,
onChanged: (value) {
setState(() {
checked = value!;
});
}),
const Text('Save Password'),
],
),
const SizedBox(height: defaultPadding),
ElevatedButton(
onPressed: () {
login(usernameController.value.text, passwordController.value.text)
.then((status) {
if (status.startsWith('Successful')) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const MainScaffold();
},
),
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(status),
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(status),
),
);
}
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"sign in".toUpperCase(),
),
const SizedBox(width: 10),
const Icon(Icons.login)
],
),
),
],
);
}
}
@@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:school_management_system/components/default_values.dart';
class LoginScreenTopImage extends StatelessWidget {
const LoginScreenTopImage({
super.key,
});
@override
Widget build(BuildContext context) {
return Column(
// mainAxisAlignment: MainAxisAlignment.start,
children: [
// const Text(
// "LOGIN",
// style: TextStyle(fontWeight: FontWeight.bold),
// ),
const SizedBox(height: defaultPadding * 2),
Row(
children: [
const Spacer(),
Expanded(
flex: 8,
child: SvgPicture.asset(
'assets/icons/school.svg',
width: 320,
height: 320,
),
),
const Spacer(),
],
),
const SizedBox(height: defaultPadding * 2),
],
);
}
}
+69
View File
@@ -0,0 +1,69 @@
import 'package:flutter/material.dart';
import 'package:school_management_system/screens/login/components/login_form.dart';
import 'package:school_management_system/screens/login/components/login_screen_top_image.dart';
import 'package:school_management_system/screens/main/main_screen.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({super.key});
@override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
@override
Widget build(BuildContext context) {
return const Scaffold(
resizeToAvoidBottomInset: false,
body: Responsive(
desktop: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: LoginScreenTopImage(),
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 350,
child: LoginForm(),
),
],
),
),
],
),
mobile: MobileLoginScreen(),
),
);
}
}
class MobileLoginScreen extends StatelessWidget {
const MobileLoginScreen({
super.key,
});
@override
Widget build(BuildContext context) {
return ListView(
// mainAxisAlignment: MainAxisAlignment.center,
children: const [
LoginScreenTopImage(),
Row(
children: [
Spacer(),
Expanded(
flex: 8,
child: LoginForm(),
),
Spacer(),
],
),
],
);
}
}
@@ -0,0 +1,68 @@
import 'package:flutter/material.dart';
import 'package:school_management_system/screens/attendance/attendance_screen.dart';
import 'package:school_management_system/screens/calender/calender_screen.dart';
import 'package:school_management_system/screens/finance/finance_screen.dart';
import 'package:school_management_system/screens/home/home_screen.dart';
import 'package:school_management_system/screens/modules/modules_screen.dart';
import 'package:school_management_system/screens/profile/profile_screen.dart';
import 'package:school_management_system/screens/results/results_screen.dart';
class NavigationItems {
String label;
Widget icon;
Widget widget;
NavigationItems({
required this.label,
required this.icon,
required this.widget,
});
}
List<NavigationItems> getNavigationItems() {
List<NavigationItems> navigationItems = [];
navigationItems.add(NavigationItems(
label: 'Home',
icon: const Icon(Icons.home),
widget: const HomeScreen(),
));
navigationItems.add(NavigationItems(
label: 'Modules',
icon: const Icon(Icons.book),
widget: const ModulesScreen(),
));
navigationItems.add(NavigationItems(
label: 'Calendar',
icon: const Icon(Icons.calendar_month),
widget: const SchoolCalender(),
));
navigationItems.add(NavigationItems(
label: 'Results',
icon: const Icon(Icons.school),
widget: const ResultsScreen(),
));
navigationItems.add(NavigationItems(
label: 'Profile',
icon: const Icon(Icons.person),
widget: const ProfileScreen(),
));
navigationItems.add(NavigationItems(
label: 'Finance',
icon: const Icon(Icons.money),
widget: const FinanceScreen(),
));
navigationItems.add(NavigationItems(
label: 'Attendance',
icon: const Icon(Icons.calendar_today_rounded),
widget: const AttendanceScreen(),
));
return navigationItems;
}
+201
View File
@@ -0,0 +1,201 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:school_management_system/api/session_requests.dart';
import 'package:school_management_system/components/default_values.dart';
import 'package:school_management_system/screens/main/components/navigation_details.dart';
import 'package:school_management_system/screens/welcome/welcome_screen.dart';
class MainScaffold extends StatefulWidget {
//final Widget child;
final String appTitle;
const MainScaffold({
super.key,
// required this.child,
this.appTitle = 'School Management Demo',
});
@override
State<MainScaffold> createState() => _MainScaffold();
}
class _MainScaffold extends State<MainScaffold> {
var selectedIndex = 0;
@override
void initState() {
super.initState();
}
List<NavigationItems> navigationItems = getNavigationItems();
@override
Widget build(BuildContext context) {
Widget page = navigationItems[selectedIndex].widget;
return FutureBuilder(
future: getCurrentSession(),
builder: (context, snapshot) {
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
title: Row(
children: [
if (navigationItems[selectedIndex].label == 'Home')
Row(
children: [
const SizedBox(width: 35),
Text(navigationItems[selectedIndex].label)
],
)
else
Row(
children: [
Image.asset(
'assets/images/unilogo.png',
width: 25,
height: 25,
fit: BoxFit.contain,
),
const SizedBox(width: 10),
Text(navigationItems[selectedIndex].label),
],
),
// Text(
// navigationItems[selectedIndex].label,
// ),
],
),
backgroundColor: primaryColor,
actions: [
IconButton(
icon: const Icon(
Icons.logout,
),
tooltip: 'Logout',
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
if (Platform.isAndroid) {
//SystemNavigator.pop();
return const WelcomeScreen();
} else if (Platform.isIOS) {
// exit(0);
return const WelcomeScreen();
} else {
return const WelcomeScreen();
}
},
),
);
},
)
],
),
drawer: SafeArea(
child: Responsive(
mobile: Row(
children: [
NavigationDrawer(
elevation: 50,
backgroundColor: primaryLightColor.withOpacity(1),
indicatorColor: primaryColor,
selectedIndex: selectedIndex,
onDestinationSelected: (value) {
setState(() {
Navigator.pop(context);
selectedIndex = value;
});
},
children:
navigationItems.map((NavigationItems navigationItem) {
return NavigationDrawerDestination(
icon: navigationItem.icon,
label: Text(navigationItem.label),
selectedIcon: navigationItem.icon,
backgroundColor: primaryColor,
);
}).toList(),
),
],
),
desktop: Row(
children: [
NavigationRail(
extended: true,
labelType: NavigationRailLabelType.none,
destinations:
navigationItems.map((NavigationItems navigationItem) {
return NavigationRailDestination(
label: Text(navigationItem.label),
icon: navigationItem.icon,
selectedIcon: navigationItem.icon,
);
}).toList(),
selectedIndex: selectedIndex,
onDestinationSelected: (value) {
setState(() {
selectedIndex = value;
});
},
),
],
),
),
),
body: SizedBox(
width: double.infinity,
height: MediaQuery.of(context).size.height,
child: Stack(
alignment: Alignment.center,
children: [
SafeArea(
child: page,
),
],
),
),
);
});
}
}
class Responsive extends StatelessWidget {
final Widget mobile;
final Widget? tablet;
final Widget desktop;
const Responsive({
super.key,
required this.mobile,
this.tablet,
required this.desktop,
});
static bool isMobile(BuildContext context) =>
MediaQuery.of(context).size.width < 576;
static bool isTablet(BuildContext context) =>
MediaQuery.of(context).size.width >= 576 &&
MediaQuery.of(context).size.width <= 992;
static bool isDesktop(BuildContext context) =>
MediaQuery.of(context).size.width > 992;
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
if (size.width > 992) {
return desktop;
} else if (size.width >= 600 && tablet != null) {
return tablet!;
} else {
return mobile;
}
}
}
+225
View File
@@ -0,0 +1,225 @@
import 'package:flutter/material.dart';
import 'package:school_management_system/api/student_requests.dart';
import 'package:school_management_system/components/default_values.dart';
import 'package:school_management_system/screens/welcome/welcome_screen.dart';
late Future<Student> _returnData;
late Student apiData;
late Map<String, List<String>>? sessiondetails;
late Map<String, List<ModuleDetail>> moduleDetail;
late Future<bool> _checkToken;
class ModulesScreen extends StatefulWidget {
const ModulesScreen({super.key});
@override
State<ModulesScreen> createState() => _ModulesScreenState();
}
class _ModulesScreenState extends State<ModulesScreen> {
String? _selectedKey;
String? _selectedItem;
List<ModuleDetail>? indivModule;
@override
void initState() {
_checkToken = checkTokenValidity();
super.initState();
_returnData = getStudentDetail(loginId);
}
@override
Widget build(BuildContext context) {
_checkToken.then(
(value) {
if (!value) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const WelcomeScreen();
},
),
);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Session Time Out / Sign Back In'),
),
);
}
},
);
return FutureBuilder<Student>(
future: _returnData,
builder: (context, snapshot) {
List<Widget> children;
if (snapshot.hasData) {
apiData = snapshot.data!;
moduleDetail = apiData.moduledetails!;
sessiondetails = apiData.sessiondetails!;
children = [
const SizedBox(height: 20),
dropDownMenu(),
const SizedBox(height: 50),
dataTableMenu(),
];
} else if (snapshot.hasError) {
children = [
const Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: ${snapshot.error}'),
),
];
} else {
children = const [
SizedBox(
width: 60,
height: 60,
child: CircularProgressIndicator(),
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Loading Data...'),
),
];
}
return Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: ListView(
scrollDirection: Axis.vertical,
children: children,
),
),
);
},
);
}
Row dropDownMenu() {
return Row(
children: [
DropdownButton(
value: _selectedKey,
icon: const Icon(Icons.arrow_drop_down),
iconSize: 30,
elevation: 16,
style: const TextStyle(fontSize: 20, color: Colors.black),
underline: Container(
height: 2,
color: Colors.grey,
),
onChanged: (newValue) {
setState(() {
_selectedKey = newValue;
_selectedItem = null;
});
},
items: sessiondetails?.keys.map((String value) {
return DropdownMenuItem(
value: value,
child: Text(value),
);
}).toList(),
),
const SizedBox(width: 30),
_selectedKey != null
? DropdownButton(
value: _selectedItem,
icon: const Icon(Icons.arrow_drop_down),
iconSize: 30,
elevation: 16,
style: const TextStyle(fontSize: 20, color: Colors.black),
underline: Container(
height: 2,
color: Colors.grey,
),
onChanged: (newValue) {
setState(() {
_selectedItem = newValue;
});
},
items: sessiondetails![_selectedKey]!.map((String value) {
return DropdownMenuItem(
value: value,
child: Text(value),
onTap: () {
setState(() {
indivModule = moduleDetail["$_selectedKey~$value"];
});
},
);
}).toList(),
)
: Container()
],
);
}
SingleChildScrollView dataTableMenu() {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: indivModule != null
? Column(
children: indivModule!.map((value) {
return Card(
elevation: 20,
color: const Color.fromARGB(255, 224, 208, 159),
child: InkWell(
onTap: () {
},
splashColor: primaryLightColor,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(
getImage(),
width: 120,
height: 120,
fit: BoxFit.cover,
),
const SizedBox(width: 10),
Padding(
padding: const EdgeInsets.only(left: 5, top: 5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
value.modulecode!,
style: const TextStyle(
fontWeight: FontWeight.w800,
),
),
Text(value.modulename!),
const Column(
children: [
Text('CLOSE'),
],
),
],
),
),
],
),
),
);
}).toList(),
)
: const Center(
child: Text(
'Nothing to Display',
style: TextStyle(fontWeight: FontWeight.w800),
),
),
);
}
}
@@ -0,0 +1,109 @@
import 'package:intl/intl.dart';
import 'package:school_management_system/api/student_requests.dart';
late DateTime dateOfBirth;
Map<String, dynamic> getPersonalDetails(Student studentDetail) {
Map<String, dynamic> personalDetails = {};
if (studentDetail.dateofbirth != null) {
dateOfBirth = studentDetail.dateofbirth!;
} else {
dateOfBirth = DateTime.now();
}
personalDetails.addEntries({'Title': studentDetail.title}.entries);
personalDetails.addEntries({
'Full Name': "${studentDetail.firstname} ${studentDetail.lastname}"
}.entries);
personalDetails.addEntries({'Gender': studentDetail.gender}.entries);
personalDetails.addEntries({
'Date of Birth': DateFormat('MMMM, dd yyyy').format(dateOfBirth)
}.entries);
personalDetails
.addEntries({'Current Year': studentDetail.currentyear}.entries);
personalDetails
.addEntries({'Current Session': studentDetail.currentsession}.entries);
personalDetails.addEntries({
'Course of Study': studentDetail.coursedetails![0].courseofstudy
}.entries);
personalDetails.addEntries(
{'Course Type': studentDetail.coursedetails![0].coursetype}.entries);
personalDetails.addEntries({
'Course Qualification': studentDetail.coursedetails![0].coursequalification
}.entries);
personalDetails.addEntries(
{'Course Mode': studentDetail.coursedetails![0].coursemode}.entries);
return personalDetails;
}
Map<String, dynamic> getContactDetails(Student studentDetail) {
Map<String, dynamic> contactDetails = {};
contactDetails
.addEntries({'Home Address': studentDetail.homeaddress}.entries);
contactDetails
.addEntries({'Mobile Number': studentDetail.mobilenumber}.entries);
contactDetails
.addEntries({'E-Mail Address': studentDetail.emailaddress}.entries);
contactDetails
.addEntries({'School Email': studentDetail.schoolemail}.entries);
contactDetails.addEntries({
'Next of Kin Name ': studentDetail.nextofkindetails![0].nextofkinname
}.entries);
contactDetails.addEntries({
'Next of Kin Contact ': studentDetail.nextofkindetails![0].nextofkincontact
}.entries);
contactDetails.addEntries({
'Next of Kin Address ': studentDetail.nextofkindetails![0].nextofkinaddress
}.entries);
contactDetails.addEntries({
'Next of Kin Relationship ': studentDetail.nextofkindetails![0].nextofkinrelationship
}.entries);
contactDetails.addEntries({
'Guardian Name ': studentDetail.guardiandetails![0].guardianname
}.entries);
contactDetails.addEntries({
'Guardian Contact ': studentDetail.guardiandetails![0].guardiancontact
}.entries);
contactDetails.addEntries({
'Guardian Address ': studentDetail.guardiandetails![0].guardianaddress
}.entries);
contactDetails.addEntries({
'Guardian Relationship ': studentDetail.guardiandetails![0].guardianrelationship
}.entries);
return contactDetails;
}
Map<String, dynamic> getMedicalDetails(Student studentDetail) {
Map<String, dynamic> medicalDetails = {};
medicalDetails
.addEntries({'Weight': studentDetail.medicaldetails![0].weight}.entries);
medicalDetails
.addEntries({'Height': studentDetail.medicaldetails![0].height}.entries);
medicalDetails.addEntries(
{'Genotype': studentDetail.medicaldetails![0].genotype}.entries);
medicalDetails.addEntries(
{'Blood Group': studentDetail.medicaldetails![0].bloodgroup}.entries);
medicalDetails.addEntries(
{'DNR': studentDetail.medicaldetails![0].dnr.toString()}.entries);
medicalDetails.addEntries(
{'Allergies': studentDetail.medicaldetails![0].allergies}.entries);
medicalDetails.addEntries({
'Medical Condition': studentDetail.medicaldetails![0].medicalcondition
}.entries);
medicalDetails.addEntries({
'Emergency Contact': studentDetail.medicaldetails![0].emergencycontactname
}.entries);
medicalDetails.addEntries({
'Emergency Number': studentDetail.medicaldetails![0].emergencycontactnumber
}.entries);
medicalDetails.addEntries({
'Emergency Relationship': studentDetail.medicaldetails![0].emergencycontractrelationship
}.entries);
return medicalDetails;
}
+265
View File
@@ -0,0 +1,265 @@
import 'package:flutter/material.dart';
import 'package:school_management_system/api/student_requests.dart';
import 'package:school_management_system/components/default_values.dart';
import 'package:school_management_system/screens/profile/components/personal_details.dart';
import 'package:school_management_system/screens/welcome/welcome_screen.dart';
//This Screen Would include the basic Student Detials
//Profile Picture, Full Name, Course of Study, Current Year, Age (DOB), Medical History (Height, Weight, et all)
//Next of Kin, Contact Details, Address
//Every other item as remembered would be added.
late Future<Student> _returnData;
late Student apiData;
late Future<bool> _checkToken;
class ProfileScreen extends StatefulWidget {
const ProfileScreen({super.key});
@override
State<ProfileScreen> createState() => _ProfileScreenState();
}
class _ProfileScreenState extends State<ProfileScreen> {
@override
void initState() {
_checkToken = checkTokenValidity();
super.initState();
_returnData = getStudentDetail(loginId);
}
@override
Widget build(BuildContext context) {
_checkToken.then(
(value) {
if (!value) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const WelcomeScreen();
},
),
);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Session Time Out / Sign Back In'),
),
);
}
},
);
return FutureBuilder<Student>(
future: _returnData,
builder: (context, snapshot) {
List<Widget> children;
if (snapshot.hasData) {
apiData = snapshot.data!;
children = [
const SizedBox(height: 20),
profileImage(),
const SizedBox(height: 30),
personalDetails(),
const SizedBox(height: 30),
contactDetails(),
const SizedBox(height: 30),
medicalDetails(),
const SizedBox(height: 30),
];
} else if (snapshot.hasError) {
children = [
const Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: ${snapshot.error}'),
),
];
} else {
children = const [
SizedBox(
width: 60,
height: 60,
child: CircularProgressIndicator(),
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Loading Data...'),
),
];
}
return Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: ListView(
scrollDirection: Axis.vertical,
children: children,
),
),
);
},
);
}
Column medicalDetails() {
var medicalDetails = getMedicalDetails(apiData);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Medical Details',
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 5),
Column(
children: [
Table(
columnWidths: const <int, TableColumnWidth>{
0: IntrinsicColumnWidth(),
1: FlexColumnWidth(),
2: FixedColumnWidth(64)
},
children: [
for (var key in medicalDetails.keys)
TableRow(children: [
Padding(
padding: const EdgeInsets.only(right: 5),
child: Text(
key,
style: const TextStyle(
fontSize: 14, fontWeight: FontWeight.w500),
),
),
Padding(
padding: const EdgeInsets.only(left: 5),
child: Text(medicalDetails[key]),
)
])
],
)
],
),
],
);
}
Column contactDetails() {
var contactDetails = getContactDetails(apiData);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Contact Details',
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 5),
Column(
children: [
Table(
columnWidths: const <int, TableColumnWidth>{
0: IntrinsicColumnWidth(),
1: FlexColumnWidth(),
2: FixedColumnWidth(64)
},
children: [
for (var key in contactDetails.keys)
TableRow(children: [
Padding(
padding: const EdgeInsets.only(right: 5),
child: Text(
key,
style: const TextStyle(
fontSize: 14, fontWeight: FontWeight.w500),
),
),
Padding(
padding: const EdgeInsets.only(left: 5),
child: Text(
contactDetails[key],
),
)
])
],
)
],
)
],
);
}
Column personalDetails() {
var personalDetails = getPersonalDetails(apiData);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Personal Details',
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 5),
Column(
children: [
Table(
// border: TableBorder.all(),
columnWidths: const <int, TableColumnWidth>{
0: IntrinsicColumnWidth(),
1: FlexColumnWidth(),
2: FixedColumnWidth(64)
},
children: [
for (var key in personalDetails.keys)
TableRow(children: [
Padding(
padding: const EdgeInsets.only(right: 5),
child: Text(
key,
style: const TextStyle(
fontSize: 14, fontWeight: FontWeight.w500),
),
),
Padding(
padding: const EdgeInsets.only(left: 5),
child: Text(personalDetails[key]),
)
])
],
)
],
),
],
);
}
Column profileImage() {
return Column(
children: [
Image.asset(
'assets/images/passport.jpg',
width: 120,
height: 120,
)
],
);
}
}
+215
View File
@@ -0,0 +1,215 @@
import 'package:flutter/material.dart';
import 'package:school_management_system/api/results_requests.dart';
import 'package:school_management_system/api/student_requests.dart';
import 'package:school_management_system/components/default_values.dart';
import 'package:school_management_system/screens/welcome/welcome_screen.dart';
late Future<bool> _checkToken;
late Future<Student> _returnData;
late Map<String, List<String>>? sessiondetails;
late Student apiData;
Future<Result>? _returnresult;
late List<Score> studentScores;
class ResultsScreen extends StatefulWidget {
const ResultsScreen({super.key});
@override
State<ResultsScreen> createState() => _ResultsScreenState();
}
class _ResultsScreenState extends State<ResultsScreen> {
String? _selectedKey;
String? _selectedItem;
Result? resultList;
@override
void initState() {
_checkToken = checkTokenValidity();
super.initState();
_returnData = getStudentDetail(loginId);
resultList = null;
}
@override
Widget build(BuildContext context) {
_checkToken.then(
(value) {
if (!value) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const WelcomeScreen();
},
),
);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Session Time Out / Sign Back In'),
),
);
}
},
);
return FutureBuilder<Student>(
future: _returnData,
builder: (context, snapshot) {
List<Widget> children;
if (snapshot.hasData) {
apiData = snapshot.data!;
sessiondetails = apiData.sessiondetails!;
children = [
const SizedBox(height: 20),
dropDownMenu(),
const SizedBox(height: 50),
dataTableMenu()
];
} else if (snapshot.hasError) {
children = [
const Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: ${snapshot.error}'),
),
];
} else {
children = const [
SizedBox(
width: 60,
height: 60,
child: CircularProgressIndicator(),
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Loading Data...'),
),
];
}
return Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: ListView(
scrollDirection: Axis.vertical,
children: children,
),
),
);
},
);
}
Row dropDownMenu() {
return Row(
children: [
DropdownButton(
value: _selectedKey,
icon: const Icon(Icons.arrow_drop_down),
iconSize: 30,
elevation: 16,
style: const TextStyle(fontSize: 20, color: Colors.black),
underline: Container(
height: 2,
color: Colors.grey,
),
onChanged: (newValue) {
setState(() {
_selectedKey = newValue;
_selectedItem = null;
});
},
items: sessiondetails?.keys.map((String value) {
return DropdownMenuItem(
value: value,
child: Text(value),
);
}).toList(),
),
const SizedBox(width: 30),
_selectedKey != null
? DropdownButton(
value: _selectedItem,
icon: const Icon(Icons.arrow_drop_down),
iconSize: 30,
elevation: 16,
style: const TextStyle(fontSize: 20, color: Colors.black),
underline: Container(
height: 2,
color: Colors.grey,
),
onChanged: (newValue) {
setState(() {
_selectedItem = newValue;
});
},
items: sessiondetails![_selectedKey]!.map((String value) {
return DropdownMenuItem(
value: value,
child: Text(value),
onTap: () {
setState(() {
_returnresult = getStudentResult(_selectedKey!, value);
// resultList = null;
});
},
);
}).toList(),
)
: Container()
],
);
}
FutureBuilder dataTableMenu() {
resultList = null;
return FutureBuilder<Result>(
future: _returnresult,
builder: (context, snapshot) {
if (snapshot.hasData) {
resultList = snapshot.data!;
studentScores = resultList!.scores!;
} else if (snapshot.hasError) {
resultList = snapshot.data;
} else {
resultList = null;
}
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: resultList != null
? Column(
children: [
DataTable(
columns: const [
//DataColumn(label: Text('Module Code')),
DataColumn(label: Text('Module Title')),
DataColumn(label: Text('Score'), numeric: true),
DataColumn(label: Text('Grade')),
],
rows: resultList!.scores!.map((value) {
return DataRow(cells: [
// DataCell(Text(value.module!)),
DataCell(Text(value.module!)),
DataCell(Text(value.score!.toString())),
DataCell(Text(studentGrade(value.score!))),
]);
}).toList()),
],
)
: const Center(
child: Text(
'Nothing to Display',
style: TextStyle(fontWeight: FontWeight.w800),
),
),
);
},
);
}
}
@@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:school_management_system/components/default_values.dart';
class WelcomeImage extends StatelessWidget {
const WelcomeImage({
super.key,
});
@override
Widget build(BuildContext context) {
return Column(
children: [
// const Text(
// "WELCOME",
// style: TextStyle(fontWeight: FontWeight.bold),
// ),
const SizedBox(height: defaultPadding * 2),
Row(
children: [
const Spacer(),
Expanded(
flex: 8,
child: SvgPicture.asset(
'assets/icons/school.svg',
width: 320,
height: 320,
),
),
const Spacer(),
],
),
const SizedBox(height: defaultPadding * 2),
],
);
}
}
@@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import 'package:school_management_system/screens/login/login_screen.dart';
class LoginButton extends StatelessWidget {
const LoginButton({
super.key,
});
@override
Widget build(BuildContext context) {
return Column(
children: [
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const LoginScreen();
},
),
);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"go to sign in".toUpperCase(),
),
const SizedBox(width: 10),
const Icon(Icons.school)
],
),
),
const SizedBox(height: 16),
],
);
}
}
+84
View File
@@ -0,0 +1,84 @@
import 'package:flutter/material.dart';
import 'package:school_management_system/components/default_values.dart';
import 'package:school_management_system/screens/main/main_screen.dart';
import 'package:school_management_system/screens/welcome/components/welcome_image.dart';
import 'package:school_management_system/screens/welcome/components/welcome_login.dart';
class WelcomeScreen extends StatefulWidget {
const WelcomeScreen({super.key});
@override
State<WelcomeScreen> createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen> {
@override
void initState() {
super.initState();
setSharedPref('authkey', '');
setSharedPref('isLogin', false);
setSharedPref('tokenValidity', '');
}
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SingleChildScrollView(
child: Responsive(
desktop: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: WelcomeImage(),
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 350,
child: LoginButton(),
),
],
),
),
],
),
mobile: MobileWelcomeScreen(),
),
),
],
),
);
}
}
class MobileWelcomeScreen extends StatelessWidget {
const MobileWelcomeScreen({
super.key,
});
@override
Widget build(BuildContext context) {
return const Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
WelcomeImage(),
Row(
children: [
Spacer(),
Expanded(
flex: 3,
child: LoginButton(),
),
Spacer(),
],
),
],
);
}
}