Files
finger_print_app/lib/presentation/screens/attendence_screen.dart
2026-02-22 14:06:02 +03:00

1300 lines
48 KiB
Dart

// // import 'package:coda_project/presentation/screens/face_screen2.dart';
// // import 'package:coda_project/presentation/screens/notifications_screen.dart';
// // import 'package:coda_project/presentation/screens/user_settings_screen.dart';
// // import 'package:flutter/material.dart';
// // import 'package:flutter_svg/flutter_svg.dart';
// // import '../widgets/settings_bar.dart';
// // import '../../core/di/injection_container.dart';
// // import '../../domain/models/attendance_login_request.dart';
// // import '../../domain/models/attendance_logout_request.dart';
// // import '../../domain/usecases/attendance_login_usecase.dart';
// // import '../../domain/usecases/attendance_logout_usecase.dart';
// // import '../../data/datasources/user_local_data_source.dart';
// // import '../../data/datasources/attendance_remote_data_source.dart';
// // class AttendanceScreen extends StatelessWidget {
// // const AttendanceScreen({super.key});
// // @override
// // Widget build(BuildContext context) {
// // final screenWidth = MediaQuery.sizeOf(context).width;
// // final screenHeight = MediaQuery.sizeOf(context).height;
// // return Directionality(
// // textDirection: TextDirection.ltr,
// // child: Stack(
// // children: [
// // SizedBox(height: MediaQuery.of(context).size.height),
// // /// ------------------------------
// // /// SETTINGS BAR (STATIC)
// // /// ------------------------------
// // SafeArea(
// // child: SettingsBar(
// // selectedIndex: 0,
// // showBackButton: false,
// // iconPaths: ['assets/images/user.svg', 'assets/images/ball.svg'],
// // onTap: (index) {
// // if (index == 0) {
// // Navigator.push(
// // context,
// // MaterialPageRoute(
// // builder: (context) => UserSettingsScreen(),
// // ),
// // );
// // } else if (index == 1) {
// // Navigator.push(
// // context,
// // MaterialPageRoute(
// // builder: (context) => NotificationsScreen(),
// // ),
// // );
// // }
// // },
// // ),
// // ),
// // /// ------------------------------
// // /// GREETING TEXT
// // /// ------------------------------
// // Positioned(
// // top:
// // screenHeight *
// // 0.14, // moved down because settings bar now exists
// // left: 0,
// // right: 0,
// // child: Center(
// // child: Text(
// // "صباح الخير, محمد",
// // style: TextStyle(
// // fontSize: 24,
// // fontWeight: FontWeight.w600,
// // color: Colors.white,
// // shadows: [Shadow(color: Color(0x42000000), blurRadius: 6)],
// // ),
// // ),
// // ),
// // ),
// // /// ------------------------------
// // /// MAIN CARD AREA
// // /// ------------------------------
// // Positioned(
// // top:
// // screenHeight *
// // 0.2, // pushed down because of settings bar + greeting
// // left: 0,
// // right: 0,
// // child: Center(
// // child: Padding(
// // padding: EdgeInsets.symmetric(vertical: screenHeight * 0.05),
// // child: Stack(
// // children: [
// // Container(
// // height: screenHeight * 0.5,
// // width: screenWidth * 0.7,
// // decoration: BoxDecoration(
// // borderRadius: BorderRadius.circular(32),
// // boxShadow: [
// // BoxShadow(
// // color: Color(0x1F2B2B2B),
// // blurRadius: 5,
// // offset: Offset(10, -10),
// // ),
// // BoxShadow(
// // color: Color(0xABCECECE),
// // blurRadius: 5,
// // offset: Offset(-2, 5),
// // ),
// // BoxShadow(
// // color: Color.fromARGB(148, 2, 70, 35),
// // blurRadius: 80,
// // offset: Offset(0, 10),
// // ),
// // ],
// // ),
// // ),
// // Container(
// // height: screenHeight * 0.5,
// // width: screenWidth * 0.7,
// // decoration: BoxDecoration(
// // color: Color(0x92757575),
// // borderRadius: BorderRadius.circular(32),
// // ),
// // ),
// // ],
// // ),
// // ),
// // ),
// // ),
// // /// ------------------------------
// // /// LOGIN BUTTON
// // /// ------------------------------
// // Positioned(
// // top: screenHeight * 0.21,
// // left: screenWidth * 0.05,
// // child: _ShadowedCard(
// // shadow: [
// // BoxShadow(
// // color: Color(0x62000000),
// // blurRadius: 10,
// // spreadRadius: 5,
// // offset: Offset(5, 5),
// // ),
// // ],
// // child: _FingerButton(
// // icon: "assets/images/faceLogin.svg",
// // label: "تسجيل الدخول",
// // onTap: () async {
// // final employeeId =
// // await sl<UserLocalDataSource>().getCachedEmployeeId();
// // print("ATTENDANCE_SCREEN: Retrieved EmployeeId: $employeeId");
// // if (employeeId == null) {
// // if (context.mounted) {
// // ScaffoldMessenger.of(context).showSnackBar(
// // const SnackBar(
// // content: Text('خطأ: لم يتم العثور على رقم الموظف'),
// // ),
// // );
// // }
// // return;
// // }
// // // ------------------------------
// // // ACTIVE SESSION CHECK (LOGIN)
// // // ------------------------------
// // try {
// // // Optional: Show a loading dialog if it takes too long
// // final hasActive = await sl<AttendanceRemoteDataSource>()
// // .hasActiveLogin(employeeId: employeeId);
// // if (hasActive) {
// // if (context.mounted) {
// // ScaffoldMessenger.of(context).showSnackBar(
// // const SnackBar(content: Text('أنت مسجل دخول بالفعل')),
// // );
// // }
// // return;
// // }
// // } catch (e) {
// // if (context.mounted) {
// // ScaffoldMessenger.of(context).showSnackBar(
// // SnackBar(content: Text('فشل التحقق من الجلسة: $e')),
// // );
// // }
// // return;
// // }
// // if (context.mounted) {
// // Navigator.of(context).push(
// // MaterialPageRoute(
// // builder:
// // (_) => OvalCameraCapturePage(
// // isLogin: true,
// // onCapture: (imageFile) async {
// // final loginUseCase =
// // sl<AttendanceLoginUsecase>();
// // await loginUseCase(
// // AttendanceLoginRequest(
// // employeeId: employeeId,
// // faceImage: imageFile,
// // ),
// // );
// // },
// // checkIfLoggedIn: () {},
// // ),
// // ),
// // );
// // }
// // },
// // ),
// // ),
// // ),
// // /// ------------------------------
// // /// LOGOUT BUTTON
// // /// ------------------------------
// // Positioned(
// // bottom: screenHeight * 0.2,
// // right: screenWidth * 0.1,
// // child: _ShadowedCard(
// // shadow: [
// // BoxShadow(
// // color: Color(0xABCECECE),
// // blurRadius: 5,
// // spreadRadius: 3,
// // offset: Offset(-6, -6),
// // ),
// // BoxShadow(
// // color: Color(0x92014221),
// // blurRadius: 10,
// // offset: Offset(-5, -5),
// // ),
// // BoxShadow(
// // color: Color(0x7D1A1A1A),
// // blurRadius: 10,
// // spreadRadius: 3,
// // offset: Offset(5, 5),
// // ),
// // ],
// // child: _FingerButton(
// // icon: "assets/images/faceLogout.svg",
// // label: "تسجيل خروج",
// // onTap: () async {
// // final employeeId =
// // await sl<UserLocalDataSource>().getCachedEmployeeId();
// // if (employeeId == null) {
// // if (context.mounted) {
// // ScaffoldMessenger.of(context).showSnackBar(
// // const SnackBar(
// // content: Text('خطأ: لم يتم العثور على رقم الموظف'),
// // ),
// // );
// // }
// // return;
// // }
// // // ------------------------------
// // // ACTIVE SESSION CHECK (LOGOUT)
// // // ------------------------------
// // try {
// // final hasActive = await sl<AttendanceRemoteDataSource>()
// // .hasActiveLogin(employeeId: employeeId);
// // if (!hasActive) {
// // if (context.mounted) {
// // ScaffoldMessenger.of(context).showSnackBar(
// // const SnackBar(
// // content: Text(
// // 'لا يوجد تسجيل دخول فعال لتسجيل الخروج',
// // ),
// // ),
// // );
// // }
// // return;
// // }
// // } catch (e) {
// // if (context.mounted) {
// // ScaffoldMessenger.of(context).showSnackBar(
// // SnackBar(content: Text('فشل التحقق من الجلسة: $e')),
// // );
// // }
// // return;
// // }
// // if (context.mounted) {
// // Navigator.of(context).push(
// // MaterialPageRoute(
// // builder:
// // (_) => OvalCameraCapturePage(
// // isLogin: false,
// // onCapture: (imageFile) async {
// // final logoutUseCase =
// // sl<AttendanceLogoutUseCase>();
// // await logoutUseCase(
// // AttendanceLogoutRequest(
// // employeeId: employeeId,
// // faceImage: imageFile,
// // ),
// // );
// // },
// // checkIfLoggedIn: () {},
// // ),
// // ),
// // );
// // }
// // },
// // ),
// // ),
// // ),
// // ],
// // ),
// // );
// // }
// // }
// // /// ---------------------------------------------
// // /// SHADOW WRAPPER
// // /// ---------------------------------------------
// // class _ShadowedCard extends StatelessWidget {
// // final Widget child;
// // final List<BoxShadow> shadow;
// // const _ShadowedCard({required this.child, required this.shadow});
// // @override
// // Widget build(BuildContext context) {
// // return Stack(
// // children: [
// // Container(
// // height: 160,
// // width: 160,
// // decoration: BoxDecoration(
// // borderRadius: BorderRadius.circular(32),
// // boxShadow: shadow,
// // ),
// // ),
// // child,
// // ],
// // );
// // }
// // }
// // /// ---------------------------------------------
// // /// BUTTON WIDGET
// // /// ---------------------------------------------
// // class _FingerButton extends StatelessWidget {
// // final String icon;
// // final String label;
// // final VoidCallback onTap;
// // const _FingerButton({
// // required this.icon,
// // required this.label,
// // required this.onTap,
// // });
// // @override
// // Widget build(BuildContext context) {
// // return GestureDetector(
// // onTap: onTap,
// // child: Container(
// // height: 160,
// // width: 160,
// // decoration: BoxDecoration(
// // color: Color(0xFFEAFBF3),
// // borderRadius: BorderRadius.circular(32),
// // ),
// // child: Column(
// // mainAxisAlignment: MainAxisAlignment.center,
// // children: [
// // SvgPicture.asset(icon, width: 75, height: 75),
// // SizedBox(height: 10),
// // Text(
// // label,
// // style: TextStyle(
// // fontSize: 18,
// // fontWeight: FontWeight.w600,
// // color: Colors.black,
// // ),
// // ),
// // ],
// // ),
// // ),
// // );
// // }
// // }
// import 'package:coda_project/presentation/screens/face_screen2.dart';
// import 'package:coda_project/presentation/screens/notifications_screen.dart';
// import 'package:coda_project/presentation/screens/user_settings_screen.dart';
// import 'package:flutter/material.dart';
// import 'package:flutter_svg/flutter_svg.dart';
// import '../widgets/settings_bar.dart';
// import '../../core/di/injection_container.dart';
// import '../../domain/models/attendance_login_request.dart';
// import '../../domain/models/attendance_logout_request.dart';
// import '../../domain/usecases/attendance_login_usecase.dart';
// import '../../domain/usecases/attendance_logout_usecase.dart';
// import '../../data/datasources/user_local_data_source.dart';
// import '../../data/datasources/attendance_remote_data_source.dart';
// class AttendanceScreen extends StatefulWidget {
// const AttendanceScreen({super.key});
// @override
// State<AttendanceScreen> createState() => _AttendanceScreenState();
// }
// class _AttendanceScreenState extends State<AttendanceScreen> {
// String _userName = '';
// @override
// void initState() {
// super.initState();
// _loadUserName();
// }
// Future<void> _loadUserName() async {
// final name = await sl<UserLocalDataSource>().getCachedFullName();
// if (mounted) {
// setState(() {
// _userName = name ?? 'مستخدم';
// });
// }
// }
// @override
// Widget build(BuildContext context) {
// final screenWidth = MediaQuery.sizeOf(context).width;
// final screenHeight = MediaQuery.sizeOf(context).height;
// return Directionality(
// textDirection: TextDirection.ltr,
// child: Stack(
// children: [
// SizedBox(height: MediaQuery.of(context).size.height),
// /// ------------------------------
// /// SETTINGS BAR (STATIC)
// /// ------------------------------
// SafeArea(
// child: SettingsBar(
// selectedIndex: 0,
// showBackButton: false,
// iconPaths: ['assets/images/user.svg', 'assets/images/ball.svg'],
// onTap: (index) {
// if (index == 0) {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => const UserSettingsScreen(),
// ),
// );
// } else if (index == 1) {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => const NotificationsScreen(),
// ),
// );
// }
// },
// ),
// ),
// /// ------------------------------
// /// GREETING TEXT
// /// ------------------------------
// Positioned(
// top: screenHeight * 0.14,
// left: 0,
// right: 0,
// child: Center(
// child: Text(
// "صباح الخير $_userName",
// style: TextStyle(
// fontSize: 24,
// fontWeight: FontWeight.w600,
// color: Colors.white,
// shadows: [Shadow(color: Color(0x42000000), blurRadius: 6)],
// ),
// ),
// ),
// ),
// /// ------------------------------
// /// MAIN CARD AREA
// /// ------------------------------
// Positioned(
// top: screenHeight * 0.2,
// left: 0,
// right: 0,
// child: Center(
// child: Padding(
// padding: EdgeInsets.symmetric(vertical: screenHeight * 0.05),
// child: Stack(
// children: [
// Container(
// height: screenHeight * 0.5,
// width: screenWidth * 0.7,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(32),
// boxShadow: [
// const BoxShadow(
// color: Color(0x1F2B2B2B),
// blurRadius: 5,
// offset: Offset(10, -10),
// ),
// const BoxShadow(
// color: Color(0xABCECECE),
// blurRadius: 5,
// offset: Offset(-2, 5),
// ),
// BoxShadow(
// color: const Color.fromARGB(148, 2, 70, 35),
// blurRadius: 80,
// offset: const Offset(0, 10),
// ),
// ],
// ),
// ),
// Container(
// height: screenHeight * 0.5,
// width: screenWidth * 0.7,
// decoration: BoxDecoration(
// color: const Color(0x92757575),
// borderRadius: BorderRadius.circular(32),
// ),
// ),
// ],
// ),
// ),
// ),
// ),
// /// ------------------------------
// /// LOGIN BUTTON
// /// ------------------------------
// Positioned(
// top: screenHeight * 0.21,
// left: screenWidth * 0.05,
// child: _ShadowedCard(
// shadow: [
// const BoxShadow(
// color: Color(0x62000000),
// blurRadius: 10,
// spreadRadius: 5,
// offset: Offset(5, 5),
// ),
// ],
// child: _FingerButton(
// icon: "assets/images/faceLogin.svg",
// label: "تسجيل الدخول",
// onTap: () async {
// final employeeId =
// await sl<UserLocalDataSource>().getCachedEmployeeId();
// print("ATTENDANCE_SCREEN: Retrieved EmployeeId: $employeeId");
// if (employeeId == null) {
// if (context.mounted) {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text('خطأ: لم يتم العثور على رقم الموظف'),
// ),
// );
// }
// return;
// }
// // ACTIVE SESSION CHECK (LOGIN)
// try {
// final hasActive = await sl<AttendanceRemoteDataSource>()
// .hasActiveLogin(employeeId: employeeId);
// if (hasActive) {
// if (context.mounted) {
// showDialog(
// context: context,
// builder:
// (_) => AlertDialog(
// title: const Text(
// 'تنبيه',
// textAlign: TextAlign.center,
// ),
// content: const Text(
// 'أنت مسجل دخول بالفعل، لا يمكنك تسجيل الدخول مرة أخرى.',
// textAlign: TextAlign.center,
// ),
// actions: [
// TextButton(
// onPressed:
// () => Navigator.of(context).pop(),
// child: const Text('حسناً'),
// ),
// ],
// ),
// );
// }
// return;
// }
// } catch (e) {
// if (context.mounted) {
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(content: Text('فشل التحقق من الجلسة: $e')),
// );
// }
// return;
// }
// if (context.mounted) {
// final result = await Navigator.of(context).push(
// MaterialPageRoute(
// builder:
// (_) => OvalCameraCapturePage(
// isLogin: true,
// onCapture: (
// imageFile, {
// required bool localAuth,
// }) async {
// final loginUseCase =
// sl<AttendanceLoginUsecase>();
// await loginUseCase(
// AttendanceLoginRequest(
// employeeId: employeeId,
// faceImage: imageFile,
// localAuth: localAuth, // ✅ NEW FIELD
// ),
// );
// },
// ),
// ),
// );
// if (!context.mounted) return;
// if (result == "local_auth_failed") {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text("فشل التحقق بالبصمة أو رمز القفل"),
// ),
// );
// } else if (result == "retry_failed") {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text("فشل تسجيل الحضور بعد التحقق المحلي"),
// ),
// );
// } else if (result == "retry_missing_file") {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text("تعذر إعادة المحاولة. حاول مرة أخرى."),
// ),
// );
// }
// }
// },
// ),
// ),
// ),
// /// ------------------------------
// /// LOGOUT BUTTON
// /// ------------------------------
// Positioned(
// bottom: screenHeight * 0.2,
// right: screenWidth * 0.1,
// child: _ShadowedCard(
// shadow: const [
// BoxShadow(
// color: Color(0xABCECECE),
// blurRadius: 5,
// spreadRadius: 3,
// offset: Offset(-6, -6),
// ),
// BoxShadow(
// color: Color(0x92014221),
// blurRadius: 10,
// offset: Offset(-5, -5),
// ),
// BoxShadow(
// color: Color(0x7D1A1A1A),
// blurRadius: 10,
// spreadRadius: 3,
// offset: Offset(5, 5),
// ),
// ],
// child: _FingerButton(
// icon: "assets/images/faceLogout.svg",
// label: "تسجيل خروج",
// onTap: () async {
// final employeeId =
// await sl<UserLocalDataSource>().getCachedEmployeeId();
// if (employeeId == null) {
// if (context.mounted) {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text('خطأ: لم يتم العثور على رقم الموظف'),
// ),
// );
// }
// return;
// }
// // ACTIVE SESSION CHECK (LOGOUT)
// try {
// final hasActive = await sl<AttendanceRemoteDataSource>()
// .hasActiveLogin(employeeId: employeeId);
// if (!hasActive) {
// if (context.mounted) {
// showDialog(
// context: context,
// builder:
// (_) => AlertDialog(
// title: const Text(
// 'تنبيه',
// textAlign: TextAlign.center,
// ),
// content: const Text(
// 'لا يوجد تسجيل دخول فعال لتسجيل الخروج.',
// textAlign: TextAlign.center,
// ),
// actions: [
// TextButton(
// onPressed:
// () => Navigator.of(context).pop(),
// child: const Text('حسناً'),
// ),
// ],
// ),
// );
// }
// return;
// }
// } catch (e) {
// if (context.mounted) {
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(content: Text('فشل التحقق من الجلسة: $e')),
// );
// }
// return;
// }
// if (context.mounted) {
// Navigator.of(context).push(
// MaterialPageRoute(
// builder:
// (_) => OvalCameraCapturePage(
// isLogin: false,
// onCapture: (imageFile) async {
// final logoutUseCase =
// sl<AttendanceLogoutUseCase>();
// await logoutUseCase(
// AttendanceLogoutRequest(
// employeeId: employeeId,
// faceImage: imageFile,
// ),
// );
// },
// ),
// ),
// );
// }
// },
// ),
// ),
// ),
// ],
// ),
// );
// }
// }
// /// ---------------------------------------------
// /// SHADOW WRAPPER
// /// ---------------------------------------------
// class _ShadowedCard extends StatelessWidget {
// final Widget child;
// final List<BoxShadow> shadow;
// const _ShadowedCard({required this.child, required this.shadow});
// @override
// Widget build(BuildContext context) {
// return Stack(
// children: [
// Container(
// height: 160,
// width: 160,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(32),
// boxShadow: shadow,
// ),
// ),
// child,
// ],
// );
// }
// }
// /// ---------------------------------------------
// /// BUTTON WIDGET
// /// ---------------------------------------------
// class _FingerButton extends StatelessWidget {
// final String icon;
// final String label;
// final VoidCallback onTap;
// const _FingerButton({
// required this.icon,
// required this.label,
// required this.onTap,
// });
// @override
// Widget build(BuildContext context) {
// return GestureDetector(
// onTap: onTap,
// child: Container(
// height: 160,
// width: 160,
// decoration: BoxDecoration(
// color: const Color(0xFFEAFBF3),
// borderRadius: BorderRadius.circular(32),
// ),
// child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// SvgPicture.asset(icon, width: 75, height: 75),
// const SizedBox(height: 10),
// Text(
// label,
// style: const TextStyle(
// fontSize: 18,
// fontWeight: FontWeight.w600,
// color: Colors.black,
// ),
// ),
// ],
// ),
// ),
// );
// }
// }
import 'package:coda_project/presentation/screens/face_screen2.dart';
import 'package:coda_project/presentation/screens/notifications_screen.dart';
import 'package:coda_project/presentation/screens/user_settings_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import '../widgets/settings_bar.dart';
import '../../core/di/injection_container.dart';
import '../../core/location/location_service.dart';
import '../../domain/models/attendance_login_request.dart';
import '../../domain/models/attendance_logout_request.dart';
import '../../domain/usecases/attendance_login_usecase.dart';
import '../../domain/usecases/attendance_logout_usecase.dart';
import '../../data/datasources/user_local_data_source.dart';
import '../../data/datasources/attendance_remote_data_source.dart';
class AttendanceScreen extends StatefulWidget {
const AttendanceScreen({super.key});
@override
State<AttendanceScreen> createState() => _AttendanceScreenState();
}
class _AttendanceScreenState extends State<AttendanceScreen> {
String _userName = '';
@override
void initState() {
super.initState();
_loadUserName();
}
Future<void> _loadUserName() async {
final name = await sl<UserLocalDataSource>().getCachedFullName();
if (mounted) {
setState(() {
_userName = name ?? 'مستخدم';
});
}
}
void _showResultSnack(String message) {
if (!mounted) return;
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text(message)));
}
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.sizeOf(context).width;
final screenHeight = MediaQuery.sizeOf(context).height;
return Directionality(
textDirection: TextDirection.ltr,
child: Stack(
children: [
SizedBox(height: MediaQuery.of(context).size.height),
/// SETTINGS BAR
SafeArea(
child: SettingsBar(
selectedIndex: 0,
showBackButton: false,
iconPaths: const [
'assets/images/user.svg',
'assets/images/ball.svg',
],
onTap: (index) {
if (index == 0) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const UserSettingsScreen(),
),
);
} else if (index == 1) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const NotificationsScreen(),
),
);
}
},
),
),
/// GREETING
Positioned(
top: screenHeight * 0.14,
left: 0,
right: 0,
child: Center(
child: Text(
"صباح الخير $_userName",
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.w600,
color: Colors.white,
shadows: [Shadow(color: Color(0x42000000), blurRadius: 6)],
),
),
),
),
/// MAIN CARD AREA
Positioned(
top: screenHeight * 0.2,
left: 0,
right: 0,
child: Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: screenHeight * 0.05),
child: Stack(
children: [
Container(
height: screenHeight * 0.5,
width: screenWidth * 0.7,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32),
boxShadow: [
const BoxShadow(
color: Color(0x1F2B2B2B),
blurRadius: 5,
offset: Offset(10, -10),
),
const BoxShadow(
color: Color(0xABCECECE),
blurRadius: 5,
offset: Offset(-2, 5),
),
BoxShadow(
color: const Color.fromARGB(148, 2, 70, 35),
blurRadius: 80,
offset: const Offset(0, 10),
),
],
),
),
Container(
height: screenHeight * 0.5,
width: screenWidth * 0.7,
decoration: BoxDecoration(
color: const Color(0x92757575),
borderRadius: BorderRadius.circular(32),
),
),
],
),
),
),
),
/// LOGIN BUTTON
Positioned(
top: screenHeight * 0.21,
left: screenWidth * 0.05,
child: _ShadowedCard(
shadow: const [
BoxShadow(
color: Color(0x62000000),
blurRadius: 10,
spreadRadius: 5,
offset: Offset(5, 5),
),
],
child: _FingerButton(
icon: "assets/images/faceLogin.svg",
label: "تسجيل الدخول",
onTap: () async {
final employeeId =
await sl<UserLocalDataSource>().getCachedEmployeeId();
if (employeeId == null) {
_showResultSnack('خطأ: لم يتم العثور على رقم الموظف');
return;
}
// ACTIVE SESSION CHECK (LOGIN)
try {
final hasActive = await sl<AttendanceRemoteDataSource>()
.hasActiveLogin(employeeId: employeeId);
if (hasActive) {
if (!mounted) return;
showDialog(
context: context,
builder:
(_) => AlertDialog(
title: const Text(
'تنبيه',
textAlign: TextAlign.center,
),
content: const Text(
'أنت مسجل دخول بالفعل، لا يمكنك تسجيل الدخول مرة أخرى.',
textAlign: TextAlign.center,
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('حسناً'),
),
],
),
);
return;
}
} catch (e) {
_showResultSnack('فشل التحقق من الجلسة: $e');
return;
}
if (!mounted) return;
// Fetch device location
final position =
await sl<LocationService>().getCurrentPosition();
if (!mounted) return;
final result = await Navigator.of(context).push(
MaterialPageRoute(
builder:
(_) => OvalCameraCapturePage(
isLogin: true,
onCapture: (
imageFile, {
required bool localAuth,
}) async {
final loginUseCase = sl<AttendanceLoginUsecase>();
await loginUseCase(
AttendanceLoginRequest(
employeeId: employeeId,
faceImage: imageFile,
localAuth: localAuth, // ✅
latitude: position?.latitude,
longitude: position?.longitude,
),
);
},
),
),
);
if (!mounted) return;
if (result == "local_auth_failed") {
_showResultSnack("فشل التحقق بالبصمة أو رمز القفل");
} else if (result == "retry_failed") {
_showResultSnack("فشل تسجيل الحضور بعد التحقق المحلي");
} else if (result == "retry_missing_file") {
_showResultSnack("تعذر إعادة المحاولة. حاول مرة أخرى.");
}
},
),
),
),
/// LOGOUT BUTTON
Positioned(
bottom: screenHeight * 0.2,
right: screenWidth * 0.1,
child: _ShadowedCard(
shadow: const [
BoxShadow(
color: Color(0xABCECECE),
blurRadius: 5,
spreadRadius: 3,
offset: Offset(-6, -6),
),
BoxShadow(
color: Color(0x92014221),
blurRadius: 10,
offset: Offset(-5, -5),
),
BoxShadow(
color: Color(0x7D1A1A1A),
blurRadius: 10,
spreadRadius: 3,
offset: Offset(5, 5),
),
],
child: _FingerButton(
icon: "assets/images/faceLogout.svg",
label: "تسجيل خروج",
onTap: () async {
final employeeId =
await sl<UserLocalDataSource>().getCachedEmployeeId();
if (employeeId == null) {
_showResultSnack('خطأ: لم يتم العثور على رقم الموظف');
return;
}
// ACTIVE SESSION CHECK (LOGOUT)
try {
final hasActive = await sl<AttendanceRemoteDataSource>()
.hasActiveLogin(employeeId: employeeId);
if (!hasActive) {
if (!mounted) return;
showDialog(
context: context,
builder:
(_) => AlertDialog(
title: const Text(
'تنبيه',
textAlign: TextAlign.center,
),
content: const Text(
'لا يوجد تسجيل دخول فعال لتسجيل الخروج.',
textAlign: TextAlign.center,
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('حسناً'),
),
],
),
);
return;
}
} catch (e) {
_showResultSnack('فشل التحقق من الجلسة: $e');
return;
}
if (!mounted) return;
// Fetch device location
final position =
await sl<LocationService>().getCurrentPosition();
if (!mounted) return;
final result = await Navigator.of(context).push(
MaterialPageRoute(
builder:
(_) => OvalCameraCapturePage(
isLogin: false,
onCapture: (
imageFile, {
required bool localAuth,
}) async {
final logoutUseCase =
sl<AttendanceLogoutUseCase>();
await logoutUseCase(
AttendanceLogoutRequest(
employeeId: employeeId,
faceImage: imageFile,
localAuth: localAuth, // ✅
latitude: position?.latitude,
longitude: position?.longitude,
),
);
},
),
),
);
if (!mounted) return;
if (result == "local_auth_failed") {
_showResultSnack("فشل التحقق بالبصمة أو رمز القفل");
} else if (result == "retry_failed") {
_showResultSnack("فشل تسجيل الخروج بعد التحقق المحلي");
} else if (result == "retry_missing_file") {
_showResultSnack("تعذر إعادة المحاولة. حاول مرة أخرى.");
}
},
),
),
),
],
),
);
}
}
/// SHADOW WRAPPER
class _ShadowedCard extends StatelessWidget {
final Widget child;
final List<BoxShadow> shadow;
const _ShadowedCard({required this.child, required this.shadow});
@override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
height: 160,
width: 160,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32),
boxShadow: shadow,
),
),
child,
],
);
}
}
/// BUTTON WIDGET
class _FingerButton extends StatelessWidget {
final String icon;
final String label;
final VoidCallback onTap;
const _FingerButton({
required this.icon,
required this.label,
required this.onTap,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
height: 160,
width: 160,
decoration: BoxDecoration(
color: const Color(0xFFEAFBF3),
borderRadius: BorderRadius.circular(32),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(icon, width: 75, height: 75),
const SizedBox(height: 10),
Text(
label,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Colors.black,
),
),
],
),
),
);
}
}