diff --git a/db/patents.csv b/db/patents.csv new file mode 100644 index 00000000..bf18b135 --- /dev/null +++ b/db/patents.csv @@ -0,0 +1,5 @@ +"Patend ID","IPD Form","Patent PDF","Status" +"17","EDP_Presentation_tGhmx5M.pdf","EDP_Presentation_cjWYh29.pdf","Pending" +"16","EDP_Presentation_dDC7iY8.pdf","EDP_Presentation_gtDJ0Gy.pdf","Approved" +"19","EDP_Presentation_QwCDZAv.pdf","EDP_Presenstation_gethd0.pdf","Disapproved" +"15","EDP_Presentation_QWWeeee.pdf","EDP_Presentation_G2vrh3s.pdf","Pending" diff --git a/lib/Components/side_drawer.dart b/lib/Components/side_drawer.dart index be08db0e..b5298885 100644 --- a/lib/Components/side_drawer.dart +++ b/lib/Components/side_drawer.dart @@ -122,27 +122,39 @@ class _SideDrawerState extends State { isActive: true, ), ModulesPadding( - line: 'Gymkhana Module', - pageMover: '/gymkhana_homepage'), + line: 'Gymkhana Module', + pageMover: '/gymkhana_homepage', + ), + ModulesPadding( - line: 'Establishment Module', - pageMover: '/establishment'), + line: 'Establishment Module', + pageMover: '/establishment', + ), ModulesPadding( - line: 'Library Module', - pageMover: '/library_homepage'), + line: 'Library Module', + pageMover: '/library_homepage', + ), ModulesPadding(line: 'Awards & Scholarship Module'), ModulesPadding( - line: 'Complaint Module', pageMover: '/complaint'), + line: 'Complaint Module', + pageMover: '/complaint', + ), ModulesPadding(line: 'Central Mess Module'), ModulesPadding(line: 'Feeds Module'), ModulesPadding( line: 'Health Center Module', pageMover: '/health_center', ), + ModulesPadding(line: 'Leave Module'), ModulesPadding(line: 'Placement Module'), ModulesPadding(line: 'Visitors Hostel Module'), ModulesPadding(line: 'File Tracking Module'), + ModulesPadding( + line: 'RSPC Module', + pageMover: '/rspc', + isActive: true, + ), ], ), ) diff --git a/lib/Components/utils.dart b/lib/Components/utils.dart new file mode 100644 index 00000000..f26d1f22 --- /dev/null +++ b/lib/Components/utils.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; + +class Utils { + final primarycolor = Colors.purple; + final primarybackgroundcolor = Colors.white; + final lightgrey = Colors.grey; + Decoration containerBorder(Color col) { + return BoxDecoration( + borderRadius: BorderRadius.circular(10), + border: Border.all(color: primarycolor)); + } + + Widget leadingPopIconsButton(Color cc, BuildContext context) { + return IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: Icon(Icons.arrow_back_ios)); + } +} diff --git a/lib/api.dart b/lib/api.dart index 802bee2d..9a6aaf8b 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -29,6 +29,15 @@ const kGymkhanaMemberRecords = '/api/gymkhana/members_record'; //HealthCentre String kHealthCentreStudent = "/healthcenter/api/student"; +//RSPC + +String kResearchProjectNew = "/research_procedures/api/new_research_project"; +String kConsultantProjectNew = + "/research_procedures/api/new_consultant_project"; +String kResearchProjects = "/research_procedures/api/get_research_projects"; +String kConsultancyProjects = + "/research_procedures/api/get_consultancy_projects"; + //------------Screens------------ //screens/Academic/Current_Semester diff --git a/lib/main.dart b/lib/main.dart index 9ca81ff8..458028e2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -35,6 +35,11 @@ import 'package:fusion/screens/Programme_Curriculum/Discipline/discipline.dart'; import 'package:fusion/screens/Programme_Curriculum/Programme/programme_home_page.dart'; import 'package:fusion/screens/Programme_Curriculum/Programme_Info/programme_info.dart'; import 'package:fusion/screens/Programme_Curriculum/programme_curriculum_home.dart'; +import 'package:fusion/screens/RSPC/Patents/patents.dart'; +import 'package:fusion/screens/RSPC/ConsultancyProject/consultancy_project.dart'; +import 'package:fusion/screens/RSPC/ResearchProject/research_project.dart'; +import 'package:fusion/screens/RSPC/ViewProject/consultancy_projects.dart'; +import 'package:fusion/screens/RSPC/ViewProject/research_projects.dart'; import 'package:fusion/screens/landing_page.dart'; import 'package:fusion/screens/Healthcenter/healthcentermodule.dart'; import 'package:fusion/screens/Healthcenter/feedback.dart'; @@ -42,6 +47,7 @@ import 'package:fusion/screens/Healthcenter/viewschedule.dart'; import 'package:fusion/screens/Healthcenter/history.dart'; import 'package:fusion/screens/Healthcenter/HealthCenter.dart'; import 'package:fusion/services/service_locator.dart'; +import 'screens/RSPC/rspc.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); @@ -60,7 +66,7 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { MediaQueryData windowData = - MediaQueryData.fromWindow(WidgetsBinding.instance.window); + MediaQueryData.fromWindow(WidgetsBinding.instance.window); windowData = windowData.copyWith( textScaleFactor: 1, ); @@ -71,10 +77,10 @@ class MyApp extends StatelessWidget { title: 'Fusion', debugShowCheckedModeBanner: false, theme: ThemeData( - // primarySwatch: Colors.blueGrey, + // primarySwatch: Colors.blueGrey, // colorSchemeSeed: Color(0xFF2085D0), colorSchemeSeed: Color(0xFFF36C35), - fontFamily: 'Nunito', + fontFamily: 'Nunito', useMaterial3: true, ), initialRoute: '/landing', @@ -127,6 +133,18 @@ class MyApp extends StatelessWidget { '/health_center/feedback': (context) => FeedBack(), '/health_center/viewschedule': (context) => ViewSchedule(), '/health_center/history': (context) => History(), + '/rspc': (context) => + RSPCModule(ModalRoute.of(context)!.settings.arguments.toString()), + '/rspc/research_project': (context) => AddResearchProject( + ModalRoute.of(context)!.settings.arguments.toString()), + '/rspc/consultancy_project': (context) => AddConsultancyProject( + ModalRoute.of(context)!.settings.arguments.toString()), + '/rspc/patents': (context) => + Patents(ModalRoute.of(context)!.settings.arguments.toString()), + '/rspc/view_research_project': (context) => ResearchProject( + ModalRoute.of(context)!.settings.arguments.toString()), + '/rspc/view_consultancy_project': (context) => ConsultancyProject( + ModalRoute.of(context)!.settings.arguments.toString()), }, ), ); diff --git a/lib/models/project.dart b/lib/models/project.dart new file mode 100644 index 00000000..f2fd3d17 --- /dev/null +++ b/lib/models/project.dart @@ -0,0 +1,19 @@ +class ProjectData { + List? projects; + + ProjectData({ + this.projects, + }); + + factory ProjectData.fromJson(Map json) { + return ProjectData( + projects: json["projects"], + ); + } + + Map toJson() { + return { + "projects": this.projects, + }; + } +} diff --git a/lib/screens/Gymkhana/GymkhanaHomepage.dart b/lib/screens/Gymkhana/GymkhanaHomepage.dart index 8b0345cb..d2e0570f 100644 --- a/lib/screens/Gymkhana/GymkhanaHomepage.dart +++ b/lib/screens/Gymkhana/GymkhanaHomepage.dart @@ -8,6 +8,8 @@ import 'package:fusion/models/profile.dart'; import 'package:fusion/services/gymkhana_service.dart'; import 'package:fusion/services/service_locator.dart'; import 'package:fusion/services/storage_service.dart'; +import 'package:http/http.dart' as http; +import 'package:http/http.dart'; class GymkhanaHomepage extends StatefulWidget { @override @@ -70,7 +72,7 @@ class _GymkhanaHomepageState extends State { //TODO: uncomment when API is functioning try { - //Response response = await gymkhanaService.getGymkhanaData(); + Response response = await gymkhanaService.getGymkhanaData(); setState(() { //TODO: uncomment when API is functioning diff --git a/lib/screens/Healthcenter/Appointment.dart b/lib/screens/Healthcenter/Appointment.dart index 8188e9d5..0fc8baec 100644 --- a/lib/screens/Healthcenter/Appointment.dart +++ b/lib/screens/Healthcenter/Appointment.dart @@ -10,7 +10,6 @@ class Appointment extends StatefulWidget { class _AppointmentState extends State { int _value = 1; - @override Widget build(BuildContext context) { return Container( diff --git a/lib/screens/LoginandDashboard/DashboardComponents/cardItems.dart b/lib/screens/LoginandDashboard/DashboardComponents/cardItems.dart index fffcde98..01efef21 100644 --- a/lib/screens/LoginandDashboard/DashboardComponents/cardItems.dart +++ b/lib/screens/LoginandDashboard/DashboardComponents/cardItems.dart @@ -116,7 +116,7 @@ class _InfoCardState extends State { setState(() { try { service.markRead(widget.notification.id!.toString()); - }catch(e){ + } catch (e) { print(e); } }); diff --git a/lib/screens/LoginandDashboard/dashboard.dart b/lib/screens/LoginandDashboard/dashboard.dart index 80c2719f..5394e143 100644 --- a/lib/screens/LoginandDashboard/dashboard.dart +++ b/lib/screens/LoginandDashboard/dashboard.dart @@ -11,6 +11,7 @@ import 'package:fusion/models/dashboard.dart'; import 'package:fusion/screens/LoginandDashboard/DashboardComponents/cardItems.dart'; import 'package:fusion/services/dashboard_service.dart'; import 'package:http/http.dart'; +import 'dart:convert'; class Dashboard extends StatefulWidget { static String tag = 'home-page'; @@ -46,9 +47,11 @@ class _DashboardState extends State { getData() async { try { Response response = await dashboardService.getDashboard(); + Response response2 = await profileService.getProfile(); setState(() { data = DashboardData.fromJson(jsonDecode(response.body)); + data2 = ProfileData.fromJson(jsonDecode(response2.body)); _loading = false; }); diff --git a/lib/screens/LoginandDashboard/login_page.dart b/lib/screens/LoginandDashboard/login_page.dart index ca09fee2..fbb1ef5f 100644 --- a/lib/screens/LoginandDashboard/login_page.dart +++ b/lib/screens/LoginandDashboard/login_page.dart @@ -20,7 +20,6 @@ class _LoginPageState extends State { @override Widget build(BuildContext context) { - final Widget logoWidget = CircleAvatar( backgroundColor: Colors.transparent, radius: 54.0, @@ -30,13 +29,16 @@ class _LoginPageState extends State { keyboardType: TextInputType.emailAddress, autofocus: false, decoration: InputDecoration( - label: Text('Username', style: TextStyle( - fontSize: 12.0, - ),), + label: Text( + 'Username', + style: TextStyle( + fontSize: 12.0, + ), + ), contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), border: OutlineInputBorder( - // borderRadius: BorderRadius.circular(32.0), - ), + // borderRadius: BorderRadius.circular(32.0), + ), ), onChanged: (input) { username = input; @@ -44,11 +46,9 @@ class _LoginPageState extends State { validator: (String? value) { if (value?.length == 0) { return 'Please enter username'; - } - else if (value?.contains('@') == true) { + } else if (value?.contains('@') == true) { return 'Please enter username only'; } - }, autofillHints: [AutofillHints.username], ); @@ -57,13 +57,16 @@ class _LoginPageState extends State { autofocus: false, obscureText: true, decoration: InputDecoration( - label: Text('Password', style: TextStyle( - fontSize: 12.0, - ),), + label: Text( + 'Password', + style: TextStyle( + fontSize: 12.0, + ), + ), contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), border: OutlineInputBorder( - // borderRadius: BorderRadius.circular(32.0), - ), + // borderRadius: BorderRadius.circular(32.0), + ), ), onChanged: (input) { pass = input; @@ -141,7 +144,7 @@ class _LoginPageState extends State { ), Padding( padding: EdgeInsets.only(bottom: 15), - child: emailFormField, + child: emailFormField, ), Padding( padding: EdgeInsets.only(bottom: 15), diff --git a/lib/screens/RSPC/ConsultancyProject/consultancy_project.dart b/lib/screens/RSPC/ConsultancyProject/consultancy_project.dart new file mode 100644 index 00000000..210840b0 --- /dev/null +++ b/lib/screens/RSPC/ConsultancyProject/consultancy_project.dart @@ -0,0 +1,368 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:fusion/services/rspc_service.dart'; + +import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/services/storage_service.dart'; +import 'package:fusion/services/profile_service.dart'; +import 'package:intl/intl.dart'; + +import '../../../Components/utils.dart'; + +kTextFieldInputDecoration(String hint) { + return InputDecoration( + hintText: hint, + filled: true, + fillColor: Colors.white, + contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Utils().primarycolor), + borderRadius: BorderRadius.all(Radius.circular(32)), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Utils().primarycolor), + borderRadius: BorderRadius.all(Radius.circular(32)), + ), + ); +} + +const kInputDateDecoration = InputDecoration( + labelText: 'Select Date', + icon: Icon(Icons.calendar_today_rounded), + filled: true, + fillColor: Colors.white, + contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), + border: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(32)), + ), +); + +class AddConsultancyProject extends StatefulWidget { + final String? uid; + AddConsultancyProject(this.uid); + + @override + State createState() => _AddConsultancyProjectState(); +} + +class _AddConsultancyProjectState extends State { + // ignore: unused_field + final GlobalKey _formKey = GlobalKey(); + String? consultant; + String? clientName; + String? financialOutlay; + String? projectTitle; + String? startDate; + String? endDate; + String? pfNo; + + Utils utils = Utils(); + + var service = locator(); + + TextEditingController startDateController = TextEditingController(); + TextEditingController endDateController = TextEditingController(); + + String reverseStringUsingRunes(String input) { + var chars = input.runes.toList(); + + return String.fromCharCodes(chars.reversed); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: utils.primarybackgroundcolor, + leading: utils.leadingPopIconsButton(utils.primarycolor, context), + title: Text( + "Consultancy Project", + style: + TextStyle(color: utils.primarycolor, fontWeight: FontWeight.bold), + ), + ), + body: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(25), + margin: EdgeInsets.only(bottom: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Add a Consultancy Project', + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 20, + color: Colors.black.withOpacity(0.6)), + ), + SizedBox( + height: 5, + ), + Container( + height: 1, + width: MediaQuery.of(context).size.width, + decoration: BoxDecoration(color: Colors.black.withOpacity(0.6)), + ), + SizedBox( + height: 30, + ), + Text( + 'Consultant *', + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + SizedBox( + height: 10, + ), + TextFormField( + autofocus: false, + style: TextStyle( + color: Colors.black, + ), + decoration: kTextFieldInputDecoration("Consultant"), + onChanged: (input) { + consultant = input; + }, + validator: (String? value) { + if (value!.isEmpty) { + return 'This field is manadatory.'; + } + }, + ), + SizedBox( + height: 20, + ), + Text( + 'Client *', + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + SizedBox( + height: 10, + ), + TextFormField( + autofocus: false, + style: TextStyle( + color: Colors.black, + ), + decoration: kTextFieldInputDecoration("Client"), + onChanged: (input) { + clientName = input; + }, + validator: (String? value) { + if (value!.isEmpty) { + return 'This field is manadatory.'; + } + }, + ), + SizedBox( + height: 20, + ), + Text( + 'Financial Outlay *', + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + SizedBox( + height: 10, + ), + TextFormField( + autofocus: false, + style: TextStyle( + color: Colors.black, + ), + decoration: kTextFieldInputDecoration("Outlay"), + onChanged: (input) { + financialOutlay = input; + }, + validator: (String? value) { + if (value!.isEmpty) { + return 'This field is manadatory.'; + } + }, + ), + SizedBox( + height: 20, + ), + Text( + 'Title *', + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + SizedBox( + height: 10, + ), + TextFormField( + autofocus: false, + style: TextStyle( + color: Colors.black, + ), + decoration: kTextFieldInputDecoration("Title"), + onChanged: (input) { + projectTitle = input; + }, + validator: (String? value) { + if (value!.isEmpty) { + return 'This field is manadatory.'; + } + }, + ), + SizedBox( + height: 20, + ), + Text( + 'Start Date *', + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 4, vertical: 10), + child: TextField( + controller: startDateController, + decoration: kInputDateDecoration, + onTap: () async { + DateTime? pickeddate = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime(2000), + lastDate: DateTime(2100)); + if (pickeddate != null) { + setState(() { + startDateController.text = + DateFormat('yyyy-MM-dd').format(pickeddate); + startDate = startDateController.text; + }); + } + }, + ), + ), + SizedBox( + height: 20, + ), + Text( + 'End Date *', + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 4, vertical: 10), + child: TextField( + controller: endDateController, + decoration: kInputDateDecoration, + onTap: () async { + DateTime? pickeddate = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime(2000), + lastDate: DateTime(2100)); + if (pickeddate != null) { + setState(() { + endDateController.text = + DateFormat('yyyy-MM-dd').format(pickeddate); + endDate = endDateController.text; + }); + } + }, + ), + ), + SizedBox( + height: 20, + ), + Center( + child: ElevatedButton( + onPressed: (() async { + dynamic res = await ProfileService().getProfile(); + dynamic user = jsonDecode(res.body)['user']; + pfNo = user['id'].toString(); + RSPCService auth = RSPCService(); + bool newConsultancyProject = + await auth.addConsultancyProject( + consultant: consultant, + clientName: clientName, + projectTitle: projectTitle, + financialOutlay: financialOutlay, + startDate: startDate, + endDate: endDate, + pfNo: pfNo, + ); + TextInput.finishAutofillContext(); + if (newConsultancyProject) { + print('Successfully added'); + return showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: Text("Success"), + content: Text("Project Added Successfully"), + actions: [ + ElevatedButton( + onPressed: () { + Navigator.of(ctx).pop(); + }, + child: Text("okay"), + ), + ], + ), + ); + } else { + print('ERROR OCCURED'); + return showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: Text("Failed"), + content: + Text("Cannot add above Consultancy Project."), + actions: [ + ElevatedButton( + onPressed: () { + Navigator.of(ctx).pop(); + }, + child: Text("okay"), + ), + ], + ), + ); + } + }), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'Submit', + style: TextStyle( + fontSize: 20, color: utils.primarybackgroundcolor), + ), + ), + style: ButtonStyle( + backgroundColor: MaterialStateProperty.resolveWith( + (Set states) { + if (states.contains(MaterialState.pressed)) + return utils.lightgrey; + return utils + .primarycolor; // Use the component's default. + }, + ), + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/screens/RSPC/Patents/patents.dart b/lib/screens/RSPC/Patents/patents.dart new file mode 100644 index 00000000..bea90288 --- /dev/null +++ b/lib/screens/RSPC/Patents/patents.dart @@ -0,0 +1,72 @@ +// ignore_for_file: unused_import + +import 'package:flutter/material.dart'; +// import 'package:fusion/Components/appBar.dart'; +import 'package:fusion/Components/side_drawer.dart'; +import 'package:fusion/screens/RSPC/Patents/patents_tab.dart'; +import 'package:flutter/services.dart' show rootBundle; + +import 'package:csv/csv.dart'; + +import '../../../Components/utils.dart'; + +class Patents extends StatefulWidget { + final uid; + Patents(this.uid); + @override + State createState() => _PatentsState(); +} + +class _PatentsState extends State { + List> _patentList = []; + Utils utils = Utils(); + Future _loadCSV() async { + final _patentsData = await rootBundle.loadString('db/patents.csv'); + List> _list = + const CsvToListConverter().convert(_patentsData); + _patentList = _list; + return 1; + } + + @override + void initState() { + super.initState(); + _loadCSV(); + } + + @override + Widget build(BuildContext context) { + return FutureBuilder( + future: _loadCSV(), + builder: (context, snapshot) { + if (!snapshot.hasData) return Scaffold(); + final patentData = { + "table": { + "columns": _patentList[0], + "rows": _patentList.skip(1).map((e) => e) + } + }; + return DefaultTabController( + length: 1, + child: Scaffold( + appBar: AppBar( + backgroundColor: utils.primarybackgroundcolor, + leading: + utils.leadingPopIconsButton(utils.primarycolor, context), + title: Text( + "Patents", + style: TextStyle( + color: utils.primarycolor, fontWeight: FontWeight.bold), + ), + ), + + // drawer: SideDrawer(), + body: TabBarView( + children: [ + PatentsStatus(data: patentData), + ], + ), + )); + }); + } +} diff --git a/lib/screens/RSPC/Patents/patents_tab.dart b/lib/screens/RSPC/Patents/patents_tab.dart new file mode 100644 index 00000000..ec785223 --- /dev/null +++ b/lib/screens/RSPC/Patents/patents_tab.dart @@ -0,0 +1,100 @@ +import 'package:flutter/material.dart'; + +class PatentsStatus extends StatefulWidget { + final data; + const PatentsStatus({this.data}); + + @override + _PatentsStatusState createState() => _PatentsStatusState(); +} + +class _PatentsStatusState extends State { + late Map? table; + var rows; + var columns; + + @override + void initState() { + super.initState(); + table = widget.data?['table']; + rows = table?['rows']; + columns = table?['columns']; + } + + @override + Widget build(BuildContext context) { + return Container( + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + //Component to lay table on the page + child: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: DataTable( + // headingRowColor: + + // MaterialStateColor.resolveWith((states) => Colors.blue), + dataRowHeight: 70.0, + columnSpacing: 10.0, + columns: tabColumnList(), + rows: tabRowList(), + // rows: [], + ), + )), + ); + } + + List tabColumnList() { + //Get the list of json and map through, to select each json and lay row to the table.. + + List data = []; + data = columns + .map( + (el) { + return DataColumn( + label: Expanded( + child: Text( + el.toString(), + style: TextStyle(fontSize: 13, fontWeight: FontWeight.bold), + textAlign: TextAlign.center, + ), + ), + ); + }, + ) + .toList() + .cast(); + return data; + } + + List tabRowList() { + //Get the list of json and map through, to select each json and lay row to the table.. + List data = []; + data = rows + .map( + (el) { + return DataRow( + cells: el + .map((e) => DataCell(GestureDetector( + onTap: () => { + // Navigator.pushNamed(context, + // '/programme_curriculum_home/courses_info', + // arguments: {'e': e}) + }, + child: Container( + //SET width + constraints: BoxConstraints(maxWidth: 200), + child: Text( + e.toString(), + ), + ), + ))) + .toList() + .cast(), + ); + }, + ) + .toList() + .cast(); + return data; + } +} diff --git a/lib/screens/RSPC/ResearchProject/research_project.dart b/lib/screens/RSPC/ResearchProject/research_project.dart new file mode 100644 index 00000000..dfc178a3 --- /dev/null +++ b/lib/screens/RSPC/ResearchProject/research_project.dart @@ -0,0 +1,470 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:fusion/services/rspc_service.dart'; + +import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/services/storage_service.dart'; +import 'package:intl/intl.dart'; + +import '../../../Components/utils.dart'; +import '../../../services/profile_service.dart'; + +kTextFieldInputDecoration(String hint) { + return InputDecoration( + hintText: hint, + filled: true, + fillColor: Colors.white, + contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Utils().primarycolor), + borderRadius: BorderRadius.all(Radius.circular(32)), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Utils().primarycolor), + borderRadius: BorderRadius.all(Radius.circular(32)), + ), + ); +} + +const kInputDateDecoration = InputDecoration( + labelText: 'Select Date', + icon: Icon(Icons.calendar_today_rounded), + filled: true, + fillColor: Colors.white, + contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), + border: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(32)), + ), +); + +class AddResearchProject extends StatefulWidget { + final String? uid; + AddResearchProject(this.uid); + + @override + State createState() => _AddResearchProjectState(); +} + +class _AddResearchProjectState extends State { + // ignore: unused_field + final GlobalKey _formKey = GlobalKey(); + String? projectIncharge; + String? coProjectIncharge; + String? fundingAgency; + String? projectTitle; + String? currentStatus; + String? financialOutlay; + String? submissionDate; + String? startDate; + String? expectedFinishDate; + String? pfNo; + Utils utils = Utils(); + + List status = [ + 'Ongoing', + 'Complete', + ]; + var service = locator(); + + TextEditingController submissionDateController = TextEditingController(); + TextEditingController startDateController = TextEditingController(); + TextEditingController expectedFinishDateController = TextEditingController(); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: utils.primarybackgroundcolor, + leading: utils.leadingPopIconsButton(utils.primarycolor, context), + title: Text( + "Research Project", + style: TextStyle( + color: utils.primarycolor, fontWeight: FontWeight.bold), + )), + body: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(25), + margin: EdgeInsets.only(bottom: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Add a new Research project', + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 20, + color: Colors.black.withOpacity(0.6)), + ), + SizedBox( + height: 5, + ), + Container( + height: 1, + width: MediaQuery.of(context).size.width, + decoration: BoxDecoration(color: Colors.black.withOpacity(0.6)), + ), + SizedBox( + height: 30, + ), + Text( + 'Project Incharge(PI) *', + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + SizedBox( + height: 10, + ), + TextFormField( + autofocus: false, + style: TextStyle( + color: Colors.black, + ), + decoration: kTextFieldInputDecoration("PI"), + onChanged: (input) { + projectIncharge = input; + }, + validator: (String? value) { + if (value!.isEmpty) { + return 'This field is mandatory.'; + } + }, + ), + SizedBox( + height: 20, + ), + Text( + 'Co-Project Incharge(CO-PI) *', + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + SizedBox( + height: 10, + ), + TextFormField( + autofocus: false, + style: TextStyle( + color: Colors.black, + ), + decoration: kTextFieldInputDecoration("Co-PI"), + onChanged: (input) { + coProjectIncharge = input; + }, + validator: (String? value) { + if (value!.isEmpty) { + return 'This field is mandatory.'; + } + }, + ), + SizedBox( + height: 20, + ), + Text( + 'Title of Project *', + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + SizedBox( + height: 10, + ), + TextFormField( + autofocus: false, + style: TextStyle( + color: Colors.black, + ), + decoration: kTextFieldInputDecoration("Title"), + onChanged: (input) { + projectTitle = input; + }, + validator: (String? value) { + if (value!.isEmpty) { + return 'This field is mandatory.'; + } + }, + ), + SizedBox( + height: 20, + ), + Text( + 'Funding Agency *', + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + SizedBox( + height: 10, + ), + TextFormField( + autofocus: false, + style: TextStyle( + color: Colors.black, + ), + decoration: kTextFieldInputDecoration("Agency"), + onChanged: (input) { + fundingAgency = input; + }, + validator: (String? value) { + if (value!.isEmpty) { + return 'This field is mandatory.'; + } + }, + ), + SizedBox( + height: 20, + ), + Text( + 'Status *', + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 4, vertical: 10), + child: Container( + padding: EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + border: Border.all( + color: Colors.grey, + ), + borderRadius: BorderRadius.circular(15), + ), + child: DropdownButton( + hint: Text('Status'), + dropdownColor: Colors.grey[200], + value: currentStatus, + icon: Icon(Icons.arrow_drop_down), + isExpanded: true, + underline: SizedBox(), + style: TextStyle(color: Colors.black, fontSize: 16), + onChanged: (newValue) { + setState(() { + currentStatus = newValue.toString(); + }); + }, + items: status.map((valueItem) { + return DropdownMenuItem( + value: valueItem, + child: Text(valueItem), + ); + }).toList(), + ), + ), + ), + SizedBox( + height: 20, + ), + Text( + 'Submission Date *', + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 4, vertical: 10), + child: TextField( + controller: submissionDateController, + decoration: kInputDateDecoration, + onTap: () async { + DateTime? pickeddate = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime(2000), + lastDate: DateTime(2100)); + if (pickeddate != null) { + setState(() { + submissionDateController.text = + DateFormat('yyyy-MM-dd').format(pickeddate); + submissionDate = submissionDateController.text; + }); + } + }, + ), + ), + SizedBox( + height: 20, + ), + Text( + 'Start Date *', + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 4, vertical: 10), + child: TextField( + controller: startDateController, + decoration: kInputDateDecoration, + onTap: () async { + DateTime? pickeddate = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime(2000), + lastDate: DateTime(2100)); + if (pickeddate != null) { + setState(() { + startDateController.text = + DateFormat('yyyy-MM-dd').format(pickeddate); + startDate = startDateController.text; + }); + } + }, + ), + ), + SizedBox( + height: 20, + ), + Text( + 'Expected Finish Date *', + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 4, vertical: 16), + child: TextField( + controller: expectedFinishDateController, + decoration: kInputDateDecoration, + onTap: () async { + DateTime? pickeddate = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime(2000), + lastDate: DateTime(2100)); + if (pickeddate != null) { + setState(() { + expectedFinishDateController.text = + DateFormat('yyyy-MM-dd').format(pickeddate); + expectedFinishDate = expectedFinishDateController.text; + }); + } + }, + ), + ), + Text( + 'Financial Outlay *', + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + SizedBox( + height: 10, + ), + TextFormField( + autofocus: false, + style: TextStyle( + color: Colors.black, + ), + decoration: kTextFieldInputDecoration("Outlay"), + onChanged: (input) { + financialOutlay = input; + }, + validator: (String? value) { + if (value!.isEmpty) { + return 'This field is manadatory.'; + } + }, + ), + SizedBox( + height: 20, + ), + Center( + child: ElevatedButton( + onPressed: (() async { + dynamic res = await ProfileService().getProfile(); + dynamic user = jsonDecode(res.body)['user']; + pfNo = user['id'].toString(); + print(pfNo); + RSPCService auth = RSPCService(); + bool addNewResearchProject = await auth.addResearchProject( + projectIncharge: projectIncharge, + coProjectIncharge: coProjectIncharge, + fundingAgency: fundingAgency, + financialOutlay: financialOutlay, + currentStatus: currentStatus, + projectTitle: projectTitle, + startDate: startDate, + submissionDate: submissionDate, + expectedFinishDate: expectedFinishDate, + pfNo: pfNo, + ); + TextInput.finishAutofillContext(); + if (addNewResearchProject) { + print('Successfully added'); + return showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: Text("Success"), + content: Text("Project Added Successfully"), + actions: [ + ElevatedButton( + onPressed: () { + Navigator.of(ctx).pop(); + }, + child: Text("okay"), + ), + ], + ), + ); + } else { + print('ERROR OCCURED'); + return showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: Text("Failed"), + content: Text("Cannot add above Research Project."), + actions: [ + ElevatedButton( + onPressed: () { + Navigator.of(ctx).pop(); + }, + child: Text("okay"), + ), + ], + ), + ); + } + }), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'Submit', + style: TextStyle( + fontSize: 20, color: utils.primarybackgroundcolor), + ), + ), + style: ButtonStyle( + backgroundColor: MaterialStateProperty.resolveWith( + (Set states) { + if (states.contains(MaterialState.pressed)) + return utils.lightgrey; + return utils + .primarycolor; // Use the component's default. + }, + ), + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/screens/RSPC/ViewProject/consultancy_projects.dart b/lib/screens/RSPC/ViewProject/consultancy_projects.dart new file mode 100644 index 00000000..66f95824 --- /dev/null +++ b/lib/screens/RSPC/ViewProject/consultancy_projects.dart @@ -0,0 +1,263 @@ +// import 'dart:ffi'; + +// import 'package:date_field/date_field.dart'; +import 'dart:async'; +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:http/http.dart'; +import '../../../Components/utils.dart'; +import '../../../models/profile.dart'; +import '../../../models/project.dart'; +import '../../../services/consultancy_project_service.dart'; +import '../../../services/service_locator.dart'; +import '../../../services/storage_service.dart'; + +class ConsultancyProject extends StatefulWidget { + final uid; + ConsultancyProject(this.uid); + @override + _ConsultancyProjectState createState() => _ConsultancyProjectState(); +} + +class _ConsultancyProjectState extends State { + bool _loading1 = true; + ProfileData? data; + late StreamController _projectController; + late ProjectService projectService; + late ProjectData projectData; + Utils utils = Utils(); + + @override + void initState() { + super.initState(); + var service = locator(); + data = service.profileData; + _projectController = StreamController(); + projectService = ProjectService(); + if (data == null) {} + getData(); + } + + getData() async { + try { + Response response = await projectService.getProjectData(); + + setState(() { + print(response.body); + projectData = ProjectData.fromJson(jsonDecode(response.body)); + print(projectData); + _loading1 = false; + }); + } catch (e) { + print(e); + } + } + + @override + void dispose() { + _projectController.close(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + theme: ThemeData.dark(), + home: _loading1 == true + ? Center(child: CircularProgressIndicator()) + : Projects(data: projectData), + debugShowCheckedModeBanner: false, + ); + } +} + +class Projects extends StatelessWidget { + final ProjectData data; + Utils utils = Utils(); + Projects({required this.data}); + + Widget bodyData() => SingleChildScrollView( + scrollDirection: Axis.vertical, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: DataTable( + columnSpacing: 35, + columns: [ + DataColumn( + label: Flexible( + child: SizedBox( + width: 100, + child: Text( + "Consultant", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.visible, + softWrap: true, + ), + ), + ), + numeric: false, + onSort: (i, b) {}, + ), + DataColumn( + label: Flexible( + child: SizedBox( + width: 100, + child: Text( + "Client", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.visible, + softWrap: true, + ), + ), + ), + numeric: false, + onSort: (i, b) {}, + ), + DataColumn( + label: Flexible( + child: SizedBox( + width: 100, + child: Text( + "Title", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.visible, + softWrap: true, + ), + ), + ), + numeric: false, + onSort: (i, b) {}, + ), + DataColumn( + label: Flexible( + child: SizedBox( + width: 100, + child: Text( + "Funding Outlay", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.visible, + softWrap: true, + ), + ), + ), + numeric: false, + onSort: (i, b) {}, + ), + DataColumn( + label: Flexible( + child: SizedBox( + width: 100, + child: Text( + "Status", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.visible, + softWrap: true, + ), + ), + ), + numeric: false, + onSort: (i, b) {}, + ), + DataColumn( + label: Flexible( + child: SizedBox( + width: 100, + child: Text( + "Start Date", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.visible, + softWrap: true, + ), + ), + ), + numeric: false, + onSort: (i, b) {}, + ), + DataColumn( + label: Flexible( + child: SizedBox( + width: 100, + child: Text( + "End Date", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.visible, + softWrap: true, + ), + ), + ), + numeric: false, + onSort: (i, b) {}, + ), + ], + rows: getRows()), + ), + ); + List getRows() { + print(data.projects); + List dummy = [ + DataRow(cells: [ + DataCell(Text('')), + DataCell(Text('')), + DataCell(Text('')), + DataCell(Text('')), + DataCell(Text('')), + DataCell(Text('')), + ]), + ]; + + if (data.projects == null) { + print("No Projects Available"); + return dummy; + } + + if (data.projects!.length == 0) { + print("No Projects Available"); + return dummy; + } + + return data.projects! + .map((element) => DataRow(cells: [ + DataCell(Text(element['consultants'])), + DataCell(Text(element['client'])), + DataCell(Text(element['title'])), + DataCell(Text(element['financial_outlay'].toString())), + DataCell(Text(element['status'])), + DataCell(Text(element['start_date'])), + DataCell(Text(element['end_date'])), + ])) + .toList(); + } + + @override + Widget build(BuildContext context) { + return DefaultTabController( + length: 1, + child: Scaffold( + appBar: AppBar( + leading: utils.leadingPopIconsButton(Colors.black, context), + title: Text( + "Research Projects", + style: TextStyle( + color: utils.primarycolor, fontWeight: FontWeight.bold), + ), + ), + body: bodyData(), + ), + ); + } +} diff --git a/lib/screens/RSPC/ViewProject/research_projects.dart b/lib/screens/RSPC/ViewProject/research_projects.dart new file mode 100644 index 00000000..785193e3 --- /dev/null +++ b/lib/screens/RSPC/ViewProject/research_projects.dart @@ -0,0 +1,281 @@ +// import 'dart:ffi'; + +// import 'package:date_field/date_field.dart'; +import 'dart:async'; +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:http/http.dart'; +import '../../../Components/utils.dart'; +import '../../../models/profile.dart'; +import '../../../models/project.dart'; +import '../../../services/research_project_service.dart'; +import '../../../services/service_locator.dart'; +import '../../../services/storage_service.dart'; + +class ResearchProject extends StatefulWidget { + final uid; + ResearchProject(this.uid); + @override + _ResearchProjectState createState() => _ResearchProjectState(); +} + +class _ResearchProjectState extends State { + bool _loading1 = true; + ProfileData? data; + late StreamController _projectController; + late ProjectService projectService; + late ProjectData projectData; + Utils utils = Utils(); + + @override + void initState() { + super.initState(); + var service = locator(); + data = service.profileData; + _projectController = StreamController(); + projectService = ProjectService(); + if (data == null) {} + getData(); + } + + getData() async { + try { + Response response = await projectService.getProjectData(); + + setState(() { + print(response.body); + projectData = ProjectData.fromJson(jsonDecode(response.body)); + print(projectData); + _loading1 = false; + }); + } catch (e) { + print(e); + } + } + + @override + void dispose() { + _projectController.close(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + theme: ThemeData.dark(), + home: _loading1 == true + ? Center(child: CircularProgressIndicator()) + : Projects(data: projectData), + debugShowCheckedModeBanner: false, + ); + } +} + +class Projects extends StatelessWidget { + final ProjectData data; + Utils utils = Utils(); + Projects({required this.data}); + + Widget bodyData() => SingleChildScrollView( + scrollDirection: Axis.vertical, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: DataTable( + columnSpacing: 35, + columns: [ + DataColumn( + label: Flexible( + child: SizedBox( + width: 100, + child: Text( + "PI", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.visible, + softWrap: true, + ), + ), + ), + numeric: false, + onSort: (i, b) {}, + ), + DataColumn( + label: Flexible( + child: SizedBox( + width: 100, + child: Text( + "Co-PI's", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.visible, + softWrap: true, + ), + ), + ), + numeric: false, + onSort: (i, b) {}, + ), + DataColumn( + label: Flexible( + child: SizedBox( + width: 100, + child: Text( + "Title", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.visible, + softWrap: true, + ), + ), + ), + numeric: false, + onSort: (i, b) {}, + ), + DataColumn( + label: Flexible( + child: SizedBox( + width: 100, + child: Text( + "Funding Agency", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.visible, + softWrap: true, + ), + ), + ), + numeric: false, + onSort: (i, b) {}, + ), + DataColumn( + label: Flexible( + child: SizedBox( + width: 100, + child: Text( + "Financial Outlay", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.visible, + softWrap: true, + ), + ), + ), + numeric: false, + onSort: (i, b) {}, + ), + DataColumn( + label: Flexible( + child: SizedBox( + width: 100, + child: Text( + "Status", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.visible, + softWrap: true, + ), + ), + ), + numeric: false, + onSort: (i, b) {}, + ), + DataColumn( + label: Flexible( + child: SizedBox( + width: 100, + child: Text( + "Submission Date", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.visible, + softWrap: true, + ), + ), + ), + numeric: false, + onSort: (i, b) {}, + ), + DataColumn( + label: Flexible( + child: SizedBox( + width: 100, + child: Text( + "Start Date", + style: TextStyle( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.visible, + softWrap: true, + ), + ), + ), + numeric: false, + onSort: (i, b) {}, + ), + ], + rows: getRows()), + ), + ); + List getRows() { + print(data.projects); + List dummy = [ + DataRow(cells: [ + DataCell(Text('')), + DataCell(Text('')), + DataCell(Text('')), + DataCell(Text('')), + DataCell(Text('')), + DataCell(Text('')), + ]), + ]; + + if (data.projects == null) { + print("No Projects Available"); + return dummy; + } + + if (data.projects!.length == 0) { + print("No Projects Available"); + return dummy; + } + + return data.projects! + .map((element) => DataRow(cells: [ + DataCell(Text(element['pi'])), + DataCell(Text(element['co_pi'])), + DataCell(Text(element['title'])), + DataCell(Text(element['funding_agency'])), + DataCell(Text(element['financial_outlay'])), + DataCell(Text(element['status'])), + DataCell(Text(element['date_submission'])), + DataCell(Text(element['start_date'])), + ])) + .toList(); + } + + @override + Widget build(BuildContext context) { + return DefaultTabController( + length: 1, + child: Scaffold( + appBar: AppBar( + leading: utils.leadingPopIconsButton(Colors.black, context), + title: Text( + "Research Projects", + style: TextStyle( + color: utils.primarycolor, fontWeight: FontWeight.bold), + ), + ), + body: bodyData(), + ), + ); + } +} diff --git a/lib/screens/RSPC/rspc.dart b/lib/screens/RSPC/rspc.dart new file mode 100644 index 00000000..5e3b8f77 --- /dev/null +++ b/lib/screens/RSPC/rspc.dart @@ -0,0 +1,390 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:fusion/models/profile.dart'; +import 'package:fusion/services/profile_service.dart'; +import 'package:http/http.dart'; +import 'package:flutter/material.dart'; +import 'package:fusion/Components/side_drawer.dart'; + +import '../../Components/utils.dart'; + +class RSPCModule extends StatefulWidget { + String? token; + RSPCModule(this.token); + + @override + State createState() => _RSPCModuleState(); +} + +class _RSPCModuleState extends State { + Utils utils = Utils(); + bool _loading = true; + + late StreamController _profileController; + late ProfileService profileService; + late ProfileData data; + @override + void initState() { + super.initState(); + + _profileController = StreamController(); + profileService = ProfileService(); + + getData(); + } + + getData() async { + //print('token-'+widget.token!); + try { + Response response = await profileService.getProfile(); + setState(() { + data = ProfileData.fromJson(jsonDecode(response.body)); + print(data.user!['username']); + _loading = false; + }); + } catch (e) { + print(e); + } + } + + loadData() async { + getData().then((res) { + _profileController.add(res); + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + leading: Builder(builder: (BuildContext context) { + return IconButton( + onPressed: () { + Scaffold.of(context).openDrawer(); + }, + tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip, + icon: Icon( + Icons.menu, + color: utils.primarycolor, + )); + }), + backgroundColor: utils.primarybackgroundcolor, + title: Container( + alignment: Alignment.center, + child: Text( + "Fusion", + style: TextStyle( + color: utils.primarycolor, fontWeight: FontWeight.bold), + ), + ), + actions: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: IconButton( + onPressed: () {}, + icon: Icon(Icons.notifications, color: utils.lightgrey)), + ) + ], + ), + drawer: SideDrawer(), + body: _loading == true + ? Center(child: CircularProgressIndicator()) + : Container( + color: Colors.white60, + child: ListView( + shrinkWrap: true, + physics: ClampingScrollPhysics(), + children: [ + Card( + elevation: 2.0, + margin: EdgeInsets.symmetric(horizontal: 50, vertical: 20), + shadowColor: Colors.black, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + margin: EdgeInsets.only(top: 20), + width: 170, + height: 170, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/profile_pic.png'), + fit: BoxFit.cover, + ), + ), + ), + SizedBox(height: 10), + Text( + data.user != null + ? (data.user!['first_name'] + + ' ' + + data.user!['last_name']) + : "User does not exist on data", + style: TextStyle(color: Colors.black, fontSize: 20), + ), + SizedBox(height: 10), + Text( + data.profile != null + ? (data.profile!['department']!['name'] + + ' ' + + data.profile!['user_type']) + : "No Profile", + style: TextStyle(color: Colors.black, fontSize: 15), + ), + SizedBox(height: 10), + ], + ), + ), + SizedBox(height: 10), + Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/rspc/research_project', + arguments: data.user != null + ? data.user!['username'] + : "null"); + }, + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10)), + shadowColor: Colors.black, + child: Container( + decoration: utils.containerBorder(Colors.grey), + alignment: Alignment.center, + height: 125, + width: MediaQuery.of(context).size.width * 0.4, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.add, + size: 60, + // shadows: [], + ), + SizedBox( + height: 4, + ), + Text( + "Add Research Project", + style: TextStyle(fontSize: 16), + textAlign: TextAlign.center, + ), + SizedBox( + height: 6, + ) + ], + ), + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.pushNamed( + context, '/rspc/consultancy_project', + arguments: data.user != null + ? data.user!['username'] + : "null"); + }, + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10)), + shadowColor: Colors.black, + child: Container( + decoration: utils.containerBorder(Colors.grey), + alignment: Alignment.center, + height: 125, + width: MediaQuery.of(context).size.width * 0.4, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.add_box, + size: 60, + // shadows: [], + ), + SizedBox( + height: 4, + ), + Text( + "Add Consultancy Project", + style: TextStyle(fontSize: 16), + textAlign: TextAlign.center, + ), + SizedBox( + height: 6, + ) + ], + ), + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/rspc/patents', + arguments: data.user != null + ? data.user!['username'] + : "null"); + }, + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10)), + shadowColor: Colors.black, + child: Container( + decoration: utils.containerBorder(Colors.grey), + alignment: Alignment.center, + height: 125, + width: MediaQuery.of(context).size.width * 0.4, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.book, + size: 60, + ), + SizedBox( + height: 4, + ), + Text( + "Patents", + style: TextStyle(fontSize: 16), + textAlign: TextAlign.center, + ), + SizedBox( + height: 6, + ) + ], + ), + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.pushNamed( + context, '/rspc/view_research_project', + arguments: data.user != null + ? data.user!['username'] + : "null"); + }, + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10)), + shadowColor: Colors.black, + child: Container( + decoration: utils.containerBorder(Colors.grey), + alignment: Alignment.center, + height: 125, + width: MediaQuery.of(context).size.width * 0.4, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.border_color_outlined, + size: 60, + ), + SizedBox( + height: 4, + ), + Text( + "Research Projects", + style: TextStyle(fontSize: 16), + textAlign: TextAlign.center, + ), + SizedBox( + height: 6, + ) + ], + ), + ), + ), + ), + GestureDetector( + onTap: () { + Navigator.pushNamed( + context, '/rspc/view_consultancy_project', + arguments: data.user != null + ? data.user!['username'] + : "null"); + }, + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10)), + shadowColor: Colors.black, + child: Container( + decoration: utils.containerBorder(Colors.grey), + alignment: Alignment.center, + height: 125, + width: MediaQuery.of(context).size.width * 0.4, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.border_color_outlined, + size: 60, + // shadows: [], + ), + SizedBox( + height: 4, + ), + Text( + "Consultancy Projects", + style: TextStyle(fontSize: 16), + textAlign: TextAlign.center, + ), + SizedBox( + height: 6, + ) + ], + ), + ), + ), + ), + ], + ) + ], + ), + ), + ); + } + + Widget buttonwidget(String name, IconData icons) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + decoration: BoxDecoration( + color: Colors.purple, + borderRadius: BorderRadius.all(Radius.circular(10)), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Icon( + icons, + color: Colors.white, + ), + SizedBox( + width: 8, + ), + Text( + name, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 18, + color: Colors.white), + ) + ], + ), + ), + ), + ); + } +} diff --git a/lib/services/consultancy_project_service.dart b/lib/services/consultancy_project_service.dart new file mode 100644 index 00000000..5e9f5332 --- /dev/null +++ b/lib/services/consultancy_project_service.dart @@ -0,0 +1,41 @@ +// ignore_for_file: non_constant_identifier_names + +import 'dart:convert'; +import '../api.dart'; +import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/services/storage_service.dart'; +import 'package:http/http.dart' as http; + +import '../constants.dart'; + +class ProjectService { + getProjectData() async { + try { + var storage_service = locator(); + if (storage_service.userInDB?.token == null) + throw Exception('Token Error'); + + Map headers = { + 'Authorization': 'Token ' + (storage_service.userInDB?.token ?? "") + }; + print("fetching Penalty"); + var client = http.Client(); + http.Response response = await client.get( + Uri.http( + getLink(), + kConsultancyProjects, + ), + headers: headers, + ); + if (response.statusCode == 200) { + print("successfully fetched Project Data"); + return response; + } else { + print("error fetching Project Data"); + } + throw Exception('Can\'t load Project Data'); + } catch (e) { + rethrow; + } + } +} diff --git a/lib/services/login_service.dart b/lib/services/login_service.dart index 17d79b42..70e2a99b 100644 --- a/lib/services/login_service.dart +++ b/lib/services/login_service.dart @@ -27,6 +27,7 @@ class LoginService { var storage_service = await StorageService.getInstance(); storage_service!.saveUserInDB(User((jsonDecode(response.body))["token"])); + return true; } catch (e) { rethrow; @@ -41,4 +42,4 @@ class LoginService { rethrow; } } -} \ No newline at end of file +} diff --git a/lib/services/profile_service.dart b/lib/services/profile_service.dart index 7214af5a..dadf3c33 100644 --- a/lib/services/profile_service.dart +++ b/lib/services/profile_service.dart @@ -25,6 +25,7 @@ class ProfileService { ), headers: headers, ); + if (response.statusCode == 200) { print("successfully fetched profile"); storage_service @@ -33,6 +34,7 @@ class ProfileService { } throw Exception('Can\'t load'); } catch (e) { + print(e); rethrow; } } diff --git a/lib/services/research_project_service.dart b/lib/services/research_project_service.dart new file mode 100644 index 00000000..a9f69a28 --- /dev/null +++ b/lib/services/research_project_service.dart @@ -0,0 +1,41 @@ +// ignore_for_file: non_constant_identifier_names + +import 'dart:convert'; +import '../api.dart'; +import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/services/storage_service.dart'; +import 'package:http/http.dart' as http; + +import '../constants.dart'; + +class ProjectService { + getProjectData() async { + try { + var storage_service = locator(); + if (storage_service.userInDB?.token == null) + throw Exception('Token Error'); + + Map headers = { + 'Authorization': 'Token ' + (storage_service.userInDB?.token ?? "") + }; + print("fetching Penalty"); + var client = http.Client(); + http.Response response = await client.get( + Uri.http( + getLink(), + kResearchProjects, + ), + headers: headers, + ); + if (response.statusCode == 200) { + print("successfully fetched Project Data"); + return response; + } else { + print("error fetching Project Data"); + } + throw Exception('Can\'t load Project Data'); + } catch (e) { + rethrow; + } + } +} diff --git a/lib/services/rspc_service.dart b/lib/services/rspc_service.dart new file mode 100644 index 00000000..2d72f791 --- /dev/null +++ b/lib/services/rspc_service.dart @@ -0,0 +1,106 @@ +import 'dart:convert'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'dart:core'; +import 'package:fusion/api.dart'; +import 'package:fusion/constants.dart'; +import 'package:fusion/services/service_locator.dart'; +import 'package:fusion/services/storage_service.dart'; +import 'package:http/http.dart' as http; + +class RSPCService { + Future addResearchProject({ + String? projectIncharge, + String? coProjectIncharge, + String? fundingAgency, + String? projectTitle, + String? currentStatus, + String? financialOutlay, + String? submissionDate, + String? startDate, + String? expectedFinishDate, + String? pfNo, + }) async { + try { + Map data = { + 'pf_no': pfNo, + 'pi': projectIncharge, + 'co_pi': coProjectIncharge, + 'title': projectTitle, + 'financial_outlay': financialOutlay, + 'funding_agency': fundingAgency, + 'status': currentStatus, + 'start_date': startDate, + 'finish_date': expectedFinishDate, + 'date_submission': submissionDate, + }; + var storageService = locator(); + if (storageService.userInDB?.token == null) + throw Exception('Token Error'); + Map headers = { + 'Authorization': 'Token ' + (storageService.userInDB?.token ?? "") + }; + + var client = http.Client(); + var response = await client.post( + Uri.http( + getLink(), + kResearchProjectNew, + ), + headers: headers, + body: data, + ); + + if (response.statusCode == 201) return true; + return false; + } catch (e) { + print('Error While posting new research project -- $e'); + rethrow; + } + } + + Future addConsultancyProject({ + String? consultant, + String? clientName, + String? financialOutlay, + String? projectTitle, + String? startDate, + String? endDate, + String? pfNo, + }) async { + try { + Map data = { + 'consultants': consultant, + 'client': clientName, + 'title': projectTitle, + 'financial_outlay': financialOutlay, + 'start_date': startDate, + 'end_date': endDate, + 'pf_no': pfNo, + }; + print(data); + var storageService = locator(); + if (storageService.userInDB?.token == null) + throw Exception('Token Error'); + Map headers = { + 'Authorization': 'Token ' + (storageService.userInDB?.token ?? "") + }; + + var client = http.Client(); + var response = await client.post( + Uri.http( + getLink(), + kConsultantProjectNew, + ), + headers: headers, + body: data, + ); + + if (response.statusCode == 201) return true; + return false; + } catch (e) { + print('Error While posting new research project -- $e'); + rethrow; + } + } +}