diff --git a/README.md b/README.md index 20444fa..f59ac0d 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ -# academico_mobile +# Acadêmico Mobile -Link do Figma: https://www.figma.com/file/tFLY9uOoiAXYoHrqj7uHiI/Untitled?node-id=0%3A1&t=LloEngcQkWGb6Bna-1 - Atividade 01: - [ ] Instalar Assets (Imagens e Fonts) - [ ] ThemeData @@ -10,7 +8,5 @@ Atividade 01: - [ ] Preparando Extensions de UI - [ ] Dotenv - [ ] RestClient - Dio - - - [ ] senha: cddbdabqeujfjluo - - [ ] lembrar do delay na requisição de 2s. + ======= \ No newline at end of file diff --git a/assets/images/background/back.png b/assets/images/background/back.png new file mode 100644 index 0000000..4997b89 Binary files /dev/null and b/assets/images/background/back.png differ diff --git a/assets/images/images_cards/documentation.png b/assets/images/images_cards/documentation.png new file mode 100644 index 0000000..127e809 Binary files /dev/null and b/assets/images/images_cards/documentation.png differ diff --git a/assets/images/images_cards/education.png b/assets/images/images_cards/education.png new file mode 100644 index 0000000..5c7b797 Binary files /dev/null and b/assets/images/images_cards/education.png differ diff --git a/assets/images/images_cards/student.png b/assets/images/images_cards/student.png new file mode 100644 index 0000000..adf9dec Binary files /dev/null and b/assets/images/images_cards/student.png differ diff --git a/assets/images/readme/229shots_so.png b/assets/images/readme/229shots_so.png new file mode 100644 index 0000000..0889dfc Binary files /dev/null and b/assets/images/readme/229shots_so.png differ diff --git a/assets/images/readme/243shots_so.png b/assets/images/readme/243shots_so.png new file mode 100644 index 0000000..00902e3 Binary files /dev/null and b/assets/images/readme/243shots_so.png differ diff --git a/assets/images/readme/903shots_so.png b/assets/images/readme/903shots_so.png new file mode 100644 index 0000000..b3790d6 Binary files /dev/null and b/assets/images/readme/903shots_so.png differ diff --git a/assets/images/readme/942shots_so.png b/assets/images/readme/942shots_so.png new file mode 100644 index 0000000..0f05b76 Binary files /dev/null and b/assets/images/readme/942shots_so.png differ diff --git a/assets/images/readme/944shots_so.png b/assets/images/readme/944shots_so.png new file mode 100644 index 0000000..9c45aff Binary files /dev/null and b/assets/images/readme/944shots_so.png differ diff --git a/lib/academico_mobile.dart b/lib/academico_mobile.dart index c481b34..72975ef 100644 --- a/lib/academico_mobile.dart +++ b/lib/academico_mobile.dart @@ -1,10 +1,13 @@ import 'package:academico_mobile/app/core/provider/application_binding.dart'; import 'package:academico_mobile/app/core/ui/theme/theme_config.dart'; +import 'package:academico_mobile/app/pages/about/about_page.dart'; import 'package:academico_mobile/app/pages/daily/daily_router.dart'; import 'package:academico_mobile/app/pages/home/home_router.dart'; import 'package:academico_mobile/app/pages/login/login_router.dart'; import 'package:academico_mobile/app/pages/recover_password/recover_password_page.dart'; +import 'package:academico_mobile/app/pages/request_documents/request_documents_page.dart'; import 'package:academico_mobile/app/pages/schedule/schedule_router.dart'; +import 'package:academico_mobile/app/pages/school_records/school_records_page.dart'; import 'package:academico_mobile/app/pages/splash/splash_page.dart'; import 'package:flutter/material.dart'; @@ -25,6 +28,9 @@ class AcademicoMobile extends StatelessWidget { '/daily': (context) => DailyRouter.page, '/home': (context) => HomeRouter.page, '/recover-password': (context) => const RecoverPasswordPage(), + '/school_records': (context) => const SchoolRecordsPage(), + '/request_documents': (context) => const RequestDocumentsPage(), + '/about': (context) => const AboutPage(), }, ), ); diff --git a/lib/app/core/rest_client/custom_dio.dart b/lib/app/core/rest_client/custom_dio.dart index 5890948..4473f28 100644 --- a/lib/app/core/rest_client/custom_dio.dart +++ b/lib/app/core/rest_client/custom_dio.dart @@ -22,8 +22,4 @@ class CustomDio extends DioForNative { CustomDio auth() { return this; } - - CustomDio unauth() { - return this; - } } diff --git a/lib/app/core/rest_client/custom_webview.dart b/lib/app/core/rest_client/custom_webview.dart deleted file mode 100644 index 548c1d5..0000000 --- a/lib/app/core/rest_client/custom_webview.dart +++ /dev/null @@ -1,18 +0,0 @@ -// import 'package:webview_flutter/webview_flutter.dart'; - -// class CustomWebview extends WebViewController { -// CustomWebview({ -// WebViewController? controller, -// }) : super() { -// controller = this; -// setJavaScriptMode(JavaScriptMode.unrestricted); -// } - -// CustomWebview auth() { -// return this; -// } - -// CustomWebview unauth() { -// return this; -// } -// } diff --git a/lib/app/core/ui/styles/colors_app.dart b/lib/app/core/ui/styles/colors_app.dart index 062062f..9048fc7 100644 --- a/lib/app/core/ui/styles/colors_app.dart +++ b/lib/app/core/ui/styles/colors_app.dart @@ -20,6 +20,9 @@ class ColorsApp { Color get primary => const Color(0xFF0D47A1); Color get secondary => const Color(0xFFFFC107); + Color get manha => const Color(0xFF3C6E71); + Color get tarde => const Color(0xFF2F3061); + Color get switchbackground => const Color(0xFF282827); Color get labelblack1 => const Color(0xFF1E1E1E); diff --git a/lib/app/core/ui/widgets/my_appbar.dart b/lib/app/core/ui/widgets/my_appbar.dart index d900ed4..33b191c 100644 --- a/lib/app/core/ui/widgets/my_appbar.dart +++ b/lib/app/core/ui/widgets/my_appbar.dart @@ -38,10 +38,7 @@ class MyAppbar extends AppBar { required final VoidCallback onPressed, }) : super( elevation: elevation, - title: Text( - title, - style: TextStyles.instance.labelPage - ), + title: Text(title, style: TextStyles.instance.labelPage), centerTitle: true, backgroundColor: ColorsApp.instance.background, leading: IconButton( @@ -56,12 +53,21 @@ class MyAppbar extends AppBar { required String title, String subtitle = '', IconData icon = Icons.arrow_back_ios, + required final VoidCallback onPressed, }) : super( elevation: elevation, title: Text(title, style: TextStyles.instance.labelPage), centerTitle: true, backgroundColor: ColorsApp.instance.background, automaticallyImplyLeading: false, + leading: IconButton( + icon: const Icon( + Icons.menu_rounded, + color: Colors.white, + size: 35, + ), + onPressed: onPressed, + ), actions: [ BlocConsumer( listener: (context, state) {}, diff --git a/lib/app/pages/about/about_page.dart b/lib/app/pages/about/about_page.dart new file mode 100644 index 0000000..a02b0c9 --- /dev/null +++ b/lib/app/pages/about/about_page.dart @@ -0,0 +1,98 @@ +import 'package:academico_mobile/app/core/ui/helpers/size_extensions.dart'; +import 'package:academico_mobile/app/core/ui/styles/colors_app.dart'; +import 'package:academico_mobile/app/core/ui/styles/text_styles.dart'; +import 'package:academico_mobile/app/pages/about/widgets/tile_about.dart'; +import 'package:flutter/material.dart'; + +class AboutPage extends StatelessWidget { + const AboutPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF1C1C1C), + appBar: AppBar( + backgroundColor: const Color(0xFF1C1C1C), + elevation: 0, + title: Text( + 'Sobre', + style: context.textStyles.texLabelH1.copyWith( + color: context.colorsApp.cardwhite, + fontSize: context.percentHeight(.03), + ), + ), + centerTitle: true, + ), + body: Column( + children: [ + Container( + color: const Color(0xFF1C1C1C), + width: double.infinity, + child: Column( + children: [ + Image.asset( + 'assets/images/logos/logo_academico.png', + height: context.percentHeight(.2), + ), + Text( + 'Acadêmico Mobile', + style: context.textStyles.texLabelH1.copyWith( + color: context.colorsApp.cardwhite, + fontSize: context.percentHeight(.03), + ), + ), + Text('Versão 1.0.0', + style: context.textStyles.texLabelH4.copyWith( + color: context.colorsApp.cardwhite, + )), + ], + ), + ), + SizedBox(height: context.percentHeight(.05)), + Expanded( + child: SingleChildScrollView( + padding: + EdgeInsets.symmetric(horizontal: context.percentWidth(.08)), + child: Column( + children: const [ + TileAbout( + text: + 'Descrição do aplicativo: Forneça uma breve descrição do aplicativo, explicando sua finalidade e recursos principais.', + ), + TileAbout( + text: + 'Desenvolvedores ou equipe: Liste os nomes ou informações sobre a equipe de desenvolvimento do aplicativo.', + ), + TileAbout( + text: + 'Informações de contato: Se desejar, forneça informações de contato, como um endereço de e-mail ou site, para que os usuários possam entrar em contato com a equipe de suporte ou fornecer feedback.', + ), + TileAbout( + text: + 'Licenças e créditos: Se o seu aplicativo usar bibliotecas de terceiros ou recursos de código aberto, mencione as licenças relevantes e dê crédito aos autores originais.', + ), + TileAbout( + text: + 'Outras informações: Dependendo do aplicativo, você pode incluir outras informações relevantes, como links para perfis de mídia social, link para avaliação do aplicativo na loja, etc.', + ), + ], + ), + ), + ), + Container( + padding: EdgeInsets.all(context.percentHeight(.03)), + alignment: Alignment.center, + child: Text( + 'Obrigado', + style: TextStyle( + color: context.colorsApp.cardwhite, + fontSize: context.percentHeight(.02), + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/app/pages/about/widgets/tile_about.dart b/lib/app/pages/about/widgets/tile_about.dart new file mode 100644 index 0000000..7134fe4 --- /dev/null +++ b/lib/app/pages/about/widgets/tile_about.dart @@ -0,0 +1,31 @@ +import 'package:academico_mobile/app/core/ui/helpers/size_extensions.dart'; +import 'package:academico_mobile/app/core/ui/styles/colors_app.dart'; +import 'package:academico_mobile/app/core/ui/styles/text_styles.dart'; +import 'package:flutter/material.dart'; + +class TileAbout extends StatefulWidget { + final String text; + + const TileAbout({Key? key, required this.text}) : super(key: key); + + @override + State createState() => _TileAboutState(); +} + +class _TileAboutState extends State { + @override + Widget build(BuildContext context) { + return Column( + children: [ + Text( + widget.text, + textAlign: TextAlign.justify, + style: context.textStyles.texLabelH4.copyWith( + color: context.colorsApp.cardwhite, + ), + ), + SizedBox(height: context.percentHeight(.03)), + ], + ); + } +} diff --git a/lib/app/pages/daily/daily_controller.dart b/lib/app/pages/daily/daily_controller.dart index c30ac86..27aae3d 100644 --- a/lib/app/pages/daily/daily_controller.dart +++ b/lib/app/pages/daily/daily_controller.dart @@ -33,21 +33,19 @@ class DailyController extends Cubit { void changeIsNow() async { emit(state.copyWith(status: DailyStateSatus.loading)); await Future.delayed( - const Duration(seconds: 2), + const Duration(milliseconds: 700), ); emit( state.copyWith( status: DailyStateSatus.loaded, isNow: !state.isNow, - ), ); } Future selectedDay(int index) async { emit(state.copyWith(status: DailyStateSatus.loading)); - await Future.delayed(const Duration(seconds: 1)); + await Future.delayed(const Duration(milliseconds: 700)); emit(state.copyWith(status: DailyStateSatus.loaded, selected: index)); } - } diff --git a/lib/app/pages/daily/daily_page.dart b/lib/app/pages/daily/daily_page.dart index 2907298..5340917 100644 --- a/lib/app/pages/daily/daily_page.dart +++ b/lib/app/pages/daily/daily_page.dart @@ -24,9 +24,7 @@ class _DailyPageState extends BaseState { @override void onReady() async { await controller.loadSemestre(); - if (controller.state.isNow) { - list = controller.state.semestres[0].disciplinas; - } + list = controller.state.semestres[0].disciplinas; } @override @@ -125,10 +123,12 @@ class _DailyPageState extends BaseState { loaded: () => true, ), builder: (context, state) { - if (state.isNow) { - list = state.semestres[0].disciplinas; - } else { - list = state.semestres[state.selected].disciplinas; + if (state.isNow && state.semestres.isNotEmpty) { + list = controller.state.semestres[0].disciplinas; + } + if (!state.isNow && state.semestres.isNotEmpty) { + list = + controller.state.semestres[state.selected].disciplinas; } return Expanded( child: ListView.builder( diff --git a/lib/app/pages/daily/widgets/lista_card_disciplina.dart b/lib/app/pages/daily/widgets/lista_card_disciplina.dart index 042bc83..2bc0631 100644 --- a/lib/app/pages/daily/widgets/lista_card_disciplina.dart +++ b/lib/app/pages/daily/widgets/lista_card_disciplina.dart @@ -20,6 +20,9 @@ class ListaCardDisciplina extends StatelessWidget { return InkWell( splashColor: ColorsApp.instance.background, onTap: () { + if (disciplina.avaliacoes.isEmpty) { + disciplina.avaliacoes.addAll(['99', '99', '99', '99', '99']); + } Navigator.of(context).push( MaterialPageRoute( builder: (context) => DashboardPage( @@ -47,7 +50,7 @@ class ListaCardDisciplina extends StatelessWidget { Container( padding: EdgeInsets.all(context.screenHeight * 0.005), decoration: BoxDecoration( - color: ColorsApp.instance.cardblue, + color: ColorsApp.instance.primary, borderRadius: BorderRadius.circular(5), ), child: Text( diff --git a/lib/app/pages/dashbord_daily/dashboard_page.dart b/lib/app/pages/dashbord_daily/dashboard_page.dart index 892a810..7c64402 100644 --- a/lib/app/pages/dashbord_daily/dashboard_page.dart +++ b/lib/app/pages/dashbord_daily/dashboard_page.dart @@ -68,17 +68,6 @@ class _DashboardPageState extends State { label: 'Carga Horária Total', value: '${widget.disciplina.resumo.cargaHoraria}H', ), - // Row( - // children: [ - // Text( - // 'Existem 6 aulas planejadas a mais que as necessárias.', - // style: TextStyles.instance.texLabelH5.copyWith( - // color: ColorsApp.instance.cardgrey, - // fontWeight: TextStyles.instance.textSemiBold.fontWeight, - // ), - // ), - // ], - // ), CardHorario( label: 'Você ainda pode ter', value: '${widget.disciplina.resumo.faltas} falta(s)', diff --git a/lib/app/pages/dashbord_daily/widgets/line_notas.dart b/lib/app/pages/dashbord_daily/widgets/line_notas.dart index c563f48..7fdea62 100644 --- a/lib/app/pages/dashbord_daily/widgets/line_notas.dart +++ b/lib/app/pages/dashbord_daily/widgets/line_notas.dart @@ -31,13 +31,27 @@ class LineNotas extends StatelessWidget { ), Padding( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 7), - child: Text( - value, - style: TextStyles.instance.texLabelH4.copyWith( - color: ColorsApp.instance.cardwhite, - fontWeight: TextStyles.instance.textSemiBold.fontWeight, - ), - ), + child: value == '99' + ? Container( + decoration: BoxDecoration( + color: ColorsApp.instance.cardnoselected, + borderRadius: BorderRadius.circular(5), + ), + child: Text( + 'N/A', + style: TextStyles.instance.texLabelH4.copyWith( + color: ColorsApp.instance.cardwhite, + fontWeight: + TextStyles.instance.textSemiBold.fontWeight, + ), + )) + : Text( + value, + style: TextStyles.instance.texLabelH4.copyWith( + color: ColorsApp.instance.cardwhite, + fontWeight: TextStyles.instance.textSemiBold.fontWeight, + ), + ), ), ], ), diff --git a/lib/app/pages/home/home_controller.dart b/lib/app/pages/home/home_controller.dart index f1f6714..9c9f092 100644 --- a/lib/app/pages/home/home_controller.dart +++ b/lib/app/pages/home/home_controller.dart @@ -25,4 +25,17 @@ class HomeController extends Cubit { } } + Future logout() async { + emit(state.copyWith(status: HomeStateStatus.loading)); + try { + await Future.delayed(const Duration(seconds: 2)); + emit(state.copyWith(status: HomeStateStatus.loaded)); + } catch (e, s) { + log('Error ao realizar logout', error: e, stackTrace: s); + emit(state.copyWith( + status: HomeStateStatus.error, + isOn: true, + errorMessage: 'Error ao realizar logout')); + } + } } diff --git a/lib/app/pages/home/home_page.dart b/lib/app/pages/home/home_page.dart index cffbc66..a25b05b 100644 --- a/lib/app/pages/home/home_page.dart +++ b/lib/app/pages/home/home_page.dart @@ -1,5 +1,6 @@ import 'package:academico_mobile/app/core/ui/base_state/base_state.dart'; import 'package:academico_mobile/app/core/ui/helpers/size_extensions.dart'; +import 'package:academico_mobile/app/core/ui/styles/colors_app.dart'; import 'package:academico_mobile/app/core/ui/widgets/my_appbar.dart'; import 'package:academico_mobile/app/pages/home/home_controller.dart'; import 'package:academico_mobile/app/pages/home/home_state.dart'; @@ -15,17 +16,154 @@ class HomePage extends StatefulWidget { } class _HomePageState extends BaseState { + final GlobalKey _scaffoldKey = GlobalKey(); + @override void onReady() { super.onReady(); controller.loadHomePage(); } + void openDrawer() { + _scaffoldKey.currentState?.openDrawer(); + } + + Widget buildDrawer(BuildContext context) => Drawer( + backgroundColor: context.colorsApp.background, + child: Column( + children: [ + buildHeaderDrawer(context), + Divider(color: Colors.grey[300], height: 1), + Expanded( + child: buildMenuItems(context), + ), + finishDrawer(context), + ], + ), + ); + + Widget finishDrawer(BuildContext context) => InkWell( + onTap: () async { + await controller.logout().then((value) { + Navigator.of(context).pop(); + }); + }, + child: Container( + padding: EdgeInsets.only( + bottom: context.percentWidth(.03), + ), + alignment: Alignment.bottomCenter, + child: Container( + margin: EdgeInsets.symmetric( + horizontal: context.percentWidth(.05), + ), + padding: EdgeInsets.symmetric( + horizontal: context.percentWidth(.05), + vertical: context.percentWidth(.03), + ), + decoration: BoxDecoration( + color: Colors.redAccent, + borderRadius: BorderRadius.circular(10), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Icon( + Icons.logout, + color: Colors.white, + ), + SizedBox(width: 30), + Text( + 'Sair', + style: TextStyle( + fontSize: 20, + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ), + ); + + Widget buildHeaderDrawer(BuildContext context) => Container( + color: context.colorsApp.background, + padding: EdgeInsets.only( + top: 24 + MediaQuery.of(context).padding.top, bottom: 24), + child: Column( + children: const [ + CircleAvatar( + radius: 50, + backgroundImage: + AssetImage('assets/images/images_cards/student.png'), + ), + SizedBox(height: 10), + Text( + 'Academico Mobile', + style: TextStyle(fontSize: 20, color: Colors.white), + ), + SizedBox(height: 4), + Text( + 'Nome do Aluno IFCE', + style: TextStyle( + fontSize: 15, + color: Colors.white70, + ), + ), + ], + ), + ); + + Widget buildMenuItems(BuildContext context) => ListView( + shrinkWrap: true, + children: [ + ListTile( + title: const Text( + 'Sobre', + style: TextStyle( + fontSize: 20, + color: Colors.grey, + ), + ), + leading: const Icon( + Icons.info_outline_rounded, + size: 30, + color: Colors.grey, + ), + onTap: () => Navigator.of(context).pushNamed('/about'), + ), + // ListTile( + // title: const Text( + // 'Contato', + // style: TextStyle( + // fontSize: 20, + // color: Colors.grey, + // ), + // ), + // leading: const Icon( + // Icons.comment_sharp, + // size: 30, + // color: Colors.grey, + // ), + // onTap: () => Navigator.of(context).pop(), + // ), + ], + ); + @override Widget build(BuildContext context) { return Scaffold( + key: _scaffoldKey, appBar: MyAppbar.home( title: 'Academico Mobile', + onPressed: () { + openDrawer(); + }, + ), + drawer: Drawer( + backgroundColor: context.colorsApp.background, + child: buildDrawer(context), ), body: BlocConsumer( listener: (context, state) { @@ -46,6 +184,9 @@ class _HomePageState extends BaseState { builder: (context, state) { return Column( children: [ + SizedBox( + height: context.percentHeight(.02), + ), Expanded( child: GridView.builder( padding: const EdgeInsets.symmetric(horizontal: 20), diff --git a/lib/app/pages/home/widgets/card_home.dart b/lib/app/pages/home/widgets/card_home.dart index 8f18b5e..7fc07e7 100644 --- a/lib/app/pages/home/widgets/card_home.dart +++ b/lib/app/pages/home/widgets/card_home.dart @@ -44,6 +44,7 @@ class CardHome extends StatelessWidget { ), Text( listaCards.name, + textAlign: TextAlign.center, style: TextStyles.instance.texLabelH4.copyWith( fontSize: context.screenWidth * 0.045, color: ColorsApp.instance.cardwhite, diff --git a/lib/app/pages/login/login_page.dart b/lib/app/pages/login/login_page.dart index 60ff3c2..809caa8 100644 --- a/lib/app/pages/login/login_page.dart +++ b/lib/app/pages/login/login_page.dart @@ -23,6 +23,7 @@ class _LoginPageState extends BaseState { TextEditingController matriculaEC = TextEditingController(); TextEditingController passwordEC = TextEditingController(); bool _obscuredText = true; + bool check = false; @override void dispose() { @@ -33,6 +34,12 @@ class _LoginPageState extends BaseState { @override Widget build(BuildContext context) { + void toogleCheck() { + setState(() { + check = !check; + }); + } + return BlocListener( listener: (context, state) { state.status.matchAny( @@ -77,8 +84,11 @@ class _LoginPageState extends BaseState { ), TextFormField( controller: matriculaEC, - validator: - Validatorless.required('Matricula Obrigatória'), + validator: Validatorless.multiple([ + Validatorless.required('Matricula Obrigatória'), + Validatorless.min( + 6, 'Matricula deve ter no mínimo 6 caracteres'), + ]), keyboardType: TextInputType.number, style: TextStyles.instance.texLabelH4.copyWith( color: ColorsApp.instance.labelblack1, @@ -152,6 +162,44 @@ class _LoginPageState extends BaseState { ], ), ), + SizedBox( + height: context.screenHeight * .02, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + check == false + ? IconButton( + onPressed: () { + toogleCheck(); + }, + icon: Icon( + Icons.check_box_outline_blank_rounded, + color: ColorsApp.instance.cardwhite, + size: 25, + ), + ) + : IconButton( + onPressed: () { + toogleCheck(); + }, + icon: Icon( + Icons.check_box_rounded, + color: ColorsApp.instance.cardwhite, + size: 25, + ), + ), + Text( + 'Me manter conectado', + style: TextStyles.instance.texLabelH3.copyWith( + color: ColorsApp.instance.cardwhite, + fontSize: 17, + fontWeight: TextStyles + .instance.textButtonLabel.fontWeight, + ), + ), + ], + ), SizedBox( height: context.screenHeight * .07, ), diff --git a/lib/app/pages/login/widgets/my_sliverfillremaining.dart b/lib/app/pages/login/widgets/my_sliverfillremaining.dart index 4743bb0..bd1d8e0 100644 --- a/lib/app/pages/login/widgets/my_sliverfillremaining.dart +++ b/lib/app/pages/login/widgets/my_sliverfillremaining.dart @@ -20,7 +20,7 @@ class MySliverfillremaining extends StatelessWidget { child: Text( 'Esqueceu sua senha? Recuperar senha.', style: TextStyles.instance.texLabelH4.copyWith( - color: ColorsApp.instance.labelblack4, + color: ColorsApp.instance.cardwhite, fontWeight: TextStyles.instance.textSemiBold.fontWeight, ), ), diff --git a/lib/app/pages/recover_password/recover_password_page.dart b/lib/app/pages/recover_password/recover_password_page.dart index 105a941..fedfb7b 100644 --- a/lib/app/pages/recover_password/recover_password_page.dart +++ b/lib/app/pages/recover_password/recover_password_page.dart @@ -1,9 +1,14 @@ +// ignore_for_file: use_build_context_synchronously + +import 'package:academico_mobile/app/core/ui/helpers/loader.dart'; +import 'package:academico_mobile/app/core/ui/helpers/messages.dart'; import 'package:academico_mobile/app/core/ui/helpers/size_extensions.dart'; import 'package:academico_mobile/app/core/ui/styles/colors_app.dart'; import 'package:academico_mobile/app/core/ui/styles/text_styles.dart'; import 'package:academico_mobile/app/core/ui/widgets/my_appbar.dart'; import 'package:academico_mobile/app/core/ui/widgets/my_input_button.dart'; import 'package:flutter/material.dart'; +import 'package:validatorless/validatorless.dart'; class RecoverPasswordPage extends StatefulWidget { const RecoverPasswordPage({super.key}); @@ -12,61 +17,116 @@ class RecoverPasswordPage extends StatefulWidget { State createState() => _RecoverPasswordPageState(); } -class _RecoverPasswordPageState extends State { +class _RecoverPasswordPageState extends State + with Loader, Messages { bool _obscuredText = true; final matriculaEC = TextEditingController(); + final formKey = GlobalKey(); + + @override + void dispose() { + matriculaEC.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { - return Scaffold( - appBar: MyAppbar( - title: 'Recuperar Senha', - onPressed: () => Navigator.of(context).pop()), - body: Padding( - padding: EdgeInsets.all(context.screenWidth * .03), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - TextFormField( - controller: matriculaEC, - obscureText: _obscuredText, - keyboardType: TextInputType.number, - style: TextStyles.instance.texLabelH4.copyWith( - color: ColorsApp.instance.labelblack1, - fontSize: 20, - fontWeight: TextStyles.instance.textButtonLabel.fontWeight, - ), - decoration: InputDecoration( - hintText: 'Matricula', - suffixIcon: IconButton( - onPressed: () { - setState(() { - _obscuredText = !_obscuredText; - }); - }, - icon: Icon( - _obscuredText ? Icons.visibility : Icons.visibility_off, - color: ColorsApp.instance.labelblack1, - size: 25), - ), - ), - ), - SizedBox( - height: context.screenHeight * .02, - ), - Row( + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Scaffold( + appBar: MyAppbar( + title: 'Recuperar Senha', + onPressed: () => Navigator.of(context).pop()), + body: Padding( + padding: EdgeInsets.all(context.screenWidth * .03), + child: Form( + key: formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ - Expanded( - child: MyInputButton( - height: context.screenHeight * .07, - label: 'Acessar', - onPressed: () { - Navigator.of(context).pushReplacementNamed('/home'); - }, + TextFormField( + controller: matriculaEC, + validator: Validatorless.multiple( + [ + Validatorless.required('Matricula obrigatória'), + Validatorless.min(6, 'Matricula inválida'), + ], + ), + obscureText: _obscuredText, + keyboardType: TextInputType.number, + style: TextStyles.instance.texLabelH4.copyWith( + color: ColorsApp.instance.labelblack1, + fontSize: 20, + fontWeight: TextStyles.instance.textButtonLabel.fontWeight, ), + decoration: InputDecoration( + hintText: 'Matricula', + suffixIcon: IconButton( + onPressed: () { + setState(() { + _obscuredText = !_obscuredText; + }); + }, + icon: Icon( + _obscuredText + ? Icons.visibility + : Icons.visibility_off, + color: ColorsApp.instance.labelblack1, + size: 25), + ), + ), + ), + SizedBox( + height: context.screenHeight * .02, + ), + Row( + children: [ + Expanded( + child: MyInputButton( + height: context.screenHeight * .07, + label: 'Enviar', + onPressed: () async { + final form = + formKey.currentState?.validate() ?? false; + if (form) { + showLoader(); + await Future.delayed(const Duration(seconds: 2)); + hideLoader(); + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Aviso do desenvolvedor'), + content: const Text( + 'Olá caro amigo, infelizmente não foi possível implementar essa funcionalidade ainda, mas não se preocupe, ela estará disponível em breve!'), + actions: [ + TextButton( + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all( + ColorsApp.instance.cardblue), + ), + child: Text('Fechar', + style: TextStyle( + color: ColorsApp + .instance.cardwhite)), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + } + }, + ), + ), + ], ), ], ), - ], + ), ), ), ); diff --git a/lib/app/pages/request_documents/request_documents_page.dart b/lib/app/pages/request_documents/request_documents_page.dart new file mode 100644 index 0000000..a85c3eb --- /dev/null +++ b/lib/app/pages/request_documents/request_documents_page.dart @@ -0,0 +1,30 @@ +import 'package:academico_mobile/app/core/ui/helpers/size_extensions.dart'; +import 'package:academico_mobile/app/core/ui/styles/colors_app.dart'; +import 'package:flutter/material.dart'; + +class RequestDocumentsPage extends StatefulWidget { + const RequestDocumentsPage({super.key}); + + @override + State createState() => _RequestDocumentsPageState(); +} + +class _RequestDocumentsPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Request Documents'), + ), + body: Center( + child: Text( + 'Função ainda não implementada', + style: TextStyle( + fontSize: context.screenWidth * 0.04, + color: context.colorsApp.cardwhite, + ), + ), + ), + ); + } +} diff --git a/lib/app/pages/schedule/schedule_controller.dart b/lib/app/pages/schedule/schedule_controller.dart index 1d5519b..d596e97 100644 --- a/lib/app/pages/schedule/schedule_controller.dart +++ b/lib/app/pages/schedule/schedule_controller.dart @@ -12,12 +12,13 @@ class ScheduleController extends Cubit { Future loadSchedule() async { emit(state.copyWith(status: ScheduleStatus.loading)); try { - await Future.delayed(const Duration(seconds: 2)); final schedule = await _scheduleRepository.findSchedule(); emit(state.copyWith(status: ScheduleStatus.loaded, schedule: schedule)); } catch (e, s) { log('Erro ao carregar o cronograma', error: e, stackTrace: s); - emit(state.copyWith(status: ScheduleStatus.error, errorMessage: 'Erro ao carregar o cronograma')); + emit(state.copyWith( + status: ScheduleStatus.error, + errorMessage: 'Erro ao carregar o cronograma')); } } @@ -26,5 +27,4 @@ class ScheduleController extends Cubit { await Future.delayed(const Duration(seconds: 1)); emit(state.copyWith(status: ScheduleStatus.loaded, selectedDay: day)); } - } diff --git a/lib/app/pages/schedule/widgets/my_card.dart b/lib/app/pages/schedule/widgets/my_card.dart index 2a2885d..2e326f3 100644 --- a/lib/app/pages/schedule/widgets/my_card.dart +++ b/lib/app/pages/schedule/widgets/my_card.dart @@ -13,18 +13,16 @@ class MyCard extends StatelessWidget { }); colorBody() { - if (horarioDetalhado.horario == '18:30 ~ 19:19') { - return ColorsApp.instance.cardwhite; - } else if (horarioDetalhado.horario == '20:20 ~ 21:09') { - return ColorsApp.instance.primary; + if (horarioDetalhado.horario == '18:30 | 19:19') { + return ColorsApp.instance.tarde; } else { return ColorsApp.instance.cardnoselected; } } colorLabel() { - if (horarioDetalhado.horario == '18:30 ~ 19:19') { - return ColorsApp.instance.cardnoselected; + if (horarioDetalhado.horario == '18:30 | 19:19') { + return ColorsApp.instance.cardwhite; } else { return ColorsApp.instance.cardwhite; } diff --git a/lib/app/pages/school_records/school_records_page.dart b/lib/app/pages/school_records/school_records_page.dart new file mode 100644 index 0000000..e239d18 --- /dev/null +++ b/lib/app/pages/school_records/school_records_page.dart @@ -0,0 +1,30 @@ +import 'package:academico_mobile/app/core/ui/helpers/size_extensions.dart'; +import 'package:academico_mobile/app/core/ui/styles/colors_app.dart'; +import 'package:flutter/material.dart'; + +class SchoolRecordsPage extends StatefulWidget { + const SchoolRecordsPage({super.key}); + + @override + State createState() => _SchoolRecordsPageState(); +} + +class _SchoolRecordsPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('School Records'), + ), + body: Center( + child: Text( + 'Função ainda não implementada', + style: TextStyle( + fontSize: context.screenWidth * 0.04, + color: context.colorsApp.cardwhite, + ), + ), + ), + ); + } +} diff --git a/lib/app/repositories/auth/auth_repository_impl.dart b/lib/app/repositories/auth/auth_repository_impl.dart index 9ea0fa1..f2f8a7b 100644 --- a/lib/app/repositories/auth/auth_repository_impl.dart +++ b/lib/app/repositories/auth/auth_repository_impl.dart @@ -18,7 +18,7 @@ class AuthRepositoryImpl implements AuthRepository { @override Future login(String matricula, String password) async { try { - final response = await dio.unauth().post( + final response = await dio.auth().post( '/login', data: {'matricula': matricula, 'password': password}, ); diff --git a/lib/app/repositories/daily/daily_repository_impl.dart b/lib/app/repositories/daily/daily_repository_impl.dart index 6ee4801..720e2bc 100644 --- a/lib/app/repositories/daily/daily_repository_impl.dart +++ b/lib/app/repositories/daily/daily_repository_impl.dart @@ -18,7 +18,7 @@ class DailyRepositoryImpl implements DailyRepository { @override Future> findDaily() async { try { - final result = await dio.unauth().get('/lista-disciplinas'); + final result = await dio.auth().get('/lista-disciplinas'); final list = result.data as List; final semestres = list.map((e) => SemestreModel.fromJson(e)).toList(); return semestres; diff --git a/lib/app/repositories/home/home_repository_impl.dart b/lib/app/repositories/home/home_repository_impl.dart index c9e32f4..e6ef89e 100644 --- a/lib/app/repositories/home/home_repository_impl.dart +++ b/lib/app/repositories/home/home_repository_impl.dart @@ -18,7 +18,7 @@ class HomeRepositoryImpl implements HomeRepository { @override Future> getHomePage() async { try { - final result = await dio.unauth().get('/homepage'); + final result = await dio.auth().get('/homepage'); return (result.data as List) .map((e) => HomePageModel.fromJson(e)) .toList(); diff --git a/lib/app/repositories/schedule/schedule_repository_impl.dart b/lib/app/repositories/schedule/schedule_repository_impl.dart index c814178..aa55741 100644 --- a/lib/app/repositories/schedule/schedule_repository_impl.dart +++ b/lib/app/repositories/schedule/schedule_repository_impl.dart @@ -19,7 +19,7 @@ class ScheduleRepositoryImpl implements ScheduleRepository { @override Future> findSchedule() async { try { - final result = await dio.unauth().get('/horarios'); + final result = await dio.auth().get('/horarios'); final data = json.decode(result.data); final retorno = (data as List).map((e) => Horario.fromJson(e)).toList(); return retorno; diff --git a/pubspec.lock b/pubspec.lock index fd4ddcd..040877b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "8880b4cfe7b5b17d57c052a5a3a8cc1d4f546261c7cc8fbd717bd53f48db0568" + sha256: "405666cd3cf0ee0a48d21ec67e65406aad2c726d9fa58840d3375e7bdcd32a07" url: "https://pub.dev" source: hosted - version: "59.0.0" + version: "60.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: a89627f49b0e70e068130a36571409726b04dab12da7e5625941d2c8ec278b96 + sha256: "1952250bd005bacb895a01bf1b4dc00e3ba1c526cf47dca54dfe24979c65f5b3" url: "https://pub.dev" source: hosted - version: "5.11.1" + version: "5.12.0" args: dependency: transitive description: @@ -292,18 +292,18 @@ packages: dependency: transitive description: name: glob - sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c" + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" graphs: dependency: transitive description: name: graphs - sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2 + sha256: "772db3d53d23361d4ffcf5a9bb091cf3ee9b22f2be52cd107cd7a2683a89ba0e" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.0" http_multi_server: dependency: transitive description: @@ -625,10 +625,10 @@ packages: dependency: transitive description: name: source_gen - sha256: b20e191de6964e98032573cecb1d2b169d96ba63fdb586d24dcd1003ba7e94f6 + sha256: "373f96cf5a8744bc9816c1ff41cf5391bbdbe3d7a96fe98c622b6738a8a7bd33" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.3.2" source_span: dependency: transitive description: @@ -713,10 +713,10 @@ packages: dependency: transitive description: name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" validatorless: dependency: "direct main" description: @@ -801,10 +801,10 @@ packages: dependency: transitive description: name: webview_flutter_wkwebview - sha256: "61f33512810bf1ee9ac89761a4b02663ff64e8227b7dc80654642acd660fd49d" + sha256: "4646bb68297803bdbb96d46853e8fcb560d6cb5e04153fa64581535767875dfe" url: "https://pub.dev" source: hosted - version: "3.4.2" + version: "3.4.3" win32: dependency: transitive description: