201 lines
7.7 KiB
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;
|
|
}
|
|
}
|