refact: device_id for manage access, and bug: userpin runned unsucces
This commit is contained in:
parent
de39c9d7fd
commit
f620157de8
|
@ -0,0 +1,23 @@
|
|||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'dart:io';
|
||||
|
||||
Future<String> getDeviceId() async {
|
||||
final deviceInfo = DeviceInfoPlugin();
|
||||
String deviceID;
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
var androidInfo = await deviceInfo.androidInfo;
|
||||
|
||||
deviceID = androidInfo.id;
|
||||
} else if (Platform.isIOS) {
|
||||
var iosInfo = await deviceInfo.iosInfo;
|
||||
|
||||
deviceID = iosInfo.identifierForVendor ?? '';
|
||||
} else {
|
||||
var uuid = Uuid();
|
||||
deviceID = uuid.v4();
|
||||
}
|
||||
|
||||
return deviceID;
|
||||
}
|
|
@ -5,8 +5,10 @@ import 'package:rijig_mobile/screen/app/cart/cart_screen.dart';
|
|||
import 'package:rijig_mobile/screen/app/home/home_screen.dart';
|
||||
import 'package:rijig_mobile/screen/app/profil/profil_screen.dart';
|
||||
import 'package:rijig_mobile/screen/app/requestpick/requestpickup_screen.dart';
|
||||
import 'package:rijig_mobile/screen/auth/inputpin_screen.dart';
|
||||
import 'package:rijig_mobile/screen/auth/login_screen.dart';
|
||||
import 'package:rijig_mobile/screen/auth/otp_screen.dart';
|
||||
import 'package:rijig_mobile/screen/auth/verifpin_screen.dart';
|
||||
import 'package:rijig_mobile/screen/launch/onboardingpage_screen.dart';
|
||||
import 'package:rijig_mobile/screen/launch/splash_screen.dart';
|
||||
|
||||
|
@ -25,10 +27,8 @@ final router = GoRouter(
|
|||
return VerifotpScreen(phone: phone!);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/inputpin',
|
||||
builder: (context, state) => OnboardingPageScreen(),
|
||||
),
|
||||
GoRoute(path: '/setpin', builder: (context, state) => UserPinScreen()),
|
||||
GoRoute(path: '/verifpin', builder: (context, state) => VerifPinScreen()),
|
||||
GoRoute(
|
||||
path: '/navigasi',
|
||||
builder: (context, state) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:intl/date_symbol_data_local.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
import 'package:rijig_mobile/core/router.dart';
|
||||
import 'package:rijig_mobile/viewmodel/auth_vmod.dart';
|
||||
import 'package:rijig_mobile/viewmodel/userpin_vmod.dart'; // Import PinViewModel
|
||||
|
||||
void main() async {
|
||||
await dotenv.load(fileName: "server/.env.dev");
|
||||
|
@ -24,6 +25,8 @@ class MyApp extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (_) => AuthViewModel(),
|
||||
child: ChangeNotifierProvider(
|
||||
create: (_) => PinViewModel(), // Tambahkan PinViewModel
|
||||
child: ScreenUtilInit(
|
||||
designSize: const Size(375, 812),
|
||||
builder: (_, child) {
|
||||
|
@ -33,6 +36,7 @@ class MyApp extends StatelessWidget {
|
|||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,11 +15,16 @@ class AuthModel {
|
|||
}
|
||||
}
|
||||
|
||||
Future<ResponseModel?> verifyOtp(String phone, String otp) async {
|
||||
Future<ResponseModel?> verifyOtp(
|
||||
String phone,
|
||||
String otp,
|
||||
String deviceId,
|
||||
) async {
|
||||
try {
|
||||
var response = await _apiService.post('/authmasyarakat/verify-otp', {
|
||||
'phone': phone,
|
||||
'otp': otp,
|
||||
'device_id': deviceId,
|
||||
});
|
||||
return ResponseModel.fromJson(response);
|
||||
} catch (e) {
|
||||
|
|
|
@ -1,25 +1,34 @@
|
|||
import 'package:rijig_mobile/core/api_services.dart';
|
||||
import 'package:rijig_mobile/model/response_model.dart';
|
||||
|
||||
class AuthService {
|
||||
class PinModel {
|
||||
final ApiService _apiService = ApiService();
|
||||
|
||||
Future<ResponseModel?> cekPinStatus(String userid) async {
|
||||
Future<bool> checkPinStatus() async {
|
||||
try {
|
||||
var response = await _apiService.get('/cek-pin-status');
|
||||
return ResponseModel.fromJson(response);
|
||||
if (response['meta']['status'] == 200) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> verifyOtp(String phone, String otp) async {
|
||||
Future<bool> setPin(String userPin) async {
|
||||
try {
|
||||
var response = await _apiService.post('/authmasyarakat/verify-otp', {
|
||||
'phone': phone,
|
||||
'otp': otp,
|
||||
});
|
||||
return response;
|
||||
var response = await _apiService.post('/set-pin', {'userpin': userPin});
|
||||
return response['meta']['status'] == 201;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> verifyPin(String userPin) async {
|
||||
try {
|
||||
var response = await _apiService.post('/verif-pin', {'userpin': userPin});
|
||||
return response['meta']['status'] == 200;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:rijig_mobile/core/guide.dart';
|
||||
import 'package:rijig_mobile/core/router.dart';
|
||||
import 'package:rijig_mobile/viewmodel/userpin_vmod.dart';
|
||||
|
||||
class UserPinScreen extends StatefulWidget {
|
||||
const UserPinScreen({super.key});
|
||||
|
||||
@override
|
||||
State<UserPinScreen> createState() => _UserPinScreenState();
|
||||
}
|
||||
|
||||
class _UserPinScreenState extends State<UserPinScreen> {
|
||||
final TextEditingController _pinController = TextEditingController();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
String errorMessage = '';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final pinViewModel = Provider.of<PinViewModel>(context);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text("Buat PIN Pengguna")),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
TextFormField(
|
||||
controller: _pinController,
|
||||
decoration: const InputDecoration(labelText: 'Masukkan PIN'),
|
||||
obscureText: true,
|
||||
maxLength: 6,
|
||||
keyboardType: TextInputType.number,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'PIN harus diisi';
|
||||
} else if (value.length != 6) {
|
||||
return 'PIN harus 6 digit';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
if (_formKey.currentState?.validate() ?? false) {
|
||||
final pin = _pinController.text;
|
||||
|
||||
bool pinCreated = await pinViewModel.checkPinStatus();
|
||||
|
||||
if (!pinCreated) {
|
||||
bool pinSet = await pinViewModel.setPin(pin);
|
||||
if (pinSet) {
|
||||
router.go('/navigasi');
|
||||
} else {
|
||||
setState(() {
|
||||
errorMessage = 'Gagal membuat PIN';
|
||||
});
|
||||
}
|
||||
} else {
|
||||
bool pinVerified = await pinViewModel.verifyPin(pin);
|
||||
if (pinVerified) {
|
||||
router.go('/navigasi');
|
||||
} else {
|
||||
setState(() {
|
||||
errorMessage = 'PIN yang anda masukkan salah';
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
child: const Text('Kirim'),
|
||||
),
|
||||
if (errorMessage.isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
child: Text(errorMessage, style: TextStyle(color: redColor)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -58,11 +58,26 @@ class _VerifotpScreenState extends State<VerifotpScreen> {
|
|||
horizontal: double.infinity,
|
||||
vertical: 50,
|
||||
onTap: () {
|
||||
// if (_otpController.text.isNotEmpty) {
|
||||
// viewModel.verifyOtp(widget.phone, _otpController.text).then(
|
||||
// (_) {
|
||||
// if (viewModel.errorMessage == null) {
|
||||
// router.go('/navigasi');
|
||||
// } else {
|
||||
// debugPrint(viewModel.errorMessage ?? '');
|
||||
// }
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
if (_otpController.text.isNotEmpty) {
|
||||
viewModel.verifyOtp(widget.phone, _otpController.text).then(
|
||||
(_) {
|
||||
if (viewModel.errorMessage == null) {
|
||||
router.go('/navigasi');
|
||||
if (viewModel.pinExists == false) {
|
||||
router.go('/setpin');
|
||||
} else {
|
||||
router.go('/verifpin');
|
||||
}
|
||||
} else {
|
||||
debugPrint(viewModel.errorMessage ?? '');
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:rijig_mobile/core/router.dart';
|
||||
import 'package:rijig_mobile/viewmodel/userpin_vmod.dart';
|
||||
|
||||
class VerifPinScreen extends StatefulWidget {
|
||||
const VerifPinScreen({super.key});
|
||||
|
||||
@override
|
||||
State<VerifPinScreen> createState() => _VerifPinScreenState();
|
||||
}
|
||||
|
||||
class _VerifPinScreenState extends State<VerifPinScreen> {
|
||||
final TextEditingController _pinController = TextEditingController();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
String errorMessage = '';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final pinViewModel = Provider.of<PinViewModel>(context);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text("Verifikasi PIN")),
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
TextFormField(
|
||||
controller: _pinController,
|
||||
decoration: const InputDecoration(labelText: 'Masukkan PIN'),
|
||||
obscureText: true,
|
||||
maxLength: 6,
|
||||
keyboardType: TextInputType.number,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'PIN harus diisi';
|
||||
} else if (value.length != 6) {
|
||||
return 'PIN harus 6 digit';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
if (_formKey.currentState?.validate() ?? false) {
|
||||
final pin = _pinController.text;
|
||||
|
||||
bool pinVerified = await pinViewModel.verifyPin(pin);
|
||||
if (pinVerified) {
|
||||
router.go('/navigasi');
|
||||
} else {
|
||||
setState(() {
|
||||
errorMessage = 'PIN yang Anda masukkan salah';
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
child: const Text('Kirim'),
|
||||
),
|
||||
if (errorMessage.isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
child: Text(
|
||||
errorMessage,
|
||||
style: const TextStyle(color: Colors.red),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,15 +1,19 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:rijig_mobile/core/getinfodevice.dart';
|
||||
import 'package:rijig_mobile/model/response_model.dart';
|
||||
import 'package:rijig_mobile/model/auth_model.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:rijig_mobile/model/userpin_model.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class AuthViewModel extends ChangeNotifier {
|
||||
final AuthModel _authModel = AuthModel();
|
||||
final PinModel _pinModel = PinModel();
|
||||
final FlutterSecureStorage _secureStorage = FlutterSecureStorage();
|
||||
bool isLoading = false;
|
||||
String? errorMessage;
|
||||
ResponseModel? authModel;
|
||||
bool? pinExists;
|
||||
|
||||
Future<void> login(String phone) async {
|
||||
try {
|
||||
|
@ -22,7 +26,6 @@ class AuthViewModel extends ChangeNotifier {
|
|||
if (response != null && response.status == 200) {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setBool('isLoggedIn', false);
|
||||
|
||||
authModel = response;
|
||||
} else {
|
||||
errorMessage = response?.message ?? 'Failed to send OTP';
|
||||
|
@ -41,7 +44,9 @@ class AuthViewModel extends ChangeNotifier {
|
|||
errorMessage = null;
|
||||
notifyListeners();
|
||||
|
||||
var response = await _authModel.verifyOtp(phone, otp);
|
||||
String deviceId = await getDeviceId();
|
||||
|
||||
var response = await _authModel.verifyOtp(phone, otp, deviceId);
|
||||
|
||||
if (response != null && response.status == 200) {
|
||||
await _secureStorage.write(
|
||||
|
@ -59,8 +64,10 @@ class AuthViewModel extends ChangeNotifier {
|
|||
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setBool('isLoggedIn', true);
|
||||
pinExists = await _pinModel.checkPinStatus();
|
||||
|
||||
authModel = response;
|
||||
notifyListeners();
|
||||
} else {
|
||||
errorMessage = response?.message ?? 'Failed to verify OTP';
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:rijig_mobile/model/userpin_model.dart';
|
||||
|
||||
class PinViewModel extends ChangeNotifier {
|
||||
final PinModel _pinService = PinModel();
|
||||
|
||||
Future<bool> checkPinStatus() async {
|
||||
try {
|
||||
return await _pinService.checkPinStatus();
|
||||
} catch (e) {
|
||||
throw Exception('Error checking PIN status: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> setPin(String userPin) async {
|
||||
try {
|
||||
return await _pinService.setPin(userPin);
|
||||
} catch (e) {
|
||||
throw Exception('Error setting PIN: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> verifyPin(String userPin) async {
|
||||
try {
|
||||
return await _pinService.verifyPin(userPin);
|
||||
} catch (e) {
|
||||
throw Exception('Error verifying PIN: $e');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,11 +5,13 @@
|
|||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import device_info_plus
|
||||
import flutter_secure_storage_macos
|
||||
import path_provider_foundation
|
||||
import shared_preferences_foundation
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
|
|
48
pubspec.lock
48
pubspec.lock
|
@ -73,6 +73,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.8"
|
||||
device_info_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: device_info_plus
|
||||
sha256: "0c6396126421b590089447154c5f98a5de423b70cfb15b1578fd018843ee6f53"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "11.4.0"
|
||||
device_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_platform_interface
|
||||
sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.2"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -97,6 +113,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.1"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fixnum
|
||||
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
@ -501,6 +525,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.1"
|
||||
sprintf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sprintf
|
||||
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -549,6 +581,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
uuid:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: uuid
|
||||
sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.5.1"
|
||||
vector_graphics:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -605,6 +645,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.12.0"
|
||||
win32_registry:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32_registry
|
||||
sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -10,6 +10,7 @@ environment:
|
|||
dependencies:
|
||||
concentric_transition: ^1.0.3
|
||||
cupertino_icons: ^1.0.8
|
||||
device_info_plus: ^11.4.0
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flutter_dotenv: ^5.2.1
|
||||
|
@ -25,6 +26,7 @@ dependencies:
|
|||
pin_code_fields: ^8.0.1
|
||||
provider: ^6.1.4
|
||||
shared_preferences: ^2.3.3
|
||||
uuid: ^4.5.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^5.0.0
|
||||
|
|
Loading…
Reference in New Issue