Untitled

 avatar
unknown
plain_text
6 months ago
18 kB
3
Indexable
import React, { useEffect } from "react";
import {
  Stack,
  TextField,
  Autocomplete,
  Button,
  Typography,
  Grid,
  Divider,
  InputAdornment,
  Box,
} from "@mui/material";
import { useFormik } from "formik";
import * as yup from "yup";
import { getCurrentUser, useUser } from "src/common/api";
import { CompanyType, User } from "src/common/types";
import { CeButton, CeMuiPhoneNumber, CeTextField } from "src/common/components";
import { Add01Icon, Delete01Icon, Tick02Icon } from "@hugeicons/react";
import countries from "src/common/utils/countries";
import { useTranslation } from "react-i18next";
import { useCompany, useUpdateCompany } from "src/common/api/company";
import { useRecoilState } from "recoil";
import { companyFormValuesState } from "src/common/state/company";
import {
  turnCompanyFormValuesIntoUpdateDto,
  turnCompanyIntoFormValues,
} from "src/common/utils/company";

interface SettingsCompanyProfileProps {
  userId?: number;
}

export const SettingsCompanyProfile: React.FC<SettingsCompanyProfileProps> = ({
  userId,
}) => {
  const { t } = useTranslation(["common", "manager", "dispatcher"]);

  const [companyFormValues, setCompanyFormValues] = useRecoilState(
    companyFormValuesState
  );

  const {
    data: user,
    isLoading: isFullUserLoading,
    isSuccess: isFullUserSuccess,
    refetch: refetchUser,
  } = useUser(userId, Boolean(userId));

  const {
    mutate: handleUpdateCompany,
    isSuccess: isUpdateCompanySuccess,
    isLoading: isUpdateCompanyLoading,
  } = useUpdateCompany();

  const isLoading = isFullUserLoading || isUpdateCompanyLoading;

  const formik = useFormik({
    initialValues: companyFormValues,
    enableReinitialize: true,
    validationSchema: yup.object({
      name: yup.string().required("Name is required"),
      type: yup.string().required("Type is required"),
      contactEmail: yup.string().email("Invalid email").nullable(),
      billingEmail: yup.string().email("Invalid email").nullable(),
      planningEmail: yup.string().email("Invalid email").nullable(),
      phoneNumber: yup.string().required("Phone number is required"),
      address: yup.string().required("Address is required"),
      secondaryAddress: yup.string().nullable(),
      vatNumber: yup.string().required("Vat number is required"),
      zipCode: yup.string().required("zip code is required").nullable(),
      city: yup.string().required("City is required"),
      country: yup.object().required("Country is required").nullable(),
    }),
    onSubmit: async (values) => {
      if (user?.company?.id) {
        const payload = turnCompanyFormValuesIntoUpdateDto({
          ...values,
          companyId: user.companyId,
        });
        handleUpdateCompany(payload);
      }
    },
  });

  useEffect(() => {
    if (user?.companyId && isFullUserSuccess) {
      const companyFormValues = turnCompanyIntoFormValues(user.company);

      setCompanyFormValues(companyFormValues);
    }
  }, [user?.company, isFullUserSuccess]);

  const handleAddTaxBracket = () => {
    formik.setFieldValue("taxes", [
      ...formik.values.taxes,
      { name: "", percentage: null },
    ]);
  };

  const handleRemoveTaxBracket = (index: number) => {
    const updatedTaxes = formik.values.taxes.filter((_, i) => i !== index);
    formik.setFieldValue("taxes", updatedTaxes);
  };

  return (
    <form onSubmit={formik.handleSubmit}>
    {/* General*/}
    <Box sx={{ paddingY: 2, paddingX: 1.5 }}>
      <Box>
        <Typography
          variant="body1"
          color="text.disabled"
          fontWeight="bold"
          gutterBottom
        >
        {t("General")}
        </Typography>
        <Divider sx={{ marginBottom: 2, marginTop: 2 }} />
      </Box>
      <Box display="flex" flexDirection="column" gap={3} sx={{ paddingY: 1.5, paddingX: 3, width: "90%" }}>
        {/* Company Name & Type */}
        <Box display="flex" alignItems="center" gap={2}>
          <Typography variant="body2" sx={{flex:"30%"}}>
              {t("company-name-type")}
          </Typography>
          <Box display="flex" flex="70%" gap={2}>
            <Box flex="1">
              <CeTextField
                fullWidth
                id="name"
                name="name"
                size="small"
                placeholder={t("name")}
                value={formik.values.name}
                onChange={formik.handleChange}
                error={formik.touched.name && Boolean(formik.errors.name)}
                helperText={formik.touched.name && formik.errors.name}
                disabled={isLoading}
                required
              />
            </Box>
            <Box flex="1">
              <Autocomplete
                id="type"
                fullWidth
                value={formik.values.type || null}
                onChange={(event: any, newValue: string | null) => {
                  formik.setFieldValue("type", newValue || null);
                }}
                options={Object.values(CompanyType)}
                getOptionLabel={(option) => option}
                renderInput={(params) => (
                  <CeTextField
                    {...params}
                    size="small"
                    placeholder={t("dispatcher:type")}
                    InputLabelProps={{ shrink: true }}
                    error={
                      formik.touched.type && Boolean(formik.errors.type)
                    }
                    helperText={formik.touched.type && formik.errors.type}
                    required
                  />
                )}
              />
            </Box>
          </Box>
        </Box>
        {/* Company VAT Number */}
        <Box display="flex" alignItems="center" gap={2}>
          <Typography variant="body2" sx={{flex:"30%"}}>
            {t("company-vat-number")}
          </Typography>
          <Box display="flex" flex="70%" gap={2}>
            <CeTextField
              fullWidth
              id="vatNumber"
              name="vatNumber"
              size="small"
              placeholder={t("vat-number")}
              value={formik.values.vatNumber}
              onChange={formik.handleChange}
              disabled={isLoading}
              error={
                formik.touched.vatNumber && Boolean(formik.errors.vatNumber)
              }
              helperText={formik.touched.vatNumber && formik.errors.vatNumber}
              required
            />
          </Box>
        </Box>
        {/* Company Address */}
        <Box display="flex" alignItems="center" gap={2}>
          <Typography variant="body2" sx={{flex:"30%"}}>
            {t("company-address")}
          </Typography>
          <Box display="flex" flex="70%" gap={2}>
            <Box flex="1">
              <CeTextField
                fullWidth
                id="address"
                name="address"
                size="small"
                placeholder={t("address-line")}
                value={formik.values.address}
                onChange={formik.handleChange}
                disabled={isLoading}
                error={
                  formik.touched.address && Boolean(formik.errors.address)
                }
                helperText={formik.touched.address && formik.errors.address}
                required
              />
            </Box>
            <Box flex="1">
              <CeTextField
                fullWidth
                id="secondaryAddress"
                name="secondaryAddress"
                size="small"
                placeholder={t("additional-address-line")}
                value={formik.values.secondaryAddress}
                onChange={formik.handleChange}
                disabled={isLoading}
              />
            </Box>
          </Box>
        </Box>

        {/* Region */}
        <Box display="flex" alignItems="center" gap={2}>
          <Typography variant="body2" sx={{flex:"30%"}}>
            {t("region")}
          </Typography>
          <Box display="flex" flex="70%" gap={2}>
            <Box flex="1">
              <CeTextField
                fullWidth
                id="zipCode"
                name="zipCode"
                size="small"
                placeholder={t("zip-code")}
                value={formik.values.zipCode}
                onChange={formik.handleChange}
                disabled={isLoading}
                error={
                  formik.touched.zipCode && Boolean(formik.errors.zipCode)
                }
                helperText={formik.touched.zipCode && formik.errors.zipCode}
                required
              />
            </Box>
            <Box flex="1">
              <CeTextField
                fullWidth
                id="city"
                name="city"
                size="small"
                placeholder={t("dispatcher:city")}
                value={formik.values.city}
                onChange={formik.handleChange}
                disabled={isLoading}
                error={formik.touched.city && Boolean(formik.errors.city)}
                helperText={formik.touched.city && formik.errors.city}
                required
              />
            </Box>
            <Box flex="1">
              <Autocomplete
                fullWidth
                id="country"
                size="small"
                value={formik.values.country || null}
                onChange={(_, selectedCountry) => {
                  formik.setFieldValue("country", selectedCountry);
                }}
                options={countries}
                getOptionLabel={(option) => option?.label || ""}
                isOptionEqualToValue={(option, value) =>
                  option.value === value?.value
                }
                renderInput={(params) => (
                  <CeTextField
                    {...params}
                    InputLabelProps={{ shrink: true }}
                    error={
                      formik.touched.country &&
                      Boolean(formik.errors.country)
                    }
                    helperText={
                      formik.touched.country && formik.errors.country
                    }
                    disabled={isLoading}
                    placeholder={t("country")}
                    size="small"
                    required
                  />
                )}
              />
            </Box>
          </Box>
        </Box>

        {/* Company Phone Number */}
        <Box display="flex" alignItems="center" gap={2}>
          <Typography variant="body2" sx={{flex:"30%"}}>
            {t("company-phone-number")}
          </Typography>
          <Box display="flex" flex="70%">
            <CeMuiPhoneNumber
              fullWidth
              defaultCountry={"be"}
              id="phoneNumber"
              name="phoneNumber"
              size="small"
              placeholder={t("phone-number")}
              value={formik.values.phoneNumber}
              onChange={(value) => formik.setFieldValue("phoneNumber", value)}
              onBlur={() => formik.setFieldTouched("phoneNumber", true)}
              error={
                formik.touched.phoneNumber &&
                Boolean(formik.errors.phoneNumber)
              }
              helperText={
                formik.touched.phoneNumber && formik.errors.phoneNumber
              }
              disabled={isLoading}
              variant="outlined"
              required
            />
          </Box>
        </Box>

        {/* Company Emails */}
        <Box display="flex" alignItems="center" gap={2}>
          <Typography variant="body2" sx={{flex:"30%"}}>
            {t("company-email-contact")}
          </Typography>
          <Box display="flex" flex="70%">
            <CeTextField
              fullWidth
              id="contactEmail"
              name="contactEmail"
              size="small"
              placeholder={t("contact-address")}
              value={formik.values.contactEmail}
              onChange={formik.handleChange}
              disabled={isLoading}
            />
          </Box>
        </Box>

        <Box display="flex" alignItems="center" gap={2}>
          <Typography variant="body2" sx={{flex:"30%"}}>
            {t("company-email-billing")}
          </Typography>
          <Box display="flex" flex="70%">
            <CeTextField
              fullWidth
              id="billingEmail"
              name="billingEmail"
              size="small"
              placeholder={t("billing-address")}
              value={formik.values.billingEmail}
              onChange={formik.handleChange}
              disabled={isLoading}
            />
          </Box>
        </Box>

        <Box display="flex" alignItems="center" gap={2}>
          <Typography variant="body2" sx={{flex:"30%"}}>
            {t("company-email-planning")}
          </Typography>
          <Box display="flex" flex="70%">
            <CeTextField
              fullWidth
              id="planningEmail"
              name="planningEmail"
              size="small"
              placeholder={t("planning-address")}
              value={formik.values.planningEmail}
              onChange={formik.handleChange}
              disabled={isLoading}
            />
          </Box>
        </Box>
      </Box>
    </Box>

  {/* Taxes Header */}
    <Box sx={{ paddingY: 2, paddingX: 1.5 }}>
      <Box>
        <Typography
          variant="body1"
          color="text.disabled"
          fontWeight="bold"
          gutterBottom
        >
        {t("Taxes")}
        </Typography>
        <Divider sx={{ marginBottom: 2, marginTop: 2 }} />
      </Box>
      {formik.values.taxes.map((tax, index) => {
        const taxErrors = formik.errors.taxes?.[index];
        return (
          <Box display="flex" flexDirection="column" gap={2} sx={{ paddingY: 1.5, paddingX: 3, width: "90%" }}>
            <Box display="flex" alignItems="center" gap={2}>
              <Typography variant="body2" sx={{flex:"30%"}}>
                {t("taxes")}
              </Typography>
              <Box display="flex" alignItems="center" flex="70%" gap={2}>

                {/* Tax Name Field */}
                <Box flex="1">
                  <CeTextField
                    id={`taxes[${index}].name`}
                    name={`taxes[${index}].name`}
                    placeholder={t("tax-name")}
                    fullWidth
                    size="small"
                    value={tax.name}
                    onChange={formik.handleChange}
                    InputLabelProps={{ shrink: true }}
                    error={
                      !!(
                        formik.touched.taxes?.[index]?.name &&
                        taxErrors &&
                        typeof taxErrors === "object" &&
                        taxErrors?.name
                      )
                    }
                    helperText={
                      formik.touched.taxes?.[index]?.name &&
                      taxErrors &&
                      typeof taxErrors === "object" &&
                      taxErrors?.name
                    }
                  />
                </Box>

                {/* Tax Percentage Field */}
                <Box flex="1">
                  <CeTextField
                    fullWidth
                    id={`taxes[${index}].percentage`}
                    name={`taxes[${index}].percentage`}
                    placeholder={t("percentage")}
                    size="small"
                    type="number"
                    value={tax.percentage ?? ""}
                    onChange={formik.handleChange}
                    InputProps={{
                      endAdornment: (
                        <InputAdornment position="end">%</InputAdornment>
                      ),
                    }}
                    error={
                      !!(
                        formik.touched.taxes?.[index]?.percentage &&
                        taxErrors &&
                        typeof taxErrors === "object" &&
                        taxErrors?.percentage
                      )
                    }
                    helperText={
                      formik.touched.taxes?.[index]?.percentage &&
                      taxErrors &&
                      typeof taxErrors === "object" &&
                      taxErrors?.percentage
                    }
                  />
                </Box>

                  {/* Remove Button */}
                  <Box flex="0.1" alignItems="center">
                    {formik.values.taxes.length > 1 && (
                      <CeButton
                        type="button"
                        onClick={() => handleRemoveTaxBracket(index)}
                        color="error"
                        variant="text"
                        size="small"
                      >
                        <Delete01Icon />
                      </CeButton>
                    )}
                  </Box>
              </Box>
            </Box>
          </Box>
            );
          })}

          {/* Add New Tax Button */}
          <Box display="flex" alignItems="center" gap={2} sx={{ paddingY: 1.5, paddingX: 3, width: "90%" }}>
            <Box sx={{flex:"30%"}}>
            </Box>
            <Box display="flex" flex="70%">
              <CeButton
                type="button"
                onClick={handleAddTaxBracket}
                variant="outlined"
                size="large" 
              >
                {t("add-tax-bracket")}
              </CeButton>
            </Box>
          </Box>
        </Box>


    {/* Submit Button */}
    <Box sx={{ padding: "16px 24px" }}>
      <Grid
        item
        xs={12}
        sx={{ display: "flex", justifyContent: "flex-end", marginTop: 3 }}
      >
        <CeButton
          variant="text"
          onClick={() => formik.resetForm()}
          disabled={isLoading}
          sx={{ marginRight: 1 }}
        >
          {t("cancel")}
        </CeButton>
        <CeButton
          type="submit"
          variant="contained"
          disabled={isLoading}
          endIcon={
            <Tick02Icon size={20} color={"currentColor"} variant={"stroke"} />
          }
        >
          {t("manager:save")}
        </CeButton>
      </Grid>
    </Box>
    </form>
  );
};
Editor is loading...
Leave a Comment