monthly report
parent
86a91ab383
commit
0b3fea230f
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
@ -0,0 +1,60 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import '../../core/api/api_client.dart';
|
||||
import '../../core/api_consts.dart';
|
||||
import '../../core/exceptions/api_failure.dart';
|
||||
import '../../services/logger_service.dart';
|
||||
|
||||
abstract class TermsConditionsRepo {
|
||||
Future<Either<Failure, String>> getTermsConditions();
|
||||
}
|
||||
|
||||
class TermsConditionsRepoImp implements TermsConditionsRepo {
|
||||
final ApiClient apiClient;
|
||||
final LoggerService loggerService;
|
||||
|
||||
TermsConditionsRepoImp({
|
||||
required this.loggerService,
|
||||
required this.apiClient,
|
||||
});
|
||||
|
||||
@override
|
||||
Future<Either<Failure, String>> getTermsConditions() async {
|
||||
Failure? failure;
|
||||
String? html;
|
||||
|
||||
try {
|
||||
await apiClient.post(
|
||||
ApiConsts.getTermsConditions,
|
||||
body: <String, dynamic>{},
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType ?? ServerFailure(error.toString());
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
try {
|
||||
|
||||
final content = response['UserAgreementContent'];
|
||||
|
||||
if (content is String && content.isNotEmpty) {
|
||||
html = content;
|
||||
} else {
|
||||
failure = DataParsingFailure(
|
||||
'UserAgreementContent is null or not String');
|
||||
}
|
||||
} catch (e) {
|
||||
failure = DataParsingFailure(e.toString());
|
||||
}
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
failure = UnknownFailure(e.toString());
|
||||
}
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (html == null || html!.isEmpty) {
|
||||
return Left(ServerFailure('No terms and conditions returned'));
|
||||
}
|
||||
|
||||
return Right(html!);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/features/terms_conditions/terms_conditions_repo.dart';
|
||||
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
|
||||
|
||||
class TermsConditionsViewModel extends ChangeNotifier {
|
||||
final TermsConditionsRepo termsConditionsRepo;
|
||||
final ErrorHandlerService errorHandlerService;
|
||||
|
||||
String? termsConditionsHtml;
|
||||
bool isLoading = false;
|
||||
|
||||
TermsConditionsViewModel({
|
||||
required this.termsConditionsRepo,
|
||||
required this.errorHandlerService,
|
||||
});
|
||||
|
||||
Future<void> getTermsConditions({
|
||||
Function()? onSuccess,
|
||||
Function(String)? onError,
|
||||
}) async {
|
||||
isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
final result = await termsConditionsRepo.getTermsConditions();
|
||||
|
||||
result.fold(
|
||||
(failure) async {
|
||||
await errorHandlerService.handleError(failure: failure);
|
||||
isLoading = false;
|
||||
notifyListeners();
|
||||
if (onError != null) {
|
||||
onError(failure.message ?? 'Something went wrong');
|
||||
}
|
||||
},
|
||||
(html) {
|
||||
termsConditionsHtml = html;
|
||||
isLoading = false;
|
||||
notifyListeners();
|
||||
if (onSuccess != null) onSuccess();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,117 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/features/terms_conditions/terms_conditions_view_model.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
import '../../theme/colors.dart';
|
||||
import '../../widgets/appbar/app_bar_widget.dart';
|
||||
|
||||
class UserAgreementPage extends StatefulWidget {
|
||||
const UserAgreementPage({super.key});
|
||||
|
||||
@override
|
||||
State<UserAgreementPage> createState() => _UserAgreementPageState();
|
||||
}
|
||||
|
||||
class _UserAgreementPageState extends State<UserAgreementPage> {
|
||||
late final WebViewController _webViewController;
|
||||
bool _isLoading = true;
|
||||
String? _errorMessage;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_webViewController = WebViewController()
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
..setBackgroundColor(const Color(0x00000000))
|
||||
..setNavigationDelegate(
|
||||
NavigationDelegate(
|
||||
onPageStarted: (_) {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
},
|
||||
onPageFinished: (_) {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
},
|
||||
onWebResourceError: (error) {
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
final vm =
|
||||
Provider.of<TermsConditionsViewModel>(context, listen: false);
|
||||
|
||||
vm.getTermsConditions(
|
||||
onSuccess: () {
|
||||
final htmlString = vm.termsConditionsHtml ?? '';
|
||||
|
||||
if (htmlString.isNotEmpty) {
|
||||
setState(() {
|
||||
_errorMessage = null;
|
||||
_isLoading = true;
|
||||
});
|
||||
_webViewController.loadHtmlString(htmlString);
|
||||
} else {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
_errorMessage = 'لا توجد شروط متاحة حالياً'.needTranslation;
|
||||
});
|
||||
}
|
||||
},
|
||||
onError: (msg) {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
_errorMessage = msg;
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.scaffoldBgColor,
|
||||
appBar: CustomAppBar(
|
||||
onBackPressed: () => Navigator.of(context).pop(),
|
||||
onLanguageChanged: (_) {},
|
||||
hideLogoAndLang: true,
|
||||
),
|
||||
body: Stack(
|
||||
children: [
|
||||
WebViewWidget(controller: _webViewController),
|
||||
|
||||
if (_errorMessage != null)
|
||||
Center(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.all(16),
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withOpacity(0.9),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Text(
|
||||
_errorMessage!,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
color: Colors.red,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (_isLoading)
|
||||
const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue