236 lines
7.8 KiB
Dart
236 lines
7.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:kmobile/api/services/limit_service.dart';
|
|
import 'package:kmobile/di/injection.dart';
|
|
import 'package:kmobile/features/profile/change_limit_otp_screen.dart';
|
|
import 'package:kmobile/l10n/app_localizations.dart';
|
|
import 'package:intl/intl.dart';
|
|
|
|
class DailyLimitScreen extends StatefulWidget {
|
|
final String mobileNumber;
|
|
const DailyLimitScreen({super.key, required this.mobileNumber});
|
|
@override
|
|
State<DailyLimitScreen> createState() => _DailyLimitScreenState();
|
|
}
|
|
|
|
class _DailyLimitScreenState extends State<DailyLimitScreen> {
|
|
double? _currentLimit;
|
|
double? _spentAmount = 0.0;
|
|
final _limitController = TextEditingController();
|
|
var service = getIt<LimitService>();
|
|
Limit? limit;
|
|
bool _isLoading = true;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_loadlimits();
|
|
}
|
|
|
|
Future<void> _loadlimits() async {
|
|
setState(() {
|
|
_isLoading = true;
|
|
});
|
|
final limit_data = await service.getLimit();
|
|
setState(() {
|
|
limit = limit_data;
|
|
_isLoading = false;
|
|
});
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_limitController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
Future<void> _showAddOrEditLimitDialog() async {
|
|
_limitController.text = _currentLimit?.toStringAsFixed(0) ?? '';
|
|
final newLimit = await showDialog<double>(
|
|
context: context,
|
|
builder: (dialogContext) {
|
|
final localizations = AppLocalizations.of(dialogContext);
|
|
final theme = Theme.of(dialogContext);
|
|
return AlertDialog(
|
|
title: Text(
|
|
_currentLimit == null
|
|
? localizations.addLimit
|
|
: localizations.editLimit,
|
|
),
|
|
content: TextField(
|
|
controller: _limitController,
|
|
autofocus: true,
|
|
keyboardType: TextInputType.number,
|
|
inputFormatters: [
|
|
FilteringTextInputFormatter.allow(RegExp(r'^\d+')),
|
|
],
|
|
decoration: InputDecoration(
|
|
labelText: localizations.limitAmount,
|
|
prefixText: '₹',
|
|
border: const OutlineInputBorder(),
|
|
),
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.of(dialogContext).pop(),
|
|
child: Text(localizations.cancel),
|
|
),
|
|
ElevatedButton(
|
|
onPressed: () async {
|
|
final value = double.tryParse(_limitController.text);
|
|
if (value == null || value <= 0) return;
|
|
|
|
if (value > 200000) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content: const Text(
|
|
"Limit To be Set must be less than 200000"),
|
|
behavior: SnackBarBehavior.floating,
|
|
backgroundColor: theme.colorScheme.error,
|
|
),
|
|
);
|
|
} else {
|
|
try {
|
|
await service.getOtpTLimit(
|
|
mobileNumber: widget.mobileNumber);
|
|
Navigator.of(context).push(
|
|
MaterialPageRoute(
|
|
builder: (context) => ChangeLimitOTPScreen(
|
|
newLimit: value.toString(),
|
|
mobileNumber: widget.mobileNumber,
|
|
),
|
|
),
|
|
);
|
|
} catch (e) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content: Text("Error: $e"),
|
|
behavior: SnackBarBehavior.floating,
|
|
backgroundColor: theme.colorScheme.error,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
},
|
|
child: Text(localizations.save),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
|
|
if (newLimit != null) {
|
|
_loadlimits();
|
|
if (!mounted) return;
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(
|
|
content: Text("Limit Updated"),
|
|
behavior: SnackBarBehavior.floating,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
if (_isLoading) {
|
|
final localizations = AppLocalizations.of(context);
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: Text(localizations.dailylimit),
|
|
),
|
|
body: const Center(
|
|
child: CircularProgressIndicator(),
|
|
),
|
|
);
|
|
}
|
|
_currentLimit = limit?.dailyLimit;
|
|
_spentAmount = limit?.usedLimit;
|
|
final localizations = AppLocalizations.of(context);
|
|
final theme = Theme.of(context);
|
|
final formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
|
|
final remainingLimit =
|
|
_currentLimit != null ? _currentLimit! - _spentAmount! : 0.0;
|
|
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: Text(localizations.dailylimit),
|
|
),
|
|
body: Center(
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
Text(
|
|
localizations.currentDailyLimit,
|
|
style: theme.textTheme.headlineSmall?.copyWith(
|
|
color: theme.colorScheme.onSurface.withOpacity(0.7),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
Text(
|
|
_currentLimit == null
|
|
? localizations.noLimitSet
|
|
: formatCurrency.format(_currentLimit),
|
|
style: theme.textTheme.headlineMedium?.copyWith(
|
|
fontWeight: FontWeight.bold,
|
|
color: _currentLimit == null
|
|
? theme.colorScheme.secondary
|
|
: theme.colorScheme.primary,
|
|
),
|
|
),
|
|
if (_currentLimit != null) ...[
|
|
const SizedBox(height: 24),
|
|
Text(
|
|
"Remaining Limit Today", // This should be localized
|
|
style: theme.textTheme.titleMedium,
|
|
),
|
|
const SizedBox(height: 4),
|
|
Text(
|
|
formatCurrency.format(remainingLimit),
|
|
style: theme.textTheme.headlineSmall?.copyWith(
|
|
fontWeight: FontWeight.bold,
|
|
color: remainingLimit > 0
|
|
? Colors.green
|
|
: theme.colorScheme.error,
|
|
),
|
|
),
|
|
],
|
|
const SizedBox(height: 48),
|
|
if (_currentLimit == null)
|
|
ElevatedButton.icon(
|
|
onPressed: _showAddOrEditLimitDialog,
|
|
icon: const Icon(Icons.add_circle_outline),
|
|
label: Text(localizations.addLimit),
|
|
style: ElevatedButton.styleFrom(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: 24, vertical: 12),
|
|
textStyle: theme.textTheme.titleMedium,
|
|
),
|
|
)
|
|
else
|
|
Column(
|
|
children: [
|
|
ElevatedButton.icon(
|
|
onPressed: _showAddOrEditLimitDialog,
|
|
icon: const Icon(Icons.edit_outlined),
|
|
label: Text(localizations.editLimit),
|
|
style: ElevatedButton.styleFrom(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: 24, vertical: 12),
|
|
textStyle: theme.textTheme.titleMedium,
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|