diff --git a/assets/logos/sg_sholars_guide_language_icon.png b/assets/logos/sg_sholars_guide_language_icon.png new file mode 100644 index 00000000..eafbb4d2 Binary files /dev/null and b/assets/logos/sg_sholars_guide_language_icon.png differ diff --git a/assets/logos/sg_sholars_guide_math_icon.png b/assets/logos/sg_sholars_guide_math_icon.png new file mode 100644 index 00000000..209868ab Binary files /dev/null and b/assets/logos/sg_sholars_guide_math_icon.png differ diff --git a/assets/logos/sg_sholars_guide_reading_icon.png b/assets/logos/sg_sholars_guide_reading_icon.png new file mode 100644 index 00000000..cd69cb3f Binary files /dev/null and b/assets/logos/sg_sholars_guide_reading_icon.png differ diff --git a/assets/logos/sg_sholars_guide_science_icon.png b/assets/logos/sg_sholars_guide_science_icon.png new file mode 100644 index 00000000..71159be3 Binary files /dev/null and b/assets/logos/sg_sholars_guide_science_icon.png differ diff --git a/lib/core/models/question_model.dart b/lib/core/models/question_model.dart index 644f3d0f..8a09e1cb 100644 --- a/lib/core/models/question_model.dart +++ b/lib/core/models/question_model.dart @@ -31,7 +31,6 @@ class Question { DocumentReference? commentRef; DocumentReference? questionRef; - DocumentReference? createdBy; final Timestamp createdAt = Timestamp.now(); @@ -95,7 +94,7 @@ class Question { static String SUBJ2string(SUBJ subj) { switch (subj) { case SUBJ.MATH: - return "Math"; + return "Mathematics"; case SUBJ.SCIENCE: return "Science"; case SUBJ.READING: @@ -109,7 +108,7 @@ class Question { static SUBJ string2SUBJ(String subj) { switch (subj) { - case "Math": + case "Mathematics": return SUBJ.MATH; case "Science": return SUBJ.SCIENCE; diff --git a/lib/features/profile/presentation/screens/profile_screen.dart b/lib/features/profile/presentation/screens/profile_screen.dart index 9a915947..73d37efe 100644 --- a/lib/features/profile/presentation/screens/profile_screen.dart +++ b/lib/features/profile/presentation/screens/profile_screen.dart @@ -115,7 +115,7 @@ class ProfileScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ CircleAvatar( - backgroundColor: Colors.blue, + backgroundColor: const Color.fromRGBO(207, 0, 15, 1), radius: 50, child: Text( username[0].toUpperCase(), @@ -164,12 +164,37 @@ class ProfileScreen extends StatelessWidget { '/profile/view-my-questions', ); }, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + const Color.fromRGBO(207, 0, 15, 1), + ), + ), child: Text( "View My Questions", style: TextStyle(fontSize: 16), ), ), ), + Container( + height: 128, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + "assets/logos/sg_scholars_guide_logo-transformed-960x960.png", + height: 50, + width: 50, + ), + const Text( + "Scholar's Guide", + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.bold, + ), + ) + ], + ) ], ); }), diff --git a/lib/features/quiz_mode/presentation/pages/finished_quiz_page.dart b/lib/features/quiz_mode/presentation/pages/finished_quiz_page.dart index 9de6b3ea..cde58ee0 100644 --- a/lib/features/quiz_mode/presentation/pages/finished_quiz_page.dart +++ b/lib/features/quiz_mode/presentation/pages/finished_quiz_page.dart @@ -22,10 +22,48 @@ class FinishedQuizPage extends StatelessWidget { ((score / subjectQuestionsMap[subject]!.length) * 100).round(); return Scaffold( + backgroundColor: const Color.fromRGBO(207, 0, 15, 1), appBar: AppBar( automaticallyImplyLeading: false, - title: const Text('Quiz Results', - style: TextStyle(fontWeight: FontWeight.bold)), + backgroundColor: const Color.fromRGBO(207, 0, 15, 1), + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text('Quiz Results', + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.white, + )), + SizedBox( + height: 35, + child: ElevatedButton( + onPressed: () { + GoRouter.of(context).go('/quiz-mode'); + }, + style: ButtonStyle( + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: BorderSide( + color: Colors.white, + ), + ), + ), + backgroundColor: MaterialStateProperty.all( + const Color.fromRGBO(207, 0, 15, 1), + ), + ), + child: Text( + "Take Another Quiz", + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ), + ), + ], + ), ), body: SingleChildScrollView( child: Column( @@ -35,19 +73,28 @@ class FinishedQuizPage extends StatelessWidget { margin: EdgeInsets.only(top: 20, bottom: 10), child: Text( "Congrats on finishing! Let's see how you did", - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.white, + ), ), ), - Card( - child: Container( - width: MediaQuery.of(context).size.width * 0.5, - margin: EdgeInsets.only(top: 20, bottom: 10), + Container( + width: double.infinity, + margin: EdgeInsets.only(left: 10, right: 10), + child: Card( child: Column( children: [ + Padding( + padding: const EdgeInsets.all(7.0), + ), Text( "Score", - style: - TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), ), Container( padding: EdgeInsets.all(10), @@ -59,38 +106,79 @@ class FinishedQuizPage extends StatelessWidget { : scorePercentage <= 80 ? Colors.orange : Colors.green, - fontSize: 20, + fontSize: 25, fontWeight: FontWeight.bold), ), ), - TextButton( - onPressed: () { - GoRouter.of(context).go( - '/quiz-mode/solutions-quiz', - extra: { - 'subjectQuestionsMap': subjectQuestionsMap, - 'subject': subject - }, - ); - }, - child: Text("Review"), - ), ], ), ), ), + Container( + width: double.infinity, + margin: EdgeInsets.only(left: 14, right: 14), + padding: EdgeInsets.only(top: 7, bottom: 10), + child: TextButton( + onPressed: () { + GoRouter.of(context).go( + '/quiz-mode/solutions-quiz', + extra: { + 'subjectQuestionsMap': subjectQuestionsMap, + 'subject': subject + }, + ); + }, + style: ButtonStyle( + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + side: MaterialStateProperty.all( + BorderSide( + color: Colors.white, + ), + ), + ), + child: Text( + "View Solutions", + style: TextStyle( + color: Colors.white, + fontSize: 18, + ), + ), + ), + ), Text( "* Results of unanswered questions will not be shown", - style: TextStyle(fontSize: 11, color: Colors.grey), + style: TextStyle( + fontSize: 11, + color: Colors.white, + ), ), QuestionDisplay( subjectQuestionsMap: subjectQuestionsMap, subject: subject), - ElevatedButton( - onPressed: () { - GoRouter.of(context).go('/quiz-mode'); - }, - child: Text('Take Another Quiz'), - ), + // Container( + // width: 200, + // child: ElevatedButton( + // onPressed: () { + // GoRouter.of(context).go('/quiz-mode'); + // }, + // style: ButtonStyle( + // shape: MaterialStateProperty.all( + // RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(10), + // ), + // ), + // backgroundColor: + // MaterialStateProperty.all(Colors.white), + // ), + // child: Text("Take Another Quiz", + // style: TextStyle( + // fontWeight: FontWeight.bold, + // color: const Color.fromRGBO(207, 0, 15, 1))), + // ), + // ), SizedBox( height: 20, ), diff --git a/lib/features/quiz_mode/presentation/pages/quiz_page.dart b/lib/features/quiz_mode/presentation/pages/quiz_page.dart index 3da20d24..e9b5cf8d 100644 --- a/lib/features/quiz_mode/presentation/pages/quiz_page.dart +++ b/lib/features/quiz_mode/presentation/pages/quiz_page.dart @@ -36,11 +36,16 @@ class _QuizPageState extends State { child: Builder( builder: (builderContext) { return Scaffold( + backgroundColor: const Color.fromRGBO(207, 0, 15, 1), appBar: AppBar( title: Text('${Question.SUBJ2string(subject)} Quiz', - style: TextStyle(fontWeight: FontWeight.bold)), + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.white, + )), + backgroundColor: const Color.fromRGBO(207, 0, 15, 1), leading: IconButton( - icon: Icon(Icons.arrow_back), + icon: Icon(Icons.arrow_back, color: Colors.white), onPressed: () { showDialog( context: context, @@ -70,20 +75,39 @@ class _QuizPageState extends State { ), // * Display the submit button - ElevatedButton( - onPressed: () { - showDialog( - context: context, - builder: (BuildContext buildContext) { - return ConfirmSubmitQuizDialogue( - quizBloc: - quizBlocContext.read(), - ); - }, - ); - }, - child: Text("Submit"), + Container( + width: 200, + child: ElevatedButton( + onPressed: () { + showDialog( + context: context, + builder: (BuildContext buildContext) { + return ConfirmSubmitQuizDialogue( + quizBloc: + quizBlocContext.read(), + ); + }, + ); + }, + style: ButtonStyle( + shape: MaterialStateProperty.all< + RoundedRectangleBorder>( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + backgroundColor: + MaterialStateProperty.all( + Colors.white), + ), + child: Text("Submit", + style: TextStyle( + fontWeight: FontWeight.bold, + color: const Color.fromRGBO( + 207, 0, 15, 1))), + ), ), + Container(height: 20), ], ), ), diff --git a/lib/features/quiz_mode/presentation/pages/ready_quiz_page.dart b/lib/features/quiz_mode/presentation/pages/ready_quiz_page.dart index a21dc3ad..db29b9ea 100644 --- a/lib/features/quiz_mode/presentation/pages/ready_quiz_page.dart +++ b/lib/features/quiz_mode/presentation/pages/ready_quiz_page.dart @@ -11,7 +11,7 @@ class ReadyQuizPage extends StatelessWidget { return Scaffold( appBar: AppBar( automaticallyImplyLeading: false, - title: const Text('Submit Questions', + title: const Text('Quiz Mode', style: TextStyle(fontWeight: FontWeight.bold)), ), body: Center( diff --git a/lib/features/quiz_mode/presentation/pages/solutions_quiz_page.dart b/lib/features/quiz_mode/presentation/pages/solutions_quiz_page.dart index 6e3d54fb..7f478285 100644 --- a/lib/features/quiz_mode/presentation/pages/solutions_quiz_page.dart +++ b/lib/features/quiz_mode/presentation/pages/solutions_quiz_page.dart @@ -6,6 +6,7 @@ import 'package:go_router/go_router.dart'; import 'package:scholars_guide/core/models/question_model.dart'; import 'package:scholars_guide/features/quiz_mode/presentation/state_management/quiz_card/quiz_card_cubit.dart'; import 'package:scholars_guide/features/quiz_mode/presentation/state_management/solution_quiz/solution_quiz_cubit.dart'; +import 'package:scholars_guide/features/quiz_mode/presentation/widgets/finished_quiz_page_widgets/confirm_back_to_quiz_page_dialogue.dart'; import 'package:scholars_guide/features/quiz_mode/presentation/widgets/quiz_page_widgets/question_loading_display.dart'; import 'package:scholars_guide/features/quiz_mode/presentation/widgets/solution_quiz_page_widgets/solution_card_display.dart'; @@ -25,10 +26,31 @@ class _SolutionsQuizPageState extends State { extraMap['subjectQuestionsMap'] as Map>; return Scaffold( + backgroundColor: const Color.fromRGBO(207, 0, 15, 1), appBar: AppBar( + backgroundColor: const Color.fromRGBO(207, 0, 15, 1), automaticallyImplyLeading: false, - title: Text('Solutions Page', - style: TextStyle(fontWeight: FontWeight.bold)), + leading: IconButton( + icon: Icon( + Icons.arrow_back, + color: Colors.white, + ), + onPressed: () { + showDialog( + context: context, + builder: (BuildContext buildContext) { + return ConfirmBackToQuizPageDialogue(); + }, + ); + }, + ), + title: Text( + 'Solutions Page', + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), ), body: BlocProvider( create: (providerContext) => SolutionQuizCubit()..loadSolutions(), diff --git a/lib/features/quiz_mode/presentation/widgets/finished_quiz_page_widgets/confirm_back_to_quiz_page_dialogue.dart b/lib/features/quiz_mode/presentation/widgets/finished_quiz_page_widgets/confirm_back_to_quiz_page_dialogue.dart new file mode 100644 index 00000000..dd449e8d --- /dev/null +++ b/lib/features/quiz_mode/presentation/widgets/finished_quiz_page_widgets/confirm_back_to_quiz_page_dialogue.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +class ConfirmBackToQuizPageDialogue extends StatelessWidget { + const ConfirmBackToQuizPageDialogue({super.key}); + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: const Text('Back to Quiz Page', + style: TextStyle(fontWeight: FontWeight.bold)), + content: + const Text("Finished Reviewing? You will go back to the Quiz Page."), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + TextButton( + child: const Text( + "Take Again", + style: TextStyle(color: Color.fromRGBO(207, 0, 15, 1)), + ), + onPressed: () { + Navigator.of(context).pop(); + GoRouter.of(context).go('/quiz-mode'); + }, + ), + TextButton( + child: const Text( + 'Continue Reviewing', + style: TextStyle(color: Color.fromRGBO(207, 0, 15, 1)), + ), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ), + ], + ); + } +} diff --git a/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/confirm_cancel_quiz_dialogue.dart b/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/confirm_cancel_quiz_dialogue.dart index 9e3ee08a..66c869d1 100644 --- a/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/confirm_cancel_quiz_dialogue.dart +++ b/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/confirm_cancel_quiz_dialogue.dart @@ -15,14 +15,20 @@ class ConfirmCancelQuizDialogue extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ TextButton( - child: const Text('Go Back'), + child: const Text( + 'Go Back', + style: TextStyle(color: Color.fromRGBO(207, 0, 15, 1)), + ), onPressed: () { Navigator.of(context).pop(); GoRouter.of(context).go('/quiz-mode'); }, ), TextButton( - child: const Text('Continue Quiz'), + child: const Text( + 'Continue Quiz', + style: TextStyle(color: Color.fromRGBO(207, 0, 15, 1)), + ), onPressed: () { Navigator.of(context).pop(); }, diff --git a/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/confirm_submit_quiz_dialogue.dart b/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/confirm_submit_quiz_dialogue.dart index 3098da5c..287037f6 100644 --- a/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/confirm_submit_quiz_dialogue.dart +++ b/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/confirm_submit_quiz_dialogue.dart @@ -20,13 +20,19 @@ class ConfirmSubmitQuizDialogue extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ TextButton( - child: const Text('Go Back'), + child: const Text( + 'Go Back', + style: TextStyle(color: Color.fromRGBO(207, 0, 15, 1)), + ), onPressed: () { Navigator.of(context).pop(); }, ), TextButton( - child: const Text('Submit Quiz'), + child: const Text( + 'Submit Quiz', + style: TextStyle(color: Color.fromRGBO(207, 0, 15, 1)), + ), onPressed: () { final SUBJ subject = quizBloc.subject; Map> subjectQuestionsMap = diff --git a/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/confirm_timeout_quiz_dialogue.dart b/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/confirm_timeout_quiz_dialogue.dart index 48981621..8caaa8b3 100644 --- a/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/confirm_timeout_quiz_dialogue.dart +++ b/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/confirm_timeout_quiz_dialogue.dart @@ -17,7 +17,14 @@ class ConfirmTimeoutQuizDialogue extends StatelessWidget { content: const Text("Time's up! You did great"), actions: [ TextButton( - child: const Text('Submit Quiz'), + child: const Center( + child: Text( + 'Submit Quiz', + style: TextStyle( + color: Color.fromRGBO(207, 0, 15, 1), + ), + ), + ), onPressed: () { final SUBJ subject = quizBloc.subject; Map> subjectQuestionsMap = diff --git a/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/timer_display.dart b/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/timer_display.dart index b2b725da..6b7d531a 100644 --- a/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/timer_display.dart +++ b/lib/features/quiz_mode/presentation/widgets/quiz_page_widgets/timer_display.dart @@ -40,17 +40,17 @@ class _CountdownTimerState extends State { controller: CountDownController(), width: MediaQuery.of(context).size.width / 6, height: MediaQuery.of(context).size.height / 6, - ringColor: Colors.indigo.withOpacity(0.0), + ringColor: Color.fromRGBO(207, 0, 15, 1).withOpacity(0.0), ringGradient: null, - fillColor: Colors.indigo.withOpacity(0.5), + fillColor: Color.fromRGBO(207, 0, 15, 1).withOpacity(0.5), fillGradient: null, - backgroundColor: Colors.indigo.withOpacity(0.3), + backgroundColor: Colors.white.withOpacity(0.3), backgroundGradient: null, strokeWidth: 5.0, strokeCap: StrokeCap.round, textStyle: TextStyle( fontSize: 20.0, - color: Colors.indigo.withOpacity(0.8), + color: Color.fromRGBO(207, 0, 15, 1).withOpacity(0.7), fontWeight: FontWeight.bold), textFormat: CountdownTextFormat.S, isReverse: true, diff --git a/lib/features/quiz_mode/presentation/widgets/quiz_widgets/question_card_choices_display.dart b/lib/features/quiz_mode/presentation/widgets/quiz_widgets/question_card_choices_display.dart index c4360db2..11970a0e 100644 --- a/lib/features/quiz_mode/presentation/widgets/quiz_widgets/question_card_choices_display.dart +++ b/lib/features/quiz_mode/presentation/widgets/quiz_widgets/question_card_choices_display.dart @@ -98,12 +98,12 @@ class ChoiceButton extends StatelessWidget { color = isCorrect ? isChosen ? Colors.green - : Colors.black + : Colors.white : isChosen - ? Colors.red - : Colors.black; + ? Color.fromRGBO(207, 0, 15, 1) + : Colors.white; } else if (isChosen) { - color = Colors.indigoAccent; + color = Color.fromRGBO(207, 0, 15, 1); } return Container( @@ -114,17 +114,24 @@ class ChoiceButton extends StatelessWidget { margin: EdgeInsets.only(top: 2.0, bottom: 2.0), child: ElevatedButton( style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( - isChosen ? Colors.deepPurple[50] : Colors.white), + backgroundColor: MaterialStateProperty.all(isRevealed + ? color + : isChosen + ? const Color.fromRGBO(207, 0, 15, 1) + : Colors.white), shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), - side: BorderSide(color: color), + side: BorderSide( + color: isRevealed && isChosen && isCorrect + ? Colors.green + : const Color.fromRGBO(207, 0, 15, 1), + ), ), ), ), onPressed: isRevealed ? null : func, - child: TextMarkdown(text: "$letter. $choice"), + child: TextMarkdown(text: "$letter. $choice", isChosen: isChosen), ), ); } @@ -134,9 +141,11 @@ class TextMarkdown extends StatelessWidget { const TextMarkdown({ super.key, required this.text, + required this.isChosen, }); final String text; + final bool isChosen; @override Widget build(BuildContext context) { @@ -146,11 +155,22 @@ class TextMarkdown extends StatelessWidget { shrinkWrap: true, data: text, builders: { - 'latex': LatexElementBuilder(), + 'latex': LatexElementBuilder( + textScaleFactor: 1.3, + textStyle: TextStyle( + fontSize: 15.0, + color: isChosen ? Colors.white : Color.fromRGBO(207, 0, 15, 1), + fontWeight: FontWeight.bold, + ), + ), }, styleSheet: MarkdownStyleSheet( textAlign: WrapAlignment.center, - p: const TextStyle(fontSize: 15.0, color: Colors.black), + p: TextStyle( + fontSize: 15.0, + color: isChosen ? Colors.white : Color.fromRGBO(207, 0, 15, 1), + fontWeight: FontWeight.bold, + ), ), extensionSet: md.ExtensionSet( [LatexBlockSyntax()], diff --git a/lib/features/quiz_mode/presentation/widgets/quiz_widgets/question_card_display.dart b/lib/features/quiz_mode/presentation/widgets/quiz_widgets/question_card_display.dart index f3aa7546..0e32dbde 100644 --- a/lib/features/quiz_mode/presentation/widgets/quiz_widgets/question_card_display.dart +++ b/lib/features/quiz_mode/presentation/widgets/quiz_widgets/question_card_display.dart @@ -29,7 +29,7 @@ class _QuestionCardDisplayState extends State { margin: EdgeInsets.only(left: 10, right: 10), child: Card( margin: EdgeInsets.all(10.0), - elevation: 5.0, + color: Colors.white, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( diff --git a/lib/features/quiz_mode/presentation/widgets/quiz_widgets/question_card_question_display.dart b/lib/features/quiz_mode/presentation/widgets/quiz_widgets/question_card_question_display.dart index df4cb426..655fd9a6 100644 --- a/lib/features/quiz_mode/presentation/widgets/quiz_widgets/question_card_question_display.dart +++ b/lib/features/quiz_mode/presentation/widgets/quiz_widgets/question_card_question_display.dart @@ -30,13 +30,20 @@ class TextMarkdown extends StatelessWidget { physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, data: text, + builders: { + 'latex': LatexElementBuilder( + textScaleFactor: 1.2, + textStyle: TextStyle( + fontSize: 15.0, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + }, styleSheet: MarkdownStyleSheet( textAlign: WrapAlignment.center, - p: const TextStyle(fontSize: 17.0), + p: const TextStyle(fontSize: 17.0, fontWeight: FontWeight.bold), ), - builders: { - 'latex': LatexElementBuilder(), - }, extensionSet: md.ExtensionSet( [LatexBlockSyntax()], [LatexInlineSyntax()], diff --git a/lib/features/quiz_mode/presentation/widgets/ready_quiz_page_widgets/choose_subject_display.dart b/lib/features/quiz_mode/presentation/widgets/ready_quiz_page_widgets/choose_subject_display.dart index 18c0e5f7..a2757f40 100644 --- a/lib/features/quiz_mode/presentation/widgets/ready_quiz_page_widgets/choose_subject_display.dart +++ b/lib/features/quiz_mode/presentation/widgets/ready_quiz_page_widgets/choose_subject_display.dart @@ -15,24 +15,52 @@ class _ChooseSubjectDisplayState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( - "Choose a subject to start the quiz", - style: TextStyle(fontSize: 20), + "Choose a subject", + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + ), ), // buildElevatedButton("UPCAT Challenge", context), // TODO: Implement UPCAT Challenge - buildElevatedButton("Math", context), - buildElevatedButton("Science", context), - buildElevatedButton("Language Proficiency", context), - buildElevatedButton("Reading Comprehension", context), + buildElevatedButton("Mathematics", + "assets/logos/sg_sholars_guide_math_icon.png", 28, context), + buildElevatedButton("Science", + "assets/logos/sg_sholars_guide_science_icon.png", 28, context), + buildElevatedButton("Language Proficiency", + "assets/logos/sg_sholars_guide_language_icon.png", 36, context), + buildElevatedButton("Reading Comprehension", + "assets/logos/sg_sholars_guide_reading_icon.png", 33, context), + const SizedBox( + height: 100, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + "assets/logos/sg_scholars_guide_logo-transformed-960x960.png", + height: 50, + width: 50, + ), + const Text( + "Scholar's Guide", + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.bold, + ), + ) + ], + ), ], ); } } -Container buildElevatedButton(String text, BuildContext context) { +Container buildElevatedButton( + String text, String path, double length, BuildContext context) { return Container( - margin: const EdgeInsets.only(bottom: 5, top: 5), + margin: const EdgeInsets.only(bottom: 5, top: 10), height: 50, - width: 220, + width: 250, child: ElevatedButton( onPressed: () { showDialog( @@ -45,6 +73,32 @@ Container buildElevatedButton(String text, BuildContext context) { }, style: ButtonStyle( elevation: MaterialStateProperty.all(3), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + 14.0, + ), // Set your desired corner radius here + ), + ), + backgroundColor: MaterialStateProperty.all( + const Color.fromRGBO(207, 0, 15, 1), + ), ), - child: Text(text))); + child: Row( + children: [ + Text( + text, + style: const TextStyle( + color: Colors.white, fontWeight: FontWeight.bold), + ), + Expanded( + child: Container(), + ), + Image.asset( + path, + height: length, + width: length, + ) + ], + ))); } diff --git a/lib/features/quiz_mode/presentation/widgets/ready_quiz_page_widgets/subject_chosen_dialogue.dart b/lib/features/quiz_mode/presentation/widgets/ready_quiz_page_widgets/subject_chosen_dialogue.dart index d990f2b5..500dad9c 100644 --- a/lib/features/quiz_mode/presentation/widgets/ready_quiz_page_widgets/subject_chosen_dialogue.dart +++ b/lib/features/quiz_mode/presentation/widgets/ready_quiz_page_widgets/subject_chosen_dialogue.dart @@ -16,20 +16,25 @@ class SubjectChosenDialogue extends StatelessWidget { ), content: Text( "Let's start answering $subjectTest!\nTimer will start. Are you ready?", - textAlign: TextAlign.center, ), actions: [ Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ TextButton( - child: const Text('Go Back'), + child: const Text( + 'Go Back', + style: TextStyle(color: Color.fromRGBO(207, 0, 15, 1)), + ), onPressed: () { Navigator.of(context).pop(); }, ), TextButton( - child: const Text('Start'), + child: const Text( + 'Start', + style: TextStyle(color: Color.fromRGBO(207, 0, 15, 1)), + ), onPressed: () { Navigator.of(context).pop(); GoRouter.of(context).go('/quiz-mode/start-quiz', diff --git a/lib/features/quiz_mode/presentation/widgets/solution_quiz_page_widgets/solution_card_display.dart b/lib/features/quiz_mode/presentation/widgets/solution_quiz_page_widgets/solution_card_display.dart index ddef7a9e..b7901560 100644 --- a/lib/features/quiz_mode/presentation/widgets/solution_quiz_page_widgets/solution_card_display.dart +++ b/lib/features/quiz_mode/presentation/widgets/solution_quiz_page_widgets/solution_card_display.dart @@ -31,7 +31,7 @@ class _SolutionCardDisplayState extends State { @override Widget build(BuildContext context) { return Card( - margin: EdgeInsets.all(10.0), + margin: EdgeInsets.all(20.0), child: Padding( padding: const EdgeInsets.all(8.0), child: Container( @@ -43,12 +43,14 @@ class _SolutionCardDisplayState extends State { children: [ Icon( Icons.arrow_back_ios_new, - color: Colors.grey, + color: const Color.fromRGBO(207, 0, 15, 1), size: 12, ), Text( - " Swipe me", - style: TextStyle(fontSize: 11, color: Colors.grey), + " Swipe", + style: TextStyle( + fontSize: 11, + color: const Color.fromRGBO(207, 0, 15, 1)), ), ], ), @@ -82,31 +84,49 @@ class _SolutionCardDisplayState extends State { ), ), ), - ElevatedButton( - onPressed: () { - showModalBottomSheet( - context: context, - showDragHandle: true, - builder: (BuildContext context) => FutureBuilder( - future: QuizModeRepositoryImpl() - .collectComments(docRef: widget.commentRef), - builder: (BuildContext context, AsyncSnapshot snapshot) { - if (snapshot.connectionState == - ConnectionState.waiting) { - return QuestionLoadingDisplay(); - } else if (snapshot.hasError) { - return Text('Error: ${snapshot.error}'); - } else { - return SolutionCommentModal( - docRef: widget.commentRef, - comments: snapshot.data, - ); - } - }, + Container( + width: 300, + child: ElevatedButton( + onPressed: () { + showModalBottomSheet( + context: context, + showDragHandle: true, + builder: (BuildContext context) => FutureBuilder( + future: QuizModeRepositoryImpl() + .collectComments(docRef: widget.commentRef), + builder: + (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == + ConnectionState.waiting) { + return QuestionLoadingDisplay(); + } else if (snapshot.hasError) { + return Text('Error: ${snapshot.error}'); + } else { + return SolutionCommentModal( + docRef: widget.commentRef, + comments: snapshot.data, + ); + } + }, + ), + ); + }, + style: ButtonStyle( + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), ), - ); - }, - child: TextTitle(title: "Comments"), + backgroundColor: MaterialStateProperty.all( + const Color.fromRGBO(207, 0, 15, 1)), + ), + child: Text("Comments", + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.white, + fontSize: 17, + )), + ), ), ], ), @@ -129,7 +149,7 @@ class TextTitle extends StatelessWidget { style: TextStyle( fontSize: 20.0, fontWeight: FontWeight.bold, - color: Color.fromARGB(255, 95, 55, 213), + color: const Color.fromRGBO(207, 0, 15, 1), )), ); } diff --git a/lib/features/quiz_upload/presentation/pages/upload_questions_page.dart b/lib/features/quiz_upload/presentation/pages/upload_questions_page.dart index 5c252e3c..2095bd9b 100644 --- a/lib/features/quiz_upload/presentation/pages/upload_questions_page.dart +++ b/lib/features/quiz_upload/presentation/pages/upload_questions_page.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:scholars_guide/features/quiz_upload/presentation/state_management/quiz_input_page/quiz_input_page_bloc.dart'; import 'package:scholars_guide/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/add_or_submit_display.dart'; import 'package:scholars_guide/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/change_subject_display.dart'; +import 'package:scholars_guide/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/latex_sample_display.dart'; import 'package:scholars_guide/features/quiz_upload/presentation/widgets/quiz_input_widgets/question_input_display.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:scholars_guide/features/quiz_upload/presentation/widgets/quiz_input_widgets/question_preview_display.dart'; @@ -20,7 +21,7 @@ class _UploadQuestionPageState extends State { Widget build(BuildContext context) { return DefaultTabController( initialIndex: 0, - length: 2, + length: 3, child: BlocProvider( create: (blocContext) => QuizInputPageBloc(), child: BlocBuilder( @@ -28,52 +29,108 @@ class _UploadQuestionPageState extends State { if (state is QuizInputPageQuestionsAdd) { return Scaffold( appBar: AppBar( + backgroundColor: Color.fromRGBO(207, 0, 15, 1), title: const Text('Upload Questions', - style: TextStyle(fontWeight: FontWeight.bold)), - bottom: TabBar( - tabs: const [ - Tab( - icon: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.edit_outlined), - SizedBox(width: 8.0), - Text('Edit'), - ], - ), - ), - Tab( - icon: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.preview_outlined), - SizedBox(width: 8.0), - Text('Preview'), - ], - ), - ), - ], - ), - ), - body: TabBarView( - children: [ - SingleChildScrollView( + style: TextStyle( + fontWeight: FontWeight.bold, color: Colors.white)), + bottom: PreferredSize( + preferredSize: Size.fromHeight(60.0), child: Column( children: [ - ChangeSubjectDisplay(), - Text( - "* Quiz Upload supports Latex. Use \$\$ to wrap the equation. \n\t\t\tDouble space for new line.", - style: TextStyle(fontSize: 11, color: Colors.grey), + Container( + width: 350, + height: 45, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8.0), + border: Border.all( + color: Colors.white, + width: 2.0, + ), + ), + child: TabBar( + indicatorColor: Color.fromRGBO(207, 0, 15, 1), + labelColor: Color.fromRGBO(207, 0, 15, 1), + unselectedLabelColor: Colors.white, + indicatorSize: TabBarIndicatorSize.tab, + indicator: BoxDecoration( + color: Colors.white, + ), + tabs: const [ + Tab( + icon: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.edit_outlined), + SizedBox(width: 8.0), + Text('Edit'), + ], + ), + ), + Tab( + icon: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.preview_outlined), + SizedBox(width: 8.0), + Text('Preview'), + ], + ), + ), + Tab( + icon: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.menu_book_outlined), + SizedBox(width: 8.0), + Text('Latex'), + ], + ), + ) + ], + ), ), - QuestionInputDisplay(), - AddOrSubmitDisplay(), + SizedBox(height: 10.0), ], + )), + ), + body: Container( + decoration: BoxDecoration( + color: Color.fromRGBO(207, 0, 15, 1), + ), + child: Container( + margin: EdgeInsets.only(top: 10.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20.0), + topRight: Radius.circular(20.0), ), ), - SingleChildScrollView( - child: QuestionPreviewDisplay(), + child: TabBarView( + children: [ + SingleChildScrollView( + child: Column( + children: [ + ChangeSubjectDisplay(), + Text( + "* Quiz Upload supports Latex. Use \$\$ to wrap the equation. \n\t\t\tDouble space for new line. Swipe left to delete a question.", + style: + TextStyle(fontSize: 11, color: Colors.grey), + ), + QuestionInputDisplay(), + AddOrSubmitDisplay(), + ], + ), + ), + SingleChildScrollView( + child: QuestionPreviewDisplay(), + ), + SingleChildScrollView( + child: LatexSampleDisplay(), + ), + ], ), - ], + ), ), ); } diff --git a/lib/features/quiz_upload/presentation/pages/upload_success_page.dart b/lib/features/quiz_upload/presentation/pages/upload_success_page.dart index 6cd1b477..5e77beb4 100644 --- a/lib/features/quiz_upload/presentation/pages/upload_success_page.dart +++ b/lib/features/quiz_upload/presentation/pages/upload_success_page.dart @@ -30,9 +30,11 @@ class _UploadSuccessPageState extends State { ..uploadQuiz(), child: Scaffold( appBar: AppBar( + backgroundColor: Color.fromRGBO(207, 0, 15, 1), automaticallyImplyLeading: false, title: const Text('Upload Questions', - style: TextStyle(fontWeight: FontWeight.bold)), + style: + TextStyle(fontWeight: FontWeight.bold, color: Colors.white)), ), body: BlocBuilder( builder: (blocBuilderContext, state) { diff --git a/lib/features/quiz_upload/presentation/state_management/quiz_input_page/quiz_input_page_bloc.dart b/lib/features/quiz_upload/presentation/state_management/quiz_input_page/quiz_input_page_bloc.dart index 3c944b05..35a36169 100644 --- a/lib/features/quiz_upload/presentation/state_management/quiz_input_page/quiz_input_page_bloc.dart +++ b/lib/features/quiz_upload/presentation/state_management/quiz_input_page/quiz_input_page_bloc.dart @@ -70,7 +70,8 @@ class QuizInputPageBloc extends Bloc { bool _questionsNotEmpty() { for (var question in questions) { - if (!question.questionNonEmpty) return false; + if (!question.questionNonEmpty || !question.solutionNonEmpty) + return false; for (var option in question.optionsNonEmpty) { if (!option) return false; } diff --git a/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/add_or_submit_display.dart b/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/add_or_submit_display.dart index c2f4443a..9410e590 100644 --- a/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/add_or_submit_display.dart +++ b/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/add_or_submit_display.dart @@ -14,25 +14,59 @@ class AddOrSubmitDisplay extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - ElevatedButton( - onPressed: () { - context - .read() - .add(QuizInputPageAddBtnPressed()); - }, - child: const Text('Add Question'), + Container( + width: 160, + child: ElevatedButton( + onPressed: () { + context + .read() + .add(QuizInputPageAddBtnPressed()); + }, + style: ButtonStyle( + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: BorderSide( + color: const Color.fromRGBO(207, 0, 15, 1), + ), + ), + ), + backgroundColor: MaterialStateProperty.all(Colors.white), + ), + child: Text("Add Question", + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.bold, + color: const Color.fromRGBO(207, 0, 15, 1))), + ), + ), + Container( + width: 160, + child: ElevatedButton( + onPressed: () { + showDialog( + context: context, + builder: (BuildContext buildContext) { + return ConfirmSubmitQuizInputDialogue( + quizInputPageBloc: context.read()); + }); + }, + style: ButtonStyle( + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + backgroundColor: MaterialStateProperty.all( + Color.fromRGBO(207, 0, 15, 1)), + ), + child: Text("Submit Questions", + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.bold, + color: Colors.white)), + ), ), - ElevatedButton( - onPressed: () { - showDialog( - context: context, - builder: (BuildContext buildContext) { - return ConfirmSubmitQuizInputDialogue( - quizInputPageBloc: context.read()); - }); - }, - child: const Text('Submit Questions'), - ) ], ), ); diff --git a/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/change_subject_display.dart b/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/change_subject_display.dart index 87fc5b7a..a16d1c24 100644 --- a/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/change_subject_display.dart +++ b/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/change_subject_display.dart @@ -27,15 +27,21 @@ class _ChangeSubjectDisplayState extends State { children: [ Text( 'Select Subject: ', + style: TextStyle(fontWeight: FontWeight.bold), ), + SizedBox(width: 10), DropdownButton( - icon: Icon(Icons.arrow_drop_down), + alignment: Alignment.center, + icon: Icon( + Icons.arrow_drop_down, + color: Color.fromRGBO(207, 0, 15, 1), + ), iconSize: 24, elevation: 16, - style: TextStyle(color: Color.fromARGB(255, 63, 86, 169)), + style: TextStyle(color: Color.fromRGBO(207, 0, 15, 1)), underline: Container( height: 2, - color: Color.fromARGB(255, 63, 86, 169), + color: Color.fromRGBO(207, 0, 15, 1), ), value: Question.SUBJ2string( context.read().subject), diff --git a/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/confirm_cancel_quiz_input_dialogue.dart b/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/confirm_cancel_quiz_input_dialogue.dart index c99039ac..f2539de1 100644 --- a/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/confirm_cancel_quiz_input_dialogue.dart +++ b/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/confirm_cancel_quiz_input_dialogue.dart @@ -22,25 +22,36 @@ class ConfirmCancelQuizInputDisplay extends StatelessWidget { title: const Text('Cancel Quiz Input', style: TextStyle(fontWeight: FontWeight.bold)), content: const Text("Your inputs will be discared! Are you sure?"), - actions: [ - ElevatedButton( - child: const Text('Continue Quiz Input'), - onPressed: () { - context - .read() - .add(QuizInputPageCancelBackBtnPressed()); - }, - ), - ElevatedButton( - child: const Text('Go Back'), - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => (ReadyQuizPage()), - ), // ! Change to home page - ); - }, + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + ElevatedButton( + child: const Text( + 'Go Back', + style: TextStyle(color: Color.fromRGBO(207, 0, 15, 1)), + ), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => (ReadyQuizPage()), + ), // ! Change to home page + ); + }, + ), + ElevatedButton( + child: const Text( + 'Continue Quiz Input', + style: TextStyle(color: Color.fromRGBO(207, 0, 15, 1)), + ), + onPressed: () { + context + .read() + .add(QuizInputPageCancelBackBtnPressed()); + }, + ), + ], ), ], ), diff --git a/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/confirm_submit_quiz_input_dialogue.dart b/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/confirm_submit_quiz_input_dialogue.dart index 509405f3..63f14a21 100644 --- a/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/confirm_submit_quiz_input_dialogue.dart +++ b/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/confirm_submit_quiz_input_dialogue.dart @@ -16,28 +16,39 @@ class ConfirmSubmitQuizInputDialogue extends StatelessWidget { title: const Text('Submit Confirmation', style: TextStyle(fontWeight: FontWeight.bold)), content: const Text("Your questions will be submitted! Are you sure?"), - actions: [ - TextButton( - child: const Text('Submit Questions'), - onPressed: () { - Navigator.of(context).pop(); - quizInputPageBloc.add(QuizInputPageSubmitBtnPressed()); + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + TextButton( + child: const Text( + 'Go Back', + style: TextStyle(color: Color.fromRGBO(207, 0, 15, 1)), + ), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + TextButton( + child: const Text( + 'Submit Questions', + style: TextStyle(color: Color.fromRGBO(207, 0, 15, 1)), + ), + onPressed: () { + Navigator.of(context).pop(); + quizInputPageBloc.add(QuizInputPageSubmitBtnPressed()); - if (quizInputPageBloc.isSubmittable()) { - GoRouter.of(context) - .go('/quiz-upload/finished-quiz-upload', extra: { - 'questionsToUpload': quizInputPageBloc.questions, - 'subjToUpload': quizInputPageBloc.subject, - }); - quizInputPageBloc.add(QuizInputPageReset()); - } - }, - ), - TextButton( - child: const Text('Go Back'), - onPressed: () { - Navigator.of(context).pop(); - }, + if (quizInputPageBloc.isSubmittable()) { + GoRouter.of(context) + .go('/quiz-upload/finished-quiz-upload', extra: { + 'questionsToUpload': quizInputPageBloc.questions, + 'subjToUpload': quizInputPageBloc.subject, + }); + quizInputPageBloc.add(QuizInputPageReset()); + } + }, + ), + ], ), ], ); diff --git a/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/latex_sample_display.dart b/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/latex_sample_display.dart new file mode 100644 index 00000000..cb85aafd --- /dev/null +++ b/lib/features/quiz_upload/presentation/widgets/quiz_input_page_widgets/latex_sample_display.dart @@ -0,0 +1,102 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:flutter_markdown_latex/flutter_markdown_latex.dart'; +import 'package:markdown/markdown.dart' as md; + +class LatexSampleDisplay extends StatelessWidget { + const LatexSampleDisplay({super.key}); + + @override + Widget build(BuildContext context) { + String latexString = r""" +This is inline latex: $f(x) = \sum_{i=0}^{n} \frac{a_i}{1+x}$ +INLINE LATEX NEEDS TEXT BEFORE \$ \$, even a space would do too. + +This is block level latex: +$$ +c = \pm\sqrt{a^2 + b^2} +$$ + +This is inline latex with displayMode: $$f(x) = \sum_{i=0}^{n} \frac{a_i}{1+x}$$ + +The relationship between the height and the side length of an equilateral triangle is: + +\[ \text{Height} = \frac{\sqrt{3}}{2} \times \text{Side Length} \] + +\[ \text{X} = \frac{1}{2} \times \text{Y} \times \text{Z} = \frac{1}{2} \times 9 \times \frac{\sqrt{3}}{2} \times 9 = \frac{81\sqrt{3}}{4} \] + +The basic form of the Taylor series is: + +\[f(x) = f(a) + f'(a)(x-a) + \frac{f''(a)}{2!}(x-a)^2 + \frac{f'''(a)}{3!}(x-a)^3 + \cdots\] + +where \(f(x)\) is the function to be expanded, \(a\) is the expansion point, \(f'(a)\), \(f''(a)\), \(f'''(a)\), etc., are the first, second, third, and so on derivatives of the function at point \(a\), and \(n!\) denotes the factorial of \(n\). +"""; + return Center( + child: Column( + children: [ + Container( + margin: const EdgeInsets.all(10), + decoration: BoxDecoration( + border: Border.all( + color: const Color.fromRGBO( + 207, 0, 15, 1), // Set your desired color here + width: 2.0, // Set your desired width here + ), + ), + padding: const EdgeInsets.all(15), + child: Text(latexString), + ), + Container( + margin: const EdgeInsets.all(10), + decoration: BoxDecoration( + border: Border.all( + color: const Color.fromRGBO( + 207, 0, 15, 1), // Set your desired color here + width: 2.0, // Set your desired width here + ), + ), + padding: const EdgeInsets.all(15), + child: TextMarkdown(text: latexString), + ) + ], + )); + } +} + +class TextMarkdown extends StatelessWidget { + const TextMarkdown({ + super.key, + required this.text, + }); + + final String text; + + @override + Widget build(BuildContext context) { + return Markdown( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + data: text, + builders: { + 'latex': LatexElementBuilder( + textScaleFactor: 1.2, + textStyle: const TextStyle( + fontSize: 15.0, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + }, + styleSheet: MarkdownStyleSheet( + textAlign: WrapAlignment.center, + p: const TextStyle(fontSize: 17.0, fontWeight: FontWeight.bold), + ), + extensionSet: md.ExtensionSet( + [LatexBlockSyntax()], + [LatexInlineSyntax()], + ), + ); + } +} diff --git a/lib/features/quiz_upload/presentation/widgets/quiz_input_widgets/question_input_card_display.dart b/lib/features/quiz_upload/presentation/widgets/quiz_input_widgets/question_input_card_display.dart index 169e52f0..1be52245 100644 --- a/lib/features/quiz_upload/presentation/widgets/quiz_input_widgets/question_input_card_display.dart +++ b/lib/features/quiz_upload/presentation/widgets/quiz_input_widgets/question_input_card_display.dart @@ -30,6 +30,7 @@ class _QuestionInputCardState extends State { TextEditingController(text: questionCubit.solution); return Card( + elevation: 0, child: FormBuilder( child: Column( children: [ @@ -43,10 +44,10 @@ class _QuestionInputCardState extends State { borderSide: BorderSide( color: quizInputPageBloc.revealBlanks ? questionCubit.questionNonEmpty - ? Color.fromARGB(255, 178, 178, 178) - : Colors.red - : Color.fromARGB(255, 178, 178, 178), - width: 1), + ? Color.fromRGBO(207, 0, 15, 1) + : Color.fromRGBO(176, 38, 38, 1) + : Color.fromRGBO(207, 0, 15, 1), + width: 3), ), hintText: "Enter the question here", filled: true, @@ -93,9 +94,9 @@ class _QuestionInputCardState extends State { borderSide: BorderSide( color: quizInputPageBloc.revealBlanks ? questionCubit.solutionNonEmpty - ? Color.fromARGB(255, 178, 178, 178) + ? Color.fromRGBO(207, 0, 15, 1) : Colors.red - : Color.fromARGB(255, 178, 178, 178), + : Color.fromRGBO(207, 0, 15, 1), width: 1), ), hintText: "Enter the solution here", @@ -111,6 +112,10 @@ class _QuestionInputCardState extends State { }, ), ), + Divider( + color: Color.fromRGBO(207, 0, 15, 1), + thickness: 1.5, + ), ], ), ), @@ -159,7 +164,7 @@ class _QuestionInputOptionsState extends State { borderSide: BorderSide( color: revealBlank ? Colors.red - : Color.fromARGB(255, 178, 178, 178), + : Color.fromRGBO(207, 0, 15, 1), width: 1), ), hintText: "Enter one of the options here", @@ -187,7 +192,7 @@ class _QuestionInputOptionsState extends State { icon: Icon(Icons.check_circle_outline_rounded), color: optionIndex.toString() == questionCubit.answerIndex ? Colors.green - : Color.fromARGB(255, 108, 108, 108), + : Color.fromRGBO(207, 0, 15, 1), onPressed: () { questionCubit.refresh(); questionCubit.answerIndex = optionIndex.toString(); diff --git a/lib/features/quiz_upload/presentation/widgets/quiz_input_widgets/question_input_display.dart b/lib/features/quiz_upload/presentation/widgets/quiz_input_widgets/question_input_display.dart index 0f331244..f984e85b 100644 --- a/lib/features/quiz_upload/presentation/widgets/quiz_input_widgets/question_input_display.dart +++ b/lib/features/quiz_upload/presentation/widgets/quiz_input_widgets/question_input_display.dart @@ -22,27 +22,31 @@ class _QuestionInputDisplayState extends State { shrinkWrap: true, itemCount: buildContext.read().questions.length, itemBuilder: (_, index) { - return Dismissible( - background: Container( - color: Colors.white, - alignment: Alignment.centerRight, - padding: EdgeInsets.only(right: 20.0), - margin: EdgeInsets.only(bottom: 10.0), - child: Icon(Icons.delete), + return Container( + margin: EdgeInsets.only(left: 7.0, right: 7.0), + child: Dismissible( + background: Container( + color: Colors.white, + alignment: Alignment.centerRight, + padding: EdgeInsets.only(right: 20.0), + margin: EdgeInsets.only(bottom: 10.0), + child: Icon(Icons.delete), + ), + direction: DismissDirection.endToStart, + key: UniqueKey(), + child: QuestionInputCard( + questionCubit: + buildContext.read().questions[index]), + onDismissed: (_) { + buildContext.read().add( + QuizInputPageDeleteBtnPressed( + questionCubit: buildContext + .read() + .questions[index], + ), + ); + }, ), - direction: DismissDirection.endToStart, - key: UniqueKey(), - child: QuestionInputCard( - questionCubit: - buildContext.read().questions[index]), - onDismissed: (_) { - buildContext.read().add( - QuizInputPageDeleteBtnPressed( - questionCubit: - buildContext.read().questions[index], - ), - ); - }, ); }, ); diff --git a/lib/features/quiz_upload/presentation/widgets/quiz_input_widgets/question_preview_card_display.dart b/lib/features/quiz_upload/presentation/widgets/quiz_input_widgets/question_preview_card_display.dart index 502e2ef6..afbeb75d 100644 --- a/lib/features/quiz_upload/presentation/widgets/quiz_input_widgets/question_preview_card_display.dart +++ b/lib/features/quiz_upload/presentation/widgets/quiz_input_widgets/question_preview_card_display.dart @@ -16,6 +16,7 @@ class QuestionPreviewCardDisplay extends StatelessWidget { int correctIndex = int.parse(questionCubit.answerIndex); return Card( + elevation: 0, margin: EdgeInsets.all(10.0), child: Column( children: [ @@ -38,6 +39,10 @@ class QuestionPreviewCardDisplay extends StatelessWidget { // Solution TextContainer(text: questionCubit.solution), + Divider( + color: Color.fromRGBO(207, 0, 15, 1), + thickness: 1.5, + ), ], ), ); @@ -57,7 +62,7 @@ class TextContainer extends StatelessWidget { return Container( decoration: BoxDecoration( border: Border.all( - color: Color.fromARGB(255, 178, 178, 178), + color: Color.fromRGBO(207, 0, 15, 1), ), borderRadius: BorderRadius.circular(10.0)), constraints: BoxConstraints( @@ -84,8 +89,7 @@ class OptionContainer extends StatelessWidget { return Container( decoration: BoxDecoration( border: Border.all( - color: - isCorrect ? Colors.green : Color.fromARGB(255, 178, 178, 178), + color: isCorrect ? Colors.green : Color.fromRGBO(207, 0, 15, 1), ), borderRadius: BorderRadius.circular(10.0)), margin: EdgeInsets.all(2.0), diff --git a/lib/features/quiz_upload/presentation/widgets/upload_quiz_widgets/upload_complete_display.dart b/lib/features/quiz_upload/presentation/widgets/upload_quiz_widgets/upload_complete_display.dart index da5e9e41..38937991 100644 --- a/lib/features/quiz_upload/presentation/widgets/upload_quiz_widgets/upload_complete_display.dart +++ b/lib/features/quiz_upload/presentation/widgets/upload_quiz_widgets/upload_complete_display.dart @@ -12,21 +12,60 @@ class UploadCompleteDisplay extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text("Upload Success!"), + Text( + "Upload Success!", + style: TextStyle( + fontSize: 20, + color: Color.fromRGBO(207, 0, 15, 1), + fontWeight: FontWeight.bold, + ), + ), // Todo: Show results / Show all questions uploaded by user - - ElevatedButton( + Container( + width: 180, + child: ElevatedButton( onPressed: () { GoRouter.of(context).go('/quiz-upload'); }, - child: Text("Add more questions")), - - ElevatedButton( + style: ButtonStyle( + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + backgroundColor: MaterialStateProperty.all( + Color.fromRGBO(207, 0, 15, 1)), + ), + child: Text("Add more questions", + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.bold, + color: Colors.white)), + ), + ), + Container( + width: 180, + child: ElevatedButton( onPressed: () { GoRouter.of(context).go('/quiz-mode'); }, - child: Text("Take a quiz now!")) + style: ButtonStyle( + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + backgroundColor: MaterialStateProperty.all( + Color.fromRGBO(207, 0, 15, 1)), + ), + child: Text("Take a quiz now!", + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.bold, + color: Colors.white)), + ), + ), ], )); } diff --git a/lib/router/scaffold_with_nav_bar.dart b/lib/router/scaffold_with_nav_bar.dart index f506810d..2ae3e92f 100644 --- a/lib/router/scaffold_with_nav_bar.dart +++ b/lib/router/scaffold_with_nav_bar.dart @@ -39,32 +39,57 @@ class ScaffoldWithNavBar extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( body: navigationShell, - bottomNavigationBar: NavigationBar( - selectedIndex: navigationShell.currentIndex, - destinations: const [ - // TODO: [P2] Provive an animation for the icons. - // NavigationDestination( - // icon: Icon(Icons.home_outlined), - // selectedIcon: Icon(Icons.home), - // label: 'Home', - // ), - NavigationDestination( - icon: Icon(Icons.school_outlined), - selectedIcon: Icon(Icons.school), - label: 'Quiz Mode', - ), - NavigationDestination( - icon: Icon(Icons.upload_file_outlined), - selectedIcon: Icon(Icons.upload_file), - label: 'Quiz Upload', - ), - NavigationDestination( - icon: Icon(Icons.person_outline_outlined), - selectedIcon: Icon(Icons.person), - label: 'Profile', - ), - ], - onDestinationSelected: (int index) => _onTap(context, index), + bottomNavigationBar: Container( + height: 60, + decoration: const BoxDecoration( + color: Color.fromARGB(0, 0, 0, 0), + ), + child: NavigationBar( + elevation: 0, + selectedIndex: navigationShell.currentIndex, + destinations: const [ + // TODO: [P2] Provive an animation for the icons. + // NavigationDestination( + // icon: Icon(Icons.home_outlined), + // selectedIcon: Icon(Icons.home), + // label: 'Home', + // ), + NavigationDestination( + icon: Icon( + Icons.school_outlined, + color: Color.fromRGBO(207, 0, 15, 1), + ), + selectedIcon: Icon( + Icons.school, + color: Color.fromRGBO(139, 0, 9, 1), + ), + label: 'Quiz Mode', + ), + NavigationDestination( + icon: Icon( + Icons.upload_file_outlined, + color: Color.fromRGBO(207, 0, 15, 1), + ), + selectedIcon: Icon( + Icons.upload_file, + color: Color.fromRGBO(139, 0, 15, 1), + ), + label: 'Quiz Upload', + ), + NavigationDestination( + icon: Icon( + Icons.person_outline_outlined, + color: Color.fromRGBO(207, 0, 15, 1), + ), + selectedIcon: Icon( + Icons.person, + color: Color.fromRGBO(139, 0, 15, 1), + ), + label: 'Profile', + ), + ], + onDestinationSelected: (int index) => _onTap(context, index), + ), ), ); } diff --git a/pubspec.lock b/pubspec.lock index 0878b225..3e547a33 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -471,18 +471,18 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: "04c4722cc36ec5af38acc38ece70d22d3c2123c61305d555750a091517bbe504" + sha256: "9921f9deda326f8a885e202b1e35237eadfc1345239a0f6f0f1ff287e047547f" url: "https://pub.dev" source: hosted - version: "0.6.23" + version: "0.7.1" flutter_markdown_latex: dependency: "direct main" description: name: flutter_markdown_latex - sha256: "080729dd4984e294e4d2b12a346328faaea23b9f96c3d5cf85d2361ca844f978" + sha256: b07ade84e661a7a2e7b7e59bcfa95e481d38fd8782a8f9f2349a8cb1b056ae89 url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.3.2" flutter_math_fork: dependency: transitive description: @@ -503,10 +503,10 @@ packages: dependency: "direct main" description: name: flutter_quill - sha256: c37ab7bd479daa7b20ef281b528d8eea10a2c4f149edb1f94acdbc41af0fbaf3 + sha256: "51d5a9d2eef893875fa2dc29ea5be9ec07e03255fee9bacd5b4b329fa871d9a5" url: "https://pub.dev" source: hosted - version: "9.3.7" + version: "9.3.9" flutter_slidable: dependency: "direct main" description: @@ -585,10 +585,10 @@ packages: dependency: "direct main" description: name: google_fonts - sha256: b1ac0fe2832c9cc95e5e88b57d627c5e68c223b9657f4b96e1487aa9098c7b82 + sha256: "5b1726fee554d1cc9db1baef8061b126567ff0a1140a03ed7de936e62f2ab98b" url: "https://pub.dev" source: hosted - version: "6.2.1" + version: "6.2.0" html: dependency: transitive description: @@ -1348,4 +1348,4 @@ packages: version: "3.1.2" sdks: dart: ">=3.3.0 <4.0.0" - flutter: ">=3.19.2" + flutter: ">=3.19.0" diff --git a/pubspec.yaml b/pubspec.yaml index b4aaf63c..f968f1bd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -113,11 +113,11 @@ dependencies: # A rich text editor built for the modern Android, iOS, web and desktop platforms. # It is the WYSIWYG editor and a Quill component for Flutter. - flutter_quill: ^9.3.1 + flutter_quill: ^9.3.9 # A Markdown renderer for Flutter. Create rich text output, including text styles, # tables, links, and more, from plain text data formatted with simple Markdown tags. - flutter_markdown: ^0.6.19 + flutter_markdown: ^0.7.1 # Functional programming in Dart and Flutter. All the main functional programming # types and patterns fully documented, tested, and with examples. @@ -135,10 +135,10 @@ dependencies: url_launcher: ^6.2.4 # A extension to render LaTeX in markdown for package flutter_markdown. - flutter_markdown_latex: ^0.2.0 + flutter_markdown_latex: ^0.3.2 # A portable Markdown library written in Dart that can parse Markdown into HTML. - markdown: ^7.2.1 + markdown: ^7.2.2 intl: ^0.18.1 dev_dependencies: