NEW: MIH Calculator Provider Setup

This commit is contained in:
2025-10-08 15:06:04 +02:00
parent a1b7a3ef28
commit bbadc58ab8
5 changed files with 174 additions and 170 deletions

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_banner_ad_provider.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_banner_ad_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calculator_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_wallet_provider.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_wallet_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@@ -77,6 +78,9 @@ class _MzansiInnovationHubState extends State<MzansiInnovationHub> {
ChangeNotifierProvider( ChangeNotifierProvider(
create: (context) => MihBannerAdProvider(), create: (context) => MihBannerAdProvider(),
), ),
ChangeNotifierProvider(
create: (context) => MihCalculatorProvider(),
),
], ],
child: MaterialApp.router( child: MaterialApp.router(
title: getTitle(), title: getTitle(),

View File

@@ -0,0 +1,21 @@
import 'package:flutter/foundation.dart';
class MihCalculatorProvider extends ChangeNotifier {
List<String> availableCurrencies;
int toolIndex;
MihCalculatorProvider({
this.availableCurrencies = const [],
this.toolIndex = 0,
});
void setToolIndex(int index) {
toolIndex = index;
notifyListeners();
}
void setAvailableCurrencies({required List<String> currencies}) async {
availableCurrencies = currencies;
notifyListeners();
}
}

View File

@@ -3,10 +3,12 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_banner_ad_provider.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_banner_ad_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calculator_provider.dart';
import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tools/currency_exchange_rate.dart'; import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tools/currency_exchange_rate.dart';
import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tools/simple_calc.dart'; import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tools/simple_calc.dart';
import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tools/tip_calc.dart'; import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tools/tip_calc.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_currency_exchange_rate_services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class MIHCalculator extends StatefulWidget { class MIHCalculator extends StatefulWidget {
@@ -21,13 +23,16 @@ class MIHCalculator extends StatefulWidget {
} }
class _MIHCalculatorState extends State<MIHCalculator> { class _MIHCalculatorState extends State<MIHCalculator> {
int _selectedIndex = 0; Future<void> getCurrencyCodeList() async {
await MihCurrencyExchangeRateServices.getCurrencyCodeList(context);
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async { WidgetsBinding.instance.addPostFrameCallback((_) async {
context.read<MihBannerAdProvider>().loadBannerAd(); context.read<MihBannerAdProvider>().loadBannerAd();
await getCurrencyCodeList();
}); });
} }
@@ -38,12 +43,9 @@ class _MIHCalculatorState extends State<MIHCalculator> {
appTools: getTools(), appTools: getTools(),
appBody: getToolBody(), appBody: getToolBody(),
appToolTitles: getToolTitle(), appToolTitles: getToolTitle(),
selectedbodyIndex: _selectedIndex, selectedbodyIndex: context.watch<MihCalculatorProvider>().toolIndex,
onIndexChange: (newValue) { onIndexChange: (newIndex) {
setState(() { context.read<MihCalculatorProvider>().setToolIndex(newIndex);
_selectedIndex = newValue;
});
print("Index: $_selectedIndex");
}, },
); );
} }
@@ -65,23 +67,17 @@ class _MIHCalculatorState extends State<MIHCalculator> {
MihPackageTools getTools() { MihPackageTools getTools() {
Map<Widget, void Function()?> temp = {}; Map<Widget, void Function()?> temp = {};
temp[const Icon(Icons.calculate)] = () { temp[const Icon(Icons.calculate)] = () {
setState(() { context.read<MihCalculatorProvider>().setToolIndex(0);
_selectedIndex = 0;
});
}; };
temp[const Icon(Icons.money)] = () { temp[const Icon(Icons.money)] = () {
setState(() { context.read<MihCalculatorProvider>().setToolIndex(1);
_selectedIndex = 1;
});
}; };
temp[const Icon(Icons.currency_exchange)] = () { temp[const Icon(Icons.currency_exchange)] = () {
setState(() { context.read<MihCalculatorProvider>().setToolIndex(2);
_selectedIndex = 2;
});
}; };
return MihPackageTools( return MihPackageTools(
tools: temp, tools: temp,
selcetedIndex: _selectedIndex, selcetedIndex: context.watch<MihCalculatorProvider>().toolIndex,
); );
} }

View File

@@ -9,8 +9,8 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_banner_ad_provider.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_banner_ad_provider.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calculator_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_currency_exchange_rate_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_currency_exchange_rate_services.dart';
@@ -30,7 +30,6 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
final TextEditingController _toCurrencyController = TextEditingController(); final TextEditingController _toCurrencyController = TextEditingController();
final TextEditingController _fromAmountController = TextEditingController(); final TextEditingController _fromAmountController = TextEditingController();
final TextEditingController _toAmountController = TextEditingController(); final TextEditingController _toAmountController = TextEditingController();
late Future<List<String>> availableCurrencies;
Future<void> submitForm() async { Future<void> submitForm() async {
String fromCurrencyCode = _fromCurrencyController.text.split(" - ")[0]; String fromCurrencyCode = _fromCurrencyController.text.split(" - ")[0];
@@ -276,7 +275,6 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
availableCurrencies = MihCurrencyExchangeRateServices.getCurrencyCodeList();
} }
@override @override
@@ -290,177 +288,155 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
} }
Widget getBody(double width) { Widget getBody(double width) {
return FutureBuilder( return Consumer<MihCalculatorProvider>(
future: availableCurrencies, builder: (context, calculatorProvider, child) {
builder: (context, snapshot) { return MihSingleChildScroll(
if (snapshot.connectionState == ConnectionState.waiting) { child: Padding(
return const Mihloadingcircle(); padding:
} else if (snapshot.connectionState == ConnectionState.done) { MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
return MihSingleChildScroll(
child: Padding(
padding: MzansiInnovationHub.of(context)!.theme.screenType ==
"desktop"
? EdgeInsets.symmetric(horizontal: width * 0.2) ? EdgeInsets.symmetric(horizontal: width * 0.2)
: EdgeInsets.symmetric(horizontal: width * 0.075), : EdgeInsets.symmetric(horizontal: width * 0.075),
child: Column( child: Column(
children: [ children: [
MihForm( MihForm(
formKey: _formKey, formKey: _formKey,
formFields: <Widget>[ formFields: <Widget>[
MihTextFormField( MihTextFormField(
fillColor: MihColors.getSecondaryColor( fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: _fromAmountController,
multiLineInput: false,
requiredText: true,
hintText: "Currency Amount",
numberMode: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
),
const SizedBox(height: 10),
MihDropdownField(
controller: _fromCurrencyController,
hintText: "From",
dropdownOptions: calculatorProvider.availableCurrencies,
editable: true,
enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
),
const SizedBox(height: 10),
MihDropdownField(
controller: _toCurrencyController,
hintText: "To",
dropdownOptions: calculatorProvider.availableCurrencies,
editable: true,
enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
),
const SizedBox(height: 15),
RichText(
textAlign: TextAlign.left,
text: TextSpan(
style: TextStyle(
fontSize: 15,
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"), "Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: _fromAmountController,
multiLineInput: false,
requiredText: true,
hintText: "Currency Amount",
numberMode: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
), ),
const SizedBox(height: 10), children: [
MihDropdownField( const TextSpan(
controller: _fromCurrencyController, text: "* Experimental Feature: Please review "),
hintText: "From", TextSpan(
dropdownOptions: snapshot.data!, text: "Diclaimer",
editable: true,
enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
),
const SizedBox(height: 10),
MihDropdownField(
controller: _toCurrencyController,
hintText: "To",
dropdownOptions: snapshot.data!,
editable: true,
enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
),
const SizedBox(height: 15),
RichText(
textAlign: TextAlign.left,
text: TextSpan(
style: TextStyle( style: TextStyle(
fontSize: 15, decoration: TextDecoration.underline,
color: MihColors.getRedColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"), "Dark"),
fontWeight: FontWeight.bold,
), ),
children: [ recognizer: TapGestureRecognizer()
const TextSpan( ..onTap = () {
text: displayDisclaimer();
"* Experimental Feature: Please review "), },
TextSpan(
text: "Diclaimer",
style: TextStyle(
decoration: TextDecoration.underline,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
fontWeight: FontWeight.bold,
),
recognizer: TapGestureRecognizer()
..onTap = () {
displayDisclaimer();
},
),
const TextSpan(text: " before use."),
],
), ),
), const TextSpan(text: " before use."),
const SizedBox(height: 25), ],
Center( ),
child: Wrap( ),
spacing: 10, const SizedBox(height: 25),
runSpacing: 10, Center(
children: [ child: Wrap(
MihButton( spacing: 10,
onPressed: () { runSpacing: 10,
if (_formKey.currentState!.validate()) { children: [
submitForm(); MihButton(
FocusScope.of(context) onPressed: () {
.requestFocus(FocusNode()); if (_formKey.currentState!.validate()) {
} else { submitForm();
MihAlertServices() FocusScope.of(context)
.formNotFilledCompletely(context); .requestFocus(FocusNode());
} } else {
}, MihAlertServices()
buttonColor: MihColors.getGreenColor( .formNotFilledCompletely(context);
}
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Calculate",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)! MzansiInnovationHub.of(context)!
.theme .theme
.mode == .mode ==
"Dark"), "Dark"),
width: 300, fontSize: 20,
child: Text( fontWeight: FontWeight.bold,
"Calculate",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
), ),
MihButton( ),
onPressed: () { ),
clearInput(); MihButton(
}, onPressed: () {
buttonColor: MihColors.getRedColor( clearInput();
},
buttonColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Clear",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)! MzansiInnovationHub.of(context)!
.theme .theme
.mode == .mode ==
"Dark"), "Dark"),
width: 300, fontSize: 20,
child: Text( fontWeight: FontWeight.bold,
"Clear",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
), ),
], ),
), ),
), ],
], ),
), ),
], ],
), ),
), ],
); ),
} else { ),
return Center( );
child: Text( },
"Error pulling Currency Exchange Data.", );
style: TextStyle(
fontSize: 25,
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark")),
textAlign: TextAlign.center,
),
);
}
});
} }
} }

View File

@@ -1,6 +1,9 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/currency.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_objects/currency.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calculator_provider.dart';
import 'package:provider/provider.dart';
import 'package:supertokens_flutter/http.dart' as http; import 'package:supertokens_flutter/http.dart' as http;
class MihCurrencyExchangeRateServices { class MihCurrencyExchangeRateServices {
@@ -21,7 +24,7 @@ class MihCurrencyExchangeRateServices {
} }
} }
static Future<List<String>> getCurrencyCodeList() async { static Future<void> getCurrencyCodeList(BuildContext context) async {
final response = await http.get(Uri.parse( final response = await http.get(Uri.parse(
"https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies.min.json")); "https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies.min.json"));
if (response.statusCode == 200) { if (response.statusCode == 200) {
@@ -32,7 +35,11 @@ class MihCurrencyExchangeRateServices {
currencies.add("$code - $name"); currencies.add("$code - $name");
}); });
currencies.sort(); currencies.sort();
return currencies; if (response.statusCode == 200) {
context
.read<MihCalculatorProvider>()
.setAvailableCurrencies(currencies: currencies);
}
} else { } else {
throw Exception('failed to fatch currencies'); throw Exception('failed to fatch currencies');
} }