initial commit: push everything

This commit is contained in:
2026-07-06 20:27:53 +05:30
commit df4e044d74
329 changed files with 36620 additions and 0 deletions

View File

@@ -0,0 +1,140 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:nearle/views/helpers/constants/Colorconstants.dart';
import 'package:nearle/views/helpers/constants/Font_constant.dart';
class Intro1 extends GetResponsiveView {
Intro1({super.key});
@override
Widget builder() {
// 🔹 Use `screen.height` and `screen.width` safely here
final height = screen.height;
final width = screen.width;
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.dark.copyWith(
// Make the status bar area white instead of black, with dark icons
statusBarColor: Colors.white,
statusBarIconBrightness: Brightness.dark,
statusBarBrightness: Brightness.light,
systemNavigationBarColor: Colors.white,
),
child: Scaffold(
backgroundColor: Colors.white,
appBar: PreferredSize(
preferredSize: Size.fromHeight(height * 0.12),
child: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.transparent,
elevation: 0,
systemOverlayStyle: SystemUiOverlayStyle.dark.copyWith(
statusBarColor: Colors.white,
statusBarIconBrightness: Brightness.dark,
statusBarBrightness: Brightness.light,
systemNavigationBarColor: Colors.white,
),
flexibleSpace: Align(
alignment: Alignment.topLeft,
child: Container(
height: height * 0.14,
width: width * 0.25,
decoration: BoxDecoration(
color: ColorConstants.primaryColor,
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(width * 0.25),
),
),
),
),
),
),
body: SafeArea(
child: Stack(
children: [
Positioned(
bottom: -height * 0.12,
left: -width * 0.1,
right: -width * 0.1,
child: Container(
width: width * 1.2,
height: height * 0.28,
decoration: BoxDecoration(
color: const Color(0xFFF3EAF9),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(width * 0.8),
topRight: Radius.circular(width * 0.8),
),
),
),
),
Center(
child: Padding(
padding: EdgeInsets.only(top: height * 0.08),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
children: [
Transform.translate(
offset: Offset(0, -height * 0.08),
child: Text(
'Welcome to',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: height * 0.045,
fontWeight: FontWeight.bold,
fontFamily: FontConstants.fontFamily,
),
),
),
Transform.translate(
offset: Offset(0, -height * 0.1),
child: Text(
'Nearle !',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: height * 0.045,
fontWeight: FontWeight.bold,
fontFamily: FontConstants.fontFamily,
),
),
),
],
),
Transform.translate(
offset: Offset(0, -height * 0.08),
child: Text(
'Find delivery opportunities anytime,\nanywhere | Earn with ease!',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: height * 0.022,
color: Colors.grey,
fontFamily: FontConstants.fontFamily,
),
),
),
Transform.translate(
offset: Offset(0, -height * 0.09),
child: Image.asset(
'assets/images/intro1.png',
height: height * 0.35,
width: width * 0.75,
fit: BoxFit.contain,
),
),
],
),
),
),
],
),
),
),
);
}
}

View File

@@ -0,0 +1,144 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:nearle/views/helpers/constants/Colorconstants.dart';
import 'package:nearle/views/helpers/constants/Font_constant.dart';
class Intro2 extends GetResponsiveView {
Intro2({super.key});
@override
Widget builder() {
final height = screen.height;
final width = screen.width;
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.dark.copyWith(
// Make the status bar area white instead of black, with dark icons
statusBarColor: Colors.white,
statusBarIconBrightness: Brightness.dark,
statusBarBrightness: Brightness.light,
systemNavigationBarColor: Colors.white,
),
child: Scaffold(
backgroundColor: Colors.white,
appBar: PreferredSize(
preferredSize: Size.fromHeight(height * 0.12),
child: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.transparent,
elevation: 0,
systemOverlayStyle: SystemUiOverlayStyle.dark.copyWith(
statusBarColor: Colors.white,
statusBarIconBrightness: Brightness.dark,
statusBarBrightness: Brightness.light,
systemNavigationBarColor: Colors.white,
),
flexibleSpace: Align(
alignment: Alignment.topRight,
child: Container(
height: height * 0.14,
width: width * 0.25,
decoration: BoxDecoration(
color: ColorConstants.primaryColor,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(width * 0.25),
),
),
),
),
),
),
body: SafeArea(
child: Stack(
children: [
// Bottom curve
Positioned(
bottom: -height * 0.12,
left: -width * 0.1,
right: -width * 0.1,
child: Container(
width: width * 1.2,
height: height * 0.28,
decoration: BoxDecoration(
color: const Color(0xFFF3EAF9),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(width * 0.8),
topRight: Radius.circular(width * 0.8),
),
),
),
),
// Center content
Center(
child: Padding(
padding: EdgeInsets.only(top: height * 0.08),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// Title
Column(
children: [
Transform.translate(
offset: Offset(0, -height * 0.08),
child: Text(
'Orders That',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: height * 0.045,
fontWeight: FontWeight.bold,
fontFamily: FontConstants.fontFamily,
),
),
),
Transform.translate(
offset: Offset(0, -height * 0.1),
child: Text(
'Find You',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: height * 0.045,
fontWeight: FontWeight.bold,
fontFamily: FontConstants.fontFamily,
),
),
),
],
),
Transform.translate(
offset: Offset(0, -height * 0.08),
child: Text(
'Get assigned deliveries based on your\nlocation for faster and smarter work.',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: height * 0.022,
color: Colors.grey,
fontFamily: FontConstants.fontFamily,
),
),
),
// Image in center
Transform.translate(
offset: Offset(0, -height * 0.09),
child: Image.asset(
'assets/images/intro2.png',
height: height * 0.35,
width: width * 0.75,
fit: BoxFit.contain,
),
),
],
),
),
),
],
),
),
),
);
}
}

