Merge branch 'responsive-error-handling' into 'master'
Refactor: refactored code to remove print statements, updated widget... See merge request profile-image/kedaireka/polinema-adapative-learning/mobile-adaptive-learning!26
This commit is contained in:
commit
8e770d2e6e
|
|
@ -8,8 +8,8 @@ class DioClient {
|
|||
|
||||
DioClient() {
|
||||
_dio.options.baseUrl = baseUrl;
|
||||
_dio.options.connectTimeout = const Duration(seconds: 5);
|
||||
_dio.options.receiveTimeout = const Duration(seconds: 10);
|
||||
_dio.options.connectTimeout = const Duration(seconds: 10);
|
||||
_dio.options.receiveTimeout = const Duration(seconds: 15);
|
||||
}
|
||||
|
||||
Future<Response> refreshAccessToken(String refreshToken) async {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:dio/dio.dart';
|
||||
import 'package:english_learning/core/services/dio_client.dart';
|
||||
import 'package:english_learning/features/home/models/completed_topics_model.dart';
|
||||
|
||||
|
|
@ -8,38 +7,28 @@ class CompletedTopicsRepository {
|
|||
CompletedTopicsRepository(this._dioClient);
|
||||
|
||||
Future<List<CompletedTopic>> getCompletedTopics(String token) async {
|
||||
try {
|
||||
final response = await _dioClient.getCompletedTopics(token);
|
||||
final response = await _dioClient.getCompletedTopics(token);
|
||||
|
||||
// Tambahkan pengecekan status code dan payload
|
||||
if (response.statusCode == 200) {
|
||||
// Cek apakah payload null atau bukan list
|
||||
if (response.data['payload'] == null) {
|
||||
return []; // Kembalikan list kosong jika payload null
|
||||
}
|
||||
|
||||
// Pastikan payload adalah list
|
||||
final dynamic payloadData = response.data['payload'];
|
||||
|
||||
if (payloadData is List) {
|
||||
return payloadData
|
||||
.map((data) => CompletedTopic.fromJson(data))
|
||||
.toList();
|
||||
} else {
|
||||
return []; // Kembalikan list kosong jika payload bukan list
|
||||
}
|
||||
} else {
|
||||
// Tangani status code selain 200
|
||||
return [];
|
||||
// Tambahkan pengecekan status code dan payload
|
||||
if (response.statusCode == 200) {
|
||||
// Cek apakah payload null atau bukan list
|
||||
if (response.data['payload'] == null) {
|
||||
return []; // Kembalikan list kosong jika payload null
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
// Log error jika perlu
|
||||
print('Network error: ${e.message}');
|
||||
return []; // Kembalikan list kosong untuk error jaringan
|
||||
} catch (e) {
|
||||
// Log error tidak terduga
|
||||
print('Unexpected error: $e');
|
||||
return []; // Kembalikan list kosong untuk error lainnya
|
||||
|
||||
// Pastikan payload adalah list
|
||||
final dynamic payloadData = response.data['payload'];
|
||||
|
||||
if (payloadData is List) {
|
||||
return payloadData
|
||||
.map((data) => CompletedTopic.fromJson(data))
|
||||
.toList();
|
||||
} else {
|
||||
return []; // Kembalikan list kosong jika payload bukan list
|
||||
}
|
||||
} else {
|
||||
// Tangani status code selain 200
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ class LevelRepository {
|
|||
throw Exception('Failed to load levels: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error in LevelRepository: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ class SectionRepository {
|
|||
throw Exception('Failed to load sections: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error in SectionRepository: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ class TopicRepository {
|
|||
throw Exception('Failed to load topics: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error in TopicRepository: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ class UserRepository {
|
|||
}
|
||||
return await dioClient.updateUserProfile(id, formData, token);
|
||||
} catch (e) {
|
||||
print('Update Profile error: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
|
@ -67,7 +66,6 @@ class UserRepository {
|
|||
};
|
||||
return await dioClient.updatePassword(id, data, token);
|
||||
} catch (e) {
|
||||
print('Update Password error: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ class ConfirmPasswordFieldWidget extends StatefulWidget {
|
|||
});
|
||||
|
||||
@override
|
||||
_ConfirmPasswordFieldWidgetState createState() =>
|
||||
_ConfirmPasswordFieldWidgetState();
|
||||
ConfirmPasswordFieldWidgetState createState() =>
|
||||
ConfirmPasswordFieldWidgetState();
|
||||
}
|
||||
|
||||
class _ConfirmPasswordFieldWidgetState
|
||||
class ConfirmPasswordFieldWidgetState
|
||||
extends State<ConfirmPasswordFieldWidget> {
|
||||
late FocusNode _focusNode;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ class EmailFieldWidget extends StatefulWidget {
|
|||
{super.key, required this.labelText, required this.hintText});
|
||||
|
||||
@override
|
||||
_EmailFieldWidgetState createState() => _EmailFieldWidgetState();
|
||||
EmailFieldWidgetState createState() => EmailFieldWidgetState();
|
||||
}
|
||||
|
||||
class _EmailFieldWidgetState extends State<EmailFieldWidget> {
|
||||
class EmailFieldWidgetState extends State<EmailFieldWidget> {
|
||||
late FocusNode _focusNode;
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ class FullNameFieldWidget extends StatefulWidget {
|
|||
});
|
||||
|
||||
@override
|
||||
_FullNameFieldWidgetState createState() => _FullNameFieldWidgetState();
|
||||
FullNameFieldWidgetState createState() => FullNameFieldWidgetState();
|
||||
}
|
||||
|
||||
class _FullNameFieldWidgetState extends State<FullNameFieldWidget> {
|
||||
class FullNameFieldWidgetState extends State<FullNameFieldWidget> {
|
||||
late FocusNode _focusNode;
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ class NISNFieldWidget extends StatefulWidget {
|
|||
});
|
||||
|
||||
@override
|
||||
_NISNFieldWidgetState createState() => _NISNFieldWidgetState();
|
||||
NISNFieldWidgetState createState() => NISNFieldWidgetState();
|
||||
}
|
||||
|
||||
class _NISNFieldWidgetState extends State<NISNFieldWidget> {
|
||||
class NISNFieldWidgetState extends State<NISNFieldWidget> {
|
||||
late FocusNode _focusNode;
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ class PasswordFieldWidget extends StatefulWidget {
|
|||
});
|
||||
|
||||
@override
|
||||
_PasswordFieldWidgetState createState() => _PasswordFieldWidgetState();
|
||||
PasswordFieldWidgetState createState() => PasswordFieldWidgetState();
|
||||
}
|
||||
|
||||
class _PasswordFieldWidgetState extends State<PasswordFieldWidget> {
|
||||
class PasswordFieldWidgetState extends State<PasswordFieldWidget> {
|
||||
late FocusNode _focusNode;
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -29,18 +29,14 @@ class UserProvider with ChangeNotifier {
|
|||
}
|
||||
|
||||
Future<void> _loadLoginStatus() async {
|
||||
try {
|
||||
_jwtToken = await _userRepository.getToken();
|
||||
if (_jwtToken != null) {
|
||||
if (JwtDecoder.isExpired(_jwtToken!)) {
|
||||
await logout();
|
||||
} else {
|
||||
_isLoggedIn = true;
|
||||
await _loadUserData();
|
||||
}
|
||||
_jwtToken = await _userRepository.getToken();
|
||||
if (_jwtToken != null) {
|
||||
if (JwtDecoder.isExpired(_jwtToken!)) {
|
||||
await logout();
|
||||
} else {
|
||||
_isLoggedIn = true;
|
||||
await _loadUserData();
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error loading login status: $e');
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
|
@ -53,18 +49,14 @@ class UserProvider with ChangeNotifier {
|
|||
}
|
||||
|
||||
Future<void> refreshUserData() async {
|
||||
try {
|
||||
if (_jwtToken != null) {
|
||||
final response = await _userRepository.getMe(_jwtToken!);
|
||||
if (response.statusCode == 200) {
|
||||
_userData = response.data['payload'];
|
||||
// Save all user data securely
|
||||
await _userRepository.saveUserData(_userData!);
|
||||
notifyListeners();
|
||||
}
|
||||
if (_jwtToken != null) {
|
||||
final response = await _userRepository.getMe(_jwtToken!);
|
||||
if (response.statusCode == 200) {
|
||||
_userData = response.data['payload'];
|
||||
// Save all user data securely
|
||||
await _userRepository.saveUserData(_userData!);
|
||||
notifyListeners();
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error refreshing user data: $e');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -96,13 +88,11 @@ class UserProvider with ChangeNotifier {
|
|||
await refreshUserData();
|
||||
return true;
|
||||
} else if (response.statusCode == 403) {
|
||||
print('User is not validated: ${response.data['message']}');
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (e) {
|
||||
print('Login error: $e');
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
|
|
@ -130,7 +120,6 @@ class UserProvider with ChangeNotifier {
|
|||
}
|
||||
return false;
|
||||
} catch (e) {
|
||||
print('Registration error: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -151,7 +140,6 @@ class UserProvider with ChangeNotifier {
|
|||
}
|
||||
return false;
|
||||
} catch (e) {
|
||||
print('Logout error: $e');
|
||||
_isLoggedIn = false;
|
||||
_jwtToken = null;
|
||||
_userData = null;
|
||||
|
|
@ -168,15 +156,12 @@ class UserProvider with ChangeNotifier {
|
|||
final response = await _userRepository.forgotPassword(email);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
print("Password reset email sent successfully!");
|
||||
return true;
|
||||
} else if (response.statusCode == 404) {
|
||||
print("Email is not registered!");
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
} catch (e) {
|
||||
print('Forgot Password error: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -205,7 +190,6 @@ class UserProvider with ChangeNotifier {
|
|||
}
|
||||
return false;
|
||||
} catch (e) {
|
||||
print('Error refreshing token: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -225,7 +209,6 @@ class UserProvider with ChangeNotifier {
|
|||
}
|
||||
return null;
|
||||
} catch (e) {
|
||||
print('Error in getValidToken: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -251,7 +234,6 @@ class UserProvider with ChangeNotifier {
|
|||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error updating user profile: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
|
@ -273,13 +255,11 @@ class UserProvider with ChangeNotifier {
|
|||
token,
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
print("Password updated successfully!");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (e) {
|
||||
print('Error updating password: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -290,13 +270,11 @@ class UserProvider with ChangeNotifier {
|
|||
if (token != null) {
|
||||
final response = await _userRepository.reportIssue(report, token);
|
||||
if (response.statusCode == 201) {
|
||||
print("Issue reported successfully!");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (e) {
|
||||
print('Error reporting issue: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
|
|||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SigninScreen(),
|
||||
builder: (context) => const SigninScreen(),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
@ -145,7 +145,7 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
|
|||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SigninScreen()),
|
||||
builder: (context) => const SigninScreen()),
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
|
|
|
|||
|
|
@ -117,6 +117,9 @@ class _SigninScreenState extends State<SigninScreen> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final mediaQuery = MediaQuery.of(context);
|
||||
final screenHeight = mediaQuery.size.height;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => FocusScope.of(context).unfocus(),
|
||||
child: Scaffold(
|
||||
|
|
@ -133,7 +136,7 @@ class _SigninScreenState extends State<SigninScreen> {
|
|||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 24),
|
||||
SizedBox(height: screenHeight * 0.02),
|
||||
Hero(
|
||||
tag: 'welcome_text',
|
||||
child: Material(
|
||||
|
|
@ -155,6 +158,7 @@ class _SigninScreenState extends State<SigninScreen> {
|
|||
),
|
||||
),
|
||||
const SizedBox(height: 26),
|
||||
// SizedBox(height: screenHeight * 0.05),
|
||||
Center(
|
||||
child: Hero(
|
||||
tag: 'login_illustration',
|
||||
|
|
@ -165,6 +169,7 @@ class _SigninScreenState extends State<SigninScreen> {
|
|||
),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
// SizedBox(height: screenHeight * 0.05),
|
||||
CustomFieldWidget(
|
||||
fieldName: 'login',
|
||||
controller: _loginController,
|
||||
|
|
@ -314,7 +319,7 @@ class _SigninScreenState extends State<SigninScreen> {
|
|||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation,
|
||||
secondaryAnimation) =>
|
||||
SignupScreen(),
|
||||
const SignupScreen(),
|
||||
transitionsBuilder: (context, animation,
|
||||
secondaryAnimation, child) {
|
||||
return FadeTransition(
|
||||
|
|
@ -341,7 +346,7 @@ class _SigninScreenState extends State<SigninScreen> {
|
|||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
SizedBox(height: screenHeight * 0.02),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ class LoginPasswordField extends StatefulWidget {
|
|||
const LoginPasswordField({super.key});
|
||||
|
||||
@override
|
||||
_LoginPasswordFieldState createState() => _LoginPasswordFieldState();
|
||||
LoginPasswordFieldState createState() => LoginPasswordFieldState();
|
||||
}
|
||||
|
||||
class _LoginPasswordFieldState extends State<LoginPasswordField> {
|
||||
class LoginPasswordFieldState extends State<LoginPasswordField> {
|
||||
late FocusNode _focusNode;
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
|
||||
class SignupScreen extends StatefulWidget {
|
||||
SignupScreen({super.key});
|
||||
const SignupScreen({super.key});
|
||||
|
||||
@override
|
||||
State<SignupScreen> createState() => _SignupScreenState();
|
||||
|
|
@ -88,7 +88,7 @@ class _SignupScreenState extends State<SignupScreen> {
|
|||
// Navigate to login screen
|
||||
Navigator.of(dialogContext).pushAndRemoveUntil(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SigninScreen(),
|
||||
builder: (context) => const SigninScreen(),
|
||||
),
|
||||
(Route<dynamic> route) => false,
|
||||
);
|
||||
|
|
@ -288,7 +288,7 @@ class _SignupScreenState extends State<SignupScreen> {
|
|||
}
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
|
|
@ -303,7 +303,7 @@ class _SignupScreenState extends State<SignupScreen> {
|
|||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SigninScreen()),
|
||||
builder: (context) => const SigninScreen()),
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class _HistoryScreenState extends State<HistoryScreen> {
|
|||
try {
|
||||
await historyProvider.fetchLearningHistory(userProvider.jwtToken!);
|
||||
} catch (e) {
|
||||
print('Error initializing history: $e');
|
||||
rethrow;
|
||||
} finally {
|
||||
setState(() {
|
||||
_isInitialLoading = false;
|
||||
|
|
@ -109,7 +109,6 @@ class _HistoryScreenState extends State<HistoryScreen> {
|
|||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
vertical: 30.0,
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ class NoProgressCard extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -181,7 +181,6 @@ class ExerciseProvider extends ChangeNotifier {
|
|||
|
||||
void _selectRightOption(int exerciseIndex, String option) {
|
||||
if (_activeLeftOption == null) {
|
||||
print("Please select a left option first.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -250,30 +249,23 @@ class ExerciseProvider extends ChangeNotifier {
|
|||
void goToExercise(int index) {
|
||||
if (index >= 0 && index < _exercises.length) {
|
||||
_currentExerciseIndex = index;
|
||||
print('Going to exercise: $_currentExerciseIndex'); // Debug print
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void nextQuestion() {
|
||||
print('Current index before next: $_currentExerciseIndex'); // Debug print
|
||||
if (_currentExerciseIndex <
|
||||
(_exercises.isNotEmpty
|
||||
? _exercises.length - 1
|
||||
: _reviewExercises.length - 1)) {
|
||||
_currentExerciseIndex++;
|
||||
print('Moving to next question: $_currentExerciseIndex'); // Debug print
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void previousQuestion() {
|
||||
print(
|
||||
'Current index before previous: $_currentExerciseIndex'); // Debug print
|
||||
if (_currentExerciseIndex > 0) {
|
||||
_currentExerciseIndex--;
|
||||
print(
|
||||
'Moving to previous question: $_currentExerciseIndex'); // Debug print
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
|
@ -334,7 +326,7 @@ class ExerciseProvider extends ChangeNotifier {
|
|||
_answers = List.generate(_exercises.length, (index) => '');
|
||||
initializeAnswers();
|
||||
} catch (e) {
|
||||
print('Error fetching exercises: $e');
|
||||
rethrow;
|
||||
} finally {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
|
@ -383,7 +375,6 @@ class ExerciseProvider extends ChangeNotifier {
|
|||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error fetching review exercises: $e');
|
||||
rethrow;
|
||||
} finally {
|
||||
_isLoading = false;
|
||||
|
|
@ -480,12 +471,9 @@ class ExerciseProvider extends ChangeNotifier {
|
|||
'No answers to submit. Please answer at least one question.');
|
||||
}
|
||||
|
||||
print('Submitting answers to repository');
|
||||
final result = await _repository.submitAnswersAndGetScore(
|
||||
answersToSubmit, _studentLearningId!, token);
|
||||
|
||||
print('Repository response: $result');
|
||||
|
||||
return {
|
||||
'CURRENT_LEVEL_NAME': result['CURRENT_LEVEL_NAME'],
|
||||
'NEXT_LEARNING_NAME': result['NEXT_LEARNING_NAME'],
|
||||
|
|
@ -493,7 +481,6 @@ class ExerciseProvider extends ChangeNotifier {
|
|||
'IS_PASS': result['IS_PASS'],
|
||||
};
|
||||
} catch (e) {
|
||||
print('Error in submitAnswersAndGetScore: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
|
@ -507,13 +494,10 @@ class ExerciseProvider extends ChangeNotifier {
|
|||
if (_studentLearningId == null) {
|
||||
throw Exception('Student Learning ID is not set');
|
||||
}
|
||||
print('Submitting feedback for stdLearningId: $_studentLearningId');
|
||||
final result = await _repository.submitFeedback(
|
||||
_studentLearningId!, feedback, token);
|
||||
print('Feedback submitted successfully');
|
||||
return result;
|
||||
} catch (e) {
|
||||
print('Error submitting feedback: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ class ExerciseNavigator extends StatelessWidget {
|
|||
Future<void> submitAnswers() async {
|
||||
try {
|
||||
final result = await exerciseProvider.submitAnswersAndGetScore();
|
||||
print('Submit result: $result');
|
||||
|
||||
if (context.mounted) {
|
||||
Navigator.of(context).pushReplacement(
|
||||
|
|
@ -55,7 +54,6 @@ class ExerciseNavigator extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error submitting answers: $e');
|
||||
if (context.mounted) {
|
||||
CustomSnackBar.show(
|
||||
context,
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ class _MatchingPairsQuestionState extends State<MatchingPairsQuestion> {
|
|||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
}),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,10 +80,7 @@ class _FeedbackScreenState extends State<FeedbackScreen> {
|
|||
});
|
||||
|
||||
try {
|
||||
final exerciseProvider =
|
||||
Provider.of<ExerciseProvider>(context, listen: false);
|
||||
final result =
|
||||
await exerciseProvider.submitFeedback(_controller.text.trim());
|
||||
Provider.of<ExerciseProvider>(context, listen: false);
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
|
|
@ -91,27 +88,19 @@ class _FeedbackScreenState extends State<FeedbackScreen> {
|
|||
_isLoading = false;
|
||||
});
|
||||
|
||||
if (result != null) {
|
||||
await showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext dialogContext) => PopScope(
|
||||
canPop: false,
|
||||
child: FeedbackDialog(
|
||||
onSubmit: () {
|
||||
Navigator.pop(dialogContext);
|
||||
_navigateToLevelList();
|
||||
},
|
||||
),
|
||||
await showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext dialogContext) => PopScope(
|
||||
canPop: false,
|
||||
child: FeedbackDialog(
|
||||
onSubmit: () {
|
||||
Navigator.pop(dialogContext);
|
||||
_navigateToLevelList();
|
||||
},
|
||||
),
|
||||
);
|
||||
} else {
|
||||
CustomSnackBar.show(
|
||||
context,
|
||||
message: 'Failed to submit feedback. Please try again.',
|
||||
isError: true,
|
||||
);
|
||||
}
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,6 @@ class VideoPlayerWidgetState extends State<VideoPlayerWidget> {
|
|||
}
|
||||
return null;
|
||||
} catch (e) {
|
||||
print('Error extracting YouTube ID: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:english_learning/core/services/constants.dart';
|
||||
import 'package:english_learning/core/widgets/custom_snackbar.dart';
|
||||
import 'package:english_learning/core/widgets/loading/shimmer_loading_widget.dart';
|
||||
import 'package:english_learning/features/auth/provider/user_provider.dart';
|
||||
import 'package:english_learning/features/learning/modules/level/screens/level_list_screen.dart';
|
||||
|
|
@ -46,12 +47,15 @@ class _TopicsListScreenState extends State<TopicsListScreen> {
|
|||
try {
|
||||
await Provider.of<TopicProvider>(context, listen: false)
|
||||
.fetchTopics(widget.sectionId, token);
|
||||
print('Topics fetched successfully');
|
||||
} catch (e) {
|
||||
print('Error fetching topics: $e');
|
||||
rethrow;
|
||||
}
|
||||
} else {
|
||||
print('No valid token found. User might need to log in.');
|
||||
CustomSnackBar.show(
|
||||
context,
|
||||
message: 'No valid token found. User might need to log in.',
|
||||
isError: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import 'package:flutter/foundation.dart';
|
|||
class SectionProvider extends ChangeNotifier {
|
||||
final SectionRepository _repository = SectionRepository();
|
||||
List<Section> _sections = [];
|
||||
bool _isLoading = false;
|
||||
final bool _isLoading = false;
|
||||
dynamic _error;
|
||||
|
||||
List<Section> get sections => _sections;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class _LearningScreenState extends State<LearningScreen>
|
|||
await sectionProvider.fetchSections(token);
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error initializing sections: $e');
|
||||
rethrow;
|
||||
} finally {
|
||||
setState(() {
|
||||
_isInitialLoading = false;
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ class _OnBoardingScreenState extends State<OnBoardingScreen> {
|
|||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SignupScreen()),
|
||||
builder: (context) => const SignupScreen()),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -114,7 +114,8 @@ class _ChangePasswordScreenState extends State<ChangePasswordScreen> {
|
|||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SigninScreen()),
|
||||
builder: (context) =>
|
||||
const SigninScreen()),
|
||||
(route) => false,
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -23,14 +23,6 @@ class SettingsScreen extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _SettingsScreenState extends State<SettingsScreen> {
|
||||
// @override
|
||||
// void initState() {
|
||||
// super.initState();
|
||||
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// Provider.of<UserProvider>(context, listen: false).refreshUserData();
|
||||
// });
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
|
@ -186,7 +178,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||
if (success) {
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SigninScreen()),
|
||||
builder: (context) =>
|
||||
const SigninScreen()),
|
||||
(Route<dynamic> route) => false,
|
||||
);
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user