TKK_E32230148/lib/login_page.dart

637 lines
20 KiB
Dart

import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'pages/home_dashboard_page.dart';
import 'register_page.dart';
class LoginPage extends StatefulWidget {
const LoginPage({super.key});
@override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final emailController = TextEditingController();
final passwordController = TextEditingController();
final FirebaseFirestore firestore = FirebaseFirestore.instance;
bool allowRegister = false;
bool isLoading = false;
bool obscurePassword = true;
@override
void initState() {
super.initState();
checkAdminExists();
}
Future<void> checkAdminExists() async {
try {
final snapshot = await firestore.collection('users').where('role', isEqualTo: 'admin').limit(1).get();
setState(() {
allowRegister = snapshot.docs.isEmpty;
});
} catch (e) {
setState(() {
allowRegister = false;
});
}
}
/// ================= LOGIN =================
Future login() async {
try {
setState(() {
isLoading = true;
});
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: emailController.text.trim(),
password: passwordController.text.trim(),
);
if (mounted) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => const HomeDashboardPage(),
),
);
}
} on FirebaseAuthException catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent,
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
content: Text(
e.message ?? "Login failed",
),
),
);
}
setState(() {
isLoading = false;
});
}
/// ================= PREMIUM CARD =================
Widget modernCard({
required Widget child,
}) {
return ClipRRect(
borderRadius: BorderRadius.circular(38),
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 30,
sigmaY: 30,
),
child: Container(
width: double.infinity,
padding: const EdgeInsets.all(30),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(38),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Colors.white.withOpacity(0.09),
Colors.white.withOpacity(0.03),
],
),
border: Border.all(
color: Colors.white.withOpacity(0.08),
width: 1.2,
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.45),
blurRadius: 40,
offset: const Offset(0, 25),
),
BoxShadow(
color: Colors.blueAccent
.withOpacity(0.08),
blurRadius: 50,
spreadRadius: 1,
),
],
),
child: child,
),
),
);
}
/// ================= MODERN TEXTFIELD =================
Widget modernField({
required String hint,
required TextEditingController controller,
required IconData icon,
bool obscure = false,
Widget? suffixIcon,
}) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
color: Colors.white.withOpacity(0.04),
border: Border.all(
color: Colors.white.withOpacity(0.05),
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.15),
blurRadius: 15,
),
],
),
child: TextField(
controller: controller,
obscureText: obscure,
style: const TextStyle(
color: Colors.white,
fontSize: 16,
),
decoration: InputDecoration(
border: InputBorder.none,
hintText: hint,
hintStyle: const TextStyle(
color: Colors.white38,
),
prefixIcon: Icon(
icon,
color: Colors.white54,
),
suffixIcon: suffixIcon,
contentPadding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 22,
),
),
),
);
}
@override
Widget build(BuildContext context) {
return AnnotatedRegion<SystemUiOverlayStyle>(
value: const SystemUiOverlayStyle(
/// STATUS BAR
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.light,
statusBarBrightness: Brightness.dark,
/// NAVIGATION BAR
systemNavigationBarColor: Color(0xff030303),
systemNavigationBarIconBrightness:
Brightness.light,
),
child: Scaffold(
backgroundColor: const Color(0xff030303),
body: Stack(
children: [
/// ================= BACKGROUND =================
Container(
decoration: const BoxDecoration(
gradient: RadialGradient(
center: Alignment.topRight,
radius: 1.5,
colors: [
Color(0xff111827),
Color(0xff050505),
Colors.black,
],
),
),
),
/// ================= TOP LIGHT =================
Positioned(
top: -120,
right: -50,
child: Container(
height: 260,
width: 260,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: RadialGradient(
colors: [
Colors.blueAccent
.withOpacity(0.25),
Colors.transparent,
],
),
),
),
),
/// ================= BOTTOM LIGHT =================
Positioned(
bottom: -120,
left: -70,
child: Container(
height: 260,
width: 260,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: RadialGradient(
colors: [
Colors.cyan.withOpacity(0.18),
Colors.transparent,
],
),
),
),
),
/// ================= BLUR =================
BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 90,
sigmaY: 90,
),
child: Container(
color: Colors.transparent,
),
),
SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 20,
),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
const SizedBox(height: 10),
/// ================= HEADER =================
Row(
children: [
Container(
padding:
const EdgeInsets.all(15),
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(22),
color: Colors.white
.withOpacity(0.05),
border: Border.all(
color: Colors.white
.withOpacity(0.06),
),
),
child: const Icon(
Icons.lock_rounded,
color: Colors.white,
size: 28,
),
),
const SizedBox(width: 16),
const Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
"DOORGUARD",
style: TextStyle(
color: Colors.white,
fontSize: 28,
fontWeight:
FontWeight.bold,
letterSpacing: 1,
),
),
SizedBox(height: 4),
Text(
"Smart Security System",
style: TextStyle(
color: Colors.white54,
fontSize: 13,
),
),
],
),
],
),
const SizedBox(height: 55),
/// ================= PREMIUM LOGO =================
Center(
child: Container(
height: 110,
width: 110,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient:
const LinearGradient(
begin: Alignment.topLeft,
end:
Alignment.bottomRight,
colors: [
Color(0xff3B82F6),
Color(0xff06B6D4),
],
),
boxShadow: [
BoxShadow(
color: Colors.blueAccent
.withOpacity(0.45),
blurRadius: 35,
spreadRadius: 5,
),
],
),
child: Container(
margin:
const EdgeInsets.all(4),
decoration: BoxDecoration(
shape: BoxShape.circle,
color:
const Color(0xff050505),
border: Border.all(
color: Colors.white
.withOpacity(0.08),
),
),
child: const Icon(
Icons.lock_person_rounded,
color: Colors.white,
size: 50,
),
),
),
),
const SizedBox(height: 18),
/// ================= TAG =================
Center(
child: Container(
padding:
const EdgeInsets.symmetric(
horizontal: 18,
vertical: 8,
),
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(50),
color: Colors.white
.withOpacity(0.05),
border: Border.all(
color: Colors.white
.withOpacity(0.06),
),
),
child: const Text(
"SMART SECURITY",
style: TextStyle(
color: Colors.white70,
fontSize: 11,
fontWeight:
FontWeight.w600,
letterSpacing: 2,
),
),
),
),
const SizedBox(height: 40),
/// ================= TITLE =================
const Text(
"Welcome",
style: TextStyle(
color: Colors.white,
fontSize: 46,
height: 1,
fontWeight: FontWeight.w800,
letterSpacing: -1.5,
),
),
const SizedBox(height: 14),
const Text(
"Access and control your smart\nRFID door security system.",
style: TextStyle(
color: Colors.white54,
fontSize: 15,
height: 1.8,
letterSpacing: 0.3,
),
),
const SizedBox(height: 35),
/// ================= LOGIN CARD =================
modernCard(
child: Column(
children: [
modernField(
hint: "Email Address",
controller:
emailController,
icon:
Icons.email_outlined,
),
const SizedBox(height: 18),
modernField(
hint: "Password",
controller:
passwordController,
icon: Icons
.lock_outline_rounded,
obscure: obscurePassword,
suffixIcon: IconButton(
onPressed: () {
setState(() {
obscurePassword =
!obscurePassword;
});
},
icon: Icon(
obscurePassword
? Icons
.visibility_off
: Icons.visibility,
color:
Colors.white54,
),
),
),
const SizedBox(height: 30),
/// ================= LOGIN BUTTON =================
SizedBox(
width: double.infinity,
height: 64,
child: ElevatedButton(
onPressed: isLoading
? null
: login,
style:
ElevatedButton
.styleFrom(
elevation: 25,
shadowColor:
Colors.blueAccent,
backgroundColor:
const Color(
0xff2563EB),
shape:
RoundedRectangleBorder(
borderRadius:
BorderRadius
.circular(
26),
),
),
child: isLoading
? const SizedBox(
height: 24,
width: 24,
child:
CircularProgressIndicator(
color: Colors
.white,
strokeWidth:
2.5,
),
)
: const Row(
mainAxisAlignment:
MainAxisAlignment
.center,
children: [
Text(
"LOGIN",
style:
TextStyle(
color: Colors
.white,
fontSize:
16,
fontWeight:
FontWeight
.w700,
letterSpacing:
1,
),
),
SizedBox(
width: 10),
Icon(
Icons
.arrow_forward_rounded,
color: Colors
.white,
size: 22,
),
],
),
),
),
const SizedBox(height: 18),
if (allowRegister)
TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const RegisterPage(role: 'admin'),
),
);
},
child: const Text(
"Create admin account",
style: TextStyle(
color: Colors.white70,
fontSize: 15,
),
),
),
],
),
),
const SizedBox(height: 35),
],
),
),
),
],
),
),
);
}
}