refresh token

This commit is contained in:
efrilm 2025-09-20 18:05:15 +07:00
parent a58d1040af
commit 59a8d7f661
3 changed files with 43 additions and 75 deletions

View File

@ -1,6 +1,9 @@
import 'package:awesome_dio_interceptor/awesome_dio_interceptor.dart'; import 'package:awesome_dio_interceptor/awesome_dio_interceptor.dart';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:enaklo_pos/core/constants/variables.dart';
import 'package:enaklo_pos/core/extensions/build_context_ext.dart'; import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart';
import 'package:enaklo_pos/data/models/response/auth_response_model.dart';
import 'package:enaklo_pos/presentation/auth/login_page.dart'; import 'package:enaklo_pos/presentation/auth/login_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -124,13 +127,17 @@ class AuthInterceptorWithRefresh extends Interceptor {
Future<bool> _tryRefreshToken() async { Future<bool> _tryRefreshToken() async {
try { try {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
final refreshToken = prefs.getString('refresh_token'); final authData = await AuthLocalDataSource().getAuthData();
if (refreshToken == null) return false; final url = '${Variables.baseUrl}/api/v1/auth/refresh';
final response = await Dio().post( final response = await Dio().post(
'YOUR_REFRESH_TOKEN_ENDPOINT', url,
data: {'refresh_token': refreshToken}, options: Options(
headers: {
'Authorization': 'Bearer ${authData.refreshToken}',
},
),
); );
if (response.statusCode == 200) { if (response.statusCode == 200) {
@ -140,6 +147,11 @@ class AuthInterceptorWithRefresh extends Interceptor {
await prefs.setString('auth_token', newToken); await prefs.setString('auth_token', newToken);
await prefs.setString('refresh_token', newRefreshToken); await prefs.setString('refresh_token', newRefreshToken);
AuthResponseModel authResponseModel =
AuthResponseModel.fromMap(response.data['data']);
AuthLocalDataSource().saveAuthData(authResponseModel);
return true; return true;
} }
} catch (e) { } catch (e) {

View File

@ -2,9 +2,11 @@ import 'dart:convert';
class AuthResponseModel { class AuthResponseModel {
final String? token; final String? token;
final String? refreshToken;
final User? user; final User? user;
AuthResponseModel({ AuthResponseModel({
this.refreshToken,
this.token, this.token,
this.user, this.user,
}); });
@ -17,11 +19,13 @@ class AuthResponseModel {
factory AuthResponseModel.fromMap(Map<String, dynamic> json) => factory AuthResponseModel.fromMap(Map<String, dynamic> json) =>
AuthResponseModel( AuthResponseModel(
token: json["token"], token: json["token"],
refreshToken: json["refresh_token"],
user: json["user"] == null ? null : User.fromMap(json["user"]), user: json["user"] == null ? null : User.fromMap(json["user"]),
); );
Map<String, dynamic> toMap() => { Map<String, dynamic> toMap() => {
"token": token, "token": token,
"refresh_token": refreshToken,
"user": user?.toMap(), "user": user?.toMap(),
}; };
} }

View File

@ -81,11 +81,11 @@ class _HomePageState extends State<HomePage> {
context.read<CurrentOutletBloc>().add(CurrentOutletEvent.currentOutlet()); context.read<CurrentOutletBloc>().add(CurrentOutletEvent.currentOutlet());
} }
void _refreshData() { // void _refreshData() {
log('🔄 Refreshing local data...'); // log('🔄 Refreshing l ocal data...');
context.read<ProductLoaderBloc>().add(const ProductLoaderEvent.refresh()); // context.read<ProductLoaderBloc>().add(const ProductLoaderEvent.refresh());
context.read<CategoryLoaderBloc>().add(const CategoryLoaderEvent.refresh()); // context.read<CategoryLoaderBloc>().add(const CategoryLoaderEvent.refresh());
} // }
void onCategoryTap(int index) { void onCategoryTap(int index) {
searchController.clear(); searchController.clear();
@ -130,9 +130,6 @@ class _HomePageState extends State<HomePage> {
backgroundColor: AppColors.white, backgroundColor: AppColors.white,
body: Column( body: Column(
children: [ children: [
// Simple local mode indicator
_buildLocalIndicator(),
// Main content // Main content
Expanded( Expanded(
child: Row( child: Row(
@ -171,44 +168,6 @@ class _HomePageState extends State<HomePage> {
); );
} }
// Simple local mode indicator without sync
Widget _buildLocalIndicator() {
return Container(
width: double.infinity,
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 16),
color: Colors.blue.shade600,
child: Row(
children: [
Icon(Icons.storage, color: Colors.white, size: 16),
SizedBox(width: 8),
Expanded(
child: Text(
'Mode Lokal - Data tersimpan di perangkat',
style: TextStyle(
color: Colors.white,
fontSize: 13,
fontWeight: FontWeight.w500,
),
),
),
// Only refresh button
InkWell(
onTap: _refreshData,
child: Container(
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(4),
),
child: Icon(Icons.refresh, color: Colors.white, size: 14),
),
),
],
),
);
}
Widget _buildCategoryLoadingState() { Widget _buildCategoryLoadingState() {
return Center( return Center(
child: Column( child: Column(
@ -303,13 +262,7 @@ class _HomePageState extends State<HomePage> {
// Simple home title // Simple home title
Widget _buildSimpleHomeTitle() { Widget _buildSimpleHomeTitle() {
return Container( return HomeTitle(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
border: Border(bottom: BorderSide(color: Colors.grey.shade200)),
),
child: HomeTitle(
controller: searchController, controller: searchController,
onChanged: (value) { onChanged: (value) {
setState(() { setState(() {
@ -328,7 +281,6 @@ class _HomePageState extends State<HomePage> {
} }
}); });
}, },
),
); );
} }