From 59a8d7f66126142c257fdcb5f0f84d584ede21f5 Mon Sep 17 00:00:00 2001 From: efrilm Date: Sat, 20 Sep 2025 18:05:15 +0700 Subject: [PATCH] refresh token --- lib/core/network/dio_client.dart | 20 +++- .../models/response/auth_response_model.dart | 4 + lib/presentation/home/pages/home_page.dart | 94 +++++-------------- 3 files changed, 43 insertions(+), 75 deletions(-) diff --git a/lib/core/network/dio_client.dart b/lib/core/network/dio_client.dart index cf50c2c..c01a0df 100644 --- a/lib/core/network/dio_client.dart +++ b/lib/core/network/dio_client.dart @@ -1,6 +1,9 @@ import 'package:awesome_dio_interceptor/awesome_dio_interceptor.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/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:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -124,13 +127,17 @@ class AuthInterceptorWithRefresh extends Interceptor { Future _tryRefreshToken() async { try { 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( - 'YOUR_REFRESH_TOKEN_ENDPOINT', - data: {'refresh_token': refreshToken}, + url, + options: Options( + headers: { + 'Authorization': 'Bearer ${authData.refreshToken}', + }, + ), ); if (response.statusCode == 200) { @@ -140,6 +147,11 @@ class AuthInterceptorWithRefresh extends Interceptor { await prefs.setString('auth_token', newToken); await prefs.setString('refresh_token', newRefreshToken); + AuthResponseModel authResponseModel = + AuthResponseModel.fromMap(response.data['data']); + + AuthLocalDataSource().saveAuthData(authResponseModel); + return true; } } catch (e) { diff --git a/lib/data/models/response/auth_response_model.dart b/lib/data/models/response/auth_response_model.dart index ff787f2..bbec144 100644 --- a/lib/data/models/response/auth_response_model.dart +++ b/lib/data/models/response/auth_response_model.dart @@ -2,9 +2,11 @@ import 'dart:convert'; class AuthResponseModel { final String? token; + final String? refreshToken; final User? user; AuthResponseModel({ + this.refreshToken, this.token, this.user, }); @@ -17,11 +19,13 @@ class AuthResponseModel { factory AuthResponseModel.fromMap(Map json) => AuthResponseModel( token: json["token"], + refreshToken: json["refresh_token"], user: json["user"] == null ? null : User.fromMap(json["user"]), ); Map toMap() => { "token": token, + "refresh_token": refreshToken, "user": user?.toMap(), }; } diff --git a/lib/presentation/home/pages/home_page.dart b/lib/presentation/home/pages/home_page.dart index ce99f69..14dd377 100644 --- a/lib/presentation/home/pages/home_page.dart +++ b/lib/presentation/home/pages/home_page.dart @@ -81,11 +81,11 @@ class _HomePageState extends State { context.read().add(CurrentOutletEvent.currentOutlet()); } - void _refreshData() { - log('🔄 Refreshing local data...'); - context.read().add(const ProductLoaderEvent.refresh()); - context.read().add(const CategoryLoaderEvent.refresh()); - } + // void _refreshData() { + // log('🔄 Refreshing l ocal data...'); + // context.read().add(const ProductLoaderEvent.refresh()); + // context.read().add(const CategoryLoaderEvent.refresh()); + // } void onCategoryTap(int index) { searchController.clear(); @@ -130,9 +130,6 @@ class _HomePageState extends State { backgroundColor: AppColors.white, body: Column( children: [ - // Simple local mode indicator - _buildLocalIndicator(), - // Main content Expanded( child: Row( @@ -171,44 +168,6 @@ class _HomePageState extends State { ); } - // 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() { return Center( child: Column( @@ -303,32 +262,25 @@ class _HomePageState extends State { // Simple home title Widget _buildSimpleHomeTitle() { - return Container( - padding: EdgeInsets.all(16), - decoration: BoxDecoration( - color: Colors.white, - border: Border(bottom: BorderSide(color: Colors.grey.shade200)), - ), - child: HomeTitle( - controller: searchController, - onChanged: (value) { - setState(() { - searchQuery = value; - }); + return HomeTitle( + controller: searchController, + onChanged: (value) { + setState(() { + searchQuery = value; + }); - // Fast local search - Future.delayed(Duration(milliseconds: 200), () { - if (value == searchController.text) { - log('🔍 Local search: "$value"'); - context.read().add( - ProductLoaderEvent.searchProduct( - query: value, - ), - ); - } - }); - }, - ), + // Fast local search + Future.delayed(Duration(milliseconds: 200), () { + if (value == searchController.text) { + log('🔍 Local search: "$value"'); + context.read().add( + ProductLoaderEvent.searchProduct( + query: value, + ), + ); + } + }); + }, ); }