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: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_calculator_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:provider/provider.dart';
@@ -77,6 +78,9 @@ class _MzansiInnovationHubState extends State<MzansiInnovationHub> {
ChangeNotifierProvider(
create: (context) => MihBannerAdProvider(),
),
ChangeNotifierProvider(
create: (context) => MihCalculatorProvider(),
),
],
child: MaterialApp.router(
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_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_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/simple_calc.dart';
import 'package:mzansi_innovation_hub/mih_packages/calculator/package_tools/tip_calc.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_currency_exchange_rate_services.dart';
import 'package:provider/provider.dart';
class MIHCalculator extends StatefulWidget {
@@ -21,13 +23,16 @@ class MIHCalculator extends StatefulWidget {
}
class _MIHCalculatorState extends State<MIHCalculator> {
int _selectedIndex = 0;
Future<void> getCurrencyCodeList() async {
await MihCurrencyExchangeRateServices.getCurrencyCodeList(context);
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
context.read<MihBannerAdProvider>().loadBannerAd();
await getCurrencyCodeList();
});
}
@@ -38,12 +43,9 @@ class _MIHCalculatorState extends State<MIHCalculator> {
appTools: getTools(),
appBody: getToolBody(),
appToolTitles: getToolTitle(),
selectedbodyIndex: _selectedIndex,
onIndexChange: (newValue) {
setState(() {
_selectedIndex = newValue;
});
print("Index: $_selectedIndex");
selectedbodyIndex: context.watch<MihCalculatorProvider>().toolIndex,
onIndexChange: (newIndex) {
context.read<MihCalculatorProvider>().setToolIndex(newIndex);
},
);
}
@@ -65,23 +67,17 @@ class _MIHCalculatorState extends State<MIHCalculator> {
MihPackageTools getTools() {
Map<Widget, void Function()?> temp = {};
temp[const Icon(Icons.calculate)] = () {
setState(() {
_selectedIndex = 0;
});
context.read<MihCalculatorProvider>().setToolIndex(0);
};
temp[const Icon(Icons.money)] = () {
setState(() {
_selectedIndex = 1;
});
context.read<MihCalculatorProvider>().setToolIndex(1);
};
temp[const Icon(Icons.currency_exchange)] = () {
setState(() {
_selectedIndex = 2;
});
context.read<MihCalculatorProvider>().setToolIndex(2);
};
return MihPackageTools(
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_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_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_calculator_provider.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_currency_exchange_rate_services.dart';
@@ -30,7 +30,6 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
final TextEditingController _toCurrencyController = TextEditingController();
final TextEditingController _fromAmountController = TextEditingController();
final TextEditingController _toAmountController = TextEditingController();
late Future<List<String>> availableCurrencies;
Future<void> submitForm() async {
String fromCurrencyCode = _fromCurrencyController.text.split(" - ")[0];
@@ -276,7 +275,6 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
@override
void initState() {
super.initState();
availableCurrencies = MihCurrencyExchangeRateServices.getCurrencyCodeList();
}
@override
@@ -290,177 +288,155 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
}
Widget getBody(double width) {
return FutureBuilder(
future: availableCurrencies,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Mihloadingcircle();
} else if (snapshot.connectionState == ConnectionState.done) {
return MihSingleChildScroll(
child: Padding(
padding: MzansiInnovationHub.of(context)!.theme.screenType ==
"desktop"
return Consumer<MihCalculatorProvider>(
builder: (context, calculatorProvider, child) {
return MihSingleChildScroll(
child: Padding(
padding:
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
? EdgeInsets.symmetric(horizontal: width * 0.2)
: EdgeInsets.symmetric(horizontal: width * 0.075),
child: Column(
children: [
MihForm(
formKey: _formKey,
formFields: <Widget>[
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
child: Column(
children: [
MihForm(
formKey: _formKey,
formFields: <Widget>[
MihTextFormField(
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 ==
"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: snapshot.data!,
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(
children: [
const TextSpan(
text: "* Experimental Feature: Please review "),
TextSpan(
text: "Diclaimer",
style: TextStyle(
fontSize: 15,
color: MihColors.getRedColor(
decoration: TextDecoration.underline,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.bold,
),
children: [
const TextSpan(
text:
"* 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."),
],
recognizer: TapGestureRecognizer()
..onTap = () {
displayDisclaimer();
},
),
),
const SizedBox(height: 25),
Center(
child: Wrap(
spacing: 10,
runSpacing: 10,
children: [
MihButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
submitForm();
FocusScope.of(context)
.requestFocus(FocusNode());
} else {
MihAlertServices()
.formNotFilledCompletely(context);
}
},
buttonColor: MihColors.getGreenColor(
const TextSpan(text: " before use."),
],
),
),
const SizedBox(height: 25),
Center(
child: Wrap(
spacing: 10,
runSpacing: 10,
children: [
MihButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
submitForm();
FocusScope.of(context)
.requestFocus(FocusNode());
} else {
MihAlertServices()
.formNotFilledCompletely(context);
}
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Calculate",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
width: 300,
child: Text(
"Calculate",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
fontSize: 20,
fontWeight: FontWeight.bold,
),
MihButton(
onPressed: () {
clearInput();
},
buttonColor: MihColors.getRedColor(
),
),
MihButton(
onPressed: () {
clearInput();
},
buttonColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Clear",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
width: 300,
child: Text(
"Clear",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
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 'package:flutter/material.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;
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(
"https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies.min.json"));
if (response.statusCode == 200) {
@@ -32,7 +35,11 @@ class MihCurrencyExchangeRateServices {
currencies.add("$code - $name");
});
currencies.sort();
return currencies;
if (response.statusCode == 200) {
context
.read<MihCalculatorProvider>()
.setAvailableCurrencies(currencies: currencies);
}
} else {
throw Exception('failed to fatch currencies');
}