Authentication check plus signin screen added to frontend
This commit is contained in:
29
Frontend/patient_manager/lib/Authentication/authCheck.dart
Normal file
29
Frontend/patient_manager/lib/Authentication/authCheck.dart
Normal file
@@ -0,0 +1,29 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:patient_manager/main.dart';
|
||||
import 'package:patient_manager/pages/home.dart';
|
||||
import 'package:patient_manager/pages/signin.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
|
||||
class AuthCheck extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StreamBuilder<AuthState>(
|
||||
stream: client.auth.onAuthStateChange.distinct(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.active) {
|
||||
final user = snapshot.data?.session;
|
||||
if (user == null) {
|
||||
// User not authenticated, show login screen
|
||||
return SignIn();
|
||||
} else {
|
||||
// User authenticated, show home screen
|
||||
return Home();
|
||||
}
|
||||
}
|
||||
|
||||
// Connection state not active, show loading indicator
|
||||
return CircularProgressIndicator();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:patient_manager/main.dart';
|
||||
|
||||
class MyAppBar extends StatelessWidget {
|
||||
final String barTitle;
|
||||
@@ -11,6 +12,15 @@ class MyAppBar extends StatelessWidget {
|
||||
backgroundColor: Colors.blueAccent,
|
||||
elevation: 8,
|
||||
shadowColor: Colors.black,
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
client.auth.signOut();
|
||||
Navigator.of(context).pushNamed('/');
|
||||
},
|
||||
icon: const Icon(Icons.logout),
|
||||
iconSize: 35,
|
||||
color: Colors.black,
|
||||
),
|
||||
title: Text(
|
||||
barTitle,
|
||||
style: const TextStyle(
|
||||
|
||||
39
Frontend/patient_manager/lib/components/myTextField.dart
Normal file
39
Frontend/patient_manager/lib/components/myTextField.dart
Normal file
@@ -0,0 +1,39 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MyTextField extends StatelessWidget {
|
||||
final controller;
|
||||
final String hintText;
|
||||
final bool obscureText;
|
||||
|
||||
const MyTextField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.hintText,
|
||||
required this.obscureText,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 25.0),
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
obscureText: obscureText,
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white,
|
||||
filled: true,
|
||||
hintText: hintText,
|
||||
hintStyle: TextStyle(color: Colors.blueGrey[400]),
|
||||
enabledBorder: const OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.blueAccent,
|
||||
width: 2.0,
|
||||
)),
|
||||
focusedBorder: const OutlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.blue),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
33
Frontend/patient_manager/lib/components/mybutton.dart
Normal file
33
Frontend/patient_manager/lib/components/mybutton.dart
Normal file
@@ -0,0 +1,33 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MyButton extends StatelessWidget {
|
||||
final void Function() onTap;
|
||||
final String buttonText;
|
||||
|
||||
const MyButton({super.key, required this.onTap, required this.buttonText});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(25),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 25),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blueAccent,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
buttonText,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 20,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,19 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:patient_manager/router/routeGenerator.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
|
||||
void main() {
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await Supabase.initialize(
|
||||
url: "https://stzluvsyhbwtfbztarmu.supabase.co",
|
||||
anonKey:
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InN0emx1dnN5aGJ3dGZienRhcm11Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTIwNzUyMTMsImV4cCI6MjAyNzY1MTIxM30.a7VHlk63JJcAotvsqtoqiKwjNK4EbnNgKilAqt1iRio",
|
||||
);
|
||||
runApp(const MzanziInnovationHub());
|
||||
}
|
||||
|
||||
final client = Supabase.instance.client;
|
||||
|
||||
class MzanziInnovationHub extends StatelessWidget {
|
||||
const MzanziInnovationHub({super.key});
|
||||
|
||||
|
||||
155
Frontend/patient_manager/lib/pages/signin.dart
Normal file
155
Frontend/patient_manager/lib/pages/signin.dart
Normal file
@@ -0,0 +1,155 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:patient_manager/components/myTextField.dart';
|
||||
import 'package:patient_manager/components/mybutton.dart';
|
||||
import 'package:patient_manager/main.dart';
|
||||
import 'package:supabase_auth_ui/supabase_auth_ui.dart';
|
||||
|
||||
class SignIn extends StatefulWidget {
|
||||
const SignIn({super.key});
|
||||
|
||||
@override
|
||||
State<SignIn> createState() => _SignInState();
|
||||
}
|
||||
|
||||
class _SignInState extends State<SignIn> {
|
||||
final emailController = TextEditingController();
|
||||
final passwordController = TextEditingController();
|
||||
|
||||
//sign user in
|
||||
Future<void> signUserIn() async {
|
||||
try {
|
||||
final response = await client.auth.signInWithPassword(
|
||||
email: emailController.text,
|
||||
password: passwordController.text,
|
||||
);
|
||||
if (response.session != null) {
|
||||
Navigator.of(context).pushNamed('/homme');
|
||||
}
|
||||
} on AuthException catch (error) {
|
||||
loginError(error.message);
|
||||
emailController.clear();
|
||||
passwordController.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void loginError(error) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(error),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
body: SafeArea(
|
||||
child: Center(
|
||||
child: SingleChildScrollView(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
//logo
|
||||
const Icon(
|
||||
Icons.lock,
|
||||
size: 100,
|
||||
color: Colors.blueAccent,
|
||||
),
|
||||
//spacer
|
||||
const SizedBox(height: 10),
|
||||
//Heading
|
||||
const Text(
|
||||
'Sign In',
|
||||
style: TextStyle(
|
||||
fontSize: 25,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.blueAccent,
|
||||
),
|
||||
),
|
||||
//spacer
|
||||
const SizedBox(height: 25),
|
||||
//email input
|
||||
SizedBox(
|
||||
width: 500.0,
|
||||
child: MyTextField(
|
||||
controller: emailController,
|
||||
hintText: 'Email',
|
||||
obscureText: false,
|
||||
),
|
||||
),
|
||||
//spacer
|
||||
const SizedBox(height: 25),
|
||||
//password input
|
||||
SizedBox(
|
||||
width: 500.0,
|
||||
child: MyTextField(
|
||||
controller: passwordController,
|
||||
hintText: 'Password',
|
||||
obscureText: true,
|
||||
),
|
||||
),
|
||||
//spacer
|
||||
const SizedBox(height: 10),
|
||||
// forgot password
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 25.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
'Forgot Password?',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
//spacer
|
||||
const SizedBox(height: 50),
|
||||
// sign in button
|
||||
SizedBox(
|
||||
width: 500.0,
|
||||
child: MyButton(
|
||||
onTap: signUserIn,
|
||||
buttonText: "Sign In",
|
||||
),
|
||||
),
|
||||
//spacer
|
||||
const SizedBox(height: 30),
|
||||
//register text
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Text(
|
||||
'New User?',
|
||||
style: TextStyle(fontSize: 18, color: Colors.grey),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 6,
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {},
|
||||
child: const Text(
|
||||
'Register Now',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
color: Colors.blueAccent,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
// ignore: file_names
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:patient_manager/Authentication/authCheck.dart';
|
||||
import 'package:patient_manager/pages/home.dart';
|
||||
import 'package:patient_manager/pages/signin.dart';
|
||||
|
||||
class RouteGenerator {
|
||||
static Route<dynamic> generateRoute(RouteSettings settings) {
|
||||
@@ -8,11 +10,11 @@ class RouteGenerator {
|
||||
|
||||
switch (settings.name) {
|
||||
case '/':
|
||||
return MaterialPageRoute(builder: (_) => AuthCheck());
|
||||
case '/home':
|
||||
return MaterialPageRoute(builder: (_) => const Home());
|
||||
// case '/business':
|
||||
// return MaterialPageRoute(builder: (_) => const Business());
|
||||
// case '/businessList':
|
||||
// return MaterialPageRoute(builder: (_) => const BusinessList());
|
||||
case '/signin':
|
||||
return MaterialPageRoute(builder: (_) => const SignIn());
|
||||
// //case '/signIn':
|
||||
// // return MaterialPageRoute(builder: (_) => SignIn());
|
||||
// case '/auth':
|
||||
|
||||
Reference in New Issue
Block a user