View File

@@ -0,0 +1,152 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:nearle/views/helpers/constants/Colorconstants.dart';
import 'package:nearle/views/helpers/constants/Font_constant.dart';
class Intro3 extends GetResponsiveView {
final VoidCallback onFinish;
Intro3({
super.key,
required this.onFinish,
required PageController controller,
});
@override
Widget builder() {
final height = screen.height;
final width = screen.width;
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.light.copyWith(
// Keep status bar transparent over the purple gradient on this screen
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.light,
statusBarBrightness: Brightness.dark,
systemNavigationBarColor: Colors.white,
),
child: Scaffold(
backgroundColor: Colors.white,
appBar: PreferredSize(
preferredSize: Size.fromHeight(height * 0.35),
child: AppBar(
automaticallyImplyLeading: false,
elevation: 0,
backgroundColor: Colors.transparent,
systemOverlayStyle: SystemUiOverlayStyle.light.copyWith(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.light,
statusBarBrightness: Brightness.dark,
),
flexibleSpace: Container(
width: double.infinity,
height: height * 0.36,
decoration: BoxDecoration(
gradient: const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
ColorConstants.primaryColor,
ColorConstants.primaryColor,
],
),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(width * 0.49),
bottomRight: Radius.circular(width * 0.49),
),
),
child: SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: width * 0.06,
vertical: height * 0.02,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(height: height * 0.06),
Text(
'Deliver. Earn.\nRepeat.',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: height * 0.045,
fontWeight: FontWeight.bold,
color: Colors.white,
height: 1.2,
fontFamily: FontConstants.fontFamily,
),
),
SizedBox(height: height * 0.02),
Text(
'Track your trips, and enjoy \npayouts every week.',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: height * 0.019,
color: Colors.white.withOpacity(0.9),
height: 1.4,
fontFamily: FontConstants.fontFamily,
),
),
],
),
),
),
),
),
),
body: SafeArea(
child: Column(
children: [
Expanded(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: width * 0.05),
child: Transform.translate(
offset: Offset(0, -height * 0.01),
child: Image.asset(
'assets/images/intro3.png',
height: height * 0.35,
width: width * 0.75,
fit: BoxFit.contain,
),
),
),
),
SizedBox(height: height * 0.04),
// Button at bottom
Padding(
padding: EdgeInsets.symmetric(horizontal: width * 0.08),
child: SizedBox(
width: double.infinity,
height: 55,
child: ElevatedButton(
onPressed: onFinish,
style: ElevatedButton.styleFrom(
backgroundColor: ColorConstants.primaryColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: Text(
"Start",
style: TextStyle(
fontSize: 21,
fontWeight: FontWeight.bold,
fontFamily: FontConstants.fontFamily,
color: Colors.white,
),
),
),
),
),
SizedBox(height: height * 0.03),
],
),
),
),
);
}
}

View File

@@ -0,0 +1,82 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:nearle/views/helpers/constants/Colorconstants.dart';
import 'package:nearle/views/introscreens/intro1.dart';
import 'package:nearle/views/introscreens/intro2.dart';
import 'package:nearle/views/introscreens/intro3.dart';
import 'package:nearle/views/onboardscreens/Sign_in.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
class Introscreen extends StatefulWidget {
const Introscreen({super.key});
@override
State<Introscreen> createState() => _IntroscreenState();
}
class _IntroscreenState extends State<Introscreen> {
late final PageController _controller;
static const String _prefsHasSeenIntroKey = 'has_seen_intro';
void _finishOnboarding() {
_completeOnboarding();
}
Future<void> _completeOnboarding() async {
try {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(_prefsHasSeenIntroKey, true);
} catch (_) {}
if (!mounted) return;
Get.offAll(() => const SignIn());
}
@override
void initState() {
super.initState();
_controller = PageController();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
alignment: Alignment.bottomCenter, // positions the indicator
children: [
PageView(
controller: _controller,
children: [
Intro1(),
Intro2(),
Intro3(controller: _controller, onFinish: _finishOnboarding),
],
),
Container(
// Move indicator slightly up so it doesn't sit under the bottom curve
alignment: const Alignment(0, 0.55),
child: SmoothPageIndicator(
controller: _controller,
count: 3,
effect: ExpandingDotsEffect(
expansionFactor: 3, // How much the active dot expands
dotHeight: 7,
dotWidth: 7,
spacing: 8,
dotColor: Colors.grey,
activeDotColor: ColorConstants.primaryColor,
),
),
),
],
),
);
}
}

