209 lines
8.1 KiB
Dart
209 lines
8.1 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:slider_button_lite/feature/presentation/slider_button/slider.dart';
|
||
import 'package:slider_button_lite/feature/presentation/slider_button/slider_button_prop.dart';
|
||
import 'package:get/get.dart';
|
||
import 'package:nearle/controllers/riderlog.dart';
|
||
import 'package:shared_preferences/shared_preferences.dart';
|
||
import 'package:nearle/widget/Bottom_page.dart';
|
||
|
||
class SigninBanner extends StatefulWidget {
|
||
const SigninBanner({super.key});
|
||
|
||
@override
|
||
State<SigninBanner> createState() => _SigninBannerState();
|
||
}
|
||
|
||
class _SigninBannerState extends State<SigninBanner> {
|
||
String _shiftText = 'Your shift: -';
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
// ✅ CRITICAL: Load shift info in background, don't block UI
|
||
_loadShiftInfo();
|
||
}
|
||
|
||
Future<void> _loadShiftInfo() async {
|
||
try {
|
||
final prefs = await SharedPreferences.getInstance();
|
||
if (mounted) {
|
||
setState(() {
|
||
final s = (prefs.getString('starttime') ?? '').trim();
|
||
final e = (prefs.getString('endtime') ?? '').trim();
|
||
_shiftText = (s.isEmpty || e.isEmpty)
|
||
? 'Your shift: -'
|
||
: 'Your shift: $s – $e';
|
||
});
|
||
}
|
||
} catch (e) {
|
||
// Keep default text on error
|
||
}
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
final size = MediaQuery.of(context).size;
|
||
final width = size.width;
|
||
final height = size.height;
|
||
|
||
return Scaffold(
|
||
appBar: AppBar(
|
||
backgroundColor: Colors.white,
|
||
elevation: 0,
|
||
scrolledUnderElevation: 0,
|
||
surfaceTintColor: Colors.transparent,
|
||
automaticallyImplyLeading: false,
|
||
),
|
||
backgroundColor: Colors.white,
|
||
body: SafeArea(
|
||
child: Center(
|
||
child: SingleChildScrollView(
|
||
padding: EdgeInsets.symmetric(horizontal: width * 0.01),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.center,
|
||
children: [
|
||
SizedBox(height: height * 0.02),
|
||
|
||
Text(
|
||
"Welcome Back!",
|
||
style: TextStyle(
|
||
fontSize: width * 0.07,
|
||
fontWeight: FontWeight.bold,
|
||
color: const Color(0xFF6A1B9A),
|
||
),
|
||
textAlign: TextAlign.center,
|
||
),
|
||
SizedBox(height: height * 0.01),
|
||
|
||
Text(
|
||
"Start your ride and make today amazing!",
|
||
style: TextStyle(
|
||
fontSize: width * 0.04,
|
||
color: Colors.grey[600],
|
||
),
|
||
textAlign: TextAlign.center,
|
||
),
|
||
SizedBox(height: height * 0.04),
|
||
|
||
CircleAvatar(
|
||
radius: width * 0.14,
|
||
backgroundColor: const Color(0xFFEDE7F6),
|
||
child: Icon(
|
||
Icons.person,
|
||
color: const Color(0xFF6A1B9A),
|
||
size: width * 0.12,
|
||
),
|
||
),
|
||
SizedBox(height: height * 0.015),
|
||
|
||
// ✅ CRITICAL: Show shift text immediately (no FutureBuilder blocking)
|
||
Text(
|
||
_shiftText,
|
||
style: TextStyle(
|
||
color: Colors.grey[700],
|
||
fontSize: width * 0.04,
|
||
fontWeight: FontWeight.w500,
|
||
),
|
||
),
|
||
SizedBox(height: height * 0.04),
|
||
|
||
Image.asset('assets/images/signin_banner.png'),
|
||
SizedBox(height: height * 0.05),
|
||
|
||
LayoutBuilder(
|
||
builder: (context, constraints) {
|
||
final sliderWidth = constraints.maxWidth;
|
||
return Padding(
|
||
padding: const EdgeInsets.all(8.0),
|
||
child: SliderButton(
|
||
properties: SliderButtonProperties(
|
||
height: height * 0.07,
|
||
width: sliderWidth,
|
||
buttonSize: height * 0.065,
|
||
disable: false,
|
||
isLoading: false,
|
||
backgroundColor: const Color(0xFF6A1B9A),
|
||
disableButtonColor: const Color(0xFFCCCCDD),
|
||
dismissThresholds: 0.9,
|
||
action: () async {
|
||
try {
|
||
final rlc = Get.find<RiderLogController>();
|
||
// Ensure any previous break is ended when coming online
|
||
debugPrint(
|
||
'[SIGNIN_BANNER] Ending break before going online',
|
||
);
|
||
final breakEnded = await rlc
|
||
.endBreakAuto()
|
||
.timeout(
|
||
const Duration(seconds: 12),
|
||
onTimeout: () => false,
|
||
);
|
||
debugPrint(
|
||
'[SIGNIN_BANNER] endBreakAuto -> $breakEnded',
|
||
);
|
||
// Set rider ON duty (onduty = 1)
|
||
final ok = await rlc.setOnDuty(true);
|
||
if (ok && context.mounted) {
|
||
Get.offAll(() => const BottomPage());
|
||
}
|
||
// Show snackbar if still on this screen (unlikely after navigation)
|
||
if (context.mounted) {
|
||
ScaffoldMessenger.of(context).showSnackBar(
|
||
SnackBar(
|
||
content: Text(
|
||
ok
|
||
? "You're now on duty"
|
||
: "Failed to update status",
|
||
),
|
||
backgroundColor: ok
|
||
? Colors.deepPurple
|
||
: Colors.red,
|
||
),
|
||
);
|
||
}
|
||
} catch (e) {
|
||
debugPrint(
|
||
'[SIGNIN_BANNER] Error updating status: $e',
|
||
);
|
||
}
|
||
return false;
|
||
},
|
||
label: Text(
|
||
'Slide to Start',
|
||
style: TextStyle(
|
||
fontSize: width * 0.05,
|
||
fontWeight: FontWeight.w600,
|
||
color: Colors.white,
|
||
),
|
||
),
|
||
alignLabel: Alignment.center,
|
||
icon: ClipOval(
|
||
child: Material(
|
||
color: Colors.white,
|
||
child: SizedBox(
|
||
width: height * 0.065,
|
||
height: height * 0.065,
|
||
child: const Icon(
|
||
Icons.arrow_forward_ios_outlined,
|
||
color: Color(0xFF6A1B9A),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
);
|
||
},
|
||
),
|
||
SizedBox(height: height * 0.04),
|
||
// Add extra bottom padding for devices with navigation bars
|
||
SizedBox(height: MediaQuery.of(context).padding.bottom),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|