286 lines
9.6 KiB
Dart
Executable File
286 lines
9.6 KiB
Dart
Executable File
import 'package:external_repos/external_repos.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:uae_stat/config/my_theme.dart';
|
|
import 'package:uae_stat/domain/use_cases/language.dart';
|
|
import 'package:uae_stat/domain/use_cases/stat_data/indicator_use_case.dart';
|
|
import 'package:uae_stat/infrastructure/services/packages/num_abbreviation.dart';
|
|
import 'package:uae_stat/presentation/components/my_bottom_nav_bar.dart';
|
|
import 'package:uae_stat/presentation/components/space.dart';
|
|
|
|
/// constrain into a fixed height
|
|
class IndicatorView extends ConsumerWidget {
|
|
const IndicatorView(
|
|
this.id, {
|
|
super.key,
|
|
});
|
|
|
|
final IndicatorEnum id;
|
|
|
|
void onPressed(
|
|
BuildContext context,
|
|
WidgetRef ref,
|
|
) {
|
|
final location =
|
|
'/${context.language}/${BottomNavBarItem.uaeNumbers.routePath}/${id.name}';
|
|
context.go(location);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final topicColor = MyTheme.topicColor(
|
|
id.topic,
|
|
);
|
|
final title = Text(
|
|
context.translate(
|
|
id.titleEN,
|
|
id.titleAR,
|
|
),
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(
|
|
fontFamily: context.translate(
|
|
'Roboto',
|
|
'NotoKufi',
|
|
),
|
|
color: Colors.black,
|
|
),
|
|
);
|
|
final provider = IndicatorProvider(id);
|
|
return ref
|
|
.watch(
|
|
provider,
|
|
)
|
|
.when(
|
|
skipLoadingOnRefresh: false,
|
|
skipLoadingOnReload: false,
|
|
skipError: false,
|
|
data: (indicatorData) {
|
|
final value = switch (id) {
|
|
// econ
|
|
IndicatorEnum.gdpGrowthConstant =>
|
|
(indicatorData as GdpEntity).constant.gdpGrowthRate.value,
|
|
// env
|
|
IndicatorEnum.exportOilQuantity =>
|
|
(indicatorData as OilEntity).crudeOilExports.value,
|
|
IndicatorEnum.municipalWaste =>
|
|
(indicatorData as WaterEntity).municipalWaste.value,
|
|
// social
|
|
IndicatorEnum.hospitalsPrivate =>
|
|
(indicatorData as HospitalsEntity).numPrivate.value,
|
|
_ => indicatorData.level1Data.value,
|
|
};
|
|
final subtitleText = switch (id) {
|
|
// econ
|
|
IndicatorEnum.gdpGrowthConstant =>
|
|
(indicatorData as GdpEntity).constant.gdpGrowthRate.subtitle,
|
|
// env
|
|
IndicatorEnum.exportOilQuantity =>
|
|
(indicatorData as OilEntity).crudeOilExports.subtitle,
|
|
IndicatorEnum.municipalWaste =>
|
|
(indicatorData as WaterEntity).municipalWaste.subtitle,
|
|
// social
|
|
IndicatorEnum.hospitalsPrivate =>
|
|
(indicatorData as HospitalsEntity).numPrivate.subtitle,
|
|
_ => indicatorData.level1Data.subtitle,
|
|
};
|
|
final hasPercentage = switch (id) {
|
|
// econ
|
|
IndicatorEnum.gdpGrowthConstant => (indicatorData as GdpEntity)
|
|
.constant
|
|
.gdpGrowthRate
|
|
.isValuePercentage,
|
|
// env
|
|
IndicatorEnum.exportOilQuantity =>
|
|
(indicatorData as OilEntity).crudeOilExports.isValuePercentage,
|
|
IndicatorEnum.municipalWaste =>
|
|
(indicatorData as WaterEntity).municipalWaste.isValuePercentage,
|
|
// social
|
|
IndicatorEnum.hospitalsPrivate =>
|
|
(indicatorData as HospitalsEntity).numPrivate.isValuePercentage,
|
|
_ => indicatorData.level1Data.isPercentage,
|
|
};
|
|
// title + subtitle on separate lines
|
|
final subtitle = Text(
|
|
context.translateFromTuple(
|
|
subtitleText,
|
|
),
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(
|
|
fontFamily: context.translate(
|
|
'Roboto',
|
|
'NotoKufi',
|
|
),
|
|
color: Colors.black45,
|
|
),
|
|
);
|
|
final textDescriptorBody = ConstrainedBox(
|
|
constraints: BoxConstraints(
|
|
maxWidth: context.translate(130, 170).toDouble(),
|
|
),
|
|
child: Column(
|
|
children: [
|
|
title,
|
|
subtitle,
|
|
],
|
|
),
|
|
);
|
|
final textValue = Text(
|
|
'${value > 9999999 ? value.toAbbreviatedString() : value.toStringWithCommas(
|
|
hideDecimals: value > 99999,
|
|
)}${(hasPercentage ? '%' : '')}',
|
|
style: TextStyle(
|
|
fontFamily:
|
|
// ref.watch(languageProvider) == Language.ar
|
|
// ? 'NotoKufi'
|
|
// :
|
|
'Roboto',
|
|
color: topicColor,
|
|
fontSize: 24,
|
|
fontWeight: FontWeight.w800,
|
|
// height: context.translate(null, 1.75),
|
|
),
|
|
);
|
|
return InkWell(
|
|
onTap: id == IndicatorEnum.municipalWaste
|
|
? null
|
|
: () => onPressed(context, ref),
|
|
borderRadius: BorderRadius.circular(10),
|
|
child: Container(
|
|
padding: const EdgeInsets.only(
|
|
top: 4,
|
|
bottom: 0,
|
|
left: 12,
|
|
right: 12,
|
|
),
|
|
decoration: BoxDecoration(
|
|
border: Border.all(
|
|
color: topicColor,
|
|
),
|
|
borderRadius: BorderRadius.circular(10),
|
|
),
|
|
child: FittedBox(
|
|
fit: BoxFit.scaleDown,
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
textDescriptorBody,
|
|
if (context.language == LanguageLocale.enUS)
|
|
6.verticalSpace,
|
|
textValue,
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
error: (err, stackTrace) {
|
|
Future(() => Error.throwWithStackTrace(err, stackTrace));
|
|
Future.delayed(
|
|
const Duration(seconds: 5),
|
|
() {
|
|
if (!context.mounted) return;
|
|
ref.invalidate(provider);
|
|
},
|
|
);
|
|
final textDescriptorBody = ConstrainedBox(
|
|
constraints: const BoxConstraints(
|
|
maxWidth: 130,
|
|
),
|
|
child: title,
|
|
);
|
|
final value = Text(
|
|
'!',
|
|
style: TextStyle(
|
|
fontFamily: context.translate(
|
|
'Roboto',
|
|
'NotoKufi',
|
|
),
|
|
color: Colors.red,
|
|
fontSize: 24,
|
|
fontWeight: FontWeight.w900,
|
|
),
|
|
);
|
|
return InkWell(
|
|
onTap: id == IndicatorEnum.municipalWaste
|
|
? null
|
|
: () => onPressed(context, ref),
|
|
borderRadius: BorderRadius.circular(10),
|
|
child: Container(
|
|
padding: const EdgeInsets.only(
|
|
top: 4,
|
|
bottom: 0,
|
|
left: 12,
|
|
right: 12,
|
|
),
|
|
decoration: BoxDecoration(
|
|
border: Border.all(
|
|
color: topicColor,
|
|
),
|
|
borderRadius: BorderRadius.circular(10),
|
|
),
|
|
child: FittedBox(
|
|
fit: BoxFit.scaleDown,
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
textDescriptorBody,
|
|
6.verticalSpace,
|
|
value,
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
loading: () {
|
|
final textDescriptorBody = ConstrainedBox(
|
|
constraints: const BoxConstraints(
|
|
maxWidth: 130,
|
|
),
|
|
child: title,
|
|
);
|
|
final value = SizedBox(
|
|
height: 24,
|
|
width: 24,
|
|
child: LinearProgressIndicator(
|
|
borderRadius: BorderRadius.circular(100),
|
|
color: MyTheme.topicColor(id.topic),
|
|
),
|
|
);
|
|
return InkWell(
|
|
onTap: id == IndicatorEnum.municipalWaste
|
|
? null
|
|
: () => onPressed(context, ref),
|
|
borderRadius: BorderRadius.circular(10),
|
|
child: Container(
|
|
padding: const EdgeInsets.only(
|
|
top: 4,
|
|
bottom: 0,
|
|
left: 12,
|
|
right: 12,
|
|
),
|
|
decoration: BoxDecoration(
|
|
border: Border.all(
|
|
color: topicColor,
|
|
),
|
|
borderRadius: BorderRadius.circular(10),
|
|
),
|
|
child: FittedBox(
|
|
fit: BoxFit.scaleDown,
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
textDescriptorBody,
|
|
6.verticalSpace,
|
|
value,
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|