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
+92
View File
@@ -0,0 +1,92 @@
import 'dart:io';
import 'dart:convert';
import 'package:http/http.dart';
import 'package:school_management_system/components/default_values.dart';
Authorise authoriseFromJson(String str) => Authorise.fromJson(json.decode(str));
String authoriseToJson(Authorise data) => json.encode(data.toJson());
class Authorise {
DateTime? validUntil;
String? token;
String? status;
String? message;
Authorise({
this.validUntil,
this.token,
this.status,
this.message,
});
factory Authorise.fromJson(Map<String, dynamic> json) => Authorise(
validUntil: DateTime.parse(json["validUntil"]),
token: json["token"],
status: json["status"],
message: json["message"],
);
Map<String, dynamic> toJson() => {
"validUntil": validUntil!.toIso8601String(),
"token": token,
"status": status,
"message": message,
};
}
Future<String> login(String username, String password) async {
try {
print("$baseUrl/auth/generateToken");
final response = await client
.post(
Uri.parse("$baseUrl/auth/generateToken"),
headers: {
"Content-Type": "application/json",
},
body: json.encode({
'username': username,
'password': password,
}),
)
.timeout(
const Duration(seconds: timeout),
onTimeout: () {
return Response('', 400);
},
);
if (response.statusCode == 200) {
var status = authoriseFromJson(response.body)
.status!; //Authorise.fromJson(json.decode(response.body)).status!;
loginId = username;
if (status.isEmpty || status.contains('failed')) {
return authoriseFromJson(response.body).message!;
} else {
setSharedPref('authkey', authoriseFromJson(response.body).token!);
setSharedPref('tokenValidity',
authoriseFromJson(response.body).validUntil.toString());
setSharedPref('isLogin', true);
header = {
"Authorization": "Bearer ${authoriseFromJson(response.body).token!}",
"Content-Type": "application/json",
};
return "Successfully Logged In";
}
} else if (response.statusCode == 400) {
return "Cannot Reach Server";
} else if (response.statusCode == 404) {
print(response.body);
return "Not Found";
} else {
return "failed";
}
} on SocketException {
return "Can not reach server";
} on HttpException {
return "Couldnt find the post";
} on FormatException {
return "Bad response format";
}
}
+157
View File
@@ -0,0 +1,157 @@
import 'dart:io';
import 'package:school_management_system/components/default_values.dart';
// To parse this JSON data, do
//
// final calendar = calendarFromJson(jsonString);
import 'dart:convert';
Calendar calendarFromJson(String str) => Calendar.fromJson(json.decode(str));
String calendarToJson(Calendar data) => json.encode(data.toJson());
class Calendar {
final String? calenderid;
final String? session;
final String? semester;
final List<Calenderrdetail>? calenderrdetails;
Calendar({
this.calenderid,
this.session,
this.semester,
this.calenderrdetails,
});
factory Calendar.fromJson(Map<String, dynamic> json) => Calendar(
calenderid: json["calenderid"],
session: json["session"],
semester: json["semester"],
calenderrdetails: json["calenderrdetails"] == null
? []
: List<Calenderrdetail>.from(json["calenderrdetails"]!
.map((x) => Calenderrdetail.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"calenderid": calenderid,
"session": session,
"semester": semester,
"calenderrdetails": calenderrdetails == null
? []
: List<dynamic>.from(calenderrdetails!.map((x) => x.toJson())),
};
}
class Calenderrdetail {
final String? note;
final String? event;
final bool? allday;
final DateTime? startdate;
final DateTime? enddate;
final String? endtime;
final String? starttime;
final String? frequency;
final String? interval;
final String? dayofweek;
Calenderrdetail({
this.note,
this.event,
this.allday,
this.startdate,
this.enddate,
this.endtime,
this.starttime,
this.frequency,
this.interval,
this.dayofweek,
});
factory Calenderrdetail.fromJson(Map<String, dynamic> json) =>
Calenderrdetail(
note: json["note"],
event: json["event"],
allday: json["allday"],
startdate: json["startdate"] == null
? null
: DateTime.parse(json["startdate"]),
enddate:
json["enddate"] == null ? null : DateTime.parse(json["enddate"]),
endtime: json["endtime"],
starttime: json["starttime"],
frequency: json["frequency"],
interval: json["interval"],
dayofweek: json["dayofweek"],
);
Map<String, dynamic> toJson() => {
"note": note,
"event": event,
"allday": allday,
"startdate":
"${startdate!.year.toString().padLeft(4, '0')}-${startdate!.month.toString().padLeft(2, '0')}-${startdate!.day.toString().padLeft(2, '0')}",
"enddate":
"${enddate!.year.toString().padLeft(4, '0')}-${enddate!.month.toString().padLeft(2, '0')}-${enddate!.day.toString().padLeft(2, '0')}",
"endtime": endtime,
"starttime": starttime,
"frequency": frequency,
"interval": interval,
"dayofweek": dayofweek,
};
}
Future<Calendar> getStudentCalender(
String calenderid, String session, String semester) async {
try {
final response = await client
.get(
Uri.parse(
"$baseUrl/calender/getCalender/$calenderid?session=$session&semester=$semester"),
headers: header,
)
.timeout(
const Duration(seconds: timeout),
);
if (response.statusCode == 200) {
return calendarFromJson(response.body);
} else {
return calendarFromJson("");
}
} on SocketException {
return throw Exception();
} on HttpException {
return throw Exception();
} on FormatException {
return throw Exception();
}
}
Future<Calendar> getSchoolCalender(
String calenderid, String session, String semester) async {
try {
final response = await client
.get(
Uri.parse(
"$baseUrl/calender/getCalender/$calenderid?session=$session&semester=$semester"),
headers: header,
)
.timeout(
const Duration(seconds: timeout),
);
if (response.statusCode == 200) {
return calendarFromJson(response.body);
} else {
return calendarFromJson(response.body);
}
} on SocketException {
return throw Exception();
} on HttpException {
return throw Exception();
} on FormatException {
return throw Exception();
}
}
View File
+167
View File
@@ -0,0 +1,167 @@
import 'dart:convert';
import 'dart:io';
import 'package:school_management_system/components/default_values.dart';
// To parse this JSON data, do
//
// final result = resultFromJson(jsonString);
Result resultFromJson(String str) => Result.fromJson(json.decode(str));
String resultToJson(Result data) => json.encode(data.toJson());
class Result {
final String? studentid;
final String? session;
final String? comments;
final bool? resit;
final String? semester;
final List<Score>? scores;
Result({
this.studentid,
this.session,
this.comments,
this.resit,
this.semester,
this.scores,
});
factory Result.fromJson(Map<String, dynamic> json) => Result(
studentid: json["studentid"],
session: json["session"],
comments: json["comments"],
resit: json["resit"],
semester: json["semester"],
scores: json["scores"] == null
? []
: List<Score>.from(json["scores"]!.map((x) => Score.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"studentid": studentid,
"session": session,
"comments": comments,
"resit": resit,
"semester": semester,
"scores": scores == null
? []
: List<dynamic>.from(scores!.map((x) => x.toJson())),
};
}
class Score {
final String? module;
final double? score;
Score({
this.module,
this.score,
});
factory Score.fromJson(Map<String, dynamic> json) => Score(
module: json["module"],
score: json["score"],
);
Map<String, dynamic> toJson() => {
"module": module,
"score": score,
};
}
Map<String, List<String>> sessionFromJson(String str) =>
Map.from(json.decode(str)).map((k, v) =>
MapEntry<String, List<String>>(k, List<String>.from(v.map((x) => x))));
String sessionToJson(Map<String, List<String>> data) =>
json.encode(Map.from(data).map((k, v) =>
MapEntry<String, dynamic>(k, List<dynamic>.from(v.map((x) => x)))));
Future<Map<String, List<String>>> getStudentSemester(String session) async {
try {
final response = await client
.get(
Uri.parse("$baseUrl/results/getSemester/$loginId?session=$session"),
headers: header)
.timeout(
const Duration(seconds: timeout),
);
if (response.statusCode == 200) {
if (response.body.isNotEmpty) {
return sessionFromJson(response.body);
} else {
return sessionFromJson("");
}
} else {
return sessionFromJson("");
}
} on SocketException {
return throw Exception();
} on HttpException {
return throw Exception();
} on FormatException {
return throw Exception();
}
}
Future<Map<String, List<String>>> getStudentSession() async {
try {
final response = await client
.get(
Uri.parse("$baseUrl/results/getSession/$loginId"),
headers: header,
)
.timeout(
const Duration(seconds: timeout),
);
if (response.statusCode == 200) {
if (response.body.isNotEmpty) {
return sessionFromJson(response.body);
} else {
return sessionFromJson("");
}
} else {
return sessionFromJson("");
}
} on SocketException {
return throw Exception();
} on HttpException {
return throw Exception();
} on FormatException {
return throw Exception();
}
}
Future<Result> getStudentResult(String session, String semester) async {
try {
final response = await client
.get(
Uri.parse(
"$baseUrl/results/list/$loginId?session=$session&semester=$semester"),
headers: header,
)
.timeout(
const Duration(seconds: timeout),
);
if (response.statusCode == 200) {
if (response.body.isNotEmpty) {
return resultFromJson(response.body);
} else {
return resultFromJson("");
}
} else {
return resultFromJson("");
}
} on SocketException {
return throw Exception();
} on HttpException {
return throw Exception();
} on FormatException {
return throw Exception();
}
}
+101
View File
@@ -0,0 +1,101 @@
import 'dart:io';
import 'package:school_management_system/components/default_values.dart';
// To parse this JSON data, do
//
// final session = sessionFromJson(jsonString);
import 'dart:convert';
Session sessionFromJson(String str) => Session.fromJson(json.decode(str));
String sessionToJson(Session data) => json.encode(data.toJson());
class Session {
final String? session;
final String? semester;
final DateTime? startdate;
final DateTime? enddate;
final String? status;
Session({
this.session,
this.semester,
this.startdate,
this.enddate,
this.status,
});
factory Session.fromJson(Map<String, dynamic> json) => Session(
session: json["session"],
semester: json["semester"],
startdate: json["startdate"] == null
? null
: DateTime.parse(json["startdate"]),
enddate:
json["enddate"] == null ? null : DateTime.parse(json["enddate"]),
status: json["status"],
);
Map<String, dynamic> toJson() => {
"session": session,
"semester": semester,
"startdate":
"${startdate!.year.toString().padLeft(4, '0')}-${startdate!.month.toString().padLeft(2, '0')}-${startdate!.day.toString().padLeft(2, '0')}",
"enddate":
"${enddate!.year.toString().padLeft(4, '0')}-${enddate!.month.toString().padLeft(2, '0')}-${enddate!.day.toString().padLeft(2, '0')}",
"status": status,
};
}
Future getCurrentSession() async {
try {
final response = await client
.get(
Uri.parse("$baseUrl/session/getCurrentSession"),
headers: header,
)
.timeout(
const Duration(seconds: timeout),
);
if (response.statusCode == 200) {
session = sessionFromJson(response.body).session!;
semester = sessionFromJson(response.body).semester!;
//return sessionFromJson(response.body);
} else {
return sessionFromJson("");
}
} on SocketException {
throw Exception();
} on HttpException {
throw Exception();
} on FormatException {
throw Exception();
}
}
// Future<List<String>> getSession() async {
// try {
// final response = await client.get(
// Uri.parse("$baseUrl/session/getSessionsList"),
// headers: header,
// );
// if (response.statusCode == 200) {
// if (response.body.isNotEmpty) {
// return sessionFromJson(response.body);
// } else {
// return sessionFromJson("");
// }
// } else {
// return sessionFromJson("");
// }
// } on SocketException {
// return throw Exception();
// } on HttpException {
// return throw Exception();
// } on FormatException {
// return throw Exception();
// }
// }
+311
View File
@@ -0,0 +1,311 @@
import 'dart:convert';
import 'dart:io';
import 'package:school_management_system/components/default_values.dart';
// To parse this JSON data, do
//
// final student = studentFromJson(jsonString);
Student studentFromJson(String str) => Student.fromJson(json.decode(str));
String studentToJson(Student data) => json.encode(data.toJson());
class Student {
final String? studentid;
final String? title;
final String? firstname;
final String? lastname;
final String? schoolemail;
final DateTime? dateofbirth;
final String? currentyear;
final String? currentsession;
final String? homeaddress;
final String? mobilenumber;
final String? emailaddress;
final List<Nextofkindetail>? nextofkindetails;
final List<Guardiandetail>? guardiandetails;
final List<Medicaldetail>? medicaldetails;
final List<Coursedetail>? coursedetails;
final String? gender;
final Map<String, List<String>>? sessiondetails;
final Map<String, List<ModuleDetail>>? moduledetails;
Student({
this.studentid,
this.title,
this.firstname,
this.lastname,
this.schoolemail,
this.dateofbirth,
this.currentyear,
this.currentsession,
this.homeaddress,
this.mobilenumber,
this.emailaddress,
this.nextofkindetails,
this.guardiandetails,
this.medicaldetails,
this.coursedetails,
this.gender,
this.sessiondetails,
this.moduledetails,
});
factory Student.fromJson(Map<String, dynamic> json) => Student(
studentid: json["studentid"],
title: json["title"],
firstname: json["firstname"],
lastname: json["lastname"],
schoolemail: json["schoolemail"],
dateofbirth: json["dateofbirth"] == null
? null
: DateTime.parse(json["dateofbirth"]),
currentyear: json["currentyear"],
currentsession: json["currentsession"],
homeaddress: json["homeaddress"],
mobilenumber: json["mobilenumber"],
emailaddress: json["emailaddress"],
nextofkindetails: json["nextofkindetails"] == null
? []
: List<Nextofkindetail>.from(json["nextofkindetails"]!
.map((x) => Nextofkindetail.fromJson(x))),
guardiandetails: json["guardiandetails"] == null
? []
: List<Guardiandetail>.from(json["guardiandetails"]!
.map((x) => Guardiandetail.fromJson(x))),
medicaldetails: json["medicaldetails"] == null
? []
: List<Medicaldetail>.from(
json["medicaldetails"]!.map((x) => Medicaldetail.fromJson(x))),
coursedetails: json["coursedetails"] == null
? []
: List<Coursedetail>.from(
json["coursedetails"]!.map((x) => Coursedetail.fromJson(x))),
gender: json["gender"],
sessiondetails: Map.from(json["sessiondetails"]!).map((k, v) =>
MapEntry<String, List<String>>(
k, List<String>.from(v.map((x) => x)))),
moduledetails: Map.from(json["moduledetails"]!).map((k, v) => MapEntry<
String, List<ModuleDetail>>(k,
List<ModuleDetail>.from(v.map((x) => ModuleDetail.fromJson(x))))),
);
Map<String, dynamic> toJson() => {
"studentid": studentid,
"title": title,
"firstname": firstname,
"lastname": lastname,
"schoolemail": schoolemail,
"dateofbirth":
"${dateofbirth!.year.toString().padLeft(4, '0')}-${dateofbirth!.month.toString().padLeft(2, '0')}-${dateofbirth!.day.toString().padLeft(2, '0')}",
"currentyear": currentyear,
"currentsession": currentsession,
"homeaddress": homeaddress,
"mobilenumber": mobilenumber,
"emailaddress": emailaddress,
"nextofkindetails": nextofkindetails == null
? []
: List<dynamic>.from(nextofkindetails!.map((x) => x.toJson())),
"guardiandetails": guardiandetails == null
? []
: List<dynamic>.from(guardiandetails!.map((x) => x.toJson())),
"medicaldetails": medicaldetails == null
? []
: List<dynamic>.from(medicaldetails!.map((x) => x.toJson())),
"coursedetails": coursedetails == null
? []
: List<dynamic>.from(coursedetails!.map((x) => x.toJson())),
"gender": gender,
"sessiondetails": Map.from(sessiondetails!).map((k, v) =>
MapEntry<String, dynamic>(k, List<dynamic>.from(v.map((x) => x)))),
"moduledetails": Map.from(moduledetails!).map((k, v) =>
MapEntry<String, dynamic>(
k, List<dynamic>.from(v.map((x) => x.toJson())))),
};
}
class Coursedetail {
final String? courseofstudy;
final String? coursetype;
final String? coursequalification;
final String? coursemode;
Coursedetail({
this.courseofstudy,
this.coursetype,
this.coursequalification,
this.coursemode,
});
factory Coursedetail.fromJson(Map<String, dynamic> json) => Coursedetail(
courseofstudy: json["courseofstudy"],
coursetype: json["coursetype"],
coursequalification: json["coursequalification"],
coursemode: json["coursemode"],
);
Map<String, dynamic> toJson() => {
"courseofstudy": courseofstudy,
"coursetype": coursetype,
"coursequalification": coursequalification,
"coursemode": coursemode,
};
}
class Guardiandetail {
final String? guardianname;
final String? guardiancontact;
final String? guardianaddress;
final String? guardianrelationship;
Guardiandetail({
this.guardianname,
this.guardiancontact,
this.guardianaddress,
this.guardianrelationship,
});
factory Guardiandetail.fromJson(Map<String, dynamic> json) => Guardiandetail(
guardianname: json["guardianname"],
guardiancontact: json["guardiancontact"],
guardianaddress: json["guardianaddress"],
guardianrelationship: json["guardianrelationship"],
);
Map<String, dynamic> toJson() => {
"guardianname": guardianname,
"guardiancontact": guardiancontact,
"guardianaddress": guardianaddress,
"guardianrelationship": guardianrelationship,
};
}
class Medicaldetail {
final String? weight;
final String? height;
final String? genotype;
final String? bloodgroup;
final String? medicalcondition;
final String? allergies;
final bool? dnr;
final String? emergencycontactname;
final String? emergencycontactnumber;
final String? emergencycontractrelationship;
Medicaldetail({
this.weight,
this.height,
this.genotype,
this.bloodgroup,
this.medicalcondition,
this.allergies,
this.dnr,
this.emergencycontactname,
this.emergencycontactnumber,
this.emergencycontractrelationship,
});
factory Medicaldetail.fromJson(Map<String, dynamic> json) => Medicaldetail(
weight: json["weight"],
height: json["height"],
genotype: json["genotype"],
bloodgroup: json["bloodgroup"],
medicalcondition: json["medicalcondition"],
allergies: json["allergies"],
dnr: json["dnr"],
emergencycontactname: json["emergencycontactname"],
emergencycontactnumber: json["emergencycontactnumber"],
emergencycontractrelationship: json["emergencycontractrelationship"],
);
Map<String, dynamic> toJson() => {
"weight": weight,
"height": height,
"genotype": genotype,
"bloodgroup": bloodgroup,
"medicalcondition": medicalcondition,
"allergies": allergies,
"dnr": dnr,
"emergencycontactname": emergencycontactname,
"emergencycontactnumber": emergencycontactnumber,
"emergencycontractrelationship": emergencycontractrelationship,
};
}
class ModuleDetail {
final String? modulecode;
final String? modulename;
ModuleDetail({
this.modulecode,
this.modulename,
});
factory ModuleDetail.fromJson(Map<String, dynamic> json) => ModuleDetail(
modulecode: json["modulecode"],
modulename: json["modulename"],
);
Map<String, dynamic> toJson() => {
"modulecode": modulecode,
"modulename": modulename,
};
}
class Nextofkindetail {
final String? nextofkinname;
final String? nextofkincontact;
final String? nextofkinaddress;
final String? nextofkinrelationship;
Nextofkindetail({
this.nextofkinname,
this.nextofkincontact,
this.nextofkinaddress,
this.nextofkinrelationship,
});
factory Nextofkindetail.fromJson(Map<String, dynamic> json) =>
Nextofkindetail(
nextofkinname: json["nextofkinname"],
nextofkincontact: json["nextofkincontact"],
nextofkinaddress: json["nextofkinaddress"],
nextofkinrelationship: json["nextofkinrelationship"],
);
Map<String, dynamic> toJson() => {
"nextofkinname": nextofkinname,
"nextofkincontact": nextofkincontact,
"nextofkinaddress": nextofkinaddress,
"nextofkinrelationship": nextofkinrelationship,
};
}
Future<Student> getStudentDetail(String studentId) async {
try {
final response = await client
.get(
Uri.parse("$baseUrl/student/$studentId"),
headers: header,
)
.timeout(
const Duration(seconds: timeout),
);
if (response.statusCode == 200) {
if (response.body.isNotEmpty) {
return studentFromJson(response.body);
} else {
return studentFromJson("");
}
} else {
return studentFromJson("");
}
} on SocketException {
return throw Exception();
} on HttpException {
return throw Exception();
} on FormatException {
return throw Exception();
}
}
+126
View File
@@ -0,0 +1,126 @@
import 'dart:math';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
// const String baseUrl = "http://localhost:8123/smsApi/v1";
// const String baseUrl = "https://api.theonasanyas.com/smsApi/v1";
const String baseUrl = "http://10.15.45.29:8123/smsApi/v1";
const primaryColor = Color.fromARGB(255, 152, 120, 57);
const primaryLightColor = Color.fromARGB(150, 238, 224, 173);
const double defaultPadding = 15.0;
const timeout = 3;
var client = http.Client();
late String session;
late String semester;
late String loginId;
late Map<String, String> header;
setSharedPref(String key, var value) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
switch (value.runtimeType.toString()) {
case 'String':
sharedPreferences.setString(key, value);
break;
case 'double':
sharedPreferences.setDouble(key, value);
break;
case 'int':
sharedPreferences.setInt(key, value);
break;
case 'bool':
sharedPreferences.setBool(key, value);
break;
}
}
getSharedPref(var key, var type) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
switch (type) {
case 'String':
return sharedPreferences.getString(key);
case 'double':
return sharedPreferences.getDouble(key);
case 'int':
return sharedPreferences.getInt(key);
case 'bool':
return sharedPreferences.getBool(key);
}
}
Future<bool> checkTokenValidity() async {
final value = await getSharedPref('tokenValidity', 'String');
print("tokenValidity --- $value");
DateTime dateTime;
DateTime currentTime;
if (value == '') {
currentTime = DateTime.now();
dateTime = DateTime.now();
} else {
currentTime = DateTime.now();
dateTime = DateTime.parse(value);
}
if (dateTime.isAfter(currentTime)) {
return true;
} else {
return false;
}
}
String getImage() {
//
//
List<String> image = [
'assets/images/image1.jpg',
'assets/images/image2.jpg',
'assets/images/image3.jpg',
'assets/images/image4.jpg',
'assets/images/image5.jpg',
'assets/images/image6.jpg',
'assets/images/image7.jpg',
'assets/images/image8.jpg'
];
var rnd = Random();
final index = rnd.nextInt(image.length);
return image[index];
}
String studentGrade(double score) {
//
//
String grade = "";
switch (score) {
case >= 70:
grade = "Distinction";
break;
case >= 60:
grade = "Merit";
break;
case >= 50:
grade = "Pass";
break;
default:
grade = "Fail";
break;
}
return grade;
}
+46
View File
@@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
import 'package:school_management_system/screens/welcome/welcome_screen.dart';
import 'package:school_management_system/components/default_values.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'School Management System Demo',
theme: ThemeData(
primaryColor: primaryColor,
scaffoldBackgroundColor: Colors.white,
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
elevation: 0,
foregroundColor: Colors.white,
backgroundColor: primaryColor,
shape: const StadiumBorder(),
maximumSize: const Size(double.infinity, 56),
minimumSize: const Size(double.infinity, 56),
),
),
inputDecorationTheme: const InputDecorationTheme(
filled: true,
fillColor: primaryLightColor,
iconColor: primaryColor,
prefixIconColor: primaryColor,
contentPadding: EdgeInsets.symmetric(
horizontal: defaultPadding, vertical: defaultPadding),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(30)),
borderSide: BorderSide.none,
),
),
fontFamily: 'Poppins',
),
home: const WelcomeScreen(),
);
}
}
@@ -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(),
],
),
],
);
}
}