Merge branch 'history-data-fetch' into 'master'

fix(history): optimize history tab initialization and data loading

See merge request profile-image/kedaireka/polinema-adapative-learning/mobile-adaptive-learning!6
This commit is contained in:
Naresh Pratista 2024-11-07 03:40:22 +00:00
commit e41d9dab23
4 changed files with 54 additions and 52 deletions

View File

@ -16,10 +16,9 @@ class HistoryRepository {
sectionId, sectionId,
token, token,
page: 1, page: 1,
limit: 1000, limit: 10,
); );
if (response.statusCode == 200 && response.data != null) { if (response.statusCode == 200 && response.data != null) {
// Perbaikan disini: langsung mengakses ['payload']['history']
final List<dynamic> historyData = response.data['payload']['history']; final List<dynamic> historyData = response.data['payload']['history'];
if (historyData.isEmpty) { if (historyData.isEmpty) {
return []; // Mengembalikan list kosong jika tidak ada data return []; // Mengembalikan list kosong jika tidak ada data

View File

@ -11,6 +11,7 @@ class HistoryProvider with ChangeNotifier {
int _selectedPageIndex = 0; int _selectedPageIndex = 0;
bool _isLoading = false; bool _isLoading = false;
String? _error; String? _error;
bool _isInitialized = false;
HistoryProvider( HistoryProvider(
this._repository, this._repository,
@ -21,16 +22,49 @@ class HistoryProvider with ChangeNotifier {
int get selectedPageIndex => _selectedPageIndex; int get selectedPageIndex => _selectedPageIndex;
bool get isLoading => _isLoading; bool get isLoading => _isLoading;
String? get error => _error; String? get error => _error;
bool get isInitialized => _isInitialized;
Future<void> loadInitialData(String token) async {
if (_isInitialized) return; // Prevent double initialization
_isLoading = true;
_error = null;
notifyListeners();
try {
// Only fetch sections if they haven't been fetched yet
if (_sectionProvider.sections.isEmpty) {
await _sectionProvider.fetchSections(token);
}
if (_sectionProvider.sections.isEmpty) {
_error = 'No sections available';
return;
}
// Get the first section's ID
String firstSectionId = _sectionProvider.sections.first.id;
// Fetch history for the first section
_learningHistory =
await _repository.getLearningHistory(firstSectionId, token);
_error = null;
_isInitialized = true; // Mark as initialized
} catch (e) {
_error = 'Error loading data: ${e.toString()}';
_learningHistory = [];
} finally {
_isLoading = false;
notifyListeners();
}
}
void setSelectedPageIndex(int index) { void setSelectedPageIndex(int index) {
_selectedPageIndex = index; _selectedPageIndex = index;
notifyListeners(); notifyListeners();
} }
Future<void> fetchLearningHistory( Future<void> fetchLearningHistory(String token) async {
String token, {
bool refresh = false,
}) async {
if (_sectionProvider.sections.isEmpty) { if (_sectionProvider.sections.isEmpty) {
_error = 'No sections available'; _error = 'No sections available';
notifyListeners(); notifyListeners();
@ -43,10 +77,7 @@ class HistoryProvider with ChangeNotifier {
notifyListeners(); notifyListeners();
try { try {
final history = await _repository.getLearningHistory( final history = await _repository.getLearningHistory(sectionId, token);
sectionId,
token,
);
_learningHistory = history; _learningHistory = history;
_error = null; _error = null;
} catch (e) { } catch (e) {
@ -133,36 +164,4 @@ class HistoryProvider with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
} }
// Future<void> loadHistoryData(String token) async {
// _isLoading = true;
// _error = null;
// notifyListeners();
// try {
// // Fetch sections and learning history in parallel
// final sectionsResult = _sectionProvider.fetchSections(token);
// // Use the first section ID for initial history fetch
// final firstSectionId = await sectionsResult
// .then((sections) => sections.isNotEmpty ? sections.first.id : null);
// if (firstSectionId != null) {
// final historyResult =
// _repository.getLearningHistory(firstSectionId, token);
// // Wait for both futures to complete
// final results = await Future.wait([sectionsResult, historyResult]);
// _learningHistory = results[1] as List<LearningHistory>;
// } else {
// _error = 'No sections available';
// }
// } catch (e) {
// _error = 'Error loading data: ${e.toString()}';
// } finally {
// _isLoading = false;
// notifyListeners();
// }
// }
} }

View File

@ -6,7 +6,7 @@ import 'package:english_learning/core/utils/styles/theme.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class CustomTabBar extends StatelessWidget { class CustomTabBar extends StatelessWidget {
const CustomTabBar({Key? key}) : super(key: key); const CustomTabBar({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -36,9 +36,9 @@ class CustomTabBar extends StatelessWidget {
void _setSelectedPageIndex(BuildContext context, int index) { void _setSelectedPageIndex(BuildContext context, int index) {
final historyProvider = final historyProvider =
Provider.of<HistoryProvider>(context, listen: false); Provider.of<HistoryProvider>(context, listen: false);
historyProvider.setSelectedPageIndex(index);
final userProvider = Provider.of<UserProvider>(context, listen: false); final userProvider = Provider.of<UserProvider>(context, listen: false);
historyProvider.setSelectedPageIndex(index);
historyProvider.fetchLearningHistory(userProvider.jwtToken!); historyProvider.fetchLearningHistory(userProvider.jwtToken!);
} }
} }

View File

@ -83,18 +83,22 @@ class _HomeScreenState extends State<HomeScreen> {
gap: 8, gap: 8,
selectedIndex: _selectedIndex, selectedIndex: _selectedIndex,
onTabChange: (index) async { onTabChange: (index) async {
setState(() { if (index == 2 && _selectedIndex != 2) {
_selectedIndex = index; // Only if switching TO history tab
_pageController.jumpToPage(index);
});
if (index == 2) {
// Index 2 adalah tab History
final historyProvider = final historyProvider =
Provider.of<HistoryProvider>(context, listen: false); Provider.of<HistoryProvider>(context, listen: false);
final userProvider = final userProvider =
Provider.of<UserProvider>(context, listen: false); Provider.of<UserProvider>(context, listen: false);
await historyProvider.loadHistoryData(userProvider.jwtToken!);
if (!historyProvider.isInitialized) {
await historyProvider.loadInitialData(userProvider.jwtToken!);
} }
}
setState(() {
_selectedIndex = index;
_pageController.jumpToPage(index);
});
}, },
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: 16, horizontal: 16,