Untitled
unknown
plain_text
a year ago
40 kB
4
Indexable
import 'dart:io'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:iskylarpm/controllers/auth_services.dart'; import 'package:iskylarpm/models/clientModel.dart'; import 'package:iskylarpm/theme/apptheme.dart'; import 'package:datetime_picker_formfield/datetime_picker_formfield.dart'; import 'package:iskylarpm/theme/common_snackbar.dart'; import 'package:iskylarpm/utils/show_snackbar.dart'; import 'package:iskylarpm/views/client_pages/allClient.dart'; import 'package:provider/provider.dart'; import '../../models/userProviders.dart'; class AddProjectScreen extends StatefulWidget { const AddProjectScreen({super.key}); @override State<AddProjectScreen> createState() => _AddProjectScreenState(); } class _AddProjectScreenState extends State<AddProjectScreen> { List<TextEditingController> amount = []; List<TextEditingController> details = []; List<bool> showButton = []; File? uploadDoc1; File? uploadDoc2; File? uploadDoc3; File? uploadDoc4; Future<void> pickedFile(int i) async { var result = await FilePicker.platform.pickFiles( allowMultiple: false, ); if (result != null) { setState(() { if (i == 1) { uploadDoc1 = File(result.files[0].path!); } else if (i == 2) { uploadDoc2 = File(result.files[0].path!); } else if (i == 3) { uploadDoc3 = File(result.files[0].path!); } else if (i == 4) { uploadDoc4 = File(result.files[0].path!); } }); } else { showSnackBar(context, 'No File Selected'); } } final format = DateFormat("yyyy-MM-dd"); final _formKey = GlobalKey<FormState>(); final GlobalKey<ScaffoldState> sKey = GlobalKey<ScaffoldState>(); String selectedValue = ''; String selectedProject = 'Active'; String selectedBilling = 'Fixed Cost'; final List<String> items = [ "Active", "Completed", "Cancelled", "On hold", "Upcoming", "Pending", "Overdue", "Not started", "Priority", ]; // final List<String> status = []; final List<String> billing = ['Fixed Cost', 'Hourly', 'Monthly']; final TextEditingController _startDateController = TextEditingController(); final TextEditingController _nameController = TextEditingController(); final TextEditingController _descController = TextEditingController(); final TextEditingController _totalAmountController = TextEditingController(); final TextEditingController _detailsController = TextEditingController(); final TextEditingController _amountController = TextEditingController(); AuthService authService = AuthService(); Future<void> projectAdd({ required String projectDate, required String projectName, required String description, required String client, required String projectStatus, required String totalAmount, required String billingMethod, required String amount, required String details, required String userId, File? document1, File? document2, File? document3, File? document4, }) async { await authService.addproject( context: context, projectDate: projectDate, projectName: projectName, description: description, client: client, projectStatus: projectStatus, totalAmount: totalAmount, billingMethod: billingMethod, amount: amount, details: details, userId: userId, documents1: document1, documents2: document2, documents3: document3, documents4: document4, ); } bool isLoading = true; Map<String, List<ClientModel>>? allClients; Future<void> getAllClient() async { if (!isLoading) { setState(() { isLoading = true; }); } allClients = await authService.getClient(context: context); if (allClients == null) { showSnackBar(context, 'Something went wrong. Try again!'); } else { setState(() { isLoading = false; }); } } List<String> clients = []; final List<Widget> rows = []; @override void initState() { super.initState(); getAllClient(); } @override Widget build(BuildContext context) { var user = Provider.of<UserProvider>(context).user; // final List<String> clients = user.clients!.map((client) => client).toList(); var mediaQuery = MediaQuery.of(context); double height = mediaQuery.size.height; double width = mediaQuery.size.width; return Scaffold( backgroundColor: Colors.white, appBar: AppBar( scrolledUnderElevation: 0, backgroundColor: Colors.white, leading: BackButton(), title: Text( 'Add Project', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500), ), ), body: SafeArea( child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 5), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: height * 0.02, ), Text( 'Basic Information', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), ), Padding( padding: const EdgeInsets.only(top: 15), child: RichText( text: TextSpan(children: [ TextSpan( text: "Project start date", style: TextStyle( color: Colors.grey.shade500, fontSize: 15.0, ), ), WidgetSpan( alignment: PlaceholderAlignment.top, child: Icon( Icons.star, color: Colors.red, size: 8, )) ])), ), SizedBox( height: 5, ), Container( height: height * 0.05, width: width, decoration: BoxDecoration( border: Border.all(color: Colors.grey.shade400), borderRadius: BorderRadius.circular(5)), child: DateTimeField( controller: _startDateController, decoration: const InputDecoration( contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 10), suffixIcon: Icon( Icons.calendar_today, color: Colors.grey, ), hintStyle: TextStyle( color: Color(0xFFB7798B), fontWeight: FontWeight.w500, fontSize: 15, ), border: InputBorder.none), format: format, onShowPicker: (context, currentValue) { return showDatePicker( context: context, firstDate: DateTime(1900), initialDate: currentValue ?? DateTime.now(), lastDate: DateTime(2100)); }, ), ), SizedBox( height: 20, ), RichText( text: TextSpan(children: [ TextSpan( text: "Project name", style: TextStyle( color: Colors.grey.shade500, fontSize: 15.0, ), ), WidgetSpan( alignment: PlaceholderAlignment.top, child: Icon( Icons.star, color: Colors.red, size: 8, )) ])), SizedBox( height: 5, ), SizedBox( height: height * 0.05, child: Form( key: _formKey, child: TextFormField( controller: _nameController, validator: (value) { if (value!.isEmpty) { return 'Please enter project name'; } return null; }, cursorColor: Colors.grey, decoration: InputDecoration( contentPadding: EdgeInsets.only(left: 10), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey)), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey)), border: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey))), ), ), ), SizedBox( height: 20, ), Text( 'Description', style: TextStyle( color: Colors.grey.shade500, fontSize: 15.0, ), ), SizedBox( height: 5, ), TextField( controller: _descController, maxLines: 4, decoration: InputDecoration( contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 10), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey)), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey)), border: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey))), ), SizedBox( height: 20, ), Text( 'Client', style: TextStyle( color: Colors.grey.shade500, fontSize: 15.0, ), ), SizedBox( height: 5, ), Container( height: height * 0.05, width: width, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.grey.shade400)), child: DropdownButtonHideUnderline( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: DropdownButton<String>( dropdownColor: Colors.white, value: selectedValue, onChanged: (String? newValue) { setState(() { selectedValue = newValue!; }); }, items: clients.map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(), ), ), ), ), SizedBox( height: 20, ), Text( 'Project Status', style: TextStyle( color: Colors.grey.shade500, fontSize: 15.0, ), ), SizedBox( height: 5, ), Container( height: height * 0.05, width: width, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.grey.shade400)), child: DropdownButtonHideUnderline( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: DropdownButton<String>( dropdownColor: Colors.white, value: selectedProject, onChanged: (String? newValue) { setState(() { selectedProject = newValue!; }); }, items: items.map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(), ), ), ), ), SizedBox( height: 30, ), Text( 'Billing', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), ), SizedBox( height: 10, ), Text( 'Total amount', style: TextStyle( color: Colors.grey.shade500, fontSize: 15.0, ), ), SizedBox( height: 5, ), Container( height: height * 0.06, width: width, decoration: BoxDecoration( border: Border.all( color: Colors.grey.shade400, ), borderRadius: BorderRadius.circular(8.0), ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Padding( padding: const EdgeInsets.only(left: 15), child: Text( 'INR', style: TextStyle(fontSize: 16.0), ), ), SizedBox(width: 8.0), Text( "|", style: TextStyle(fontSize: 25, color: Colors.grey), ), Expanded( child: TextField( controller: _totalAmountController, cursorColor: Colors.grey, keyboardType: TextInputType.number, decoration: InputDecoration( alignLabelWithHint: true, contentPadding: EdgeInsets.only(left: 10), hintText: 'Enter amount', hintStyle: TextStyle(color: Colors.grey), border: InputBorder.none, ), ), ), ], ), ), SizedBox( height: 20, ), Text( 'BILLING METHOD', style: TextStyle( color: Colors.grey.shade500, fontSize: 15.0, ), ), SizedBox( height: 5, ), Container( height: height * 0.05, width: width, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.grey.shade400)), child: DropdownButtonHideUnderline( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: DropdownButton<String>( dropdownColor: Colors.white, value: selectedBilling, onChanged: (String? newValue) { setState(() { selectedBilling = newValue!; }); }, items: billing.map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(), ), ), ), ), SizedBox( height: 20, ), Text( 'MILESTONE DETAIL', style: TextStyle( color: Colors.grey.shade500, fontSize: 15.0, ), ), SizedBox( height: 10, ), Row( children: [ Text( 'AMOUNT', style: TextStyle( color: Colors.grey.shade500, fontSize: 15.0, ), ), SizedBox( width: width * 0.27, ), Text( 'DETAIL', style: TextStyle( color: Colors.grey.shade500, fontSize: 15.0, ), ) ], ), SizedBox( height: 10, ), Column( children: [ ...rows, SizedBox( height: height * 0.02, ), Row( children: [ SizedBox( width: width * 0.37, height: height * 0.05, child: TextField( controller: _amountController, cursorColor: Colors.grey, keyboardType: TextInputType.number, decoration: InputDecoration( contentPadding: EdgeInsets.only(left: 10), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey)), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey)), border: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey)), alignLabelWithHint: true, hintText: 'Enter amount', hintStyle: TextStyle(color: Colors.grey), ), ), ), SizedBox( width: 20, ), SizedBox( width: width * 0.4, height: height * 0.05, child: TextField( controller: _detailsController, cursorColor: Colors.grey, decoration: InputDecoration( contentPadding: EdgeInsets.only(left: 10), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey)), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey)), border: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey)), alignLabelWithHint: true, hintStyle: TextStyle(color: Colors.grey), ), ), ), IconButton( onPressed: addRow, icon: Icon(Icons.add_circle_outline), color: AppTheme.primaryColor, ) ], ), ], ), SizedBox( height: height * 0.03, ), Text( 'DOCUMENT', style: TextStyle( color: Colors.grey.shade500, fontSize: 15.0, ), ), SizedBox( height: 20, ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ InkWell( onTap: () { showModalBottomSheet( context: context, builder: (BuildContext context) { return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(20), topRight: Radius.circular(20))), width: width, height: height * .12, padding: EdgeInsets.all(16.0), child: CircleAvatar( radius: 25, backgroundColor: Colors.grey.shade300, child: IconButton( onPressed: () async { Navigator.of(context).pop(); await pickedFile(1); }, icon: Icon( Icons.filter, color: AppTheme.primaryColor, )), )); }); }, child: Container( height: height * 0.05, width: width * 0.4, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: AppTheme.primaryColor), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.upload, color: Colors.white, size: 15, ), SizedBox( width: 10, ), Text( uploadDoc1 != null ? uploadDoc1!.path.split('/').last : 'Upload Document', style: TextStyle(color: Colors.white, fontSize: 10), ) ]), ), ), SizedBox( height: 20, ), // SizedBox(width: width * 0.017), InkWell( onTap: () { showModalBottomSheet( context: context, builder: (BuildContext context) { return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(20), topRight: Radius.circular(20))), width: width, height: height * .12, padding: EdgeInsets.all(16.0), child: CircleAvatar( radius: 25, backgroundColor: Colors.grey.shade300, child: IconButton( onPressed: () async { Navigator.of(context).pop(); await pickedFile(2); }, icon: Icon( Icons.filter, color: AppTheme.primaryColor, )), )); }); }, child: Container( height: height * 0.05, width: width * 0.4, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: AppTheme.primaryColor), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.upload, color: Colors.white, size: 15, ), SizedBox( width: 10, ), Text( uploadDoc2 != null ? uploadDoc2!.path.split('/').last : 'Upload Document', style: TextStyle(color: Colors.white, fontSize: 10), ) ]), ), ), ], ), SizedBox( height: 20, ), // SizedBox(width: width * 0.017), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ InkWell( onTap: () { showModalBottomSheet( context: context, builder: (BuildContext context) { return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(20), topRight: Radius.circular(20))), width: width, height: height * .12, padding: EdgeInsets.all(16.0), child: CircleAvatar( radius: 25, backgroundColor: Colors.grey.shade300, child: IconButton( onPressed: () async { Navigator.of(context).pop(); await pickedFile(3); }, icon: Icon( Icons.filter, color: AppTheme.primaryColor, )), )); }); }, child: Container( height: height * 0.05, width: width * 0.4, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: AppTheme.primaryColor), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.upload, color: Colors.white, size: 15, ), SizedBox( width: 10, ), Text( uploadDoc3 != null ? uploadDoc3!.path.split('/').last : 'Upload Document', style: TextStyle(color: Colors.white, fontSize: 10), ) ]), ), ), SizedBox( height: 20, ), // SizedBox(width: width * 0.017), InkWell( onTap: () { showModalBottomSheet( context: context, builder: (BuildContext context) { return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(20), topRight: Radius.circular(20))), width: width, height: height * .12, padding: EdgeInsets.all(16.0), child: CircleAvatar( radius: 25, backgroundColor: Colors.grey.shade300, child: IconButton( onPressed: () async { Navigator.of(context).pop(); await pickedFile(4); }, icon: Icon( Icons.filter, color: AppTheme.primaryColor, )), )); }); }, child: Container( height: height * 0.05, width: width * 0.4, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: AppTheme.primaryColor), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.upload, color: Colors.white, size: 15, ), SizedBox( width: 10, ), Text( uploadDoc4 != null ? uploadDoc4!.path.split('/').last : 'Upload Document', style: TextStyle(color: Colors.white, fontSize: 10), ) ]), ), ), ], ), SizedBox( height: height * 0.03, ), SizedBox(height: height * 0.02), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ InkWell( onTap: () { Navigator.pop(context); }, child: Container( height: height * 0.05, width: width * 0.37, decoration: BoxDecoration( border: Border.all( color: AppTheme.primaryColor, ), borderRadius: BorderRadius.circular(5)), child: Center( child: Text( 'Cancel', style: TextStyle( color: AppTheme.primaryColor, ), ), ), ), ), InkWell( onTap: () async { showProgressIndicator(context); await projectAdd( projectDate: _startDateController.text, projectName: _nameController.text, description: _descController.text, client: selectedValue.toString(), projectStatus: selectedProject.toString(), totalAmount: _totalAmountController.text, billingMethod: selectedBilling.toString(), amount: _amountController.text, details: _detailsController.text, userId: user.id!, document1: uploadDoc1, document2: uploadDoc2, document3: uploadDoc3, document4: uploadDoc4, ); }, child: Container( height: height * 0.05, width: width * 0.37, decoration: BoxDecoration( color: AppTheme.primaryColor, borderRadius: BorderRadius.circular(5)), child: Center( child: Text( "Save", style: TextStyle(color: Colors.white), ), ), ), ), ], ), SizedBox( height: 15, ), ], ), ), )), ); } List<TextEditingController> _amountControllers = []; List<TextEditingController> _detailsControllers = []; List<bool> showAddButton = [true]; void addRow() { var mediaQuery = MediaQuery.of(context); double height = mediaQuery.size.height; double width = mediaQuery.size.width; // TextEditingController _amountController = TextEditingController(); // TextEditingController _detailsController = TextEditingController(); setState(() { // Add the new row _amountControllers.add(_amountController); _detailsControllers.add(_detailsController); rows.add( Column( children: [ SizedBox( height: height * 0.015, ), Row( children: [ SizedBox( width: width * 0.37, height: height * 0.05, child: TextField( controller: _amountController, cursorColor: Colors.grey, keyboardType: TextInputType.number, decoration: InputDecoration( contentPadding: EdgeInsets.only(left: 10), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey), ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey), ), alignLabelWithHint: true, hintText: 'Enter amount', hintStyle: TextStyle(color: Colors.grey), ), ), ), SizedBox( width: 20, ), SizedBox( width: width * 0.4, height: height * 0.05, child: TextField( controller: _detailsController, cursorColor: Colors.grey, decoration: InputDecoration( contentPadding: EdgeInsets.only(left: 10), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey), ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: Colors.grey), ), alignLabelWithHint: true, hintStyle: TextStyle(color: Colors.grey), ), ), ), IconButton( onPressed: () { if (_amountControllers.length > 1) { removeRow(_amountControllers.length - 1); } }, icon: Icon(Icons.remove_circle_outline), color: Colors.red, ), if (_amountControllers.length == rows.length) // Only show add button on the last row IconButton( onPressed: addRow, icon: Icon(Icons.add_circle_outline), color: AppTheme.primaryColor, ), ], ), ], ), ); }); } void removeRow(int index) { setState(() { if (index < _amountControllers.length) { _amountControllers[index].dispose(); _detailsControllers[index].dispose(); _amountControllers.removeAt(index); _detailsControllers.removeAt(index); rows.removeAt(index); if (_amountControllers.isEmpty) { addRow(); } } }); } }
Editor is loading...
Leave a Comment