Skip to content

Commit

Permalink
Merge pull request #27 from B3-3iL-DLW/ui/create-login-page
Browse files Browse the repository at this point in the history
UI/create login page
  • Loading branch information
julesartd authored Mar 13, 2024
2 parents 48be23c + 96f81e4 commit a8b3d22
Show file tree
Hide file tree
Showing 14 changed files with 345 additions and 52 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/deploy-backend-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ on:
push:
branches:
- dev
pull_request:
branches:
- dev

env:
FLUTTER_VERSION: 3.10.1
Expand Down
46 changes: 46 additions & 0 deletions frontend/app_student/lib/login/cubit/login_cubit.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import 'package:bloc/bloc.dart';
import 'package:meta/meta.dart';
import 'package:shared_preferences/shared_preferences.dart';

part 'login_state.dart';

class LoginCubit extends Cubit<LoginState> {
LoginCubit() : super(LoginInitial()) {
checkUserAuthentication();
}

Future<bool> areFieldsFilled(
String ine, String name, String birthDate) async {
if (ine.isEmpty || name.isEmpty || birthDate.isEmpty) {
return false;
}
return true;
}

Future<void> saveLoginDetails(
String ine, String name, String birthDate) async {
if (!(await areFieldsFilled(ine, name, birthDate))) {
emit(LoginFieldError());
return;
}
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('ine', ine);
await prefs.setString('name', name);
await prefs.setString('birthDate', birthDate);
emit(RedirectToClassSelection());
}

Future<void> checkUserAuthentication() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? ine = prefs.getString('ine');
String? name = prefs.getString('name');
String? birthDate = prefs.getString('birthDate');
String? className = prefs.getString('className');

if (ine != null && name != null && birthDate != null && className != null) {
emit(LoginAuthenticated());
} else {
emit(LoginInitial());
}
}
}
12 changes: 12 additions & 0 deletions frontend/app_student/lib/login/cubit/login_state.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
part of 'login_cubit.dart';

@immutable
abstract class LoginState {}

class LoginInitial extends LoginState {}

class LoginAuthenticated extends LoginState {}

class LoginFieldError extends LoginState {}

class RedirectToClassSelection extends LoginState {}
72 changes: 64 additions & 8 deletions frontend/app_student/lib/login/views/login_page.dart
Original file line number Diff line number Diff line change
@@ -1,22 +1,78 @@
import 'package:app_student/api/api_service.dart';
import 'package:app_student/api/class_groups/repositories/class_group_repository.dart';
import 'package:app_student/config/config.dart';
import 'package:app_student/login/cubit/login_cubit.dart';
import 'package:app_student/login/widgets/form/form_login.dart';
import 'package:app_student/login/widgets/header/header_text.dart';
import 'package:app_student/week_schedule/views/week_schedule.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/provider.dart';

import '../../class_groups/cubit/class_group_cubit.dart';
import '../../class_groups/views/class_group_view.dart';
import '../widgets/header/header_logo.dart';

class LoginPage extends StatelessWidget {
const LoginPage({super.key});

@override
Widget build(BuildContext context) {
return const Scaffold(
body: Column(
children: [
HeaderLogo(),
HeaderText('Bonjour :)'),
Expanded(child: FormLogin()),
],
),
return BlocBuilder<LoginCubit, LoginState>(
builder: (context, state) {
if (state is RedirectToClassSelection) {
WidgetsBinding.instance.addPostFrameCallback((_) {
final config = Provider.of<Config>(context, listen: false);
Navigator.of(context).pushReplacement(
MaterialPageRoute<ClassListPage>(
builder: (context) => BlocProvider(
create: (_) => ClassGroupCubit(
classRepository: ClassGroupRepository(
apiService: ApiService(apiUrl: config.apiUrl))),
child: const ClassListPage()),
),
);
});
return Container();
} else if (state is LoginInitial) {
return const Scaffold(
body: Column(
children: [
HeaderLogo(),
HeaderText('Bonjour :)'),
Expanded(child: FormLogin()),
],
),
);
} else if (state is LoginAuthenticated) {
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => const WeekSchedulePage()),
);
});
return Container();
} else if (state is LoginFieldError) {
WidgetsBinding.instance.addPostFrameCallback((_) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Veuillez remplir tous les champs'),
backgroundColor: Colors.red,
),
);
});
return const Scaffold(
body: Column(
children: [
HeaderLogo(),
HeaderText('Bonjour :)'),
Expanded(child: FormLogin()),
],
),
);
} else {
return Container();
}
},
);
}
}
23 changes: 21 additions & 2 deletions frontend/app_student/lib/login/widgets/form/button_submit.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import '../../cubit/login_cubit.dart';

class SubmitButton extends StatelessWidget {
const SubmitButton({super.key});
final TextEditingController ineController;
final TextEditingController nameController;
final TextEditingController birthDateController;

const SubmitButton(
{super.key,
required this.ineController,
required this.nameController,
required this.birthDateController});

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -30,7 +41,15 @@ class SubmitButton extends StatelessWidget {
),
),
),
onPressed: () {},
onPressed: () {
final String ine = ineController.text.trim();
final String name = nameController.text.trim();
final String birthDate = birthDateController.text.trim();

context
.read<LoginCubit>()
.saveLoginDetails(ine, name, birthDate);
},
child: const Text('Connexion'),
),
),
Expand Down
33 changes: 24 additions & 9 deletions frontend/app_student/lib/login/widgets/form/form_login.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,34 @@ import 'inputs/input_birthdate.dart';
import 'inputs/input_ine.dart';
import 'inputs/input_prenom.dart';

