Files
Xpress-rider/lib/providers/auth/auth_provider.dart

201 lines
7.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:nearle/Models/login/login.dart';
import 'package:shared_preferences/shared_preferences.dart';
// ignore: unused_import
import 'package:nearle/controllers/riderlog.dart';
class AuthProvider {
Future<http.Response> login({
required String contactNo,
required String deviceType,
required int configId,
required String deviceId,
required String fcmToken,
int? pin,
}) async {
final uri = Uri.parse(
'https://jupiter.nearle.app/live/api/v2/users/rider/login',
);
final body = {
'contactno': contactNo,
'devicetype': deviceType,
'configid': configId,
'deviceid': deviceId,
'userfcmtoken': fcmToken,
if (pin != null) 'pin': pin,
};
debugPrint('[AUTH][LOGIN] URL: ${uri.toString()}');
debugPrint('[AUTH][LOGIN] Body: ${json.encode(body)}');
final res = await http.post(
uri,
headers: {'Content-Type': 'application/json'},
body: json.encode(body),
);
debugPrint('[AUTH][LOGIN] Status: ${res.statusCode}');
debugPrint('[AUTH][LOGIN] Response: ${res.body}');
return res;
}
// Convenience: send using a Login model body
Future<http.Response> loginWith(Login request) async {
final uri = Uri.parse(
'https://jupiter.nearle.app/live/api/v2/users/rider/login',
);
final body = request.toJson();
debugPrint('[AUTH][LOGIN] URL: ${uri.toString()}');
debugPrint('[AUTH][LOGIN] Body: ${json.encode(body)}');
final res = await http.post(
uri,
headers: {'Content-Type': 'application/json'},
body: json.encode(body),
);
debugPrint('[AUTH][LOGIN] Status: ${res.statusCode}');
debugPrint('[AUTH][LOGIN] Response: ${res.body}');
return res;
}
// Convenience: parsed response as Login model
Future<Login> loginParsed({
required String contactNo,
required String deviceType,
required int configId,
required String deviceId,
required String fcmToken,
int? pin,
}) async {
final res = await login(
contactNo: contactNo,
deviceType: deviceType,
configId: configId,
deviceId: deviceId,
fcmToken: fcmToken,
pin: pin,
);
final Map<String, dynamic> jsonMap = res.body.isNotEmpty
? json.decode(res.body) as Map<String, dynamic>
: <String, dynamic>{};
debugPrint('[AUTH] Raw Login JSON: $jsonMap');
if (jsonMap.containsKey('details')) {
final details = jsonMap['details'];
final prefs = await SharedPreferences.getInstance();
await prefs.setInt('userid', details['userid'] ?? 0);
await prefs.setInt('userId', details['userid'] ?? 0);
await prefs.setInt('shiftid', details['shiftid'] ?? 0);
await prefs.setInt('shiftId', details['shiftid'] ?? 0);
await prefs.setInt('logid', details['logid'] ?? 0);
await prefs.setInt('logId', details['logid'] ?? 0);
await prefs.setInt('riderid', details['riderid'] ?? 0);
await prefs.setInt('partnerid', details['partnerid'] ?? 0);
await prefs.setInt('partnerId', details['partnerid'] ?? 0);
await prefs.setInt('configid', details['configid'] ?? 0);
await prefs.setInt('logseconds', details['logseconds'] ?? 0);
await prefs.setInt('locationid', details['locationid'] ?? 0);
await prefs.setInt('tenantid', details['tenantid'] ?? 0);
await prefs.setInt('applocationid', details['applocationid'] ?? 0);
final String fcm = (details['userfcmtoken'] ?? '').toString();
if (fcm.isNotEmpty) {
await prefs.setString('userfcmtoken', fcm);
}
// Persist rider name variants for downstream usage (e.g. rider logs)
final String firstName = (details['firstname'] ?? '').toString();
final String lastName = (details['lastname'] ?? '').toString();
final String apiUsername = (details['username'] ?? '').toString();
final String combinedName = ('$firstName $lastName').trim();
if (apiUsername.isNotEmpty) {
await prefs.setString('username', apiUsername);
} else if (combinedName.isNotEmpty) {
await prefs.setString('username', combinedName);
}
if (firstName.isNotEmpty) {
await prefs.setString('firstname', firstName);
}
if (lastName.isNotEmpty) {
await prefs.setString('lastname', lastName);
}
if (details['onduty'] != null) {
final int od = (details['onduty'] is num)
? (details['onduty'] as num).toInt()
: int.tryParse('${details['onduty']}') ?? 0;
await prefs.setInt('onduty', od);
}
// Persist rider payout config (per-kilometer fuel/rider charge) if provided
if (details.containsKey('fuelcharge')) {
final double fuelCharge =
double.tryParse('${details['fuelcharge']}') ?? 0.0;
await prefs.setDouble('fuelcharge', fuelCharge);
}
// Backward compatibility with older field names
if (details.containsKey('firstmilecharge')) {
final double firstMileCharge =
double.tryParse('${details['firstmilecharge']}') ?? 0.0;
await prefs.setDouble('firstmilecharge', firstMileCharge);
} else if (details.containsKey('firstmilecharges')) {
final double firstMileCharge =
double.tryParse('${details['firstmilecharges']}') ?? 0.0;
await prefs.setDouble('firstmilecharge', firstMileCharge);
}
// Save shift window for header display
if (details['starttime'] != null) {
await prefs.setString('starttime', details['starttime'].toString());
}
await prefs.setString('endtime', details['endtime'].toString());
// Save delivery radius for geofencing (default 100m if not provided)
if (details['deliveryradius'] != null) {
final int radius = (details['deliveryradius'] is num)
? (details['deliveryradius'] as num).toInt()
: int.tryParse('${details['deliveryradius']}') ?? 100;
await prefs.setInt('deliveryradius', radius);
debugPrint('[AUTH] Saved deliveryradius: $radius meters');
} else {
await prefs.setInt('deliveryradius', 100); // Default
debugPrint('[AUTH] Saved default deliveryradius: 100 meters');
}
debugPrint(
'[AUTH] SharedPrefs Saved: '
'userid=${details['userid']}, shiftid=${details['shiftid']}, '
'logid=${details['logid']}, riderid=${details['riderid']},'
'partnerid=${details['partnerid']}, configid=${details['configid']}',
);
// Rider log creation is deferred until the rider goes ON duty.
//
// NOTE: We intentionally do NOT auto-navigate from here anymore.
// Navigation after login / PIN verification is handled in the UI flows
// (e.g. MPIN screen) so that riders cannot reach the homepage before
// successfully entering a valid PIN.
}
return Login.fromJson(jsonMap);
}
Future<http.Response> updatePin({
required int userId,
required int pin,
}) async {
final uri = Uri.parse(
'https://jupiter.nearle.app/live/api/v2/users/update',
);
final body = {'userid': userId, 'pin': pin};
debugPrint('[AUTH][UPDATE PIN] URL: ${uri.toString()}');
debugPrint('[AUTH][UPDATE PIN] Body: ${json.encode(body)}');
final res = await http.put(
uri,
headers: {'Content-Type': 'application/json'},
body: json.encode(body),
);
debugPrint('[AUTH][UPDATE PIN] Status: ${res.statusCode}');
debugPrint('[AUTH][UPDATE PIN] Response: ${res.body}');
return res;
}
}