Files
tripz-llc/apps/rider/lib/views/auth/otp_register.dart
T
HamzaandClaude Opus 4.8 6234e66471 feat: Gemini AI (doc OCR + face match) + role-assignment endpoints
- GeminiService (integrations/gemini, @Global): extractDocument (OCR fields) + faceMatch; graceful if no GEMINI_API_KEY
- documents: face-match now real via Gemini; POST /admin/documents/:id/ocr extracts fields for CS auto-fill
- roles: PATCH /admin/users/:id/role (admin) + POST /platform/users/role (bootstrap via x-platform-secret)
- config: gemini + platform.secret; .env.example entries

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 20:01:26 +03:00

177 lines
7.0 KiB
Dart

import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../constant/box_name.dart';
import '../../controller/auth/login_controller.dart';
import '../../controller/auth/otp_controller.dart';
import '../../controller/local/phone_intel/intl_phone_field.dart';
import '../../main.dart';
class OtpPage extends StatefulWidget {
final String phoneNumber;
const OtpPage({super.key, required this.phoneNumber});
@override
State<OtpPage> createState() => _OtpPageState();
}
class _OtpPageState extends State<OtpPage> {
final _otpController = TextEditingController();
final _formKey = GlobalKey<FormState>();
bool _loading = false;
void _verifyOtp() async {
if (!_formKey.currentState!.validate()) return;
setState(() => _loading = true);
final otp = _otpController.text.trim();
try {
// await PhoneAuthHelper.verifyOtpAndRegister(widget.phoneNumber, otp);
// بعد نجاح التسجيل أو تسجيل الدخول، نذهب مباشرة للصفحة الرئيسية
if (mounted) {
Get.find<LoginController>().loginUsingCredentials(
box.read(BoxName.passengerID).toString(),
box.read(BoxName.email).toString(),
// widget.phoneNumber,
);
}
} catch (e) {
_showError('فشل التحقق. حاول مرة أخرى.');
} finally {
if (mounted) setState(() => _loading = false);
}
}
void _showError(String message) {
Get.snackbar(
'Error',
message,
backgroundColor: Colors.redAccent,
colorText: Colors.white,
snackPosition: SnackPosition.BOTTOM,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF2E1C59), Color(0xFF1A237E), Color(0xFF0D1117)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: Center(
child: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: Column(
children: [
Image.asset('assets/images/logo.gif', height: 90),
const SizedBox(height: 20),
const Text('OTP Verification',
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
color: Colors.white)),
const SizedBox(height: 10),
Text(
'أدخل رمز التحقق المرسل إلى ${widget.phoneNumber}',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white.withOpacity(0.7)),
),
const SizedBox(height: 30),
ClipRRect(
borderRadius: BorderRadius.circular(22),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20),
child: Container(
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: const Color(0xFF1A237E).withOpacity(0.25),
borderRadius: BorderRadius.circular(22),
border: Border.all(color: Colors.white24),
),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: _otpController,
keyboardType: TextInputType.number,
maxLength: 6,
style: const TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText: 'OTP'.tr,
counterText: '',
labelStyle:
const TextStyle(color: Colors.white70),
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.white30),
borderRadius: BorderRadius.circular(12)),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Color(0xFF00E5FF), width: 2),
borderRadius: BorderRadius.circular(12)),
),
validator: (v) {
if (v == null || v.trim().length != 6) {
return 'رمز التحقق يجب أن يكون 6 أرقام';
}
return null;
},
),
const SizedBox(height: 24),
_loading
? const CircularProgressIndicator(
color: Colors.white)
: SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: _verifyOtp,
style: ElevatedButton.styleFrom(
backgroundColor:
const Color(0xFF00E5FF),
padding: const EdgeInsets.symmetric(
vertical: 16),
),
child: const Text('Verify OTP',
style: TextStyle(
color: Color(0xFF1A1A2E),
fontWeight: FontWeight.bold)),
),
),
],
),
),
),
),
),
const SizedBox(height: 16),
TextButton(
onPressed: () async {
// إعادة إرسال OTP
setState(() => _loading = true);
// final success = await PhoneAuthHelper.sendOtpAndOpenVerify(
// widget.phoneNumber);
setState(() => _loading = false);
// if (!success) _showError('فشل إعادة الإرسال');
},
child: const Text('Resend OTP',
style: TextStyle(color: Colors.white70)),
),
],
),
),
),
),
);
}
}