class FormLogin extends StatelessWidget {
class FormLogin extends StatefulWidget {
const FormLogin({super.key});

@override
FormLoginState createState() => FormLoginState();
}

class FormLoginState extends State<FormLogin> {
final TextEditingController ineController = TextEditingController();
final TextEditingController nameController = TextEditingController();
final TextEditingController birthDateController = TextEditingController();

@override
Widget build(BuildContext context) {
return const Scaffold(
body: Column(
children: [
INETextField(),
BirthDateField(),
FirstnameTextField(),
SubmitButton()
],
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
INETextField(controller: ineController),
BirthDateField(controller: birthDateController),
FirstnameTextField(controller: nameController),
SubmitButton(
ineController: ineController,
nameController: nameController,
birthDateController: birthDateController,
)
],
),
),
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import 'package:flutter/material.dart';

class BirthDateField extends StatefulWidget {
const BirthDateField({super.key});
final TextEditingController controller;

const BirthDateField({super.key, required this.controller});

@override
BirthDateFieldState createState() => BirthDateFieldState();
Expand All @@ -20,6 +22,8 @@ class BirthDateFieldState extends State<BirthDateField> {
if (picked != null && picked != _selectedDate) {
setState(() {
_selectedDate = picked;
widget.controller.text =
_selectedDate.toLocal().toString().split(' ')[0];
});
}
}
Expand All @@ -40,6 +44,7 @@ class BirthDateFieldState extends State<BirthDateField> {
),
const SizedBox(height: 10.0),
TextFormField(
controller: widget.controller,
readOnly: true,
decoration: InputDecoration(
hintText: _selectedDate.toLocal().toString().split(' ')[0],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import 'package:flutter/material.dart';

class INETextField extends StatelessWidget {
const INETextField({super.key});
final TextEditingController controller;

const INETextField({super.key, required this.controller});

@override
Widget build(BuildContext context) {
Expand All @@ -22,6 +24,7 @@ class INETextField extends StatelessWidget {
),
const SizedBox(height: 10.0),
TextFormField(
controller: controller,
decoration: InputDecoration(
hintText: 'Numéro INE',
contentPadding:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import 'package:flutter/material.dart';

class FirstnameTextField extends StatelessWidget {
const FirstnameTextField({super.key});
final TextEditingController controller;

const FirstnameTextField({super.key, required this.controller});

@override
Widget build(BuildContext context) {
Expand All @@ -19,6 +21,7 @@ class FirstnameTextField extends StatelessWidget {
),
const SizedBox(height: 10.0),
TextFormField(
controller: controller,
style: TextStyle(
color: Colors.grey[600],
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class HeaderLogo extends StatelessWidget {
child: SizedBox(
width: 200.0, // Largeur de l'image
height: 200.0, // Hauteur de l'image
child: Image.asset('images/3il-logo.jpg'),
child: Image.asset('assets/images/3il-logo.jpg'),
),
),
);
Expand Down
49 changes: 25 additions & 24 deletions frontend/app_student/lib/main_dev.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
import 'package:app_student/api/week_schedule/repositories/week_schedule_repository.dart';
import 'package:app_student/config/dev_config.dart';
import 'package:app_student/week_schedule/views/week_schedule.dart';

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/provider.dart';

import 'api/api_service.dart';
import 'api/class_groups/repositories/class_group_repository.dart';
import 'config/config.dart';
import 'login/cubit/login_cubit.dart';
import 'login/views/login_page.dart';

void main() {
final ClassGroupRepository classGroupRepository = ClassGroupRepository(
apiService: ApiService(apiUrl: DevConfig().apiUrl),
);

runApp(
Provider<Config>(
create: (_) => DevConfig(),
MultiProvider(
providers: [
Provider<Config>(
create: (_) => DevConfig(),
),
RepositoryProvider<ClassGroupRepository>(
create: (context) => classGroupRepository,
),
],
child: const MyApp(),
),
);
Expand All @@ -23,26 +34,16 @@ class MyApp extends StatelessWidget {

@override
Widget build(BuildContext context) {
return Provider<Config>(
create: (_) => DevConfig(),
child: RepositoryProvider<WeekScheduleRepository>(
create: (context) => WeekScheduleRepository(
apiService: ApiService(apiUrl: context.read<Config>().apiUrl),
className: 'B3 Groupe 3 DLW-FA'),
child: const MaterialApp(home: WeekSchedulePage()),
return MaterialApp(
title: 'Class List',
theme: ThemeData(
primarySwatch: Colors.blue,
focusColor: const Color(0xffE84E0F),
),
home: BlocProvider(
create: (context) => LoginCubit(),
child: const LoginPage(),
),
);
}

// @override
// Widget build(BuildContext context) {
// return Provider<Config>(
// create: (_) => DevConfig(),
// child: RepositoryProvider<ClassGroupRepository>(
// create: (context) => ClassGroupRepository(
// apiService: ApiService(apiUrl: context.read<Config>().apiUrl)),
// child: const MaterialApp(home: ClassListPage()),
// ),
// );
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import FlutterMacOS
import Foundation

import shared_preferences_foundation

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
}
Loading

0 comments on commit a8b3d22

Please sign in to comment.