227 lines
8.2 KiB
Dart
Executable File
227 lines
8.2 KiB
Dart
Executable File
// lib/screens/savings_calculator_screen.dart
|
|
import 'package:flutter/material.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart'; // Importar shared_preferences
|
|
|
|
class SavingsCalculatorScreen extends StatefulWidget {
|
|
const SavingsCalculatorScreen({super.key});
|
|
|
|
@override
|
|
State<SavingsCalculatorScreen> createState() => _SavingsCalculatorScreenState();
|
|
}
|
|
|
|
class _SavingsCalculatorScreenState extends State<SavingsCalculatorScreen> {
|
|
final TextEditingController _initialDepositController = TextEditingController();
|
|
final TextEditingController _interestRateController = TextEditingController();
|
|
int _savingPeriodMonths = 6;
|
|
DateTime _startDate = DateTime.now();
|
|
double _calculatedFinalAmount = 0.0;
|
|
double _calculatedInterest = 0.0;
|
|
String _currentCurrency = 'KZ'; // Adicionar a variável para a moeda
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_loadCurrency(); // Chamar a função para carregar a moeda no initState
|
|
}
|
|
|
|
// Função para carregar a moeda das Shared Preferences
|
|
Future<void> _loadCurrency() async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
setState(() {
|
|
_currentCurrency = prefs.getString('currencySymbol') ?? 'KZ'; // Pega o símbolo salvo
|
|
});
|
|
}
|
|
|
|
Future<void> _selectDate(BuildContext context) async {
|
|
final DateTime? picked = await showDatePicker(
|
|
context: context,
|
|
initialDate: _startDate,
|
|
firstDate: DateTime(2000),
|
|
lastDate: DateTime(2101),
|
|
locale: const Locale('pt', 'BR'),
|
|
);
|
|
if (picked != null && picked != _startDate) {
|
|
setState(() {
|
|
_startDate = picked;
|
|
});
|
|
}
|
|
}
|
|
|
|
void _calculateSavings() {
|
|
final double initialDeposit = double.tryParse(_initialDepositController.text) ?? 0.0;
|
|
final double annualInterestRate = double.tryParse(_interestRateController.text) ?? 0.0;
|
|
|
|
if (initialDeposit <= 0 || annualInterestRate <= 0) {
|
|
setState(() {
|
|
_calculatedFinalAmount = 0.0;
|
|
_calculatedInterest = 0.0;
|
|
});
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(content: Text('Por favor, insira valores válidos para depósito e taxa de juros.')),
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Convertendo a taxa anual para mensal e para decimal
|
|
final double monthlyInterestRate = (annualInterestRate / 100) / 12;
|
|
// Calculando juros compostos mensais
|
|
double finalAmount = initialDeposit * (1 + monthlyInterestRate);
|
|
for (int i = 1; i < _savingPeriodMonths; i++) {
|
|
finalAmount = finalAmount * (1 + monthlyInterestRate);
|
|
}
|
|
|
|
double totalInterest = finalAmount - initialDeposit;
|
|
|
|
setState(() {
|
|
_calculatedFinalAmount = finalAmount;
|
|
_calculatedInterest = totalInterest;
|
|
});
|
|
}
|
|
|
|
void _resetFields() {
|
|
setState(() {
|
|
_initialDepositController.clear();
|
|
_interestRateController.clear();
|
|
_savingPeriodMonths = 6;
|
|
_startDate = DateTime.now();
|
|
_calculatedFinalAmount = 0.0;
|
|
_calculatedInterest = 0.0;
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: const Text('Calculadora de Economia'),
|
|
actions: [
|
|
IconButton(
|
|
icon: const Icon(Icons.history),
|
|
onPressed: () {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(content: Text('Histórico de cálculos (a ser implementado)')),
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
body: SingleChildScrollView(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
TextFormField(
|
|
controller: _initialDepositController,
|
|
keyboardType: TextInputType.number,
|
|
decoration: InputDecoration( // Use InputDecoration para o suffixText dinâmico
|
|
labelText: 'Depósito inicial',
|
|
border: const OutlineInputBorder(),
|
|
suffixText: _currentCurrency, // Usar a moeda carregada
|
|
),
|
|
),
|
|
const SizedBox(height: 20),
|
|
TextFormField(
|
|
controller: _interestRateController,
|
|
keyboardType: TextInputType.number,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Taxa de juros',
|
|
border: OutlineInputBorder(),
|
|
suffixText: '%/ano',
|
|
),
|
|
),
|
|
const SizedBox(height: 20),
|
|
Row(
|
|
children: [
|
|
const Text('Período de poupança:', style: TextStyle(fontSize: 16)),
|
|
const SizedBox(width: 10),
|
|
DropdownButton<int>(
|
|
value: _savingPeriodMonths,
|
|
onChanged: (int? newValue) {
|
|
setState(() {
|
|
_savingPeriodMonths = newValue!;
|
|
});
|
|
},
|
|
items: <int>[3, 6, 12, 24, 36, 60] // Exemplo de períodos
|
|
.map<DropdownMenuItem<int>>((int value) {
|
|
return DropdownMenuItem<int>(
|
|
value: value,
|
|
child: Text('$value Meses'),
|
|
);
|
|
}).toList(),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 20),
|
|
Row(
|
|
children: [
|
|
Text(
|
|
'Data de Início',
|
|
style: TextStyle(fontSize: 16, color: Colors.grey[700]),
|
|
),
|
|
const SizedBox(width: 10),
|
|
Expanded(
|
|
child: GestureDetector(
|
|
onTap: () => _selectDate(context),
|
|
child: AbsorbPointer(
|
|
child: TextFormField(
|
|
decoration: InputDecoration(
|
|
hintText: DateFormat('dd \'de\' MMM \'de\' yyyy', 'pt_BR').format(_startDate),
|
|
suffixIcon: const Icon(Icons.calendar_today),
|
|
border: const OutlineInputBorder(),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 30),
|
|
SizedBox(
|
|
width: double.infinity,
|
|
child: ElevatedButton(
|
|
onPressed: _calculateSavings,
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: Colors.blue,
|
|
foregroundColor: Colors.white,
|
|
padding: const EdgeInsets.symmetric(vertical: 15),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(8.0),
|
|
),
|
|
),
|
|
child: const Text('Calcular', style: TextStyle(fontSize: 18)),
|
|
),
|
|
),
|
|
const SizedBox(height: 10),
|
|
SizedBox(
|
|
width: double.infinity,
|
|
child: TextButton(
|
|
onPressed: _resetFields,
|
|
child: const Text('Redefinir campos', style: TextStyle(color: Colors.blue)),
|
|
),
|
|
),
|
|
const SizedBox(height: 30),
|
|
if (_calculatedFinalAmount > 0)
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text('Resultado:', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
|
|
const SizedBox(height: 10),
|
|
Text(
|
|
// Usar _currentCurrency aqui para exibir o símbolo correto
|
|
'Valor Final: $_currentCurrency ${NumberFormat.currency(locale: 'pt_BR', symbol: '').format(_calculatedFinalAmount)}',
|
|
style: const TextStyle(fontSize: 18),
|
|
),
|
|
Text(
|
|
// Usar _currentCurrency aqui para exibir o símbolo correto
|
|
'Juros Ganhos: $_currentCurrency ${NumberFormat.currency(locale: 'pt_BR', symbol: '').format(_calculatedInterest)}',
|
|
style: const TextStyle(fontSize: 18, color: Colors.green),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
} |