This commit is contained in:
Daniah Ayad Al-sultani
2026-01-13 14:17:59 +03:00
parent 4df24f5d8d
commit d5d07a901e
10 changed files with 336 additions and 210 deletions

View File

@@ -7,66 +7,75 @@ class AboutScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: AppBackground(
child: Column(
children: [
/// -------------------- SETTINGS BAR --------------------
SettingsBar(
selectedIndex: 0,
onTap: (_) {},
showBackButton: true,
onBackTap: () => Navigator.pop(context),
iconPaths: const [],
),
return Scaffold(
body: AppBackground(
child: SafeArea(
child: SingleChildScrollView(
child: Column(
children: [
/// -------------------- SETTINGS BAR --------------------
SettingsBar(
selectedIndex: 0,
onTap: (_) {},
showBackButton: true,
onBackTap: () => Navigator.pop(context),
iconPaths: const [],
),
const SizedBox(height: 12),
const SizedBox(height: 12),
/// -------------------- CENTER CONTENT --------------------
///
Expanded(
child: Center(
child: Align(
alignment: Alignment.topCenter,
child: Directionality(
textDirection: TextDirection.rtl,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text(
"عن الشركة",
style: TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
color: Colors.white,
/// -------------------- CENTER CONTENT --------------------
///
Center(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 24.0,
vertical: 10,
),
child: Align(
alignment: Alignment.topCenter,
child: Directionality(
textDirection: TextDirection.rtl,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text(
"عن الشركة",
style: TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
const SizedBox(height: 12),
const SizedBox(height: 12),
Container(
width: 200,
height: 1,
color: Color(0x8732C599),
),
const SizedBox(height: 14),
const Text(
"نص",
style: TextStyle(
fontSize: 18,
color: Colors.white70,
Container(
width: 200,
height: 1,
color: const Color(0x8732C599),
),
),
],
const SizedBox(height: 14),
const Text(
"شركة كودا ذ.م.م هي شركة عراقية رائدة تقدم حلولاً متميزة في البرمجيات المخصصة والتطبيقات وإدارة الخوادم والمواقع، ومنظومات الاتصال وخدمات الأمن السيبراني. تأسست عام 2008 ولديها عقود واتفاقيات عديدة مع مؤسسات حكومية عراقية والقطاع الخاص.\n\nوسعت الشركة شراكاتها مع وكالات عالمية مثل CODACS الأمريكية و Laipac الكندية و Teltonika اللتوانية وWolf Team الصينية وLibelium الإسبانية وOdoo العالمية وغيرها. مما أتاح لها تقديم أحدث التقنيات والمنتجات المبتكرة لعملائها.\n\nتوفر كودا حلولاً برمجية مخصصة للمؤسسات الكبيرة والدوائر الحكومية، مما يسهم في تبسيط الإجراءات وتقديم الخدمات للمواطنين بشكل إلكتروني وفعال.\n\nكما تقدم كودا مجموعة واسعة من المنتجات والخدمات الحديثة، بما في ذلك الشاشات الإعلانية، والبوابات الذكية، والمواقف الذكية، والأقفال، والمباني الذكية، وأجهزة الكشك (الخدمة الإلكترونية الذاتية)، وأجهزة محمولة تخصصية، وحساسات، وأجهزة نداء واستغاثة.\n\nبفضل هذه المنتجات والخدمات المبتكرة، تعزز كودا مكانتها الرائدة في السوق المحلي والإقليمي، وتساهم في تطوير التكنولوجيا وتعزيز جودة الحياة في العراق .",
style: TextStyle(
fontSize: 18,
color: Colors.white70,
height:
1.5, // Added line height for better readability
),
),
const SizedBox(height: 20), // Bottom padding
],
),
),
),
),
),
),
],
],
),
),
),
),

View File

@@ -3,7 +3,6 @@ import 'package:coda_project/screens/notifications_screen.dart';
import 'package:coda_project/screens/user_settings_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import '../widgets/login_animation.dart';
import '../widgets/settings_bar.dart';
class AttendanceScreen extends StatelessWidget {
@@ -17,45 +16,43 @@ class AttendanceScreen extends StatelessWidget {
textDirection: TextDirection.ltr,
child: Stack(
children: [
SizedBox(height: MediaQuery.of(context).size.height
),
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(),
),
);
}
},
),
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
top:
screenHeight *
0.14, // moved down because settings bar now exists
left: 0,
right: 0,
child: Center(
@@ -65,9 +62,7 @@ class AttendanceScreen extends StatelessWidget {
fontSize: 24,
fontWeight: FontWeight.w600,
color: Colors.white,
shadows: [
Shadow(color: Color(0x42000000), blurRadius: 6),
],
shadows: [Shadow(color: Color(0x42000000), blurRadius: 6)],
),
),
),
@@ -77,7 +72,9 @@ class AttendanceScreen extends StatelessWidget {
/// MAIN CARD AREA
/// ------------------------------
Positioned(
top: screenHeight * 0.2, // pushed down because of settings bar + greeting
top:
screenHeight *
0.2, // pushed down because of settings bar + greeting
left: 0,
right: 0,
child: Center(
@@ -110,7 +107,7 @@ class AttendanceScreen extends StatelessWidget {
),
),
Container(
height: screenHeight * 0.5,
height: screenHeight * 0.5,
width: screenWidth * 0.7,
decoration: BoxDecoration(
color: Color(0x92757575),
@@ -139,13 +136,12 @@ class AttendanceScreen extends StatelessWidget {
),
],
child: _FingerButton(
icon: "assets/images/login.svg",
icon: "assets/images/faceLogin.svg",
label: "تسجيل الدخول",
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => OvalCameraCapturePage(
),
builder: (_) => OvalCameraCapturePage(isLogin: true),
),
);
},
@@ -180,15 +176,12 @@ class AttendanceScreen extends StatelessWidget {
),
],
child: _FingerButton(
icon: "assets/images/logout.svg",
icon: "assets/images/faceLogout.svg",
label: "تسجيل خروج",
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => LoginAnimationScreen(
isLogin: false,
isSuccess: true,
),
builder: (_) => OvalCameraCapturePage(isLogin: false),
),
);
},
@@ -258,7 +251,7 @@ class _FingerButton extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(icon, width: 62, height: 62),
SvgPicture.asset(icon, width: 75, height: 75),
SizedBox(height: 10),
Text(
label,

View File

@@ -1,8 +1,11 @@
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'dart:async';
class OvalCameraCapturePage extends StatefulWidget {
const OvalCameraCapturePage({super.key});
final bool isLogin;
const OvalCameraCapturePage({super.key, this.isLogin = true});
@override
State<OvalCameraCapturePage> createState() => _OvalCameraCapturePageState();
@@ -12,6 +15,8 @@ class _OvalCameraCapturePageState extends State<OvalCameraCapturePage> {
CameraController? _cameraController;
bool _isCameraInitialized = false;
String? _errorMessage;
bool _isSuccess = false;
Timer? _timer;
@override
void initState() {
@@ -27,7 +32,7 @@ class _OvalCameraCapturePageState extends State<OvalCameraCapturePage> {
// Get available cameras
final cameras = await availableCameras();
// Check if cameras list is available
if (cameras.isEmpty) {
setState(() {
@@ -64,16 +69,31 @@ class _OvalCameraCapturePageState extends State<OvalCameraCapturePage> {
);
await _cameraController!.initialize();
if (!mounted) return;
setState(() {
_isCameraInitialized = true;
_errorMessage = null;
});
_timer = Timer(const Duration(seconds: 3), () {
if (mounted) {
setState(() {
_isSuccess = true;
});
// Auto-close after 2 seconds
Future.delayed(const Duration(seconds: 2), () {
if (mounted) {
Navigator.of(context).pop();
}
});
}
});
} catch (e) {
if (!mounted) return;
setState(() {
_errorMessage = "خطأ في تهيئة الكاميرا: $e";
_isCameraInitialized = false;
@@ -82,11 +102,10 @@ class _OvalCameraCapturePageState extends State<OvalCameraCapturePage> {
}
}
@override
void dispose() {
_cameraController?.dispose();
_timer?.cancel();
super.dispose();
}
@@ -95,88 +114,151 @@ class _OvalCameraCapturePageState extends State<OvalCameraCapturePage> {
return Scaffold(
backgroundColor: Color(0xff000000),
body: _errorMessage != null
? Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.camera_alt_outlined,
size: 64,
color: Colors.white70,
),
SizedBox(height: 16),
Text(
_errorMessage!,
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
body:
_errorMessage != null
? Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.camera_alt_outlined,
size: 64,
color: Colors.white70,
),
textAlign: TextAlign.center,
),
SizedBox(height: 24),
ElevatedButton(
onPressed: _initializeCamera,
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xffE8001A),
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 32, vertical: 12),
SizedBox(height: 16),
Text(
_errorMessage!,
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
child: Text("إعادة المحاولة"),
),
],
SizedBox(height: 24),
ElevatedButton(
onPressed: _initializeCamera,
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xffE8001A),
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(
horizontal: 32,
vertical: 12,
),
),
child: Text("إعادة المحاولة"),
),
],
),
),
),
)
: _isCameraInitialized && _cameraController != null
)
: _isCameraInitialized && _cameraController != null
? Stack(
children: [
SizedBox(height: MediaQuery.of(context).size.height ),
// Camera Preview
Positioned(
child: Center(child: CameraPreview(_cameraController!)),
),
// Oval overlay with dimmed background
Positioned.fill(
child: CustomPaint(
painter: _OvalOverlayPainter(),
children: [
SizedBox(height: MediaQuery.of(context).size.height),
// Camera Preview
Positioned(
child: Center(child: CameraPreview(_cameraController!)),
),
// Oval overlay with dimmed background
Positioned.fill(
child: CustomPaint(painter: _OvalOverlayPainter()),
),
// Top Text
Positioned(
top: 100,
left: 0,
right: 0,
child: Center(
child: Text(
widget.isLogin ? "تسجيل الدخول" : "تسجيل خروج",
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold,
fontFamily:
'Cairo', // Assuming Cairo font based on Arabic text
),
),
),
// // Capture button
// Positioned(
// bottom: 60,
// left: 0,
// right: 0,
// child: Center(
// child: GestureDetector(
// onTap: (){},
// child: Container(
// width: 72,
// height: 72,
// decoration: BoxDecoration(
// shape: BoxShape.circle,
// color: Colors.white,
// boxShadow: [
// BoxShadow(
// color: Colors.black26,
// blurRadius: 8,
// offset: Offset(0, 4),
// ),
// ],
// ),
// child: Icon(Icons.camera_alt, color: Color(0xffE8001A), size: 36),
// ),
// ),
// ),
// ),
],
)
: Center(child: CircularProgressIndicator(color: Color(0xffE8001A))),
),
// Bottom Text and Logo
Positioned(
bottom: 80,
left: 0,
right: 0,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
_isSuccess
? (widget.isLogin
? "تم تسجيل دخولك بنجاح"
: "تم تسجيل خروجك بنجاح")
: (widget.isLogin
? "يتم تسجيل الدخول ..."
: "يتم تسجيل الخروج ..."),
style: const TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 20),
// Logo
SizedBox(
height: _isSuccess ? 80 : 60,
width: _isSuccess ? 80 : 60,
child: SvgPicture.asset(
_isSuccess
? 'assets/images/logSuccess.svg'
: 'assets/images/logLoading.svg',
// ignore: deprecated_member_use
color: Colors.white,
fit: BoxFit.contain,
),
),
],
),
),
// // Capture button
// Positioned(
// bottom: 60,
// left: 0,
// right: 0,
// child: Center(
// child: GestureDetector(
// onTap: (){},
// child: Container(
// width: 72,
// height: 72,
// decoration: BoxDecoration(
// shape: BoxShape.circle,
// color: Colors.white,
// boxShadow: [
// BoxShadow(
// color: Colors.black26,
// blurRadius: 8,
// offset: Offset(0, 4),
// ),
// ],
// ),
// child: Icon(Icons.camera_alt, color: Color(0xffE8001A), size: 36),
// ),
// ),
// ),
// ),
],
)
: Center(
child: CircularProgressIndicator(color: Color(0xffE8001A)),
),
);
}
}
@@ -194,11 +276,16 @@ class _OvalOverlayPainter extends CustomPainter {
);
// Create a path for the whole screen
final screenPath = Path()..addRect(Rect.fromLTWH(0, 0, size.width, size.height));
final screenPath =
Path()..addRect(Rect.fromLTWH(0, 0, size.width, size.height));
// Create a path for the oval
final ovalPath = Path()..addOval(ovalRect);
// Subtract the oval from the screen path
final overlayPath = Path.combine(PathOperation.difference, screenPath, ovalPath);
final overlayPath = Path.combine(
PathOperation.difference,
screenPath,
ovalPath,
);
// Draw the dimmed area outside the oval with gradient
final gradient = LinearGradient(
@@ -209,11 +296,12 @@ class _OvalOverlayPainter extends CustomPainter {
Color.fromARGB(255, 0, 20, 15), // bottom deep green
],
);
final paint = Paint()
..shader = gradient.createShader(
Rect.fromLTWH(0, 0, size.width, size.height),
)
..style = PaintingStyle.fill;
final paint =
Paint()
..shader = gradient.createShader(
Rect.fromLTWH(0, 0, size.width, size.height),
)
..style = PaintingStyle.fill;
canvas.drawPath(overlayPath, paint);
// Draw glowing circles effect (like AppBackground) - drawn after overlay
@@ -222,9 +310,10 @@ class _OvalOverlayPainter extends CustomPainter {
final topCircleRadius = 150.0;
// Draw multiple circles with different opacities for spread effect (spreadRadius: 160)
for (int i = 0; i < 5; i++) {
final spreadPaint = Paint()
..color = Color.fromARGB(69 ~/ (i + 1), 62, 254, 190)
..maskFilter = MaskFilter.blur(BlurStyle.normal, 140 - (i * 20));
final spreadPaint =
Paint()
..color = Color.fromARGB(69 ~/ (i + 1), 62, 254, 190)
..maskFilter = MaskFilter.blur(BlurStyle.normal, 140 - (i * 20));
canvas.drawCircle(
topCircleCenter,
topCircleRadius + (i * 30),
@@ -237,9 +326,10 @@ class _OvalOverlayPainter extends CustomPainter {
final bottomCircleRadius = 160.0;
// Draw multiple circles with different opacities for spread effect (spreadRadius: 60)
for (int i = 0; i < 5; i++) {
final spreadPaint = Paint()
..color = Color.fromARGB(83 ~/ (i + 1), 62, 254, 190)
..maskFilter = MaskFilter.blur(BlurStyle.normal, 180 - (i * 25));
final spreadPaint =
Paint()
..color = Color.fromARGB(83 ~/ (i + 1), 62, 254, 190)
..maskFilter = MaskFilter.blur(BlurStyle.normal, 180 - (i * 25));
canvas.drawCircle(
bottomCircleCenter,
bottomCircleRadius + (i * 40),
@@ -248,13 +338,14 @@ class _OvalOverlayPainter extends CustomPainter {
}
// Draw oval border
final borderPaint = Paint()
..color = Colors.greenAccent
..style = PaintingStyle.stroke
..strokeWidth = 4;
final borderPaint =
Paint()
..color = Colors.greenAccent
..style = PaintingStyle.stroke
..strokeWidth = 4;
canvas.drawOval(ovalRect, borderPaint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
}