Untitled

 avatar
unknown
plain_text
a year ago
30 kB
8
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> amountControllers = [];
  List<TextEditingController> detailsControllers = [];
  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> billing = ['Fixed Cost', 'Hourly', 'Monthly'];
  final TextEditingController _startDateController = TextEditingController();
  final TextEditingController _nameController = TextEditingController();
  final TextEditingController _descController = TextEditingController();
  final TextEditingController _totalAmountController = 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 List<Map<String, String>> milestoneDetails,
    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,
      milestoneDetails: milestoneDetails,
      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();
    addRow();
  }

  @override
  Widget build(BuildContext context) {
    var user = Provider.of<UserProvider>(context).user;
    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),
                Column(
                  children: [
                    ...rows,
                    SizedBox(height: height * 0.02),
                    Row(
                      children: [
                        SizedBox(
                          width: width * 0.37,
                          height: height * 0.05,
                          child: TextField(
                            controller: amountControllers.isNotEmpty
                                ? amountControllers.last
                                : TextEditingController(),
                            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: detailsControllers.isNotEmpty
                                ? detailsControllers.last
                                : TextEditingController(),
                            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: [
                    buildDocumentUploadButton(1, uploadDoc1, width, height),
                    buildDocumentUploadButton(2, uploadDoc2, width, height),
                  ],
                ),
                SizedBox(height: 20),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    buildDocumentUploadButton(3, uploadDoc3, width, height),
                    buildDocumentUploadButton(4, uploadDoc4, width, height),
                  ],
                ),
                SizedBox(height: height * 0.03),
                SizedBox(height: height * 0.02),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: [
                    buildActionButton('Cancel', AppTheme.primaryColor, () {
                      Navigator.pop(context);
                    }, width, height),
                    buildActionButton('Save', Colors.white, () async {
                      showProgressIndicator(context);
                      List<Map<String, String>> milestoneDetails = [];
                      for (int i = 0; i < amountControllers.length; i++) {
                        milestoneDetails.add({
                          'amount': amountControllers[i].text,
                          'details': detailsControllers[i].text,
                        });
                      }
                      await projectAdd(
                        projectDate: _startDateController.text,
                        projectName: _nameController.text,
                        description: _descController.text,
                        client: selectedValue.toString(),
                        projectStatus: selectedProject.toString(),
                        totalAmount: _totalAmountController.text,
                        billingMethod: selectedBilling.toString(),
                        milestoneDetails: milestoneDetails,
                        userId: user.id!,
                        document1: uploadDoc1,
                        document2: uploadDoc2,
                        document3: uploadDoc3,
                        document4: uploadDoc4,
                      );
                    }, width, height, AppTheme.primaryColor),
                  ],
                ),
                SizedBox(height: 15),
              ],
            ),
          ),
        ),
      ),
    );
  }

  void addRow() {
    setState(() {
      TextEditingController amountController = TextEditingController();
      TextEditingController detailsController = TextEditingController();
      amountControllers.add(amountController);
      detailsControllers.add(detailsController);

      rows.add(
        Column(
          children: [
            SizedBox(height: 10),
            Row(
              children: [
                buildMilestoneTextField(amountController, 'Enter amount'),
                SizedBox(width: 20),
                buildMilestoneTextField(detailsController, 'Enter details'),
                IconButton(
                  onPressed: () {
                    removeRow(amountControllers.length - 1);
                  },
                  icon: Icon(Icons.remove_circle_outline),
                  color: Colors.red,
                ),
                if (amountControllers.length == rows.length)
                  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();
        }
      }
    });
  }

  Widget buildDocumentUploadButton(
      int docNumber, File? uploadDoc, double width, double height) {
    return 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(docNumber);
                  },
                  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(
              uploadDoc != null
                  ? uploadDoc.path.split('/').last
                  : 'Upload Document',
              style: TextStyle(color: Colors.white, fontSize: 10),
            ),
          ],
        ),
      ),
    );
  }

  Widget buildActionButton(String label, Color textColor, VoidCallback onTap,
      double width, double height, Color? backgroundColor) {
    return InkWell(
      onTap: onTap,
      child: Container(
        height: height * 0.05,
        width: width * 0.37,
        decoration: BoxDecoration(
          color: backgroundColor ?? Colors.transparent,
          borderRadius: BorderRadius.circular(5),
          border: backgroundColor == null
              ? Border.all(color: textColor)
              : Border.all(color: Colors.transparent),
        ),
        child: Center(
          child: Text(
            label,
            style: TextStyle(
              color: textColor,
            ),
          ),
        ),
      ),
    );
  }

  Widget buildMilestoneTextField(
      TextEditingController controller, String hintText) {
    return Expanded(
      child: TextField(
        controller: controller,
        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,
          hintText: hintText,
          hintStyle: TextStyle(color: Colors.grey),
        ),
      ),
    );
  }
}
Editor is loading...
Leave a Comment