diff --git a/lib/controllers/notifications_controller.dart b/lib/controllers/notifications_controller.dart index b0d0d70..6bc7259 100644 --- a/lib/controllers/notifications_controller.dart +++ b/lib/controllers/notifications_controller.dart @@ -11,7 +11,7 @@ class NotificationsController extends GetxController { 0, "Happy Birthday", "We wish you a happy birthday and prosperous new year", - DateTime.now().add(Duration(seconds: 10))); + DateTime.now().add(const Duration(seconds: 10))); debugPrint("Notifications Done!"); } @@ -47,7 +47,7 @@ class NotificationsController extends GetxController { // If the scheduled date is in the past, add a week to it if (now.isAfter(scheduledDate)) { - scheduledDate = scheduledDate.add(Duration(days: 7)); + scheduledDate = scheduledDate.add(const Duration(days: 7)); } // Schedule the notification diff --git a/lib/controllers/profile_page_controller.dart b/lib/controllers/profile_page_controller.dart deleted file mode 100644 index dcf5c73..0000000 --- a/lib/controllers/profile_page_controller.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:academia/constants/common.dart'; -import 'package:academia/models/user.dart'; -import 'package:get/get.dart'; - -class ProfilePageController extends GetxController { - var currentUser = User().obs; - - ProfilePageController() { - currentUser.value = user; - } - - // fetch user details - Future refreshUserDetails() async { - await user.getUserDetails(user.admno!, user.password!); - currentUser.value = await appDB.get("user"); - } -} diff --git a/lib/main.dart b/lib/main.dart index e011ed6..e07a0b5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -44,7 +44,6 @@ void main() async { GetMaterialApp( home: isLoggedIn ? const HomePage() : const IntroPage(), theme: lightModeTheme, - debugShowCheckedModeBanner: false, ), ); } diff --git a/lib/pages/exams_timetable_page.dart b/lib/pages/exams_timetable_page.dart index 3946783..7c6eb92 100644 --- a/lib/pages/exams_timetable_page.dart +++ b/lib/pages/exams_timetable_page.dart @@ -100,9 +100,7 @@ class _ExamTimeTablePageState extends State { itemBuilder: (context, index) => Padding( padding: const EdgeInsets.only(bottom: 8), child: ExamCourseCard( - ontap: () { - print("Hi"); - }, + ontap: () {}, code: snapshot.data![index]["course_code"] .toString(), date: DateFormat('EEE dd/MM/yy').format( diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 39cee42..26a48fe 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -1,7 +1,7 @@ import 'package:academia/controllers/settings_controller.dart'; import 'package:academia/pages/courses_page.dart'; import 'package:academia/pages/dashboard.dart'; -import 'package:academia/pages/profile_page.dart'; +import 'package:academia/pages/settings_page.dart'; import 'package:academia/pages/tool_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; @@ -20,7 +20,7 @@ class _HomePageState extends State { DashBoard(), ToolsPage(), CoursesPage(), - ProfilePage(), + SettingsPage(), ]; @override Widget build(BuildContext context) { @@ -56,9 +56,9 @@ class _HomePageState extends State { label: 'Courses', ), BottomNavigationBarItem( - icon: Icon(Icons.person_outline), - activeIcon: Icon(Icons.person), - label: 'Profile', + icon: Icon(Icons.settings_outlined), + activeIcon: Icon(Icons.settings), + label: 'Settings', ), ], ), diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index ca641ce..d49df56 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -88,8 +88,8 @@ class LoginPage extends StatelessWidget { Obx( () => !loginController.isloading.value ? ElevatedButton( - onPressed: () { - loginController.login(); + onPressed: () async { + await loginController.login(); }, child: const Text( 'Get started', diff --git a/lib/pages/pdf_viewer.dart b/lib/pages/pdf_viewer.dart index bf31e1e..a9d02eb 100644 --- a/lib/pages/pdf_viewer.dart +++ b/lib/pages/pdf_viewer.dart @@ -18,7 +18,6 @@ class PdfViewer extends StatefulWidget { } class _PdfViewerState extends State { - late PDFViewController _pdfViewerController; int currentPage = 0, totalPages = 0; bool isReady = false; String errorMessage = ''; @@ -93,7 +92,7 @@ class _PdfViewerState extends State { currentPage = page!; }); }, - onRender: (_pages) { + onRender: (pages) { setState(() {}); }, onError: (error) { diff --git a/lib/pages/profile_page.dart b/lib/pages/profile_page.dart deleted file mode 100644 index 51e457f..0000000 --- a/lib/pages/profile_page.dart +++ /dev/null @@ -1,356 +0,0 @@ -import 'dart:convert'; - -import 'package:academia/constants/common.dart'; -import 'package:academia/controllers/profile_page_controller.dart'; -import 'package:academia/controllers/settings_controller.dart'; -import 'package:academia/notifications/notification_service.dart'; -import 'package:academia/pages/settings_page.dart'; -import 'package:academia/widgets/info_card.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:get/get.dart'; -import 'package:intl/intl.dart'; -import 'package:liquid_pull_to_refresh/liquid_pull_to_refresh.dart'; - -class ProfilePage extends StatefulWidget { - const ProfilePage({super.key}); - - @override - State createState() => _ProfilePageState(); -} - -class _ProfilePageState extends State { - @override - Widget build(BuildContext context) { - // Birthday Notification - DateFormat inputFormat = DateFormat('dd/MM/yyyy'); - var dob = inputFormat.parse(user.dateOfBirth!); - NotificationService().scheduleBirthdayNotification(dob); - - // controllers - var controller = Get.put(ProfilePageController()); - var settingsController = Get.find(); - // controller.currentUser.value.gpa = 0.1; - //controller.currentUser.value.name = "Erick"; - return Scaffold( - appBar: AppBar( - title: const Text( - "Profile", - ), - centerTitle: true, - elevation: 0, - actions: [ - IconButton( - onPressed: () { - Get.to(const SettingsPage()); - }, - icon: const Icon(Icons.settings_sharp), - ) - ], - ), - body: LiquidPullToRefresh( - height: 200, - color: Theme.of(context).primaryColor, - backgroundColor: Colors.white, - onRefresh: () async { - try { - await controller.refreshUserDetails(); - } catch (e) { - Get.snackbar( - "Connection Problem", - "Please review your internet connection and try again", - icon: const Icon(Icons.network_check), - ); - } - }, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const SizedBox( - height: 10, - ), - // profile pic - Align( - alignment: Alignment.center, - child: Obx( - () => Stack( - children: [ - CircleAvatar( - radius: 60.0, - child: ClipRRect( - borderRadius: const BorderRadius.all( - Radius.circular(800), - ), - child: settingsController.showProfilePic.value - ? Image.memory( - Uint8List.fromList( - base64Decode(controller - .currentUser.value.profile! - .replaceFirst( - "data:image/gif;base64,", "")), - ), - ) - : Image.asset(user.gender == "male" - ? "assets/images/male_student.png" - : "assets/images/female_student.png"), - ), - ), - if (controller.currentUser.value.gpa! > 3.0) - Positioned( - bottom: 0, - right: 0, - child: Container( - padding: const EdgeInsets.all(2.0), - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - shape: BoxShape.circle, - ), - child: const Icon( - CupertinoIcons.checkmark_seal_fill, - color: Colors.white, - size: 20.0, - ), - ), - ), - ], - ), - ), - ), - - // name - Container( - padding: const EdgeInsets.only(top: 12, bottom: 3), - child: Align( - alignment: Alignment.center, - child: Text( - controller.currentUser.value.name!.toString().title(), - style: const TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - - // Course - Container( - padding: const EdgeInsets.only(bottom: 12), - child: Align( - alignment: Alignment.center, - child: Text( - controller.currentUser.value.programme!.title(), - ), - ), - ), - - // school info - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Container( - padding: const EdgeInsets.all(12), - child: Align( - alignment: Alignment.center, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Obx( - () => Text( - settingsController.showGPA.value - ? controller.currentUser.value.gpa - .toString() - : "🔒", - style: const TextStyle( - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - ), - const SizedBox( - height: 2, - ), - const Text( - "GPA", - style: TextStyle( - color: Colors.grey, - fontSize: 15, - fontWeight: FontWeight.w400, - fontFamily: "Poppins", - ), - ), - ], - ), - ), - ), - Container( - padding: const EdgeInsets.all(12), - child: Align( - alignment: Alignment.center, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - controller.currentUser.value.completedUnits - .toString(), - style: const TextStyle( - fontSize: 20, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox( - height: 2, - ), - const Text( - "Completed Units", - style: TextStyle( - color: Colors.grey, - fontSize: 15, - fontWeight: FontWeight.w400, - fontFamily: "Poppins", - ), - ), - ], - ), - ), - ), - ], - ), - ), - ), - const SizedBox( - height: 12, - ), - Expanded( - child: Container( - decoration: const BoxDecoration( - borderRadius: BorderRadius.only( - topRight: Radius.circular(20), - topLeft: Radius.circular(20), - ), - color: Colors.white, - ), - child: Align( - alignment: Alignment.topLeft, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16, vertical: 12), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - const Text( - "Your Details", - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w700, - ), - ), - const SizedBox( - height: 12, - ), - - // info cards - Expanded( - child: ListView( - children: [ - // admno - InfoCard( - title: "Admission No", - content: controller.currentUser.value.admno!, - icon: CupertinoIcons.person_fill, - ), - - // gender - InfoCard( - title: "Gender", - content: controller.currentUser.value.gender! - .title(), - icon: CupertinoIcons.person_2_fill, - ), - - // dob - InfoCard( - title: "Date Of Birth", - content: - controller.currentUser.value.dateOfBirth!, - icon: CupertinoIcons.calendar, - ), - // address - InfoCard( - title: "Address", - content: controller.currentUser.value.address!, - icon: CupertinoIcons.envelope_fill, - ), - // email - InfoCard( - title: "Email", - content: controller.currentUser.value.email!, - icon: CupertinoIcons.envelope_fill, - ), - InfoCard( - title: "Academic Status", - content: controller.currentUser.value.status! - .title(), - icon: CupertinoIcons.circle, - ), - - // campus - InfoCard( - title: "Campus", - content: controller.currentUser.value.campus! - .title(), - icon: CupertinoIcons.flag_fill, - ), - - // fee Info - Obx( - () => InfoCard( - title: "Amount Billed", - content: settingsController.showFees.value - ? controller - .currentUser.value.amountBilled! - : "🔒🔒🔒", - icon: CupertinoIcons.money_rubl_circle_fill, - ), - ), - Obx( - () => InfoCard( - title: "Fee Paid", - content: settingsController.showFees.value - ? controller.currentUser.value.amountPaid! - : "🔒🔒🔒", - icon: CupertinoIcons.money_euro_circle, - ), - ), - Obx( - () => InfoCard( - title: "Fee Balance", - content: settingsController.showFees.value - ? controller.currentUser.value.balance! - : "🔒🔒🔒", - icon: CupertinoIcons.money_euro_circle_fill, - ), - ), - ], - ), - ), - ], - ), - ), - ), - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/pages/settings_page.dart b/lib/pages/settings_page.dart index 1e2178d..1119619 100644 --- a/lib/pages/settings_page.dart +++ b/lib/pages/settings_page.dart @@ -1,6 +1,10 @@ +import 'dart:convert'; +import 'dart:typed_data'; + import 'package:academia/controllers/settings_controller.dart'; import 'package:academia/notifications/notification_service.dart'; import 'package:academia/pages/webview_page.dart'; +import 'package:academia/widgets/info_card.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -16,308 +20,412 @@ class SettingsPage extends StatelessWidget { @override Widget build(BuildContext context) { var controller = Get.find(); - return Scaffold( - backgroundColor: Colors.white, - appBar: AppBar( - elevation: 0, - leading: IconButton( - onPressed: () { - Get.back(); - }, - icon: const Icon(CupertinoIcons.xmark), - ), - title: const Text("Settings"), - actions: [ - IconButton( - tooltip: "About this app", - onPressed: () { - Get.to( - const WebviewPage( - title: "About Academia", - url: - "https://github.com/IamMuuo/academia/blob/main/README.md", - ), - ); - }, - icon: const Icon(CupertinoIcons.question_circle), + return DefaultTabController( + length: 2, + child: Scaffold( + appBar: AppBar( + elevation: 0, + title: const Text("Settings"), + actions: [ + IconButton( + tooltip: "About this app", + onPressed: () { + Get.to( + const WebviewPage( + title: "About Academia", + url: + "https://github.com/IamMuuo/academia/blob/main/README.md", + ), + ); + }, + icon: const Icon(CupertinoIcons.question_circle), + ), + ], + bottom: const TabBar( + tabs: [ + Tab( + text: "Profile", + icon: Icon(Icons.person_4), + ), + Tab( + text: "Settings", + icon: Icon(Icons.settings), + ), + ], ), - ], - ), - body: Obx( - () => ListView( + ), + body: TabBarView( children: [ - const Align( - alignment: Alignment.center, - child: Text( - "Academia Contributors", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20, - ), - ), - ), - - // Devs - FutureBuilder( - future: magnet.fetchContributors(), - builder: (context, snapshot) => snapshot.hasData - ? SizedBox( - height: 120, - child: ListView.builder( - itemCount: snapshot.data!.length, - scrollDirection: Axis.horizontal, - itemBuilder: (context, index) => Column( + Container( + padding: const EdgeInsets.all(12), + child: SingleChildScrollView( + child: Column( + children: [ + CircleAvatar( + radius: 70.0, + child: Obx( + () => Stack( children: [ - CircleAvatar( - radius: 33, - backgroundColor: - Theme.of(context).primaryColorDark, - child: ClipRRect( - borderRadius: - const BorderRadius.all(Radius.circular(50)), - child: CachedNetworkImage( - height: 65, - fit: BoxFit.contain, - imageUrl: snapshot.data![index] - ["avatar_url"]), + ClipRRect( + borderRadius: const BorderRadius.all( + Radius.circular(800), ), + child: controller.showProfilePic.value + ? Image.memory( + Uint8List.fromList( + base64Decode(user.profile!.replaceFirst( + "data:image/gif;base64,", "")), + ), + fit: BoxFit.contain, + ) + : Image.asset( + user.gender == "male" + ? "assets/images/male_student.png" + : "assets/images/female_student.png", + ), ), - Text( - snapshot.data![index]["login"], - style: normal.copyWith(fontSize: 8), + Positioned( + right: -2, + bottom: 0, + child: Icon( + CupertinoIcons.checkmark_seal_fill, + color: Theme.of(context).primaryColorDark, + ), ), ], ), ), + ), + const SizedBox( + height: 12, + ), + Text( + user.name!.title(), + style: h4, + ), + const SizedBox( + height: 12, + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.5, + child: ListView( + children: [ + InfoCard( + title: "National ID", + content: user.idno ?? "Unknown", + icon: Icons.numbers, + ), + InfoCard( + title: "Admission Number", + content: user.admno ?? "00-0000", + icon: Icons.person, + ), + InfoCard( + title: "Gender", + content: (user.gender ?? "unknown").title(), + icon: Icons.female, + ), + InfoCard( + title: "Email Address", + content: user.email ?? "someone@example.com", + icon: Icons.email, + ), + InfoCard( + title: "Address", + content: user.address ?? "unknown", + icon: Icons.mail, + ), + InfoCard( + title: "Birthday", + content: (user.dateOfBirth ?? "unknown").title(), + icon: Icons.cake_sharp, + ), + ], + ), ) - : LoadingAnimationWidget.flickr( - leftDotColor: Theme.of(context).primaryColor, - rightDotColor: Theme.of(context).primaryColorDark, - size: 60), - ), - // Personal - const Align( - alignment: Alignment.center, - child: Text( - "Personal Settings", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20, + ], ), ), ), + Obx( + () => ListView( + children: [ + const Align( + alignment: Alignment.center, + child: Text( + "Academia Contributors", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + ), + ), + ), - ListTile( - title: const Text("Show my profile picture"), - trailing: Switch( - value: controller.showProfilePic.value, - onChanged: (value) async { - controller.showProfilePic.value = value; - await controller.saveSettings(); - }), - ), - const Divider(), - - ListTile( - title: const Text("Show GPA"), - trailing: Switch( - value: controller.showGPA.value, - onChanged: (value) async { - controller.showGPA.value = value; - await controller.saveSettings(); - }), - ), + // Devs + FutureBuilder( + future: magnet.fetchContributors(), + builder: (context, snapshot) => snapshot.hasData + ? SizedBox( + height: 120, + child: ListView.builder( + itemCount: snapshot.data!.length, + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) => Column( + children: [ + CircleAvatar( + radius: 33, + backgroundColor: + Theme.of(context).primaryColorDark, + child: ClipRRect( + borderRadius: const BorderRadius.all( + Radius.circular(50)), + child: CachedNetworkImage( + height: 65, + fit: BoxFit.contain, + imageUrl: snapshot.data![index] + ["avatar_url"]), + ), + ), + Text( + snapshot.data![index]["login"], + style: normal.copyWith(fontSize: 8), + ), + ], + ), + ), + ) + : LoadingAnimationWidget.flickr( + leftDotColor: Theme.of(context).primaryColor, + rightDotColor: Theme.of(context).primaryColorDark, + size: 60), + ), + // Personal + const Align( + alignment: Alignment.center, + child: Text( + "Personal Settings", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + ), + ), + ), - const Divider(), + ListTile( + title: const Text("Show my profile picture"), + trailing: Switch( + value: controller.showProfilePic.value, + onChanged: (value) async { + controller.showProfilePic.value = value; + await controller.saveSettings(); + }), + ), + const Divider(), - // Todos - const Align( - alignment: Alignment.center, - child: Text( - "Tool Settings", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20, - ), - ), - ), + ListTile( + title: const Text("Show GPA"), + trailing: Switch( + value: controller.showGPA.value, + onChanged: (value) async { + controller.showGPA.value = value; + await controller.saveSettings(); + }), + ), - ListTile( - title: const Text("Lock showing audit tool"), - trailing: Switch( - value: controller.showAudit.value, - onChanged: (value) async { - controller.showAudit.value = value; - await controller.saveSettings(); - }), - ), - const Divider(), - ListTile( - title: const Text("Lock showing transcript tool"), - trailing: Switch( - value: controller.showTranscript.value, - onChanged: (value) async { - controller.showTranscript.value = value; - await controller.saveSettings(); - }), - ), - const Divider(), - ListTile( - title: const Text("Show fees statistics"), - trailing: Switch( - value: controller.showFees.value, - onChanged: (value) async { - controller.showFees.value = value; - await controller.saveSettings(); - }), - ), + const Divider(), - // notifications + // Todos + const Align( + alignment: Alignment.center, + child: Text( + "Tool Settings", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + ), + ), + ), - const Divider(), - const Align( - alignment: Alignment.center, - child: Text( - "Notifications", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20, - ), - ), - ), - ListTile( - title: const Text("Show exam timetable during exam period"), - trailing: Switch( - value: controller.showExamTimeTable.value, - onChanged: (value) async { - controller.showExamTimeTable.value = value; - await controller.saveSettings(); - }), - ), - const Divider(), + ListTile( + title: const Text("Lock showing audit tool"), + trailing: Switch( + value: controller.showAudit.value, + onChanged: (value) async { + controller.showAudit.value = value; + await controller.saveSettings(); + }), + ), + const Divider(), + ListTile( + title: const Text("Lock showing transcript tool"), + trailing: Switch( + value: controller.showTranscript.value, + onChanged: (value) async { + controller.showTranscript.value = value; + await controller.saveSettings(); + }), + ), + const Divider(), + ListTile( + title: const Text("Show fees statistics"), + trailing: Switch( + value: controller.showFees.value, + onChanged: (value) async { + controller.showFees.value = value; + await controller.saveSettings(); + }), + ), - ListTile( - title: const Text("Wish me happy birthday"), - trailing: Switch( - value: controller.birthdayNotify.value, - onChanged: (value) async { - controller.birthdayNotify.value = value; - await controller.saveSettings(); - }), - ), - const Divider(), + // notifications - const Align( - alignment: Alignment.center, - child: Text( - "Features", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20, - ), - ), - ), - ListTile( - title: const Text("Report a bug or issue"), - trailing: IconButton( - onPressed: () {}, - icon: const Icon(CupertinoIcons.arrow_right_circle), - ), - ), - const Divider(), - ListTile( - title: const Text("How to contribute to Academia"), - trailing: IconButton( - onPressed: () { - Get.to( - const WebviewPage( - title: "How to contribute", - url: - "https://github.com/IamMuuo/academia/blob/main/CONTRIBUTING.md"), - ); - }, - icon: const Icon(CupertinoIcons.arrow_right_circle)), - ), + const Divider(), + const Align( + alignment: Alignment.center, + child: Text( + "Notifications", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + ), + ), + ), + ListTile( + title: const Text("Show exam timetable during exam period"), + trailing: Switch( + value: controller.showExamTimeTable.value, + onChanged: (value) async { + controller.showExamTimeTable.value = value; + await controller.saveSettings(); + }), + ), + const Divider(), - const Divider(), - ListTile( - title: const Text("How to contact us"), - trailing: IconButton( - onPressed: () { - Get.to(const WebviewPage( - title: "DITA Contact", - url: "https://dita.co.ke/#contact")); - }, - icon: const Icon(CupertinoIcons.arrow_right_circle)), - ), - const Divider(), + ListTile( + title: const Text("Wish me happy birthday"), + trailing: Switch( + value: controller.birthdayNotify.value, + onChanged: (value) async { + controller.birthdayNotify.value = value; + await controller.saveSettings(); + }), + ), + const Divider(), - // button to refresh all content - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), - child: ElevatedButton( - // log out the use - onPressed: () async { - bool flag = await Get.defaultDialog( - title: "Confirmation", - content: Column( - children: [ - Image.asset( - "assets/images/bot_sad.png", - height: 80, - width: 80, - ), - const Text("Are you sure you wish to leave?"), - ], + const Align( + alignment: Alignment.center, + child: Text( + "Features", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + ), + ), + ), + ListTile( + title: const Text("Report a bug or issue"), + trailing: IconButton( + onPressed: () {}, + icon: const Icon(CupertinoIcons.arrow_right_circle), ), - textConfirm: "Leave", - textCancel: "I'll stay", - onCancel: () { - Get.back(result: false); - }, - onConfirm: () => Get.back(result: true), - ); + ), + const Divider(), + ListTile( + title: const Text("How to contribute to Academia"), + trailing: IconButton( + onPressed: () { + Get.to( + const WebviewPage( + title: "How to contribute", + url: + "https://github.com/IamMuuo/academia/blob/main/CONTRIBUTING.md"), + ); + }, + icon: const Icon(CupertinoIcons.arrow_right_circle)), + ), + + const Divider(), + ListTile( + title: const Text("How to contact us"), + trailing: IconButton( + onPressed: () { + Get.to(const WebviewPage( + title: "DITA Contact", + url: "https://dita.co.ke/#contact")); + }, + icon: const Icon(CupertinoIcons.arrow_right_circle)), + ), + const Divider(), + + // button to refresh all content + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 12, vertical: 4), + child: ElevatedButton( + // log out the use + onPressed: () async { + bool flag = await Get.defaultDialog( + title: "Confirmation", + content: Column( + children: [ + Image.asset( + "assets/images/bot_sad.png", + height: 80, + width: 80, + ), + const Text("Are you sure you wish to leave?"), + ], + ), + textConfirm: "Leave", + textCancel: "I'll stay", + onCancel: () { + Get.back(result: false); + }, + onConfirm: () => Get.back(result: true), + ); - if (flag) { - user.logout(); - Get.offAll(const IntroPage()); - Get.deleteAll(); // Clear all the controllers - Get.snackbar( - "Logout success", - "Please take your time to let us know what we would have done to make you stay", - backgroundColor: Colors.white, - icon: const Icon(CupertinoIcons.checkmark_seal), - ); - NotificationService().showNotification( - id: notifications["user"] ?? 0, - body: "Goodbye friend see you maybe", - title: "Goodbye", - ); - } - }, - style: ElevatedButton.styleFrom( - backgroundColor: Colors.blueGrey, - elevation: 0, - minimumSize: const Size(300, 60), - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all( - Radius.circular(12), + if (flag) { + user.logout(); + Get.offAll(const IntroPage()); + Get.deleteAll(); // Clear all the controllers + Get.snackbar( + "Logout success", + "Please take your time to let us know what we would have done to make you stay", + backgroundColor: Colors.white, + icon: const Icon(CupertinoIcons.checkmark_seal), + ); + NotificationService().showNotification( + id: notifications["user"] ?? 0, + body: "Goodbye friend see you maybe", + title: "Goodbye", + ); + } + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.blueGrey, + elevation: 0, + minimumSize: const Size(300, 60), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(12), + ), + ), + ), + child: const Text( + 'Log out', + style: TextStyle( + fontWeight: FontWeight.w500, + ), + ), ), ), - ), - child: const Text( - 'Log out', - style: TextStyle( - fontWeight: FontWeight.w500, + + Image.asset( + "assets/icons/branding.png", + height: 100, ), - ), + ], ), ), - - Image.asset( - "assets/icons/branding.png", - height: 100, - ), ], ), ), diff --git a/lib/pages/tool_page.dart b/lib/pages/tool_page.dart index d5b6bdf..b05cde8 100644 --- a/lib/pages/tool_page.dart +++ b/lib/pages/tool_page.dart @@ -4,7 +4,6 @@ import 'package:academia/controllers/settings_controller.dart'; import 'package:academia/pages/birthday_page.dart'; import 'package:academia/widgets/tool_card.dart'; import 'package:flutter/cupertino.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; diff --git a/lib/themes/theme.dart b/lib/themes/theme.dart index 9d454b0..cd6ea5a 100644 --- a/lib/themes/theme.dart +++ b/lib/themes/theme.dart @@ -1,81 +1,85 @@ import 'package:flutter/material.dart'; ThemeData lightModeTheme = ThemeData( - fontFamily: 'Nunito', - useMaterial3: true, - primarySwatch: Colors.blueGrey, - colorScheme: ColorScheme.fromSwatch( + fontFamily: 'Nunito', + useMaterial3: true, primarySwatch: Colors.blueGrey, - errorColor: Colors.red, - backgroundColor: Colors.white, - cardColor: Colors.white, - // brightness: Brightness.light, - ), - scaffoldBackgroundColor: Colors.grey[100], - bottomNavigationBarTheme: BottomNavigationBarThemeData( - showSelectedLabels: true, - showUnselectedLabels: false, - elevation: 20, - selectedItemColor: Colors.blueGrey[800], - unselectedItemColor: Colors.blueGrey[300], - ), - dividerTheme: DividerThemeData( - color: Colors.blueGrey[100], - indent: 10, - endIndent: 10, - thickness: 0.5, - ), - inputDecorationTheme: const InputDecorationTheme( - outlineBorder: BorderSide( - color: Colors.blueGrey, - width: 2, + colorScheme: ColorScheme.fromSwatch( + primarySwatch: Colors.blueGrey, + errorColor: Colors.red, + backgroundColor: Colors.white, + cardColor: Colors.white, + // brightness: Brightness.light, + ), + scaffoldBackgroundColor: Colors.grey[100], + bottomNavigationBarTheme: BottomNavigationBarThemeData( + showSelectedLabels: true, + showUnselectedLabels: false, + elevation: 20, + selectedItemColor: Colors.blueGrey[800], + unselectedItemColor: Colors.blueGrey[300], + ), + dividerTheme: DividerThemeData( + color: Colors.blueGrey[100], + indent: 10, + endIndent: 10, + thickness: 0.5, + ), + inputDecorationTheme: const InputDecorationTheme( + outlineBorder: BorderSide( + color: Colors.blueGrey, + width: 2, + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: Colors.grey, + ), + ), ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - width: 1, - color: Colors.grey, + iconButtonTheme: IconButtonThemeData( + style: ButtonStyle( + iconColor: MaterialStateColor.resolveWith((states) => Colors.white), ), ), - ), - iconButtonTheme: IconButtonThemeData( - style: ButtonStyle( - iconColor: MaterialStateColor.resolveWith((states) => Colors.white), + switchTheme: SwitchThemeData( + thumbColor: MaterialStateColor.resolveWith((states) => Colors.blueGrey), + trackColor: + MaterialStateColor.resolveWith((states) => Colors.transparent), + trackOutlineColor: + MaterialStateColor.resolveWith((states) => Colors.blueGrey), ), - ), - switchTheme: SwitchThemeData( - thumbColor: MaterialStateColor.resolveWith((states) => Colors.blueGrey), - trackColor: MaterialStateColor.resolveWith((states) => Colors.transparent), - trackOutlineColor: - MaterialStateColor.resolveWith((states) => Colors.blueGrey), - ), - elevatedButtonTheme: ElevatedButtonThemeData( - style: ElevatedButton.styleFrom( - elevation: 0, - backgroundColor: Colors.blueGrey, - foregroundColor: Colors.white, - minimumSize: const Size(327, 60), - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all( - Radius.circular(12), + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + elevation: 0, + backgroundColor: Colors.blueGrey, + foregroundColor: Colors.white, + minimumSize: const Size(327, 60), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(12), + ), ), ), ), - ), - appBarTheme: const AppBarTheme( - elevation: 0, - color: Colors.blueGrey, - titleTextStyle: TextStyle( - fontFamily: 'Nunito', - fontSize: 20, - fontWeight: FontWeight.bold, - color: Colors.white, + appBarTheme: const AppBarTheme( + elevation: 0, + color: Colors.blueGrey, + titleTextStyle: TextStyle( + fontFamily: 'Nunito', + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.white, + ), ), - ), - dataTableTheme: DataTableThemeData( - headingRowColor: - MaterialStateColor.resolveWith((states) => Colors.blueGrey), - headingTextStyle: const TextStyle( - color: Colors.white, + dataTableTheme: DataTableThemeData( + headingRowColor: + MaterialStateColor.resolveWith((states) => Colors.blueGrey), + headingTextStyle: const TextStyle( + color: Colors.white, + ), ), - ), -); + tabBarTheme: const TabBarTheme( + unselectedLabelColor: Colors.white60, + labelColor: Colors.white, + )); diff --git a/lib/widgets/info_card.dart b/lib/widgets/info_card.dart index 768fe14..ffdaea0 100644 --- a/lib/widgets/info_card.dart +++ b/lib/widgets/info_card.dart @@ -13,43 +13,29 @@ class InfoCard extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.only(bottom: 12), - child: Column( - children: [ - Row( - children: [ - Icon( - icon, - color: Colors.grey, - size: 20, - ), - const SizedBox( - width: 4, - ), - Text( - title, - style: const TextStyle( - fontWeight: FontWeight.w400, - fontSize: 14, - color: Colors.grey, - ), - ), - const Spacer(), - Text( - content, - style: const TextStyle( - fontWeight: FontWeight.w400, - fontSize: 14, - color: Colors.black, - ), - ) - ], + return Padding( + padding: const EdgeInsets.symmetric(vertical: 4), + child: Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(12)), + color: Theme.of(context).cardColor, + ), + padding: const EdgeInsets.all(6), + child: ListTile( + title: Text(title), + subtitle: Text(content), + leading: Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(12)), + color: Theme.of(context).primaryColor, + ), + padding: const EdgeInsets.all(12), + child: Icon( + icon, + color: Theme.of(context).primaryColorLight, + ), ), - const Divider( - thickness: 2, - ), - ], + ), ), ); }