bookmywages/lib/view/auth/otp_screen.dart
2025-10-16 11:21:52 +05:30

301 lines
10 KiB
Dart

import 'package:bookmywages/consts_widgets/app_assets.dart';
import 'package:bookmywages/consts_widgets/app_colors.dart';
import 'package:bookmywages/consts_widgets/comman_button.dart';
import 'package:bookmywages/model/otp_model.dart' show OtpModel;
import 'package:bookmywages/viewmodel/api_controller.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:pinput/pinput.dart';
class OtpScreen extends ConsumerStatefulWidget {
final String? userId;
const OtpScreen({super.key, required this.userId});
@override
ConsumerState<OtpScreen> createState() => _OtpScreenState();
}
class _OtpScreenState extends ConsumerState<OtpScreen> {
String _enteredOtp = '';
bool _isLoading = false;
@override
void initState() {
super.initState();
// No need to parse userId, keeping it as String
}
void _verifyOtp() async {
if (widget.userId!.isEmpty || _enteredOtp.length != 4) {
Fluttertoast.showToast(
msg: "Invalid OTP or missing user information",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
);
return;
}
setState(() {
_isLoading = true;
});
try {
// Use userId directly as String
final otpModel = OtpModel(
userId: widget.userId.toString(),
otp: _enteredOtp,
);
final result = await ref.read(otpVerificationProvider(otpModel).future);
if (mounted) {
Fluttertoast.showToast(
msg: "Verification Successful: ${result['message'] ?? 'Success'}",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.green,
textColor: Colors.white,
);
// context.push(RouterConts.homescreen);
}
} catch (e) {
if (mounted) {
Fluttertoast.showToast(
msg: "Verification Failed: ${e.toString()}",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.red,
textColor: Colors.white,
);
}
} finally {
if (mounted) {
setState(() {
_isLoading = false;
});
}
}
}
void _resendOtp() async {
if (widget.userId!.isEmpty) {
Fluttertoast.showToast(
msg: "Missing user information",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.red,
textColor: Colors.white,
);
return;
}
setState(() {
_isLoading = true;
});
try {
// Implement resend OTP API call using String userId
// For example:
// final result = await ref.read(resendOtpProvider(widget.userId).future);
if (mounted) {
Fluttertoast.showToast(
msg: "OTP resent successfully",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.green,
textColor: Colors.white,
);
}
} catch (e) {
if (mounted) {
Fluttertoast.showToast(
msg: "Failed to resend OTP: ${e.toString()}",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.red,
textColor: Colors.white,
);
}
} finally {
if (mounted) {
setState(() {
_isLoading = false;
});
}
}
}
@override
Widget build(BuildContext context) {
final screenSize = MediaQuery.of(context).size;
final double horizontalPadding = screenSize.width * 0.05;
return WillPopScope(
onWillPop: () async {
// context.push(RouterConts.siguppage);
return false;
},
child: Scaffold(
backgroundColor: AppColors.secondprimary,
resizeToAvoidBottomInset: true,
body: SafeArea(
child: SingleChildScrollView(
child: Column(
children: [
Image.asset(
AppAssets.login,
width: screenSize.width,
fit: BoxFit.cover,
),
Transform.translate(
offset: const Offset(0, -150),
child: Container(
width: double.infinity,
margin: EdgeInsets.symmetric(horizontal: horizontalPadding),
padding: EdgeInsets.all(screenSize.width * 0.05),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32.73),
border: Border.all(
width: 1.09,
color: const Color(0xFFA39898),
),
boxShadow: const [
BoxShadow(
offset: Offset(0, -4),
blurRadius: 12.3,
color: Color(0x66E0E0E0),
),
BoxShadow(
offset: Offset(0, 4),
blurRadius: 4,
color: Color(0x66000000),
),
],
color: Colors.white,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(height: 20),
const Text(
"OTP Verification",
style: TextStyle(
fontSize: 28,
fontFamily: "Gilroy-ExtraBold",
fontWeight: FontWeight.w800,
height: 1.0,
letterSpacing: 0.64,
),
),
SizedBox(height: screenSize.height * 0.03),
const Text(
"Enter the OTP sent to your number",
style: TextStyle(
fontFamily: 'Gilroy-Medium',
fontWeight: FontWeight.w400,
fontSize: 16,
height: 1.0,
letterSpacing: 0.16,
),
),
const SizedBox(height: 27),
Pinput(
length: 4,
defaultPinTheme: PinTheme(
width: 56,
height: 56,
textStyle: const TextStyle(
fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.w600,
),
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.grey,
width: 3,
),
),
),
),
focusedPinTheme: PinTheme(
width: 56,
height: 56,
textStyle: const TextStyle(
fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.w600,
),
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
color: AppColors.primary,
width: 3,
),
),
),
),
onChanged: (pin) => setState(() => _enteredOtp = pin),
onCompleted:
(pin) => setState(() => _enteredOtp = pin),
),
const SizedBox(height: 40),
RichText(
text: TextSpan(
text: "Didn't receive code? ",
style: const TextStyle(
fontFamily: 'Gilroy-ExtraBold',
fontWeight: FontWeight.w700,
fontSize: 17,
height: 1.0,
letterSpacing: 0.01,
color: Color(0xFF9F9F9F),
),
children: [
TextSpan(
text: "Resend",
style: const TextStyle(
color: Color(0xFF0066FF),
),
recognizer:
TapGestureRecognizer()..onTap = _resendOtp,
),
],
),
),
const SizedBox(height: 40),
CommanButton(
text: 'Verify',
textStyle: const TextStyle(
fontFamily: 'Gilroy-Black',
fontWeight: FontWeight.w800,
fontSize: 20,
height: 1.0,
color: AppColors.secondprimary,
),
onPressed: _verifyOtp,
isPrimary: true,
backgroundColor: AppColors.primary,
textColor: AppColors.secondprimary,
width: 230,
),
const SizedBox(height: 10),
],
),
),
),
],
),
),
),
),
);
}
}