feat(ui): full‑width ShadTable across app; fix rent dialog width; correct equipment pagination
- ShadTable: ensure full-width via LayoutBuilder+ConstrainedBox minWidth - BaseListScreen: default data area padding = 0 for table edge-to-edge - Vendor/Model/User/Company/Inventory/Zipcode: set columnSpanExtent per column and add final filler column to absorb remaining width; pin date/status/actions widths; ensure date text is single-line - Equipment: unify card/border style; define fixed column widths + filler; increase checkbox column to 56px to avoid overflow - Rent list: migrate to ShadTable.list with fixed widths + filler column - Rent form dialog: prevent infinite width by bounding ShadProgress with SizedBox and remove Expanded from option rows; add safe selectedOptionBuilder - Admin list: fix const with non-const argument in table column extents - Services/Controller: remove hardcoded perPage=10; use BaseListController perPage; trust server meta (total/totalPages) in equipment pagination - widgets/shad_table: ConstrainedBox(minWidth=viewport) so table stretches Run: flutter analyze → 0 errors (warnings remain).
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:injectable/injectable.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import '../../core/errors/failures.dart';
|
||||
import '../../domain/repositories/auth_repository.dart';
|
||||
import '../datasources/remote/auth_remote_datasource.dart';
|
||||
@@ -17,6 +18,7 @@ import '../models/auth/token_response.dart';
|
||||
class AuthRepositoryImpl implements AuthRepository {
|
||||
final AuthRemoteDataSource remoteDataSource;
|
||||
final SharedPreferences sharedPreferences;
|
||||
final FlutterSecureStorage secureStorage;
|
||||
|
||||
// SharedPreferences 키 상수
|
||||
static const String _keyAccessToken = 'access_token';
|
||||
@@ -26,6 +28,7 @@ class AuthRepositoryImpl implements AuthRepository {
|
||||
AuthRepositoryImpl({
|
||||
required this.remoteDataSource,
|
||||
required this.sharedPreferences,
|
||||
required this.secureStorage,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -36,7 +39,7 @@ class AuthRepositoryImpl implements AuthRepository {
|
||||
return result.fold(
|
||||
(failure) => Left(failure),
|
||||
(loginResponse) async {
|
||||
// 로그인 성공 시 토큰과 사용자 정보를 로컬에 저장
|
||||
// 로그인 성공 시 토큰과 사용자 정보를 로컬에 저장 (보안 저장소)
|
||||
await _saveTokens(loginResponse.accessToken, loginResponse.refreshToken);
|
||||
await _saveUserData(loginResponse.user);
|
||||
|
||||
@@ -93,7 +96,7 @@ class AuthRepositoryImpl implements AuthRepository {
|
||||
return result.fold(
|
||||
(failure) => Left(failure),
|
||||
(tokenResponse) async {
|
||||
// 새 토큰 저장
|
||||
// 새 토큰 저장 (보안 저장소)
|
||||
await _saveTokens(tokenResponse.accessToken, tokenResponse.refreshToken);
|
||||
return Right(tokenResponse);
|
||||
},
|
||||
@@ -219,10 +222,10 @@ class AuthRepositoryImpl implements AuthRepository {
|
||||
|
||||
// Private 헬퍼 메서드들
|
||||
|
||||
/// 액세스 토큰과 리프레시 토큰을 로컬에 저장
|
||||
/// 액세스 토큰과 리프레시 토큰을 로컬에 저장 (보안 저장소 사용)
|
||||
Future<void> _saveTokens(String accessToken, String refreshToken) async {
|
||||
await sharedPreferences.setString(_keyAccessToken, accessToken);
|
||||
await sharedPreferences.setString(_keyRefreshToken, refreshToken);
|
||||
await secureStorage.write(key: _keyAccessToken, value: accessToken);
|
||||
await secureStorage.write(key: _keyRefreshToken, value: refreshToken);
|
||||
}
|
||||
|
||||
/// 사용자 데이터를 로컬에 저장
|
||||
@@ -231,20 +234,22 @@ class AuthRepositoryImpl implements AuthRepository {
|
||||
await sharedPreferences.setString(_keyUserData, user.toJson().toString());
|
||||
}
|
||||
|
||||
/// 액세스 토큰 조회
|
||||
/// 액세스 토큰 조회 (보안 저장소)
|
||||
Future<String?> _getAccessToken() async {
|
||||
return sharedPreferences.getString(_keyAccessToken);
|
||||
return await secureStorage.read(key: _keyAccessToken);
|
||||
}
|
||||
|
||||
/// 리프레시 토큰 조회
|
||||
/// 리프레시 토큰 조회 (보안 저장소)
|
||||
Future<String?> _getRefreshToken() async {
|
||||
return sharedPreferences.getString(_keyRefreshToken);
|
||||
return await secureStorage.read(key: _keyRefreshToken);
|
||||
}
|
||||
|
||||
/// 로컬 데이터 전체 삭제
|
||||
/// 로컬 데이터 전체 삭제 (토큰은 보안 저장소에서 삭제)
|
||||
Future<void> _clearLocalData() async {
|
||||
await sharedPreferences.remove(_keyAccessToken);
|
||||
await sharedPreferences.remove(_keyRefreshToken);
|
||||
// 토큰 삭제
|
||||
await secureStorage.delete(key: _keyAccessToken);
|
||||
await secureStorage.delete(key: _keyRefreshToken);
|
||||
// 사용자 데이터는 SharedPreferences에 저장되어 있으므로 제거
|
||||
await sharedPreferences.remove(_keyUserData);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user