View File

@@ -0,0 +1,188 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'dart:async';
import 'package:nearle/views/helpers/constants/Colorconstants.dart';
import 'package:nearle/views/introscreens/introscreen.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:nearle/widget/Bottom_page.dart';
import 'package:nearle/views/onboardscreens/Sign_in.dart';
import 'package:nearle/views/onboardscreens/signin_banner.dart';
import 'package:nearle/views/updatescreen/UpdateScreen.dart';
import 'package:new_version_plus/new_version_plus.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:nearle/views/onboardscreens/Mpin.dart';
import 'package:nearle/controllers/auth.dart';
class Splashscreen extends StatefulWidget {
const Splashscreen({super.key});
@override
State<Splashscreen> createState() => _SplashscreenState();
}
class _SplashscreenState extends State<Splashscreen> {
late final ImageProvider _logoProvider;
bool _imagePrecached = false;
bool _hasCheckedUpdate = false;
@override
void initState() {
super.initState();
_logoProvider = const AssetImage("assets/images/nearlesplash2.png");
WidgetsBinding.instance.addPostFrameCallback((_) async {
try {
await precacheImage(_logoProvider, context);
if (mounted) {
setState(() {
_imagePrecached = true;
});
}
} catch (e) {
if (mounted) {
setState(() {
_imagePrecached = true;
});
}
}
});
// FAST splash: 1 second
Timer(const Duration(seconds: 1), () {
if (mounted) {
_startNextStep();
}
});
}
// FAST second step: 0.2 sec
void _startNextStep() {
Timer(const Duration(milliseconds: 200), () {
if (mounted && !_hasCheckedUpdate) {
_checkForUpdateAndNavigate();
}
});
}
Future<void> _checkForUpdateAndNavigate() async {
if (_hasCheckedUpdate) return;
_hasCheckedUpdate = true;
try {
final newVersion = NewVersionPlus(
iOSId: '284882215',
androidId: "com.nearle.partner",
);
final status = await newVersion.getVersionStatus();
if (status != null && status.canUpdate) {
if (mounted) {
Get.offAll(
() => UpdateScreen(
mCurrentVersion: status.localVersion,
mUpdateVersion: status.storeVersion,
mIsForceUpdate: true,
),
transition: Transition.fadeIn,
);
}
return;
}
} catch (e) {}
_navigateToNextScreen();
}
Future<void> _navigateToNextScreen() async {
final prefs = await SharedPreferences.getInstance();
final bool isLoggedOut = prefs.getBool('logged_out') ?? false;
final bool hasSeenIntro = prefs.getBool('has_seen_intro') ?? false;
final int? savedUserId = prefs.getInt('userid');
// 🚀 Check for App Update (Force Login if version changed)
try {
final packageInfo = await PackageInfo.fromPlatform();
final currentVersion = packageInfo.version;
final lastRunVersion = prefs.getString('last_run_version');
if (lastRunVersion != null && lastRunVersion != currentVersion) {
debugPrint(
'[SPLASH] App update detected: $lastRunVersion -> $currentVersion. Forcing re-verification.',
);
final String? savedPhone = prefs.getString('contactno');
final int? savedUserId = prefs.getInt('userid');
// Update stored version
await prefs.setString('last_run_version', currentVersion);
if (savedUserId != null && savedPhone != null && savedPhone.isNotEmpty) {
debugPrint('[SPLASH] User was logged in. Redirecting to MPIN page.');
// Initialize AuthController and set the phone for MPIN verification
final auth = Get.put(AuthController());
auth.currentPhone = savedPhone;
// Clear sensitive session data to force re-verification
await prefs.remove('userid');
await prefs.remove('partnerid');
await prefs.remove('onduty');
await prefs.setBool('logged_out', true);
if (mounted) {
Get.offAll(() => Mpin());
}
return;
} else {
debugPrint('[SPLASH] User was not logged in. Redirecting to Sign In.');
if (mounted) {
Get.offAll(() => const SignIn());
}
return;
}
}
// Save current version for next run
await prefs.setString('last_run_version', currentVersion);
} catch (e) {
debugPrint('[SPLASH] Version check error: $e');
}
if (!mounted) return;
if (!isLoggedOut && savedUserId != null && savedUserId > 0) {
final onduty = prefs.getInt('onduty') ?? 0;
if (onduty == 0) {
Get.offAll(() => const SigninBanner());
} else {
Get.offAll(() => const BottomPage());
}
} else {
if (hasSeenIntro) {
Get.offAll(() => const SignIn());
} else {
Get.offAll(() => Introscreen());
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: ColorConstants.secondaryColor,
body: SafeArea(
child: Center(
child: _imagePrecached
? Image(
image: _logoProvider,
fit: BoxFit.contain,
)
: const SizedBox(),
),
),
);
}
}