Migrate from BitBucket
This commit is contained in:
@@ -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),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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,
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user