From fc495eca09435b35654741e8934c2a8b6c2447d5 Mon Sep 17 00:00:00 2001 From: asif Date: Thu, 19 Mar 2026 13:23:34 +0530 Subject: [PATCH] APY integrated and Account UI done --- .../screens/account_opening_screen.dart | 284 ++++++------ .../screens/create_deposit_screen.dart | 429 ++++++++++++++++++ .../account_opening/screens/fd_screen.dart | 242 ---------- .../screens/interest_rates_screen.dart | 17 - .../account_opening/screens/loan_screen.dart | 19 - .../account_opening/screens/rd_screen.dart | 19 - .../account_opening/screens/td_screen.dart | 19 - .../dashboard/screens/dashboard_screen.dart | 13 +- .../service/screens/service_screen.dart | 43 +- .../yojna/screens/apy_register_screen.dart | 24 +- 10 files changed, 617 insertions(+), 492 deletions(-) create mode 100644 lib/features/account_opening/screens/create_deposit_screen.dart delete mode 100644 lib/features/account_opening/screens/fd_screen.dart delete mode 100644 lib/features/account_opening/screens/interest_rates_screen.dart delete mode 100644 lib/features/account_opening/screens/loan_screen.dart delete mode 100644 lib/features/account_opening/screens/rd_screen.dart delete mode 100644 lib/features/account_opening/screens/td_screen.dart diff --git a/lib/features/account_opening/screens/account_opening_screen.dart b/lib/features/account_opening/screens/account_opening_screen.dart index 45a746f..b25b1c0 100644 --- a/lib/features/account_opening/screens/account_opening_screen.dart +++ b/lib/features/account_opening/screens/account_opening_screen.dart @@ -1,14 +1,15 @@ -import 'package:flutter/material.dart'; // Keep if User model is generic -import 'package:kmobile/features/account_opening/screens/fd_screen.dart'; -import 'package:kmobile/features/account_opening/screens/loan_screen.dart'; -import 'package:kmobile/features/account_opening/screens/rd_screen.dart'; -import 'package:kmobile/features/account_opening/screens/td_screen.dart'; -import 'package:material_symbols_icons/material_symbols_icons.dart'; -import '../../../l10n/app_localizations.dart'; +import 'package:flutter/material.dart'; +import 'package:kmobile/data/models/user.dart'; +import 'package:kmobile/l10n/app_localizations.dart'; +import 'package:kmobile/features/account_opening/screens/create_deposit_screen.dart'; class AccountOpeningScreen extends StatefulWidget { + final List users; + final int selectedIndex; const AccountOpeningScreen({ super.key, + required this.users, + required this.selectedIndex, }); @override @@ -16,153 +17,154 @@ class AccountOpeningScreen extends StatefulWidget { } class _AccountOpeningScreenState extends State { + User? _selectedAccount; + List _filteredUsers = []; + final _formKey = GlobalKey(); + bool _isLoading = false; + + @override + void initState() { + super.initState(); + _filteredUsers = widget.users + .where((user) => ['SA', 'SB', 'CA', 'CC'].contains(user.accountType)) + .toList(); + + // Pre-fill the account number if possible + if (widget.users.isNotEmpty && widget.selectedIndex < widget.users.length) { + if (_filteredUsers.isNotEmpty) { + if (_filteredUsers.contains(widget.users[widget.selectedIndex])) { + _selectedAccount = widget.users[widget.selectedIndex]; + } else { + _selectedAccount = _filteredUsers.first; + } + } else { + _selectedAccount = widget.users[widget.selectedIndex]; + } + } else { + if (_filteredUsers.isNotEmpty) { + _selectedAccount = _filteredUsers.first; + } + } + } + @override Widget build(BuildContext context) { + final l10n = AppLocalizations.of(context); return Scaffold( appBar: AppBar( - title: const Text( - "Account Opening", - ), + title: Text(l10n.accountOpeningDeposit), centerTitle: false, ), - body: Stack( - children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Expanded( - child: AccountOpeningCardTile( - icon: Symbols.savings, - label: "Fixed Deposit (FD)", - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const FdScreen(), + body: SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Card( + elevation: 2, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + "Select your source account to proceed with opening a new FD, TD, or RD account. Your KYC details will be verified.", + style: Theme.of(context).textTheme.titleMedium, + ), + ), + ), + const SizedBox(height: 16), + Card( + elevation: 2, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DropdownButtonFormField( + value: _selectedAccount, + decoration: InputDecoration( + labelText: l10n.accountNumber, + border: const OutlineInputBorder(), + contentPadding: const EdgeInsets.symmetric( + vertical: 20, horizontal: 12), ), - ); - }, - ), - ), - Expanded( - child: AccountOpeningCardTile( - icon: Symbols.currency_rupee, - label: "Term Deposit", - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const TermDepositScreen()), - ); - }, - ), - ), - Expanded( - child: AccountOpeningCardTile( - icon: Symbols.account_balance, - label: AppLocalizations.of(context).recurringDeposit, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - const RecurringDepositScreen()), - ); - }, - ), - ), - Expanded( - child: AccountOpeningCardTile( - icon: Symbols.credit_card, - label: "Request Loan", - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const LoanScreen()), - ); - }, - ), - ), - ], - ), - ), - IgnorePointer( - child: Center( - child: Opacity( - opacity: 0.07, - child: ClipOval( - child: Image.asset( - 'assets/images/logo.png', - width: 200, - height: 200, + items: _filteredUsers.map((user) { + return DropdownMenuItem( + value: user, + child: Text(user.accountNo.toString()), + ); + }).toList(), + onChanged: (User? newUser) { + setState(() { + _selectedAccount = newUser; + }); + }, + validator: (value) { + if (value == null) { + return l10n.accountNumberRequired; + } + return null; + }, + ), + ], ), ), ), - ), - ), - ], - ), - ); - } -} + const SizedBox(height: 24), + ElevatedButton( + onPressed: _isLoading + ? null + : () async { + if (_formKey.currentState!.validate() && + _selectedAccount != null) { + // Simulating API response + final mockResponse = { + "addressline1": "DATA CENTRE KCCB CIVIL BAZAR D/SHALA DHA", + "addressline2": "RAMSHALA KANGRA", + "cifNo": "30022497139", + "customername": "Mr. RAJAT KUMAR MAHARANA", + "idno": "536652226333 61", + "nationality": "IN", + "pincode": "176047" + }; -class AccountOpeningCardTile extends StatelessWidget { - final IconData icon; - final String label; - final VoidCallback onTap; - final bool disable; - - const AccountOpeningCardTile({ - super.key, - required this.icon, - required this.label, - required this.onTap, - this.disable = false, - }); - - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - return Card( - margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12.0), - ), - elevation: 4, - child: InkWell( - onTap: disable ? null : onTap, - borderRadius: BorderRadius.circular(12.0), - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 24.0, horizontal: 16.0), - child: Center( - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - icon, - size: 48, - color: disable - ? theme.disabledColor - : theme.colorScheme.primary, + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => CreateDepositScreen( + selectedAccount: _selectedAccount!, + initialData: mockResponse, + ), + ), + ); + } + }, + style: ElevatedButton.styleFrom( + backgroundColor: + Theme.of(context).colorScheme.primaryContainer, + foregroundColor: + Theme.of(context).colorScheme.onPrimaryContainer, + minimumSize: const Size(double.infinity, 50), + elevation: 4, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), ), - const SizedBox(height: 12), - Text( - label, - textAlign: TextAlign.center, - style: theme.textTheme.titleLarge?.copyWith( - fontWeight: FontWeight.bold, - color: disable - ? theme.disabledColor - : theme.colorScheme.onSurface, - ), - ), - ], + ), + child: _isLoading + ? const SizedBox( + height: 20, + width: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + ), + ) + : Text( + l10n.proceedButton, + style: const TextStyle( + fontSize: 16, fontWeight: FontWeight.bold), + ), ), - ), + ], ), ), ), diff --git a/lib/features/account_opening/screens/create_deposit_screen.dart b/lib/features/account_opening/screens/create_deposit_screen.dart new file mode 100644 index 0000000..3a55ad2 --- /dev/null +++ b/lib/features/account_opening/screens/create_deposit_screen.dart @@ -0,0 +1,429 @@ +import 'package:flutter/material.dart'; +import 'package:kmobile/data/models/user.dart'; +import 'package:kmobile/l10n/app_localizations.dart'; + +class CreateDepositScreen extends StatefulWidget { + final User selectedAccount; + final Map? initialData; + const CreateDepositScreen({ + super.key, + required this.selectedAccount, + this.initialData, + }); + + @override + State createState() => _CreateDepositScreenState(); +} + +class _CreateDepositScreenState extends State { + final _formKey = GlobalKey(); + + // Controllers + late final _fromAcctNoController = + TextEditingController(text: widget.selectedAccount.accountNo.toString()); + late final _cifNoController = TextEditingController( + text: widget.initialData?['cifNo']?.toString()); + late final _idNoController = TextEditingController( + text: widget.initialData?['idno']?.toString()); + late final _customerNameController = TextEditingController( + text: widget.initialData?['customername']?.toString()); + late final _nationalityController = TextEditingController( + text: widget.initialData?['nationality']?.toString()); + late final _addressLine1Controller = TextEditingController( + text: widget.initialData?['addressline1']?.toString()); + late final _addressLine2Controller = TextEditingController( + text: widget.initialData?['addressline2']?.toString()); + late final _pincodeController = TextEditingController( + text: widget.initialData?['pincode']?.toString()); + + late final _productController = TextEditingController(); + late final _typeController = TextEditingController(); + late final _customerCategoryController = TextEditingController(); + late final _termLocationController = TextEditingController(); + late final _currencyController = TextEditingController(); + late final _acctSgmtCodeController = TextEditingController(); + late final _interestPaymentMethodController = TextEditingController(); + late final _taxFileNumberIndicatorController = TextEditingController(); + late final _termLengthController = TextEditingController(); + late final _termBasisController = TextEditingController(); + late final _termValueDepositedController = TextEditingController(); + late final _interestFrequencyController = TextEditingController(); + late final _termDaysController = TextEditingController(); + late final _termMonthsController = TextEditingController(); + late final _termYearsController = TextEditingController(); + late final _nominationRequiredController = TextEditingController(); + late final _printNomineeNameController = TextEditingController(); + + // RD specific controllers + late final _rdInstallmentValueController = TextEditingController(); + late final _monthlyRDInstallmentDueDayController = TextEditingController(); + late final _rdInstlFreqController = TextEditingController(); + + final Map _productOptions = { + '20': 'Term Deposit', + '25': 'Fixed Deposit', + '28': 'Recurring Deposit', + }; + + final Map _typeOptions = { + '01': 'Member', + '02': 'Non-Member', + '03': 'Staff', + '04': 'Govt', + '05': 'School', + '06': 'Panchayat', + '07': 'Trusts', + '08': 'Municipal Council', + '09': 'NRO', + '10': 'Bank', + '11': 'No Frill', + '12': 'Special Schemes', + '13': 'Minor', + }; + + final Map _customerCategoryOptions = { + '1': 'Public Individual', + '2': 'Societies', + '3': 'Senior Citizen', + '5': 'Government', + '6': 'Local Bodies', + '7': 'Other', + }; + + final Map _termLocationOptions = { + '10': 'SB/CA', + '13': '46–90 Days', + '14': '91–180 Days', + '15': '180 Days–1 Year', + '16': '1 Year–<18 Months', + '20': '18 Months–<2 Years', + '17': '2–3 Years', + '18': '3–10 Years', + '22': 'Above 10 Years', + '24': 'Dev Kanya Yojna 9+1', + '25': 'Hazar Dain Lakh Ley Jayain', + }; + + final Map _currencyOptions = { + '1': 'INR', + }; + + final Map _acctSgmtCodeOptions = { + '0706': 'Public Individual', + '5002': 'Societies', + '5005': 'Government', + '5050': 'GL Others', + }; + + final Map _interestPaymentMethodOptions = { + 'R': 'Re-invest', + }; + + final Map _termBasisOptions = { + 'D': 'Days', + 'M': 'Months', + }; + + final Map _interestFrequencyOptions = { + 'M': 'On Maturity / Roll Over', + '1M': 'Monthly', + '3M': 'Quarterly', + '1A': 'Anniversary Monthly', + '3A': 'Anniversary Quarterly', + }; + + final Map _rdInstlFreqOptions = { + 'M': 'Monthly', + }; + + @override + void dispose() { + _fromAcctNoController.dispose(); + _cifNoController.dispose(); + _idNoController.dispose(); + _customerNameController.dispose(); + _nationalityController.dispose(); + _addressLine1Controller.dispose(); + _addressLine2Controller.dispose(); + _pincodeController.dispose(); + _productController.dispose(); + _typeController.dispose(); + _customerCategoryController.dispose(); + _termLocationController.dispose(); + _currencyController.dispose(); + _acctSgmtCodeController.dispose(); + _interestPaymentMethodController.dispose(); + _taxFileNumberIndicatorController.dispose(); + _termLengthController.dispose(); + _termBasisController.dispose(); + _termValueDepositedController.dispose(); + _interestFrequencyController.dispose(); + _termDaysController.dispose(); + _termMonthsController.dispose(); + _termYearsController.dispose(); + _nominationRequiredController.dispose(); + _printNomineeNameController.dispose(); + _rdInstallmentValueController.dispose(); + _monthlyRDInstallmentDueDayController.dispose(); + _rdInstlFreqController.dispose(); + super.dispose(); + } + + void _handleCreate() { + if (_formKey.currentState!.validate()) { + // Implementation logic goes here + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text("Processing Deposit Creation...")), + ); + } + } + + @override + Widget build(BuildContext context) { + final l10n = AppLocalizations.of(context); + return Scaffold( + appBar: AppBar( + title: const Text("Create Deposit"), + ), + body: SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // Tile 1: Customer Info + Card( + elevation: 2, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text("Customer Information", + style: TextStyle( + fontSize: 18, fontWeight: FontWeight.bold)), + const SizedBox(height: 16), + _buildTextField(_fromAcctNoController, "From Account No", + mandatory: true, readOnly: true), + _buildTextField(_cifNoController, "CIF No"), + _buildTextField(_idNoController, "ID No"), + _buildTextField(_customerNameController, "Customer Name"), + _buildTextField(_nationalityController, "Nationality"), + _buildTextField(_addressLine1Controller, "Address Line 1"), + _buildTextField(_addressLine2Controller, "Address Line 2"), + _buildTextField(_pincodeController, "Pincode", + keyboardType: TextInputType.number), + ], + ), + ), + ), + const SizedBox(height: 16), + // Tile 2: Deposit Details + Card( + elevation: 2, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text("Deposit Details", + style: TextStyle( + fontSize: 18, fontWeight: FontWeight.bold)), + const SizedBox(height: 16), + _buildDropdownField( + _productController, "Product", _productOptions, + mandatory: true, onChanged: (val) { + setState(() { + _productController.text = val ?? ''; + }); + }), + _buildDropdownField(_typeController, "Type", _typeOptions, + mandatory: true), + _buildDropdownField(_customerCategoryController, + "Customer Category", _customerCategoryOptions, + mandatory: true), + _buildDropdownField(_termLocationController, + "Term Location", _termLocationOptions, + mandatory: true), + _buildDropdownField( + _currencyController, "Currency", _currencyOptions, + mandatory: true), + _buildDropdownField(_acctSgmtCodeController, + "Account Segment Code", _acctSgmtCodeOptions, + mandatory: true), + ], + ), + ), + ), + const SizedBox(height: 16), + // Tile 3: Interest & Term Settings + Card( + elevation: 2, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text("Interest & Term Settings", + style: TextStyle( + fontSize: 18, fontWeight: FontWeight.bold)), + const SizedBox(height: 16), + _buildDropdownField(_interestPaymentMethodController, + "Interest Payment Method", _interestPaymentMethodOptions, + mandatory: true), + _buildTextField(_taxFileNumberIndicatorController, + "Tax File Number Indicator"), + _buildTextField(_termLengthController, "Term Length"), + _buildDropdownField( + _termBasisController, "Term Basis", _termBasisOptions, + mandatory: true), + _buildTextField(_termValueDepositedController, + "Term Value Deposited", + keyboardType: TextInputType.number, mandatory: true), + _buildDropdownField(_interestFrequencyController, + "Interest Frequency", _interestFrequencyOptions), + _buildTextField(_termDaysController, "Term Days", + keyboardType: TextInputType.number), + _buildTextField(_termMonthsController, "Term Months", + keyboardType: TextInputType.number), + _buildTextField(_termYearsController, "Term Years", + keyboardType: TextInputType.number, mandatory: true), + _buildTextField( + _nominationRequiredController, "Nomination Required"), + _buildTextField( + _printNomineeNameController, "Print Nominee Name"), + ], + ), + ), + ), + const SizedBox(height: 16), + + // Tile 4: RD Specific Fields (Conditional) + if (_productController.text == '28') + Card( + elevation: 2, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text("Recurring Deposit Settings", + style: TextStyle( + fontSize: 18, fontWeight: FontWeight.bold)), + const SizedBox(height: 16), + _buildTextField(_rdInstallmentValueController, + "RD Installment Value", + keyboardType: TextInputType.number), + _buildTextField(_monthlyRDInstallmentDueDayController, + "Monthly RD Installment Due Day", + keyboardType: TextInputType.number), + _buildDropdownField(_rdInstlFreqController, + "RD Installment Frequency", _rdInstlFreqOptions), + ], + ), + ), + ), + + const SizedBox(height: 24), + ElevatedButton( + onPressed: _handleCreate, + style: ElevatedButton.styleFrom( + backgroundColor: + Theme.of(context).colorScheme.primaryContainer, + foregroundColor: + Theme.of(context).colorScheme.onPrimaryContainer, + padding: const EdgeInsets.symmetric(vertical: 16), + elevation: 4, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + child: const Text( + "Proceed", + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + ), + ), + const SizedBox(height: 32), + ], + ), + ), + ), + ); + } + + Widget _buildDropdownField(TextEditingController controller, String label, + Map options, + {bool readOnly = false, + bool mandatory = false, + void Function(String?)? onChanged}) { + String? currentValue = + options.containsKey(controller.text) ? controller.text : null; + + return Padding( + padding: const EdgeInsets.only(bottom: 16.0), + child: DropdownButtonFormField( + value: currentValue, + onChanged: readOnly + ? null + : (newValue) { + if (newValue != null) { + setState(() { + controller.text = newValue; + }); + } + if (onChanged != null) { + onChanged(newValue); + } + }, + decoration: InputDecoration( + labelText: mandatory ? '$label *' : label, + border: const OutlineInputBorder(), + contentPadding: + const EdgeInsets.symmetric(vertical: 16, horizontal: 12), + ), + validator: (value) { + if (mandatory && (value == null || value.isEmpty)) { + return 'This field is required'; + } + return null; + }, + items: options.entries.map((entry) { + return DropdownMenuItem( + value: entry.key, + child: Text(entry.value), + ); + }).toList(), + ), + ); + } + + Widget _buildTextField(TextEditingController controller, String label, + {TextInputType keyboardType = TextInputType.text, + bool readOnly = false, + bool mandatory = false, + VoidCallback? onTap}) { + return Padding( + padding: const EdgeInsets.only(bottom: 16.0), + child: TextFormField( + controller: controller, + readOnly: readOnly || onTap != null, + onTap: onTap, + decoration: InputDecoration( + labelText: mandatory ? '$label *' : label, + border: const OutlineInputBorder(), + suffixIcon: onTap != null ? const Icon(Icons.calendar_today) : null, + contentPadding: + const EdgeInsets.symmetric(vertical: 16, horizontal: 12), + ), + keyboardType: keyboardType, + validator: (value) { + if (mandatory && (value == null || value.isEmpty)) { + return 'This field is required'; + } + return null; + }, + ), + ); + } +} diff --git a/lib/features/account_opening/screens/fd_screen.dart b/lib/features/account_opening/screens/fd_screen.dart deleted file mode 100644 index 96aa5a4..0000000 --- a/lib/features/account_opening/screens/fd_screen.dart +++ /dev/null @@ -1,242 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:kmobile/features/account_opening/screens/interest_rates_screen.dart'; - -class FdScreen extends StatefulWidget { - const FdScreen({super.key}); - - @override - State createState() => _FdScreenState(); -} - -class _FdScreenState extends State { - final TextEditingController _debitAccountController = TextEditingController(); - final TextEditingController _amountController = TextEditingController(); - final TextEditingController _yearsController = TextEditingController(); - final TextEditingController _monthsController = TextEditingController(); - final TextEditingController _daysController = TextEditingController(); - - String _rateOfInterest = "N/A"; - String _maturityDate = "N/A"; - String _maturityAmount = "N/A"; - - @override - void dispose() { - _debitAccountController.dispose(); - _amountController.dispose(); - _yearsController.dispose(); - _monthsController.dispose(); - _daysController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Fixed Deposit (FD)'), - ), - body: SingleChildScrollView( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Explanation Tile - Card( - margin: const EdgeInsets.only(bottom: 20), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Earn more on your savings with a simple, secure Fixed Deposit.', - style: Theme.of(context).textTheme.bodyMedium, - ), - ], - ), - ), - ), - - // Debit Account Number - TextFormField( - controller: _debitAccountController, - decoration: const InputDecoration( - labelText: 'Debit Account Number', - border: OutlineInputBorder(), - ), - keyboardType: TextInputType.number, - ), - const SizedBox(height: 20), - - // Enter Amount - TextFormField( - controller: _amountController, - decoration: const InputDecoration( - labelText: 'Enter Amount', - border: OutlineInputBorder(), - prefixText: '₹ '), - keyboardType: TextInputType.number, - ), - const SizedBox(height: 20), - - // Duration and Interest Rates Link - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - 'Duration', - style: Theme.of(context).textTheme.titleLarge, - ), - GestureDetector( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const InterestRatesScreen()), - ); - }, - child: Text('Interest Rates', - style: Theme.of(context).textTheme.titleSmall), - ), - ], - ), - const SizedBox(height: 10), - - // Duration TextBoxes - Row( - children: [ - Expanded( - child: TextFormField( - controller: _yearsController, - decoration: const InputDecoration( - labelText: 'Years', - border: OutlineInputBorder(), - ), - keyboardType: TextInputType.number, - ), - ), - const SizedBox(width: 10), - Expanded( - child: TextFormField( - controller: _monthsController, - decoration: const InputDecoration( - labelText: 'Months', - border: OutlineInputBorder(), - ), - keyboardType: TextInputType.number, - ), - ), - const SizedBox(width: 10), - Expanded( - child: TextFormField( - controller: _daysController, - decoration: const InputDecoration( - labelText: 'Days', - border: OutlineInputBorder(), - ), - keyboardType: TextInputType.number, - ), - ), - ], - ), - const SizedBox(height: 20), - - // Rate of Interest and Maturity Date Display - Row( - children: [ - Expanded( - child: Card( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Rate of Interest', - style: Theme.of(context).textTheme.bodySmall, - ), - const SizedBox(height: 5), - Text( - _rateOfInterest, - style: Theme.of(context).textTheme.headlineSmall, - ), - ], - ), - ), - ), - ), - const SizedBox(width: 10), - Expanded( - child: Card( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Maturity Date', - style: Theme.of(context).textTheme.bodySmall, - ), - const SizedBox(height: 5), - Text( - _maturityDate, - style: Theme.of(context).textTheme.headlineSmall, - ), - ], - ), - ), - ), - ), - ], - ), - const SizedBox(height: 10), - // Maturity Amount Display - Row( - children: [ - Expanded( - child: Card( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Maturity Amount', - style: Theme.of(context).textTheme.bodySmall, - ), - const SizedBox(height: 5), - Text( - _maturityAmount, - style: Theme.of(context).textTheme.headlineSmall, - ), - ], - ), - ), - ), - ), - ], - ), - const SizedBox(height: 30), - - // Proceed Button - Center( - child: ElevatedButton( - onPressed: () { - // TODO: Implement proceed logic - }, - style: ElevatedButton.styleFrom( - padding: - const EdgeInsets.symmetric(horizontal: 40, vertical: 15), - ), - child: const Text( - 'Proceed', - style: TextStyle(fontSize: 18), - ), - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/features/account_opening/screens/interest_rates_screen.dart b/lib/features/account_opening/screens/interest_rates_screen.dart deleted file mode 100644 index 069d288..0000000 --- a/lib/features/account_opening/screens/interest_rates_screen.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:flutter/material.dart'; - -class InterestRatesScreen extends StatelessWidget { - const InterestRatesScreen({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Interest Rates'), - ), - body: const Center( - child: Text('This page will display a table of interest rates.'), - ), - ); - } -} diff --git a/lib/features/account_opening/screens/loan_screen.dart b/lib/features/account_opening/screens/loan_screen.dart deleted file mode 100644 index 41eb1e6..0000000 --- a/lib/features/account_opening/screens/loan_screen.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/material.dart'; - -class LoanScreen extends StatelessWidget { - const LoanScreen({ - super.key, - }); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text("Request Loan"), - ), - body: const Center( - child: Text("Loan Account"), - ), - ); - } -} diff --git a/lib/features/account_opening/screens/rd_screen.dart b/lib/features/account_opening/screens/rd_screen.dart deleted file mode 100644 index 022de28..0000000 --- a/lib/features/account_opening/screens/rd_screen.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/material.dart'; - -class RecurringDepositScreen extends StatelessWidget { - const RecurringDepositScreen({ - super.key, - }); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text("Recurring Deposit"), - ), - body: const Center( - child: Text("Recurring Deposit"), - ), - ); - } -} diff --git a/lib/features/account_opening/screens/td_screen.dart b/lib/features/account_opening/screens/td_screen.dart deleted file mode 100644 index cd2f509..0000000 --- a/lib/features/account_opening/screens/td_screen.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/material.dart'; - -class TermDepositScreen extends StatelessWidget { - const TermDepositScreen({ - super.key, - }); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text("Term Deposit (TD)"), - ), - body: const Center( - child: Text("Term Deposit (TD)"), - ), - ); - } -} diff --git a/lib/features/dashboard/screens/dashboard_screen.dart b/lib/features/dashboard/screens/dashboard_screen.dart index 99b0d64..cb92900 100644 --- a/lib/features/dashboard/screens/dashboard_screen.dart +++ b/lib/features/dashboard/screens/dashboard_screen.dart @@ -14,7 +14,7 @@ import 'package:kmobile/features/beneficiaries/screens/manage_beneficiaries_scre import 'package:kmobile/features/fund_transfer/screens/fund_transfer_screen.dart'; import 'package:kmobile/features/profile/profile_screen.dart'; import 'package:kmobile/features/quick_pay/screens/quick_pay_screen.dart'; -import 'package:kmobile/features/service/screens/branch_locator_screen.dart'; +import 'package:kmobile/features/account_opening/screens/account_opening_screen.dart'; import 'package:kmobile/features/yojna/screens/gov_scheme_screen.dart'; import 'package:kmobile/security/secure_storage.dart'; import 'package:local_auth/local_auth.dart'; @@ -618,14 +618,15 @@ class _DashboardScreenState extends State selectedIndex: selectedAccountIndex, ))); }), - _buildQuickLink(Icons.location_pin, - AppLocalizations.of(context).branchlocator, () { + _buildQuickLink(Symbols.box, "Create FD/TD or RD", () { Navigator.push( context, MaterialPageRoute( - builder: (context) => - const BranchLocatorScreen())); - }, disable: false), + builder: (context) => AccountOpeningScreen( + users: users, + selectedIndex: selectedAccountIndex, + ))); + }, disable: isPaymentDisabled), _buildQuickLink(Icons.group, AppLocalizations.of(context).manageBeneficiary, () { diff --git a/lib/features/service/screens/service_screen.dart b/lib/features/service/screens/service_screen.dart index 72a5ffb..406c7bb 100644 --- a/lib/features/service/screens/service_screen.dart +++ b/lib/features/service/screens/service_screen.dart @@ -1,6 +1,6 @@ import 'package:kmobile/features/account_opening/screens/account_opening_screen.dart'; -import 'package:kmobile/features/card/screens/card_management_screen.dart'; import 'package:kmobile/features/service/screens/atm_locator_screen.dart'; +import 'package:kmobile/features/service/screens/branch_locator_screen.dart'; import 'package:kmobile/features/service/screens/enquiry_screen.dart'; import '../../../l10n/app_localizations.dart'; import 'package:flutter/material.dart'; @@ -72,32 +72,20 @@ class _ServiceScreen extends State { disabled: false, ), ), - // Expanded( - // child: ServiceManagementTile( - // icon: Symbols.box, - // label: "Account Opening", - // onTap: () { - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => const AccountOpeningScreen())); - // }, - // disabled: false, - // ), - // ), - // Expanded( - // child: ServiceManagementTile( - // icon: Symbols.credit_card, - // label: AppLocalizations.of(context).cardManagement, - // onTap: () { - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => const CardManagementScreen())); - // }, - // disabled: false, - // ), - // ), + + Expanded( + child: ServiceManagementTile( + icon: Icons.location_pin, + label: AppLocalizations.of(context).branchlocator, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const BranchLocatorScreen())); + }, + disabled: false, + ), + ), Expanded( child: ServiceManagementTile( icon: Symbols.support_agent, @@ -111,7 +99,6 @@ class _ServiceScreen extends State { disabled: false, ), ), - // No Spacer() needed here as Expanded children will fill space ], ), ), diff --git a/lib/features/yojna/screens/apy_register_screen.dart b/lib/features/yojna/screens/apy_register_screen.dart index 74d6369..1f938e1 100644 --- a/lib/features/yojna/screens/apy_register_screen.dart +++ b/lib/features/yojna/screens/apy_register_screen.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:kmobile/api/services/yojna_service.dart'; @@ -212,6 +211,29 @@ class _APYRegisterScreenState extends State { void _handleRegister() async { if (_formKey.currentState!.validate()) { + final age = int.tryParse(_ageOfJoiningController.text) ?? 0; + if (age < 18 || age > 40) { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => AlertDialog( + title: const Text('Age Restriction'), + content: const Text( + 'Age of joining must be between 18 and 40 years to register for APY.'), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); // Close dialog + Navigator.popUntil(context, (route) => route.isFirst); + }, + child: const Text('OK'), + ), + ], + ), + ); + return; + } + showDialog( context: context, barrierDismissible: false,