Snippets Collections
export function TailwindIndicator() {
  if (process.env.NODE_ENV === "production") return null

  return (
    <div className="fixed bottom-1 left-1 z-50 flex h-6 w-6 items-center justify-center rounded-full bg-gray-800 p-3 font-mono text-xs text-white">
      <div className="block sm:hidden">xs</div>
      <div className="hidden sm:block md:hidden">sm</div>
      <div className="hidden md:block lg:hidden">md</div>
      <div className="hidden lg:block xl:hidden">lg</div>
      <div className="hidden xl:block 2xl:hidden">xl</div>
      <div className="hidden 2xl:block">2xl</div>
    </div>
  )
}
function MyPage() {
  const [theme, setTheme] = useState('dark');
  return (
    <ThemeContext.Provider value={theme}>
      <Form />
      <Button onClick={() => {
        setTheme('light');
      }}>
        Switch to light theme
      </Button>
    </ThemeContext.Provider>
  );
}
// importing
import ReactPaginate from 'react-paginate';

// handling the pagination
const [page, setPage] = useState(0);
const handlePageClick = (num) => {
  setPage(num);
};

// fetching all the employee details from the mongoDB database
const [loadedEmployees, setLoadedEmployees] = useState();
useEffect(() => {
  const fetchEmployees = async () => {
    try {
      const responseData = await sendRequest(
        `http://localhost:5000/api/employees/emp?page=${page}`
      );
      setLoadedEmployees(responseData.employees);
    } catch (err) {
      console.log("Error in fetching employees: "+err);
    }
  };
  fetchEmployees();
}, [sendRequest, page]);


// returning this component
<ReactPaginate
  containerClassName="flex gap-2 justify-center mt-4"
  pageClassName="text-gray-500"
  activeClassName="text-gray-900 border-2 border-black px-2"
  previousClassName="text-gray-500"
  nextClassName="text-gray-500"
  breakLabel="..."
  nextLabel="next >"
  onPageChange={(selected) => handlePageClick(selected.selected + 1)}
  pageRangeDisplayed={2}
  marginPagesDisplayed={1}
  pageCount={pageCount}
  previousLabel="< previous"
  renderOnZeroPageCount={null}
/>



// backend - controller methods
const getEmployeeCount = async (req, res, next) => {
  let employeeCount;
  try {
    employeeCount = await Employee.countDocuments();
  } catch (err) {
    const error = new HttpError(
      'Fetching employee count failed, please try again later.',
      500
    );
    return next(error);
  }

  res.json({ employeeCount });
  console.log("DEBUG -- Employee-Controller - Fetching employee count successful!");
};
const getEmployees = async (req, res, next) => {
  const page = req.query.page || 0;
  const employeesPerPage = 2; 

  let allEmployees;
  try {
    allEmployees = await Employee
      .find()
      .skip(page * employeesPerPage)
      .limit(employeesPerPage);
  } catch (err) {
    const error = new HttpError(
      'Fetching Employees failed, please try again later.',
      500
    );
    return next(error);
  }

  if (!allEmployees || allEmployees.length === 0) {
    return next(new HttpError('No employees found.', 404));
  }

  res.json({
    employees: allEmployees.map((emp) => emp.toObject({ getters: true })),
  });
  console.log("DEBUG -- Employee-Controller - Fetching employees successful!");
};
      <FormLayoutSection className="Location-Info" title="Location Info">
        <div className="mb-5">
          <div className="inline-flex justify-between w-full">
            <div className="block mb-1 text-sm font-semibold text-gray-700 dark:text-gray-100">
              County FIPS(s):
              <span className="text-red-500 text-md">{`  `}*</span>
            </div>
            <Tooltip
              className="-mt-1"
              direction="left"
              content="This is a 6-digit numeric code identifying the geographic area for where you want to send the alert - the 5-digit numeric code must be prefaced with an additional zero"
            />
          </div>
          {/* {FIPSList.map(fipsCode => (
            <div key={fipsCode}>
              <input
                type="checkbox"
                id={fipsCode}
                name="CountyFIPS"
                value={fipsCode}
                ref={register({ required: true })}
                onChange={() => handleSelect(fipsCode)}
                checked={selectedOptions.includes(fipsCode)}
              />
              <label htmlFor={fipsCode}>
                {fipsCode} - {findFipsCodeName(fipsCode)}, {findFipsCodeState(fipsCode)}
              </label>
            </div>
          ))} */}
          {/* {FIPSList.map(fipsCode => (
            <div key={fipsCode}>
              <Checkbox
                id={fipsCode}
                name="CountyFIPS"
                value={fipsCode}
                ref={register({ required: true })}
                defaultChecked={false}
              >
                {fipsCode} - {findFipsCodeName(fipsCode)}, {findFipsCodeState(fipsCode)}
              </Checkbox>
            </div>
          ))} */}
        </div>
        <div className="mb-5">
          <Controller
            name="CountyFIPS"
            control={control}
            defaultValue={[]}
            render={({ ...field }) => (
              <div>
                {FIPSList.map(fipsCode => (
                  <label key={fipsCode} className="inline-flex items-center">
                    <input
                      className="rounded border-gray-300 focus:ring-2 focus:ring-opacity-50"
                      type="checkbox"
                      {...field}
                      value={fipsCode}
                      checked={field.value.includes(fipsCode)}
                      onChange={e => {
                        const selectedOptions = [...field.value]
                        if (e.target.checked) {
                          selectedOptions.push(fipsCode)
                        } else {
                          const index = selectedOptions.indexOf(fipsCode)
                          if (index > -1) {
                            selectedOptions.splice(index, 1)
                          }
                        }
                        field.onChange(selectedOptions)
                      }}
                    />
                    <span className="mx-2 text-sm">
                      {fipsCode} - {findFipsCodeName(fipsCode)},{' '}
                      {findFipsCodeState(fipsCode)}
                    </span>
                  </label>
                ))}
              </div>
            )}
          />
          {/* <MultiSelect
            id="CountyFIPS"
            ref={register({ required: true })}
            name="CountyFIPS"
            label="OCV County FIPS(s):"
            labelTooltipComponent={
              <Tooltip
                content="This is a 6-digit numeric code identifying the geographic area for where you want to send the alert - the 5-digit numeric code must be prefaced with an additional zero"
                direction="left"
              />
            }
            required
            multiple
            onChange={event => {
              if (event.target.value === 'Select FIPS Code') {
                setError('CountyFIPS', {
                  type: 'manual',
                  message: 'Please select the FIPS Code',
                })
              }
            }}
            onBlur={event => {
              if (event.target.value === 'Select FIPS Code') {
                setError('CountyFIPS', {
                  type: 'manual',
                  message: 'Please select the FIPS Code',
                })
              }
            }}
            value={FIPSList}
          >
            <option defaultValue="">Select FIPS Code</option>
            {FIPSList.map((fipsCode, index) => (
              <option key={index} value={fipsCode}>
                {fipsCode} - {findFipsCodeName(fipsCode)}, {findFipsCodeState(fipsCode)}
              </option>
            ))}
            {!FIPSList.length && (
              <option defaultValue="">No FIPS Codes. Please add in settings.</option>
            )}
          </MultiSelect> */}
          <p className="text-sm text-red-500">
            {errors.CountyFIPS && errors.CountyFIPS.message}
          </p>
        </div>
        <div className="mb-5">
          <p className="block text-sm font-semibold text-gray-700 dark:text-gray-100">
            Validation Info:{' '}
            <span className="text-sm font-semibold text-red-500">
              {locationPoints > 100 &&
                'More than 100 points added please remove locations.'}{' '}
              {locationShapes > 10 &&
                'More than 10 shapes added please remove locations.'}
            </span>
          </p>
          <p className="text-sm font-semibold text-gray-700 dark:text-gray-100">
            {locationPoints} Points - {locationShapes} Shapes
          </p>
        </div>
        {!locationShapes && (
          <div className="px-2 py-1 bg-yellow-700 rounded-md mb-5">
            <p className="text-md font-semibold text-gray-100">
              Note: If no shape is selected, the notification will go to the entire FIPS
              Code.
            </p>
          </div>
        )}

        {/* {notificationType === 'IPAWS' && (
            //   <Input
            //     id="CountyFIPS"
            //     name="CountyFIPS"
            //     type="number"
            //     onBlur={e =>
            //       e.target.removeEventListener('wheel', function (e) {
            //         e.preventDefault()
            //       })
            //     }
            //     onFocus={e =>
            //       e.target.addEventListener(
            //         'wheel',
            //         function (e) {
            //           e.preventDefault()
            //         },
            //         { passive: false }
            //       )
            //     }
            //     label="County FIPS(s):"
            //     labelTooltipComponent={
            //       <Tooltip
            //         content="This is a 6-digit numeric code identifying the geographic area for where you want to send the alert - the 5-digit numeric code must be prefaced with an additional zero"
            //         direction="left"
            //       />
            //     }
            //     placeholder="######"
            //     required
            //     ref={register({
            //       required: true,
            //       validate: validateSixDigits,
            //     })}
            //     error={errors.FIPS ? errors.FIPS.message : ''}
            //   />
            // )}
            // {errors.CountyFIPS && (
            //   <p className="text-sm text-red-500">{errors.CountyFIPS.message}</p>*/}
        {/* <div className="mb-5">
          <NativeSelect
            id="CountyFIPS"
            ref={register({ required: true })}
            name="CountyFIPS"
            label="County FIPS(s):"
            labelTooltipComponent={
              <Tooltip
                content="This is a 6-digit numeric code identifying the geographic area for where you want to send the alert - the 5-digit numeric code must be prefaced with an additional zero"
                direction="left"
              />
            }
            required
            onChange={event => {
              if (event.target.value === 'Select FIPS Code') {
                setError('CountyFIPS', {
                  type: 'manual',
                  message: 'Please select the FIPS Code',
                })
              }
            }}
            onBlur={event => {
              if (event.target.value === 'Select FIPS Code') {
                setError('CountyFIPS', {
                  type: 'manual',
                  message: 'Please select the FIPS Code',
                })
              }
            }}
          >
            <option defaultValue="">Select FIPS Code</option>
            {FIPSList.map((fipsCode, index) => (
              <option key={index} value={fipsCode}>
                {fipsCode} - {findFipsCodeName(fipsCode)}, {findFipsCodeState(fipsCode)}
              </option>
            ))}
            {!FIPSList.length && (
              <option defaultValue="">No FIPS Codes. Please add in settings.</option>
            )}
          </NativeSelect>
          <p className="text-sm text-red-500">{errors.CountyFIPS && errors.CountyFIPS.message}</p>
        </div> */}
        {/* <MultiSelect options={FIPSList} onSelect={handleSelect} ref></MultiSelect> */}

        <div className="flex flex-col">
          <p className="block mb-1 text-sm font-semibold text-gray-700 dark:text-gray-100">
            Choose a Geographic Location
          </p>
          <Button
            onClick={mapModalState}
            icon={<Icon className="mr-2 -ml-1" name="globe" />}
          >
            Choose Location
          </Button>
        </div>
      </FormLayoutSection>
import React, { useState } from 'react'
import {
  FormLayoutSection,
  Input,
  Textarea,
  Button,
  Checkbox,
  Icon,
  NativeSelect,
  Tooltip,
} from '@ocv-web/ui'

import {
  categoryMap,
  certaintyMap,
  eventCodeKeysFilter,
  eventCodes,
  eventResponses,
  severityMap,
  urgencyMap,
  weaCertaintyMap,
  weaHandling,
  weaSeverityMap,
  weaUrgencyMap,
} from '../../config'
import { useSettings } from '../../api/settings'
import { fipsCodeList, stateFips } from '../../api/settings/fips'

export interface IFormData {
  watchWEA: boolean
  watchWEASpanish: boolean
  watchNWEM: boolean
  watchRecurring: boolean
  watchSchedule: boolean
  watchScheduleHide: boolean
  watchWEAHandle: string
  errors: any
  register: any
  setValue?: any
  setError?: any
  // submitStatus: string
  mapModalState: React.Dispatch<React.SetStateAction<any>>
  locationPoints: number
  locationShapes: number
  notificationType: string
}
export const FormData: React.FC<IFormData> = ({
  watchWEA,
  watchWEASpanish,
  watchNWEM,
  watchRecurring,
  watchSchedule,
  watchScheduleHide,
  watchWEAHandle,
  errors,
  register,
  setValue,
  setError,
  mapModalState,
  locationPoints,
  locationShapes,
  notificationType,
  // submitStatus,
}) => {
  const [charactersWEAShort, setCharactersWEAShort] = useState(0)
  const [charactersWEALong, setCharactersWEALong] = useState(0)
  const [charactersWEASpanish, setCharactersWEASpanish] = useState(0)
  const [charactersWEALongSpanish, setCharactersWEALongSpanish] = useState(0)
  const [charactersTitle, setCharactersTitle] = useState(0)
  const [charactersDescription, setCharactersDescription] = useState(0)
  const [charactersInstructions, setCharactersInstructions] = useState(0)
  const { data } = useSettings()
  const FIPSList = JSON.parse(data?.Results?.[0]?.FIPSList || '[]')
  const findFipsCodeName = fipsCode => {
    const foundEntry = fipsCodeList.find(entry => entry['FIPS code'] === fipsCode)
    return foundEntry ? foundEntry.name : 'Unknown'
  }
  const findFipsCodeState = fipsCode => {
    const fipsDigit = fipsCode?.slice(0, 3)
    const foundEntry = stateFips.find(entry => entry['Digit'] === fipsDigit)
    return foundEntry ? foundEntry.name : 'Unknown'
  }
  const [selectedOptions, setSelectedOptions] = useState([])

  const handleSelect = fipsCode => {
    console.log('Checkbox clicked:', fipsCode)
    setValue('CountyFIPS', prevSelected => {
      const isSelected = prevSelected.includes(fipsCode)
      const selectedFipsCodes = isSelected
        ? prevSelected.filter(selected => selected !== fipsCode)
        : [...prevSelected, fipsCode]
      setSelectedOptions(prevOptions => {
        if (prevOptions.includes(fipsCode)) {
          return prevOptions.filter(code => code !== fipsCode)
        } else {
          return [...prevOptions, fipsCode]
        }
      })
      return JSON.stringify(Object.values(selectedFipsCodes))
    })
  }

  // React.useEffect(() => {
  //   if (submitStatus === 'success') {
  //     setCharactersWEAShort(0)
  //     setCharactersWEALong(0)
  //     setCharactersWEASpanish(0)
  //     setCharactersTitle(0)
  //     setCharactersWEALongSpanish(0)
  //     setCharactersDescription(0)
  //     setCharactersInstructions(0)
  //   }
  // }, [submitStatus])
  // const validateSixDigits = value => {
  //   if (value.length !== 6 || isNaN(value)) {
  //     return 'County FIPS must be a 6-digit numeric code.'
  //   }
  //   return true
  // }

  return (
    <>
      <FormLayoutSection
        title="Compose Your Message"
        description="Notify your contacts about the information."
        className="Message"
      >
        <div className="space-y-5">
          {notificationType === 'IPAWS' && watchWEA && (
            <Input
              id="WEAShortText"
              name="WEAShortText"
              type="text"
              placeholder="Add your WEA Short Text"
              label="WEA Short Text"
              labelTooltipComponent={
                <Tooltip
                  content="This is the text that appears in one-way radio broadcasts that send to cell phones or mobile devices based on the recipient's proximity to the selected cell tower"
                  className="-mt-0.5"
                  direction="left"
                />
              }
              limit={90}
              onChange={e => {
                const value = e.target.value
                setCharactersWEAShort(value.length)
              }}
              currentCount={charactersWEAShort}
              required={watchWEA}
              error={errors.WEAShortText}
              ref={register({
                required: true,
                maxLength: {
                  value: 90,
                  message: 'The short text must be between 1 - 90 characters',
                },
                pattern: {
                  value: /^[^{}|\\^~[\]]{0,}$/m,
                  message:
                    'The message cannot include any of the following characters: {, }, |, \\, ^, ~, [, or ]',
                },
              })}
            />
          )}
          {notificationType === 'IPAWS' && watchWEA && (
            <Textarea
              id="WEALongText"
              name="WEALongText"
              placeholder="Add your WEA Long Text"
              label="WEA Long Text"
              labelTooltipComponent={
                <Tooltip
                  content="This is the text that appears in one-way radio broadcasts that send to cell phones or mobile devices based on the recipient's proximity to the selected cell tower (use if more than 90 characters are needed)"
                  className="-mt-0.5"
                  direction="left"
                />
              }
              limit={360}
              onChange={e => {
                const value = e.target.value
                setCharactersWEALong(value.length)
              }}
              currentCount={charactersWEALong}
              error={errors.weaLongText}
              ref={register({
                maxLength: {
                  value: 360,
                  message: 'The character length must be between 1 - 360 characters',
                },
                pattern: {
                  value: /^[^{}|\\^~[\]]{0,}$/m,
                  message:
                    'The message cannot include any of the following characters: {, }, |, \\, ^, ~, [, or ]',
                },
              })}
            />
          )}
          {notificationType === 'IPAWS' && watchWEA && (
            <Checkbox name="WEASpanish" ref={register}>
              Add WEA Spanish Translation
            </Checkbox>
          )}
          {notificationType === 'IPAWS' && watchWEA && watchWEASpanish && (
            <Input
              id="WEAShortTextSpanish"
              name="WEAShortTextSpanish"
              type="text"
              placeholder="Add your WEA Short Text (Spanish)"
              label="WEA Short Text (Spanish)"
              labelTooltipComponent={
                <Tooltip
                  content="This is the spanish translation of the text that appears in one-way radio broadcasts that send to cell phones or mobile devices based on the recipient's proximity to the selected cell tower"
                  className="-mt-0.5"
                  direction="left"
                />
              }
              limit={90}
              onChange={e => {
                const value = e.target.value
                setCharactersWEASpanish(value.length)
              }}
              required={watchWEASpanish}
              error={errors.WEAShortTextSpanish}
              currentCount={charactersWEASpanish}
              ref={register({
                required: true,
                maxLength: {
                  value: 90,
                  message: 'The short text must be between 1 - 90 characters',
                },
                pattern: {
                  value: /^[^{}|\\^~[\]]{0,}$/m,
                  message:
                    'The message cannot include any of the following characters: {, }, |, \\, ^, ~, [, or ]',
                },
              })}
            />
          )}
          {notificationType === 'IPAWS' && watchWEA && watchWEASpanish && (
            <Textarea
              id="WEALongTextSpanish"
              name="WEALongTextSpanish"
              placeholder="Add your WEA Long Text (Spanish)"
              label="WEA Long Text (Spanish)"
              labelTooltipComponent={
                <Tooltip
                  content="This is the spanish translation of the text that appears in one-way radio broadcasts that send to cell phones or mobile devices based on the recipient's proximity to the selected cell tower (use if more than 90 characters are needed)"
                  className="-mt-0.5"
                  direction="left"
                />
              }
              limit={360}
              onChange={e => {
                const value = e.target.value
                setCharactersWEALongSpanish(value.length)
              }}
              currentCount={charactersWEALongSpanish}
              error={errors.weaLongTextSpanish}
              ref={register({
                maxLength: {
                  value: 360,
                  message: 'The character length must be between 1 - 360 characters',
                },
                pattern: {
                  value: /^[^{}|\\^~[\]]{0,}$/m,
                  message:
                    'The message cannot include any of the following characters: {, }, |, \\, ^, ~, [, or ]',
                },
              })}
            />
          )}
          <Input
            id="Title"
            type="text"
            name="Title"
            placeholder="New Alert"
            label="Headline (Title)"
            labelTooltipComponent={
              <Tooltip
                content="This is the text headline of the alert message"
                className="-mt-0.5"
                direction="left"
              />
            }
            limit={140}
            onChange={e => {
              const value = e.target.value
              setCharactersTitle(value.length)
            }}
            required
            error={errors.Title}
            currentCount={charactersTitle}
            ref={register({
              required: watchNWEM,
              maxLength: {
                value: 140,
                message: 'The character length must be between 1 - 140 characters',
              },
              pattern: {
                value: /^[^{}|\\^~[\]]{0,}$/m,
                message:
                  'The message cannot include any of the following characters: {, }, |, \\, ^, ~, [, or ]',
              },
            })}
          />
          <Textarea
            id="Description"
            name="Description"
            placeholder="Instructions to follow"
            label="Description"
            labelTooltipComponent={
              <Tooltip
                content="This is the text describing the subject event of the alert message"
                className="-mt-0.5"
                direction="left"
              />
            }
            rows={4}
            limit={1800}
            onChange={e => {
              const value = e.target.value
              setCharactersDescription(value.length)
            }}
            currentCount={charactersDescription}
            required
            error={errors.Description}
            ref={register({
              required: true,
              maxLength: {
                value: 1800,
                message: 'The character length must be between 1 - 1,800 characters',
              },
              pattern: {
                value: /^[^{}|\\^~[\]]{0,}$/m,
                message:
                  'The message cannot include any of the following characters: {, }, |, \\, ^, ~, [, or ]',
              },
            })}
          />
          {notificationType === 'IPAWS' && (
            <Textarea
              id="Instructions"
              name="Instructions"
              placeholder="Long description of alert"
              label="Instructions"
              labelTooltipComponent={
                <Tooltip
                  content="This is the optional extended description of the subject event of the alert message"
                  className="-mt-0.5"
                  direction="left"
                />
              }
              rows={4}
              limit={1800}
              onChange={e => {
                const value = e.target.value
                setCharactersInstructions(value.length)
              }}
              currentCount={charactersInstructions}
              ref={register({
                maxLength: {
                  value: 1800,
                  message: 'The character length must be between 1 - 1,800 characters',
                },
                pattern: {
                  value: /^[^{}|\\^~[\]]{0,}$/m,
                  message:
                    'The message cannot include any of the following characters: {, }, |, \\, ^, ~, [, or ]',
                },
              })}
            />
          )}
          {/* <div className="flex flex-col">
            <p className="block mb-1 text-sm font-semibold text-gray-700 dark:text-gray-100">
              Attachments (Max 10MB)
            </p>
            <Button>Upload Media</Button>
          </div> */}
        </div>
      </FormLayoutSection>
      {notificationType === 'IPAWS' && (
        <>
          <FormLayoutSection className="Message-Details" title="Message Details">
            <div className="mb-5">
              <NativeSelect
                id="AlertCategory"
                ref={register({ required: true })}
                name="AlertCategory"
                label="Alert Category"
                labelTooltipComponent={
                  <Tooltip
                    content="This is the category of the alert message"
                    direction="left"
                  />
                }
                required
                onChange={event => {
                  if (event.target.value === 'Select Alert Category') {
                    setError('AlertCategory', {
                      type: 'manual',
                      message: 'Please select the Alert Category',
                    })
                  }
                }}
                onBlur={event => {
                  if (event.target.value === 'Select Alert Category') {
                    setError('AlertCategory', {
                      type: 'manual',
                      message: 'Please select the Alert Category',
                    })
                  }
                }}
              >
                <option defaultValue="">Select Alert Category</option>
                {Object.keys(categoryMap).map(category => (
                  <option key={category} value={categoryMap[category].name}>
                    {categoryMap[category].name}
                  </option>
                ))}
              </NativeSelect>
              <p style={{ color: 'red' }}>
                {errors.AlertCategory && errors.AlertCategory.message}
              </p>
            </div>
            <div className="mb-5">
              <NativeSelect
                id="Severity"
                ref={register({ required: true })}
                name="Severity"
                label="Severity"
                labelTooltipComponent={
                  <Tooltip
                    content="This is the code denoting the severity of the subject event of the alert message"
                    direction="left"
                  />
                }
                required
                onChange={event => {
                  if (event.target.value === 'Select Severity') {
                    setError('Severity', {
                      type: 'manual',
                      message: 'Please select the Severity',
                    })
                  }
                }}
                onBlur={event => {
                  if (event.target.value === 'Select Severity') {
                    setError('Severity', {
                      type: 'manual',
                      message: 'Please select the Severity',
                    })
                  }
                }}
              >
                <option defaultValue="">Select Severity</option>
                {Object.keys(watchWEA ? weaSeverityMap : severityMap).map(severity => (
                  <option key={severity} value={severity}>
                    {severity}
                  </option>
                ))}
              </NativeSelect>
              <p style={{ color: 'red' }}>{errors.Severity && errors.Severity.message}</p>
            </div>
            <div className="mb-5">
              <NativeSelect
                id="Urgency"
                ref={register({ required: true })}
                name="Urgency"
                label="Urgency"
                labelTooltipComponent={
                  <Tooltip
                    content="This is the code denoting the urgency of the subject event of the alert message"
                    direction="left"
                  />
                }
                required
                onChange={event => {
                  if (event.target.value === 'Select Urgency') {
                    setError('Urgency', {
                      type: 'manual',
                      message: 'Please select the Urgency',
                    })
                  }
                }}
                onBlur={event => {
                  if (event.target.value === 'Select Urgency') {
                    setError('Urgency', {
                      type: 'manual',
                      message: 'Please select the Urgency',
                    })
                  }
                }}
              >
                <option defaultValue="">Select Urgency</option>
                {Object.keys(watchWEA ? weaUrgencyMap : urgencyMap).map(urgency => (
                  <option key={urgency} value={urgency}>
                    {urgency}
                  </option>
                ))}
              </NativeSelect>
              <p style={{ color: 'red' }}>{errors.Urgency && errors.Urgency.message}</p>
            </div>
            <div className="mb-5">
              <NativeSelect
                id="Certainty"
                ref={register({ required: true })}
                name="Certainty"
                label="Certainty"
                labelTooltipComponent={
                  <Tooltip
                    content="This is the code denoting the certainty of the subject event of the alert message"
                    direction="left"
                  />
                }
                required
                onChange={event => {
                  if (event.target.value === 'Select Certainty') {
                    setError('Certainty', {
                      type: 'manual',
                      message: 'Please select the Certainty',
                    })
                  }
                }}
                onBlur={event => {
                  if (event.target.value === 'Select Certainty') {
                    setError('Certainty', {
                      type: 'manual',
                      message: 'Please select the Certainty',
                    })
                  }
                }}
              >
                <option defaultValue="">Select Certainty</option>
                {Object.keys(watchWEA ? weaCertaintyMap : certaintyMap).map(certainty => (
                  <option key={certainty} value={certainty}>
                    {certainty}
                  </option>
                ))}
              </NativeSelect>
              <p style={{ color: 'red' }}>
                {errors.Certainty && errors.Certainty.message}
              </p>
            </div>
          </FormLayoutSection>
          <FormLayoutSection className="Advanced-Options" title="Advanced Options">
            {watchWEA && (
              <div className="mb-5">
                <NativeSelect
                  id="WEAHandling"
                  ref={register({ required: true })}
                  name="WEAHandling"
                  label="WEA Handling"
                  labelTooltipComponent={
                    <Tooltip
                      content="This is the code determining the type of handling required for this alert"
                      direction="left"
                    />
                  }
                  required
                  onChange={event => {
                    if (event.target.value === 'Select WEA Handling') {
                      setError('WEAHandling', {
                        type: 'manual',
                        message: 'Please select the WEA Handling',
                      })
                    }
                  }}
                  onBlur={event => {
                    if (event.target.value === 'Select WEA Handling') {
                      setError('WEAHandling', {
                        type: 'manual',
                        message: 'Please select the WEA Handling',
                      })
                    }
                  }}
                >
                  <option defaultValue="">Select WEA Handling</option>
                  {Object.keys(weaHandling).map(handle => (
                    <option key={handle} value={handle}>
                      {weaHandling[handle]}
                    </option>
                  ))}
                </NativeSelect>
                <p style={{ color: 'red' }}>
                  {errors.WEAHandling && errors.WEAHandling.message}
                </p>
              </div>
            )}
            <div className="mb-5">
              <NativeSelect
                id="EventCode"
                required
                ref={register({ required: true })}
                name="EventCode"
                label="Event Code"
                labelTooltipComponent={
                  <Tooltip
                    content="This is a system-specific code identifying the event type of the alert message"
                    direction="left"
                  />
                }
                onChange={event => {
                  if (event.target.value === 'Select Event Code') {
                    setError('EventCode', {
                      type: 'manual',
                      message: 'Please select the Event Code',
                    })
                  }
                }}
                onBlur={event => {
                  if (event.target.value === 'Select Event Code') {
                    setError('EventCode', {
                      type: 'manual',
                      message: 'Please select the Event Code',
                    })
                  }
                }}
              >
                <option defaultValue="">Select Event Code</option>
                {eventCodeKeysFilter(watchWEA, watchNWEM, watchWEAHandle).map(code => (
                  <option
                    key={code}
                    value={code}
                  >{`${code} - ${eventCodes[code].name}`}</option>
                ))}
              </NativeSelect>
              <p style={{ color: 'red' }}>
                {errors.EventCode && errors.EventCode.message}
              </p>
            </div>
            <div className="mb-5">
              <NativeSelect
                id="EventResponse"
                ref={register({ required: true })}
                name="EventResponse"
                label="Event Response"
                labelTooltipComponent={
                  <Tooltip
                    content="This is the event denoting the type of alert message"
                    direction="left"
                  />
                }
                required
                onChange={event => {
                  if (event.target.value === 'Select Event Response') {
                    setError('EventResponse', {
                      type: 'manual',
                      message: 'Please select the Event Response',
                    })
                  }
                }}
                onBlur={event => {
                  if (event.target.value === 'Select Event Response') {
                    setError('EventResponse', {
                      type: 'manual',
                      message: 'Please select the Event Response',
                    })
                  }
                }}
              >
                <option defaultValue="">Select Event Response</option>
                {Object.keys(eventResponses).map(response => (
                  <option key={response} value={response}>
                    {response}
                  </option>
                ))}
              </NativeSelect>
              <p style={{ color: 'red' }}>
                {errors.EventResponse && errors.EventResponse.message}
              </p>
            </div>
          </FormLayoutSection>
        </>
      )}
      <FormLayoutSection className="Location-Info" title="Location Info">
        {/* {FIPSList.map(fipsCode => (
            <div key={fipsCode}>
              <input
                type="checkbox"
                id={fipsCode}
                name="CountyFIPS"
                value={fipsCode}
                ref={register} // Make sure you have register function from react-hook-form
                onChange={() => selectedOptions.includes(fipsCode)}
                defaultChecked={selectedOptions.includes(fipsCode)}
              />
              <label htmlFor={fipsCode}>
                {fipsCode} - {findFipsCodeName(fipsCode)}, {findFipsCodeState(fipsCode)}
              </label>
            </div>
          ))} */}
        <div className="mb-5">
          <p className="block text-sm font-semibold text-gray-700 dark:text-gray-100">
            Validation Info:{' '}
            <span className="text-sm font-semibold text-red-500">
              {locationPoints > 100 &&
                'More than 100 points added please remove locations.'}{' '}
              {locationShapes > 10 &&
                'More than 10 shapes added please remove locations.'}
            </span>
          </p>
          <p className="text-sm font-semibold text-gray-700 dark:text-gray-100">
            {locationPoints} Points - {locationShapes} Shapes
          </p>
        </div>
        {!locationShapes && (
          <div className="px-4 py-3 bg-yellow-700 rounded-md mb-5">
            <p className="text-md font-semibold text-gray-100">
              Note: If no shape is selected, the notification will go to the entire FIPS
              Code.
            </p>
          </div>
        )}

        {/* {notificationType === 'IPAWS' && (
            //   <Input
            //     id="CountyFIPS"
            //     name="CountyFIPS"
            //     type="number"
            //     onBlur={e =>
            //       e.target.removeEventListener('wheel', function (e) {
            //         e.preventDefault()
            //       })
            //     }
            //     onFocus={e =>
            //       e.target.addEventListener(
            //         'wheel',
            //         function (e) {
            //           e.preventDefault()
            //         },
            //         { passive: false }
            //       )
            //     }
            //     label="County FIPS(s):"
            //     labelTooltipComponent={
            //       <Tooltip
            //         content="This is a 6-digit numeric code identifying the geographic area for where you want to send the alert - the 5-digit numeric code must be prefaced with an additional zero"
            //         direction="left"
            //       />
            //     }
            //     placeholder="######"
            //     required
            //     ref={register({
            //       required: true,
            //       validate: validateSixDigits,
            //     })}
            //     error={errors.FIPS ? errors.FIPS.message : ''}
            //   />
            // )}
            // {errors.CountyFIPS && (
            //   <p style={{ color: 'red' }}>{errors.CountyFIPS.message}</p>*/}
        <div className="mb-5">
          <NativeSelect
            id="CountyFIPS"
            ref={register({ required: true })}
            name="CountyFIPS"
            label="County FIPS(s):"
            labelTooltipComponent={
              <Tooltip
                content="This is a 6-digit numeric code identifying the geographic area for where you want to send the alert - the 5-digit numeric code must be prefaced with an additional zero"
                direction="left"
              />
            }
            required
            onChange={event => {
              if (event.target.value === 'Select FIPS Code') {
                setError('CountyFIPS', {
                  type: 'manual',
                  message: 'Please select the FIPS Code',
                })
              }
            }}
            onBlur={event => {
              if (event.target.value === 'Select FIPS Code') {
                setError('CountyFIPS', {
                  type: 'manual',
                  message: 'Please select the FIPS Code',
                })
              }
            }}
          >
            <option defaultValue="">Select FIPS Code</option>
            {FIPSList.map((fipsCode, index) => (
              <option key={index} value={fipsCode}>
                {fipsCode} - {findFipsCodeName(fipsCode)}, {findFipsCodeState(fipsCode)}
              </option>
            ))}
            {!FIPSList.length && (
              <option defaultValue="">No FIPS Codes. Please add in settings.</option>
            )}
          </NativeSelect>
          <p style={{ color: 'red' }}>{errors.CountyFIPS && errors.CountyFIPS.message}</p>
        </div>
        {/* <MultiSelect options={FIPSList} onSelect={handleSelect} ref></MultiSelect>
          )} */}
        <div className="flex flex-col">
          <p className="block mb-1 text-sm font-semibold text-gray-700 dark:text-gray-100">
            Choose a Geographic Location
          </p>
          <Button
            onClick={mapModalState}
            icon={<Icon className="mr-2 -ml-1" name="globe" />}
          >
            Choose Location
          </Button>
        </div>
      </FormLayoutSection>
      <FormLayoutSection className="Scheduling-Options" title="Scheduling Options">
        <div className="space-y-5">
          {notificationType === 'MAXX' && (
            <Checkbox name="ScheduleNotification" ref={register}>
              Schedule Notification for Later?
            </Checkbox>
          )}
          {watchSchedule && (
            <>
              <Input
                type="datetime-local"
                id="ScheduleDate"
                name="ScheduledDate"
                ref={register}
                placeholder="mm/dd/yyyy hh/mm PM"
                label="Scheduled Date"
                onBlur={e =>
                  e.target.removeEventListener('wheel', function (e) {
                    e.preventDefault()
                  })
                }
                onFocus={e =>
                  e.target.addEventListener(
                    'wheel',
                    function (e) {
                      e.preventDefault()
                    },
                    { passive: false }
                  )
                }
              />
              <Checkbox name="ScheduleHide" ref={register}>
                Schedule Hide?
              </Checkbox>
              {watchScheduleHide && (
                <Input
                  type="datetime-local"
                  id="ScheduleHideDate"
                  name="ScheduledHideDate"
                  ref={register}
                  placeholder="mm/dd/yyyy hh/mm AM"
                  label="Scheduled Hide"
                  onBlur={e =>
                    e.target.removeEventListener('wheel', function (e) {
                      e.preventDefault()
                    })
                  }
                  onFocus={e =>
                    e.target.addEventListener(
                      'wheel',
                      function (e) {
                        e.preventDefault()
                      },
                      { passive: false }
                    )
                  }
                />
              )}
              <Checkbox name="ScheduleRecurring" ref={register}>
                Is this a recurring Notification?
              </Checkbox>
              {watchRecurring && (
                <NativeSelect id="Frequency" name="Frequency" label="Frequency">
                  <option value="Does Not Repeat">Does Not Repeat</option>
                  <option value="Daily">Daily</option>
                  <option value="Weekly">Weekly</option>
                  <option value="Monthly">Monthly</option>
                  <option value="Weekdays">Weekdays</option>
                  <option value="Weekends">Weekends</option>
                </NativeSelect>
              )}
            </>
          )}

          <div className="grid grid-cols-1 sm:grid-cols-2 sm:gap-x-4 sm:gap-y-0 gap-y-1">
            <div className="mb-1 sm:col-span-2">
              <div className="inline-flex justify-between w-full">
                <h3>Expires in</h3>
                <Tooltip
                  content="This is the expire time of the information of the alert message."
                  direction="left"
                />
              </div>
            </div>
            <Input
              id="ExpiresInHours"
              name="ExpiresInHours"
              type="number"
              label="Hours"
              placeholder=""
              required
              onBlur={e =>
                e.target.removeEventListener('wheel', function (e) {
                  e.preventDefault()
                })
              }
              onFocus={e =>
                e.target.addEventListener(
                  'wheel',
                  function (e) {
                    e.preventDefault()
                  },
                  { passive: false }
                )
              }
              error={errors.ExpiresInHours ? errors.ExpiresInHours.message : ''}
              ref={register({
                required: true,
                min: {
                  value: 0,
                  message: 'The hours value must be greater than or equal to 0.',
                },
                // max: {
                //   value: 24,
                //   message: 'The hours value must be less than or equal to 24.',
                // },
                pattern: {
                  value: /^-?\d+$/,
                  message: 'This must be a whole number.',
                },
              })}
            />
            <NativeSelect
              id="ExpiresInMinutes"
              name="ExpiresInMinutes"
              label="Minutes"
              required
              ref={register({ required: true })}
            >
              <option value={0}>0</option>
              <option value={15}>15</option>
              <option value={30}>30</option>
              <option value={30}>45</option>
            </NativeSelect>
            {errors.ExpiresInMinutes && (
              <p style={{ color: 'red' }}>{errors.ExpiresInMinutes.message}</p>
            )}
          </div>
        </div>
      </FormLayoutSection>
    </>
  )
}

export default FormData
  // useEffect(() => {
  //   setIsLoading(true);
  //   setTimeout(() => {
  //     if (fromWillPreview && isSpouseSelected) {
  //       // From WillPreview of Spouse
  //       setList(
  //         steps.filter((s: any) => s.bookedForProfileGuid === profileGuid),
  //       ); // List should contain incomplete steps of Main Testator
  //       // setIsLoading(false);
  //     }

  //     if (fromUploadDocs) {
  //       const guid = isSpouseSelected ? spouseGuid : profileGuid;
  //       setList(steps.filter((s: any) => s.bookedForProfileGuid === guid));
  //       // setIsLoading(false);
  //     }

  //     if (fromWillPreview && !isSpouseSelected) {
  //       // From WillPreview of Main Testator
  //       setList(
  //         steps.filter((s: any) => s.bookedForProfileGuid === spouseGuid),
  //       ); // List should contain incomplete steps of spouse
  //       // setIsLoading(false);
  //     }
  //     setIsLoading(false);
  //   }, 2000);
  // }, [steps, isSpouseSelected, fromWillPreview, fromUploadDocs]);

  // useEffect(() => {
  //   setIsLoading(true);
  //   setTimeout(() => {
  //     if (fromWillPreview && isSpouseSelected) {
  //       // From WillPreview of Spouse
  //       setList(
  //         steps.filter((s: any) => s.bookedForProfileGuid === profileGuid),
  //       ); // List should contain incomplete steps of Main Testator
  //     }
  //     setIsLoading(false);
  //   }, 2000);
  // }, [steps, fromWillPreview, isSpouseSelected]);

  // // Incomplete steps listing from submit button in Modify Appointment
  // useEffect(() => {
  //   setTimeout(() => {
  //     setList(
  //       steps.filter((s: any) => (s.bookedForProfileGuid === isSpouseSelected ? spouseGuid : profileGuid)),
  //     );
  //   }, 1000);
  // }, [steps, isSpouseSelected]);

  // ---------------------------->>>

  // useEffect(() => {
  //   if (fromWillPreview && !isSpouseSelected) { // From WillPreview of Main Testator
  //     setTimeout(() => {
  //       setList(steps?.filter((s: any) => s.bookedForProfileGuid === spouseGuid)); // List should contain incomplete steps of spouse
  //     }, 1000);
  //   }
  // }, [steps, fromWillPreview, isSpouseSelected]);

  // useEffect(() => {
  //   if (fromUploadDocs) {
  //     const guid = isSpouseSelected ? spouseGuid : profileGuid;
  //     setList(
  //       steps.filter((s: any) => (s.bookedForProfileGuid === guid)),
  //     );
  //   }
  // }, [steps, fromUploadDocs, isSpouseSelected]);
  // ------------NewChanges --------------------------------
      // DW ==> allow navigation if incomplete steps list is empty ==> only in GuardianShip and Full Will
      // if (id === 13 && (willTypeID === FULL_WILL || willTypeID === GUARDIANSHIP_WILL)) {
      //   const steps = await dispatch<any>(fetchAllIncompleteWillsSteps(profileGuid, spouseGuid, serviceId));
      //   if (steps.length === 0) {
      //     dispatch(setHighlightedSteps(getDraftWillStepNumber()));
      //     dispatch(setNavigationIndex(getDraftWillStepNumber()));
      //     dispatch(getNewActiveStep(13));
      //   }
      // }

      // /**
      //  * WILL PREVIEW
      //  * if fullWill || Guardianshipwill => allow navigation to Will Preview if only Draft Will is completed else allow navigation if incomplete steps list is empty
      //  */
      // if (id === 21) {
      //   const steps = await dispatch<any>(fetchAllIncompleteWillsSteps(profileGuid, spouseGuid, serviceId));
      //   if (willTypeID === FULL_WILL || willTypeID === GUARDIANSHIP_WILL) {
      //     if (steps.length === 0 && completedStepNumArray.includes(getDraftWillStepNumber())) {
      //       dispatch(setHighlightedSteps(getWillPreviewStepNumber()));
      //       dispatch(setNavigationIndex(getWillPreviewStepNumber()));
      //       dispatch(getNewActiveStep(21));
      //     } else {
      //       await dispatch<any>(resetErrorState());
      //       await dispatch<any>(setErrorInfo('Please complete Draft will to reach to Will Preview'));
      //     }
      //   }

      //   // All other willTypes
      //   if (willTypeID === PROPERTY_WILL
      //     || willTypeID === BUISINESS_OWNERS_WILL
      //     || willTypeID === FINANCIAL_ASSETS_WILL
      //     || willTypeID === TEMPLATED_FULL_WILL) {
      //     if (steps.length === 0) {
      //       dispatch(setHighlightedSteps(getWillPreviewStepNumber()));
      //       dispatch(setNavigationIndex(getWillPreviewStepNumber()));
      //       dispatch(getNewActiveStep(21));
      //     } else {
      //       await dispatch<any>(resetErrorState());
      //       await dispatch<any>(setErrorInfo('Please complete all steps to preview the will'));
      //     }
      //   }
      // }

      // // Book Appointment ==> allow navigation only if will preview is completed
      // if (id === 9) {
      //   const steps = await dispatch<any>(fetchAllIncompleteWillsSteps(profileGuid, spouseGuid, serviceId));
      //   const condition = steps.length === 0 && completedStepNumArray.includes(getWillPreviewStepNumber());
      //   console.log('step condition', condition);
      //   if (condition) {
      //     dispatch(setHighlightedSteps(getBookAppointmentStepNumber()));
      //     dispatch(setNavigationIndex(getBookAppointmentStepNumber()));
      //     dispatch(getNewActiveStep(9));
      //   } else {
      //     await dispatch<any>(resetErrorState());
      //     await dispatch<any>(setErrorInfo('Please complete all steps to book appointment'));
      //   }
      // }

      // // Payment ==> allow navigation only if book appointment is completed
      // if (id === 10) {
      //   const steps = await dispatch<any>(fetchAllIncompleteWillsSteps(profileGuid, spouseGuid, serviceId));
      //   if (steps.length === 0 && completedStepNumArray.includes(getBookAppointmentStepNumber())) {
      //     dispatch(setHighlightedSteps(getBookAppointmentStepNumber()));
      //     dispatch(setNavigationIndex(getBookAppointmentStepNumber()));
      //     dispatch(getNewActiveStep(10));
      //   }
      // }
      // ------------------New Changes --------------------------------

      // -------------------------------Validations in stepper for all willtypes--------------------------------
      // Will Preview navigation in stepper
      // if (id === 21 && isShowBookAppointment) {
      //   dispatch(setHighlightedSteps(getWillPreviewStepNumber()));
      //   dispatch(setNavigationIndex(getWillPreviewStepNumber()));
      //   dispatch(getNewActiveStep(21));
      // } else if (id === 21 && !isShowBookAppointment) {
      //   // Prevent navigation to will preview if all steps are not completed
      //   dispatch(setHighlightedSteps(highlightedStep));
      //   dispatch(setNavigationIndex(highlightedStep));
      //   dispatch(getNewActiveStep(newActiveStep));
      //   await dispatch<any>(resetErrorState());
      //   await dispatch<any>(setErrorInfo('Please complete all steps to proceed!'));
      // }

      /**
       * Navigation to Book Appointment only if isShowBookAppointment = true && draftWill() && WillPreview Completed
       */
      // if (id === 9 && isShowBookAppointment) {
      //   const { testatorSteps } = await getIncompleteStepsList(
      //     profileGuid,
      //     spouseGuid,
      //     profileGuid,
      //     serviceId,
      //   );

      //   if (testatorSteps.length === 0) {
      //     dispatch(setHighlightedSteps(getBookAppointmentStepNumber()));
      //     dispatch(setNavigationIndex(getBookAppointmentStepNumber()));
      //     dispatch(getNewActiveStep(9));
      //   } else {
      //     await dispatch<any>(resetErrorState());
      //     await dispatch<any>(setErrorInfo('Please complete all steps to proceed!'));
      //   }
      // } else if (id === 9 && !isShowBookAppointment) {
      //   await dispatch<any>(resetErrorState());
      //   await dispatch<any>(setErrorInfo('Please complete all steps to proceed!'));
      // }

      // Navigate to payment only if book appointment is completed and isShowBookAppointment === true
      // if (id === 10 && bookAppointmentCompleted && isShowBookAppointment) {
      //   dispatch(setHighlightedSteps(getPaymentStepNumber()));
      //   dispatch(setNavigationIndex(getPaymentStepNumber()));
      //   dispatch(getNewActiveStep(10));
      // }
      // -------------------------------Validations in stepper --------------------------------
/* eslint-disable func-names */
/* eslint-disable no-param-reassign */
/* eslint-disable no-return-assign */
/* eslint-disable no-alert */
/* eslint-disable no-unreachable-loop */
/* eslint-disable no-restricted-syntax */
/* eslint-disable no-dupe-else-if */
/* eslint-disable @typescript-eslint/no-use-before-define */
/* eslint-disable no-confusing-arrow */
/* eslint-disable no-nested-ternary */
/* eslint-disable no-fallthrough */
/* eslint-disable consistent-return */
/* eslint-disable @typescript-eslint/no-shadow */
/* eslint-disable @typescript-eslint/no-unused-expressions */
/* eslint-disable react/no-unstable-nested-components */
/* eslint-disable @typescript-eslint/comma-spacing */
/* eslint-disable array-callback-return */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable react/no-unstable-nested-components */
/* eslint-disable react/prop-types */
/* eslint-disable max-len */
/* eslint-disable react/no-array-index-key */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable react/destructuring-assignment */
import * as React from 'react';
import './styles.scss';
// MUI imports
import { styled } from '@mui/material/styles';
import Stack from '@mui/material/Stack';
import Stepper from '@mui/material/Stepper';
import Step from '@mui/material/Step';
import StepLabel from '@mui/material/StepLabel';
import StepDoneIcon from '@mui/icons-material/Done';
import StepConnector, {
  stepConnectorClasses,
} from '@mui/material/StepConnector';
import { StepIconProps } from '@mui/material/StepIcon';
// import Button from '@mui/material/Button';
// import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';

// Package imports
import {
  useParams, useNavigate, useLocation, Navigate,
} from 'react-router';
import { useSelector, useDispatch } from 'react-redux';
import { Modal, Button } from 'react-bootstrap';
import { trackPromise } from 'react-promise-tracker';

// Redux Reducers import
import {
  WillStepState,
  fetchWillStepList,
  willStepSelector,
} from '@redux/slices/wills-steps-list';
import {
  WillBeneficiaryShareStateaftersave,
  fetchWillBeneficiaryShareStateaftersave,
  willBeneficiaryShareListSelector,
} from '@redux/slices/wills-getbeneficiary-sharelist';
import {
  WillBeneficiaryState,
  fetchWillBeneficiaryState,
  willBeneficiaryListSelector,
} from '@redux/slices/wills-shares-estate';
import {
  WillBeneficiaryShareState,
  fetchGetAllPropertyDetailsDetailsByProfileID,
  willBeneficiaryListShareSelector,
  fetchGetBeneficiaryShareList,
} from '@redux/slices/wills-specific-estate';
import {
  fetchPersonalInformationByGuid,
  getServiceId,
  resetErrorState,
  setErrorInfo,
  setIsSpouseSelected,
  setShowSpouseDetails,
  setTestatorName,
  willPersonalInformationSelector,
} from '@redux/slices/will-personal-information';
import {
  WillBookState,
  fetchWillBookState,
  willBookSelector,
} from '@redux/slices/wills-book-appointment';

import {
  WillSubstituteBeneficiaryState,
  fetchWillSubsitituteBeneficiaryState,
  willSubstituteBeneficiaryListSelector,
} from '@redux/slices/will-substitute-beneficiarylist';

import {
  checkMirrorWillSelected,
  checkSingleWillSelected,
  checkVirtualSelected,
  clearSelectedDistribution,
  clearSelectedWillType,
  disableNavigation,
  fetchIncompleteSteps,
  getIncompleteSteps,
  getNewActiveStep,
  setCompletedStepList,
  setCompletedSteps,
  setHighlightedSteps,
  setHusbandCompletedSteps,
  setIsChangeService,
  setIsCompleteWillInfo,
  setIsTestatorStepsCompleted,
  setIsUpgradeWill,
  setNavigationIndex,
  setShowIncompleteStepsModal,
  setSpouseCompletedSteps,
  setStepFlow,
  setWillPreviewCompleted,
  setWillTypeID,
  storeActiveStep,
  willsValidatorSelector,
} from '@redux/slices/willsValidator';
import {
  setPropertyAdded,
  willRealEstateSelector,
} from '@redux/slices/will-realEstate';
import { setBeneficiaryAdded, willBeneficiaryDataSelector } from '@redux/slices/wills-beneficiary-details';
import { clearState } from '@redux/reducers/actions';

import {
  fetchActiveServices,
  fetchLawyerDraftWills,
  setIsModifyWill,
  setModifyAppointment,
  willActiveServiceSelector,
} from '@redux/slices/will-active-service';
import {
  setFromWillPreview,
  willPreviewSelector,
} from '@redux/slices/will-preview';
import {
  setFromUploadDocs,
  willDocumentUploadSelector,
} from '@redux/slices/will-documents-upload';
import { willAccountInformationSelector } from '@redux/slices/wills-financial-Accounts';
import { willCompanyShareInformationSelector } from '@redux/slices/will-company-share-information';

// Assets Import
import tickIcon from '@assets/tick.svg';
import closeIcon from '@assets/Group 151.svg';
import sticker from '@assets/Rectangle 786.png';

// Components Import
import WillTypeSelection from '@components/WillTypeSelection';
import WillPayment from '@components/WillPayment';
import WillRealEstateDetail from '@components/WillRealEstateDetail';
import WillBookAppointment from '@components/WillBookAppointment';
import CompanyShareInfo from '@components/CompanyShareInfo';
import RegistrationStepper from '@components/RegistrationStepper';
import WillBeneficiaryDetail from '@components/WillBeneficiaryDetail';
import WillsMinorChildren from '@components/WillsMinorChildern';
import WillExecutorDetail from '@components/WillExecutorDetail';
import WillRealEstateDistribution from '@components/WillRealEstateDistribution';
import WillBySpecificRealEstate from '@components/WillBySpecificRealEstate';
import WillBySpecificRealEstateBusinessOwners from '@components/WillBySpecificRealEstateBusinessOwners';
import WillBySpecificRealEstateFinancialAssets from '@components/WillBySpecificRealEstateFinancialAssets';
import WillBySharesOfEstate from '@components/WillBySharesOfEstate';
import DocumentManager from '@components/DocumentManager';
import WillPersonalInformation from '@components/WillPersonalInformation';
import WillDraftDetail from '@components/WillDraftDetail';
import WillWitnessDetails from '@components/WillWitnessDetails';
import WillInterimGuardianDetail from '@components/WillInterimGuardianDetail';
import WillGuardianDetail from '@components/WillGuardianDetail';
import WillGuardianInformation from '@components/WillGuardianInformation';
import AccountsInformation from '@components/AccountsInformation';
import MovableAndImmovableProperty from '@components/MovableAndImmovableProperty';
import WillLocationTypeSelection from '@components/WillLocationTypeSelection';
import WillPreview from '@components/WillPreview';
import ScaffoldingIcons from '@components/ScaffoldingIcons';
import QuickBookingWarningModal from '@components/QuickBookingWarningModal';
import { dropDownSelector } from '@redux/slices/dropDowns';
import { willPaymentDetailSelector } from '@redux/slices/will-payment-detail';
import {
  BUISINESS_OWNERS_WILL, FINANCIAL_ASSETS_WILL, FULL_WILL, GUARDIANSHIP_WILL, PROPERTY_WILL, TEMPLATED_FULL_WILL,
} from '@utils/config';
import useWillsIncompleteSteps from '@utils/hooks/useWillsIncompleteSteps';
import getIncompleteStepsList from '@utils/getIncompleteSteps';
import getThirdStepName from '@utils/getThirdStepName';
import useHandleReload from '@utils/hooks/useHandleReload';
import useWillsCompletedSteps from '@utils/hooks/useWillsCompletedSteps';
import { loginSelector } from '@redux/slices/login-flow';
import IncompleteStepsModal from './incompleteStepsModal';
// API
import api from '../../api';

// import DeleteConfirmationModal from '@components/DeleteConfirmationModal';
const DeleteConfirmationModal = React.lazy(
  () => import('@components/DeleteConfirmationModal'),
);

const ColorlibConnector = styled(StepConnector)(({ theme }) => ({
  [`&.${stepConnectorClasses.alternativeLabel}`]: {
    top: 22,
  },
  [`&.${stepConnectorClasses.active}`]: {
    [`& .${stepConnectorClasses.line}`]: {
      height: 3,
      border: 0,
      backgroundColor:
        theme.palette.mode === 'dark' ? theme.palette.grey[800] : '#eaeaf0',
      borderRadius: 1,
    },
  },
  [`&.${stepConnectorClasses.completed}`]: {
    [`& .${stepConnectorClasses.line}`]: {
      height: 3,
      border: 0,
      backgroundColor:
        theme.palette.mode === 'dark' ? theme.palette.grey[800] : '#eaeaf0',
      borderRadius: 1,
    },
  },
  [`& .${stepConnectorClasses.line}`]: {
    height: 3,
    border: 0,
    backgroundColor:
      theme.palette.mode === 'dark' ? theme.palette.grey[800] : '#eaeaf0',
    borderRadius: 1,
  },
}));

const ColorlibStepIconRoot = styled('div')<{
  ownerState: { completed?: boolean; active?: boolean };
}>(({ theme, ownerState }) => ({
  backgroundColor:
    theme.palette.mode === 'dark' ? theme.palette.grey[700] : '#1B202D',
  zIndex: 1,
  color: '#fff',
  width: 60,
  height: 60,
  display: 'flex',
  borderRadius: '50%',
  justifyContent: 'center',
  alignItems: 'center',
  // marginRight: (ownerState.completed || ownerState.active) ? 327 : 0,
  ...(ownerState.active && {
    backgroundColor: '#023979',
    boxShadow: '0 4px 10px 0 rgba(0,0,0,.25)',
  }),
  ...(ownerState.completed && {
    backgroundColor: '#3ECDAB',
  }),
}));

function ColorlibStepIcon(
  props: StepIconProps & {
    stepNumber: Array<number>;
    currentIndex: number;
    data: Array<string>;
  },
) {
  // , data: Array<string>, currentIndex: number
  const {
    active, completed, className, currentIndex, stepNumber, icon, data,
  } = props;
  // console.log('props',props);
  const { currentStep } = useSelector(willsValidatorSelector);

  const selectedNum = currentIndex - 1;

  // console.log('currentIndex', currentIndex);
  // console.log('stepNumber', stepNumber);

  // console.log('currentStep from selector in custom comp', currentStep);

  const icons: { [index: string]: React.ReactElement | any } = {
    1: completed ? <StepDoneIcon /> : null,
    2: completed ? <StepDoneIcon /> : null,
    3: completed ? <StepDoneIcon /> : null,
    4: completed ? <StepDoneIcon /> : null,
    5: completed ? <StepDoneIcon /> : null,
    6: completed ? <StepDoneIcon /> : null,
    7: completed ? <StepDoneIcon /> : null,
    8: completed ? <StepDoneIcon /> : null,
    9: completed ? <StepDoneIcon /> : null,
    10: completed ? <StepDoneIcon /> : null,
    11: completed ? <StepDoneIcon /> : null,
    12: completed ? <StepDoneIcon /> : null,
    13: completed ? <StepDoneIcon /> : null,
    14: completed ? <StepDoneIcon /> : null,
    15: completed ? <StepDoneIcon /> : null,
    16: completed ? <StepDoneIcon /> : null,
  };

  return (
    <ColorlibStepIconRoot
      ownerState={{ completed, active }}
      className={className}
    >
      {icons[String(props.icon)] ? icons[String(icon)] : icon}
    </ColorlibStepIconRoot>
  );
}
export interface CustomizedSteppersProps {
  data: Array<string>;
  currentIndex: number;
  setCurrentIndex: React.Dispatch<React.SetStateAction<number>>;
}

// eslint-disable-next-line max-len, react/function-component-definition
const CustomizedSteppers: React.FC<CustomizedSteppersProps> = () => {
  const [activeStep, setActiveStep] = React.useState(0);
  const [skipped, setSkipped] = React.useState(new Set<number>());
  // const [completedSteps, setCompletedSteps] = React.useState([]);
  const [num1, setNum1] = React.useState(0);
  const [num2, setNum2] = React.useState(1);
  const [currentBtnStep, setCurrentBtnStep] = React.useState<number>();
  const [iconNum1, setIconNum1] = React.useState(0);
  const [iconNum2, setIconNum2] = React.useState(3);
  const [childData, setChildData] = React.useState('');
  const [childData1, setChildData1] = React.useState('');
  const [currentIndex, setCurrentIndex] = React.useState(0);
  const [data, setdata] = React.useState<string>();
  const [newCompletedSteps, setNewCompletedSteps] = React.useState([]);
  // const [incompleteSteps, setIncompleteSteps] = React.useState([]);
  const [isShowBookAppointment, setIsShowBookAppointment] = React.useState(false);
  const [currentSelectedStep, setCurrentSelectedStep] = React.useState<number>(null);
  // Will Preview Reached
  const [willPreviewReached, setWillPreviewReached] = React.useState<boolean>(false);
  // Skip to bookAppointment flag
  const [showSkipToAppointmentModal, setShowSkipToAppointmentModal] = React.useState<boolean>(false);
  const [stepLabel, setStepLabel] = React.useState([]);
  // Steps to map in the modal (incomplete steps)
  const [steps, setSteps] = React.useState<any>([]);
  const [spouseIncomplete, setSpouseIncomplete] = React.useState<any>([]);
  const [husbandIncomplete, setHusbandIncomplete] = React.useState<any>([]);
  const [show, setShow] = React.useState<boolean>(false);

  // Router Navigation
  const navigate = useNavigate();
  const { state } = useLocation();
  console.log('state', state);

  // Params
  const { parameterGuid } = useParams();
  // Will type ID (For identifying willTypes)
  // const willTypeID = Number(parameterGuid);

  // Dispatch actions using dispatch
  const dispatch = useDispatch();

  // Store Subscriptions
  const {
    mirrorWillCheck,
    singleWillCheck,
    currentStep,
    newActiveStep,
    navigationEnabled,
    navigationIndex,
    isQuickBooking,
    guardianShipWill,
    byShareCheck,
    bySpecificCheck,
    isVirtual,
    isInPerson,
    incompleteSteps,
    spouseCompletedSteps,
    husbandCompletedSteps,
    willPreviewCompleted,
    isCompleteWillInfo,
    isChangeService,
    willTypeID, // Will type ID (For identifying willTypes)
    isUpgradeWill,
    showIncompleteStepsModal,
    highlightedStep,
    distributionCompleted,
    isMirrorWill,
  } = useSelector(willsValidatorSelector);

  // Will Personal Informations
  const {
    profileGuid, isSpouseSelected, spouseGuid, serviceId,
  } = useSelector(
    willPersonalInformationSelector,
  );

  // User loggedIn Slice
  const { userData } = useSelector(loginSelector);

  const { lawyerDraftWills } = useSelector(willActiveServiceSelector);

  // Step List
  const { results, loading, hasErrors } = useSelector<unknown, WillStepState>(
    willStepSelector,
  );

  // States to handle incompleteSteps Modal
  const { fromWillPreview } = useSelector(willPreviewSelector);
  const { fromUploadDocs,isDocumentsChanged } = useSelector(willDocumentUploadSelector);

  // Active service
  const { activeService, isModifyWill, modifyAppointment } = useSelector(
    willActiveServiceSelector,
  );

  // Distribution of Shares Enabling conditions
  const { propertyAdded, propertyList, isPropertyChanged } = useSelector(
    willRealEstateSelector,
  );
  const { beneficiaryAdded, isBeneficiaryChanged,beneficiaryList } = useSelector(
    willBeneficiaryDataSelector,
  );

  const { accountList, isaddAccountInformation } = useSelector(
    willAccountInformationSelector,
  );
  const { companyShareInformationList, isCompanyShareInformationChanged } = useSelector(willCompanyShareInformationSelector);

  const { selectedEmiratesList } = useSelector(dropDownSelector);

  const { handleRedirectEvent } = useSelector(willPaymentDetailSelector);

  const willTypeNumber = localStorage.getItem('willTypeID');
  const willTypeId = Number(willTypeNumber);

  const handleChildData = (data: string) => {
    setChildData(data);
  };
  const handleDataFromChild = (data: string) => {
    setChildData1(data);
  };
  const [showModal, setShowModal] = React.useState(false);
  const [draftSActiveService, setDraftSActiveService] = React.useState<any>([]);

  console.log('draftSActiveService', draftSActiveService);

  React.useEffect(() => {
    switch (activeService?.length) {
      case 2:
        // There is a modify will service available in active services
        setDraftSActiveService(activeService[1]);
        break;
      case 1:
        // There is only one active service in active services API
        setDraftSActiveService(activeService[0]);
        break;
      default:
      // Do nothing
    }
  }, [activeService]);

  // Custom hook to handle Reload when on forms => Wills,Registrations,Cases etc
  useHandleReload(activeService,'/wills');

  /**
   * Handles showing the incomplete steps modal.
   *
   * @param {string} stepName - The name of the step.
   * @return {void} This function does not return anything.
   */
  const handleShowIncompleteStepsModal = (stepName?: string): void => {
    setShowModal(true);
  };

  /**
   * Handles closing of the incomplete steps modal.
   *
   * @return {void} This function does not return anything.
   */
  const handleCloseModal = (): void => {
    setShowModal(false);
    dispatch(setShowIncompleteStepsModal(false));
  };

  const isStepSkipped = (step: number) => skipped.has(step);

  /**
   * Retrieves the list of completed steps for a given user profile.
   *
   * @return {Promise<void>} This function does not return anything.
   */
  const getCompletedSteps = React.useCallback(async () => {
    const completedSteps = await trackPromise(
      api.getCompletedStepsListByGUID(
        isSpouseSelected ? spouseGuid : profileGuid,
      ),
    );
    const completedStepNumbers = completedSteps?.data?.Output;
    const steps = completedStepNumbers.map((stepNumber: any) => Number(stepNumber.stepNumber));
    setNewCompletedSteps(steps);
  }, [isSpouseSelected, spouseGuid, profileGuid]);

  React.useEffect(() => {
    const condition = willTypeID === TEMPLATED_FULL_WILL || willTypeID === FINANCIAL_ASSETS_WILL || willTypeID === PROPERTY_WILL || willTypeID === BUISINESS_OWNERS_WILL;
    if (condition) {
      if (newCompletedSteps.includes(3) && newCompletedSteps.includes(5)) {
        dispatch(setPropertyAdded(true));
        dispatch(setBeneficiaryAdded(true));
      } else {
        dispatch(setPropertyAdded(false));
        dispatch(setBeneficiaryAdded(false));
      }
    }
  },[newCompletedSteps,willTypeID]);

  // Clear all states here (global && local)
  // Page Mount LifeCycle
  React.useEffect(() => {
    dispatch<any>(fetchActiveServices());
    window.scrollTo(0, 0);
    dispatch(clearState());
    // dispatch(storeActiveStep(0));
    // Set activeStep (stepID) === 1(willTypeSelection) on initial page mount
    dispatch(getNewActiveStep(1));
    dispatch(clearSelectedWillType());
    // Set Default step as will type selection
    dispatch(storeActiveStep(0));
    // Set highlighted step to 1
    dispatch(setHighlightedSteps(1));
    dispatch(resetErrorState());
    setNewCompletedSteps([]);
    window.addEventListener('popstate', () => {
      window.location.reload();
    });

    return () => {
      window.removeEventListener('popstate', () => console.log('listner removed'));
      // setNewCompletedSteps([]);
    };
  }, []);

  // If user is a draftsman fetch draftsman details here
  React.useEffect(() => {
    if (userData.DraftsmanGuid) {
      dispatch<any>(fetchLawyerDraftWills());
    }
  },[userData]);

  //  if the selected lawyer from the Draftman list is mirrorWill then set the mirrorwill flag to true
  React.useEffect(() => {
    setTimeout(() => {
      if (isMirrorWill) {
        dispatch(checkMirrorWillSelected());
      }
    },100);
  },[]);

  // Redirect to wills page if the dummy url is entered by the user
  React.useEffect(() => {
    if (state === null) {
      navigate('/wills');
    }
  }, [state]);

  // Fetch completedSteps each time the switcher is changed or Beneficiary or (account/property/company) is added || removed && if document is uploaded or removed (in any case)
  const getCompletedStepsCallback = React.useCallback(() => getCompletedSteps(), [
    isSpouseSelected,
    isBeneficiaryChanged,
    isPropertyChanged,
    isCompanyShareInformationChanged,
    isaddAccountInformation,
    isDocumentsChanged,
  ]);

  React.useEffect(() => {
    getCompletedStepsCallback();
  }, [getCompletedStepsCallback]);

  // If accountList is present && propertyList is present && companyShareInformationList is present ==> enable condition to allow Distribution Of Shares/Accounts
  React.useEffect(() => {
    if (
      accountList?.length !== 0
      || propertyList?.length !== 0
      || companyShareInformationList?.length !== 0
      || selectedEmiratesList?.length !== 0
    ) {
      dispatch(setPropertyAdded(true));
    } else {
      dispatch(setPropertyAdded(false));
    }
  }, [accountList, propertyList, companyShareInformationList,selectedEmiratesList]);

  React.useEffect(() => {
    if (beneficiaryList.length > 0) {
      dispatch(setBeneficiaryAdded(true));
    } else {
      dispatch(setBeneficiaryAdded(false));
    }
  },[beneficiaryList]);

  // If stepNumber === 3 OR 5 is not present in completedSteps response && activeStep === Distribution Of Shares ==> TODO ==> Redirection to any other step ?
  React.useEffect(() => {
    if (
      (!newCompletedSteps.includes(3) || !newCompletedSteps.includes(5))
      && (newActiveStep === 18 || newActiveStep === 6)
    ) {
      setShow(true);
      // const result = window.confirm('Please complete accounts/property/company && beneficiary steps');
      // if (result) {
      //   // Navigate to step 4 for now ==> change later on
      //   dispatch(setHighlightedSteps(5));
      //   dispatch(setNavigationIndex(5));
      //   dispatch(getNewActiveStep(5));
      // } else {
      //   dispatch(setHighlightedSteps(5));
      //   dispatch(setNavigationIndex(5));
      //   dispatch(getNewActiveStep(5));
      // }
    }
  }, [newCompletedSteps, newActiveStep]);

  // If activeServices present && changeService is true && has willTypeID ==> set willTypeID from activeServices here
  React.useEffect(() => {
    if (isChangeService && draftSActiveService?.willTypeID) {
      dispatch(setWillTypeID(draftSActiveService?.willTypeID));
    }
  }, [activeService, isChangeService]);

  // Set willtypeID here if lawyerDetails have willtypeID and changeService is true ==>  to change dynamically
  // React.useEffect(() => {
  //   if (isChangeService && lawyerDraftWills[0]?.willTypeID) {
  //     dispatch(setWillTypeID(lawyerDraftWills[0]?.willTypeID));
  //   }
  // },[lawyerDraftWills]);

  /**
   * Handles Complete Will Info Functionality
   *
   * @return {Promise<void>} A promise that resolves when the function completes.
   */
  const handleCompleteWillInfo = async (): Promise<void> => {
    try {
      // Get Completed Steps list and enable tick mark condition in the stepper
      await getCompletedSteps();
      // dispatch(setShowSpouseDetails(false));

      const {
        stepID,stepNumber,steps,testatorSteps,spouseSteps,
      } = await getIncompleteStepsList(
        profileGuid,
        spouseGuid,
        isSpouseSelected ? spouseGuid : profileGuid,
        serviceId,
      );
      console.log('totalSteps',steps);
      console.log('spouseSteps',spouseSteps);
      console.log('testatorSteps',testatorSteps);
      // dispatch(setIsSpouseSelected(!!spouseSteps)); need clarity here

      const getStepID = () => testatorSteps.length > 0 ? testatorSteps[0].stepID : spouseSteps[0].stepID;

      const getStepNumber = () => testatorSteps.length > 0 ? Number(testatorSteps[0].stepNumber) : Number(spouseSteps[0].stepNumber);

      if (steps?.length === 0) {
        if (willTypeID === 1) {
          // Full Will
          dispatch(getNewActiveStep(9)); // Book Appointment
          dispatch(setHighlightedSteps(11));
          dispatch(setNavigationIndex(11));
        } else if (willTypeID === 2) {
          // GuardianShip Will
          dispatch(getNewActiveStep(9)); // Book Appointment
          dispatch(setHighlightedSteps(9));
          dispatch(setNavigationIndex(9));
        } else {
          // All other wills
          dispatch(getNewActiveStep(21)); // Will Preview
          dispatch(setHighlightedSteps(9));
          dispatch(setNavigationIndex(9));
        }
      } else {
        /* use this condition to check spouseGUID is present in activeServices Mirror Will
         * if Not ==> redirect all navigation to Personal Details step
         * else ==> redirect to first incomplete step as normal */
        const condition = draftSActiveService?.isMirrorWill
          && draftSActiveService?.spouseProfileGUID === null;
        console.log('draftSActiveServiceincompletewillinfo',draftSActiveService);

        if (singleWillCheck) {
          dispatch(getNewActiveStep(condition ? 2 : getStepID()));
          dispatch(setHighlightedSteps(condition ? 2 : getStepNumber()));
          dispatch(setNavigationIndex(condition ? 2 : getStepNumber()));
        } else if (mirrorWillCheck) {
          dispatch(setIsSpouseSelected(testatorSteps.length === 0));
          dispatch(getNewActiveStep(spouseGuid === null ? 2 : getStepID()));
          dispatch(setHighlightedSteps(spouseGuid === null ? 2 : getStepNumber()));
          dispatch(setNavigationIndex(spouseGuid === null ? 2 : getStepNumber()));
        }
      }
    } catch (error) {
      dispatch(resetErrorState());
      dispatch(setErrorInfo('Some Error occured !'));
    }
  };

  const handleChangeService = async () => {
    dispatch<any>(fetchActiveServices());
    dispatch(setIsCompleteWillInfo(false));
    dispatch(getNewActiveStep(2));
    dispatch(setHighlightedSteps(2));
    dispatch(setNavigationIndex(2));
    // Get Completed Steps list and enable tick mark condition in the stepper
    await getCompletedSteps();
  };

  const handleUpgradeWill = async () => {
    // dispatch(storeActiveStep(1));
    dispatch(setHighlightedSteps(2));
    dispatch(setNavigationIndex(2));
    // dispatch(getNewActiveStep(2));
    // Get Completed Steps list and enable tick mark condition in the stepper
    await getCompletedSteps();
  };

  const handleModifyAppointment = () => {
    if (willTypeID === FULL_WILL) {
      dispatch(getNewActiveStep(9));
      dispatch(setHighlightedSteps(11));
      dispatch(setNavigationIndex(11));
      dispatch(checkVirtualSelected());
    } else if (willTypeID === GUARDIANSHIP_WILL) {
      dispatch(getNewActiveStep(9));
      dispatch(setHighlightedSteps(9));
      dispatch(setNavigationIndex(9));
      dispatch(checkVirtualSelected());
    } else {
      dispatch(getNewActiveStep(9));
      dispatch(setHighlightedSteps(10));
      dispatch(setNavigationIndex(10));
      dispatch(checkVirtualSelected());
    }
  };

  const handleModifyWill = async () => {
    dispatch(storeActiveStep(1));
    dispatch(setHighlightedSteps(2));
    dispatch(setNavigationIndex(2));
    dispatch(getNewActiveStep(2));
  };

  // Complete Will Info Functionality Handled in this useEffect
  React.useEffect(() => {
    if (isCompleteWillInfo) {
      handleCompleteWillInfo();
    }
  }, [isCompleteWillInfo]);

  // If Active Service is present
  React.useEffect(() => {
    if (draftSActiveService?.isMirrorWill) {
      dispatch(checkMirrorWillSelected());
      dispatch(setIsSpouseSelected(false));
    } else {
      dispatch(checkSingleWillSelected());
    }
  }, [activeService, isChangeService]);

  // Change Service functionality
  React.useEffect(() => {
    if (isChangeService) {
      handleChangeService();
    }
  }, [isChangeService]);

  React.useEffect(() => {
    if (isUpgradeWill) {
      dispatch(setWillTypeID(1));
      // TODO ==> complete API integration for upgrade will and check for isUpgradeWill Flag in the response; Use the new profileGUID for fetching completed steps
      handleUpgradeWill();
    }
  }, [isUpgradeWill]);

  // Modify Appointment Functionality ==> Here ==> Navigates to Book Appointment step
  React.useEffect(() => {
    if (modifyAppointment) {
      handleModifyAppointment();
    }
  },[modifyAppointment]);

  // If modifyWill is selected ==> navigate to Personal Details
  /*
  if single will ==> navigate to Personal Details  ==> Done
  if mirror will
          ==> Testator ==> Yes ==> navigate to Personal Details
                       ==> No ==> navigate to Personal Details (change to Single Will)
          ==> Spouse ==> Yes ==> navigate to Personal Details (change to Single Will)
                     ==> Cancel ==> Do Nothing (Close Modal)
  */
  React.useEffect(() => {
    if (isModifyWill) {
      handleModifyWill();
    }
  },[isModifyWill]);

  // Check if property && beneficiary are added for navigation to Real Estate Distribution

  const dateSelected = childData;

  // Fetch all steps list
  React.useEffect(() => {
    dispatch<any>(fetchWillStepList(willTypeID || willTypeId)); // from LocalStorage && Redux
  }, [dispatch, willTypeID, dateSelected, isSpouseSelected,willTypeId]);

  // React.useEffect(() => {
  //   dispatch<any>(fetchWillBookState(dateSelected));
  // }, [dispatch, dateSelected]);

  // Map stepID(Number) to the array
  const stepNumber: any = results?.map((d: any) => d.stepID);
  // Map stepNumber(string) to the array
  const stepNumArray: any = results?.map((d: any) => Number(d.stepNumber));

  // Check draft and remaining will steps here---------------------------------
  const isDraft: boolean = false;

  // if (incompleteSteps.length > 0) {
  //   isDraft = true;
  // } else {
  //   isDraft = false;
  // }

  // test response steps
  const responseSteps = [8, 9];
  const finishedSteps: any = [];
  stepNumber.forEach((s: any) => {
    // Use incompletSteps array here
    if (!responseSteps.includes(s)) {
      finishedSteps.push(s);
    }
  });

  /**
   * Handle continue in incomplete steps modal
   *
   * @param {any} id - stepNumber ()
   * @param {number} number - stepId
   * @return {void} The function does not return anything.
   */
  const handleContinue = async (id: any, number: number): Promise<void> => {
    window.scrollTo(0, 0);
    dispatch(setShowIncompleteStepsModal(false));
    setShowModal(false);

    // Optimization
    if (singleWillCheck) { // TODO ==> Check Single will condition
      dispatch(setNavigationIndex(id));
      dispatch(setHighlightedSteps(id)); // PS:: This is stepNumber
      dispatch(getNewActiveStep(number)); // PS:: This is stepID
    } else if (mirrorWillCheck) {
      if (fromUploadDocs) {
        dispatch(setNavigationIndex(id));
        dispatch(setHighlightedSteps(id)); // PS:: This is stepNumber
        dispatch(getNewActiveStep(number)); // PS:: This is stepID
      }
      if (fromWillPreview) {
        await getCompletedSteps(); // Get completed Steps of the testator/spouse
        await dispatch(setIsSpouseSelected(!isSpouseSelected));
        dispatch(setNavigationIndex(id));
        dispatch(setHighlightedSteps(id)); // PS:: This is stepNumber
        dispatch(getNewActiveStep(number)); // PS:: This is stepID
      }

      // Handle continue case from Submit Button for ModifyAppointment
      // dispatch(setNavigationIndex(id));
      // dispatch(setHighlightedSteps(id)); // PS:: This is stepNumber
      // dispatch(getNewActiveStep(number)); // PS:: This is stepID
    }

    // Set states to initial state/false here after the function is executed
    dispatch(setFromUploadDocs(false));
    dispatch(setFromWillPreview(false));
  };

  const getIncompleteStepsByGuid = (step: any) => {
    const husbandIncompleteSteps = step?.filter(
      (s: any) => s?.bookedForProfileGuid === profileGuid,
    );
    const spouseIncompleteSteps = step?.filter(
      (s: any) => s?.bookedForProfileGuid === spouseGuid,
    );
    setSpouseIncomplete(spouseIncompleteSteps);
    setHusbandIncomplete(husbandIncompleteSteps);
    if (willPreviewCompleted) {
      setSteps(spouseIncompleteSteps);
    } else {
      setSteps(husbandIncompleteSteps);
    }
  };

  React.useEffect(() => {
    if (incompleteSteps?.length !== 0) {
      getIncompleteStepsByGuid(incompleteSteps);
    }
  }, [incompleteSteps]);

  console.log('isShowBookAppointment',isShowBookAppointment);

  // Get StepID when navigating from Beneficiary Details using next button
  const getStepIDFromBeneficiaryStep = (willType: number): number => {
    switch (willType) {
      case PROPERTY_WILL:
        return 6;
      case FINANCIAL_ASSETS_WILL:
      case BUISINESS_OWNERS_WILL:
      case TEMPLATED_FULL_WILL:
        return 18;
      case FULL_WILL:
        return 12;
      default:
        return 0;
    }
  };

  /**
   * Handles the next step in the process.
   *
   * @param {number} step - The current step number.
   * @param {any} stepName - The name of the current step.
   * @param {boolean} completed - Indicates if the step is completed.
   */
  const handleNext = async (
    step: number,
    stepName?: any,
    completed?: boolean,
  ) => {
    console.log('STEPNUMBER', step);
    console.log('COMPLETED', completed);
    window.scrollTo(0, 0);
    setCurrentSelectedStep(step);
    // Revert Active Service Funtionalities back to initial state on first handleNext Step
    dispatch(setIsChangeService(false));
    // dispatch(setIsCompleteWillInfo(false));
    dispatch(setModifyAppointment(false));
    // dispatch(setIsUpgradeWill(false));
    dispatch(setIsModifyWill(false));

    // Set upgradeWill flag to false if next clicked from Personal Details
    if (stepName === 'personal') {
      dispatch(setIsUpgradeWill(false));
    }

    // Show selection option in Real Estate Distribution for Property Will up on next from beneficiary Details
    if (step === 5) {
      dispatch(clearSelectedDistribution());
    }

    // If quick booking is enabled
    if (isQuickBooking && stepName !== 'willTypeSelection') {
      setActiveStep(8);
      if (stepName === 'bookAppointment') {
        setActiveStep((prev) => prev + 1);
      }
    } else if (!isQuickBooking && stepName !== 'willTypeSelection') {
      // setActiveStep(3);
    }

    if (stepName === 'personal' && isQuickBooking) {
      setShowSkipToAppointmentModal(true);
    }

    // If upload documents is active and Book appointment is visible
    if (stepName === 'upload' && !isShowBookAppointment) {
      // Incomplete steps API called here
      try {
        const response = await trackPromise(
          api.validateWillSteps(
            profileGuid,
            spouseGuid,
            isSpouseSelected ? spouseGuid : profileGuid,
            serviceId,
          ),
        );
        // Save incomplete steps list in store (redux)

        const incompletedSteps = response?.data?.Output;
        const testatorIncompleteSteps = incompletedSteps.filter((step:any) => step.bookedForProfileGuid === profileGuid);
        const spouseIncompleteSteps = incompletedSteps.filter((step:any) => step.bookedForProfileGuid === spouseGuid);
        console.log('testatorIncompleteSteps', testatorIncompleteSteps);
        console.log('spouseIncompleteSteps', spouseIncompleteSteps);

        dispatch(getIncompleteSteps(isSpouseSelected ? spouseIncompleteSteps : testatorIncompleteSteps));

        // Mirror Will && Testator
        if (mirrorWillCheck && !isSpouseSelected) {
          if (testatorIncompleteSteps.length !== 0) {
            handleShowIncompleteStepsModal();
          } else {
            // alert('go to next step');
            dispatch(setHighlightedSteps(9));
            dispatch(setNavigationIndex(9));
            dispatch(getNewActiveStep(13));
          }
        } else if (mirrorWillCheck && isSpouseSelected) { // Mirror Will && Spouse
          if (spouseIncompleteSteps.length !== 0) {
            handleShowIncompleteStepsModal();
          } else {
            dispatch(setHighlightedSteps(9));
            dispatch(setNavigationIndex(9));
            dispatch(getNewActiveStep(13));
          }
        }

        if (singleWillCheck) {
          // Show incomplete steps Modal only if the response is not empty
          if (incompletedSteps.length !== 0) {
            handleShowIncompleteStepsModal();
          } else {
          // Ask for confirmation on this functionality
            setIsShowBookAppointment(true);
            // Set View component, highlighted step in stepper and icon
            dispatch(setHighlightedSteps(9));
            dispatch(setNavigationIndex(9));
            dispatch(getNewActiveStep(21));
            setNewCompletedSteps((prev: any) => [...prev, 3, 4, 5, 6, 7, 8]);
          // dispatch(storeActiveStep(9));
          }
        }
      } catch (error) {
        console.log(error);
      }
    } else if (stepName === 'beneficiary-details' && willTypeID !== 1) {
      // Not needed for Full Will
      // If property and beneficiray is added then only we can navigate or go next to Real Estate Distribution
      if (propertyAdded && beneficiaryAdded) {
        dispatch(setHighlightedSteps(6));
        dispatch(getNewActiveStep(getStepIDFromBeneficiaryStep(willTypeID)));
        dispatch(setNavigationIndex(null));
        // // Highlighted step handled here
        // dispatch(setHighlightedSteps(step + 1));
        // // Set Current step number
        // dispatch(disableNavigation());
        // setCurrentSelectedStep(step);
        // // getWillStep(step);
        // const nextIndex = (currentIndex + 1) % stepNumber.length;
        // setCurrentIndex(nextIndex);

        // // setActiveStep((prevActiveStep) => prevActiveStep + 1);
        // // Need more testing here
        // setCurrentBtnStep(step + 1);
        // setActiveStep((prevActiveStep) => prevActiveStep + 1);
        // dispatch(storeActiveStep(step));
        // dispatch(getNewActiveStep(0));
        // dispatch(setNavigationIndex(null));
      } else {
        await dispatch<any>(resetErrorState());
        await dispatch<any>(setErrorInfo(`Please complete Beneficiary Details and ${getThirdStepName(willTypeID)}`));
      }
    } else {
      // ----------------------------------------------------------------
      // Highlighted step handled here
      // dispatch(setHighlightedSteps(step + 1));
      // // Test case
      // // getWillStep(step);
      // dispatch(disableNavigation());
      // const nextIndex = (currentIndex + 1) % stepNumber.length;
      // setCurrentIndex(nextIndex);
      // // dispatch(storeActiveStep(activeStep + 1));

      // // Get stepNumber list from the stepList array
      // const stepNumberList: any = results?.map((res) => Number(res?.stepNumber));

      // // // Handling ICONS navigation in handleNext()
      // if (step === 3) {
      //   setIconNum1(3);
      //   setIconNum2(6);
      // } else if (step === 6) {
      //   setIconNum1(6);
      //   setIconNum2(9);
      // } else if (step === 9) {
      //   if (willTypeID === 2) {
      //     // Guardianship Will
      //     setIconNum1(7);
      //     setIconNum2(10);
      //   } else {
      //     setIconNum1(8);
      //     setIconNum2(11);
      //   }
      // } else if (step > stepNumberList[stepNumberList.length - 2]) {
      //   // setIconNum1(8);
      //   // setIconNum2(11);
      //   navigate('/wills');
      // }

      // // Handle distribution of shares/Real estate distribution in ICONS
      // if (step === 7) {
      //   setIconNum1(6);
      //   setIconNum2(9);
      // }

      // // Set current step to pass as a prop to the further components to use
      // //  the handleNext method in those respective components
      // // NB:increment the step number by 1 to get correct list of completed steps
      // setCurrentBtnStep(step + 1);

      // let newSkipped = skipped;
      // if (isStepSkipped(activeStep)) {
      //   newSkipped = new Set(newSkipped.values());
      //   newSkipped.delete(activeStep);
      // }
      // // Increment activestep from state
      // setActiveStep((prevActiveStep) => prevActiveStep + 1);
      // // Increment currentStep from store state
      // dispatch(storeActiveStep(step));
      // dispatch(setStepFlow());
      // setSkipped(newSkipped);
      // dispatch(getNewActiveStep(0));
      // dispatch(setNavigationIndex(null));

      // if (navigationEnabled) {
      //   setNewCompletedSteps((prevSteps: any) => [
      //     ...prevSteps,
      //     completed ? navigationIndex : null,
      //   ]);
      //   dispatch(setCompletedStepList(completed ? navigationIndex : null));
      //   dispatch(storeActiveStep(navigationIndex));
      //   setActiveStep(navigationIndex);
      // } else {
      //   setNewCompletedSteps((prevStep: any) => [
      //     ...prevStep,
      //     completed ? step : null,
      //   ]);
      //   dispatch(setCompletedStepList(completed ? step : null));
      //   // setNewCompletedSteps((prevStep: any) => [...prevStep,step]);
      // }

      // ----------------------------------------------------------------

      // Stepper/Next Optimisations
      dispatch(setHighlightedSteps(step + 1));
      dispatch(storeActiveStep(step));
      dispatch(getNewActiveStep(0));
      dispatch(setNavigationIndex(step + 1));
      // dispatch(setNavigationIndex(null));

      setNewCompletedSteps((prev:any) => [...prev,completed ? step : null]);
    }
  };

  console.log('stepNumArray', stepNumArray);

  // Stepper Icons (scaffolding Icons) Optimisation
  React.useEffect(() => {
    if (highlightedStep !== 1) {
      if (stepNumArray.length === highlightedStep) {
        setIconNum1(highlightedStep - 3);
        setIconNum2(highlightedStep);
      } else {
        setIconNum1(highlightedStep - 2);
        setIconNum2(highlightedStep + 1);
      }
    }
  },[highlightedStep]);

  React.useEffect(() => {
    if (newActiveStep === 9 && isQuickBooking) {
      setIconNum1(8);
      setIconNum2(11);
    }
    if (willTypeID === 2 && guardianShipWill) {
      // Guardianship Will
      setIconNum1(navigationIndex === 2 ? 0 : 6);
      setIconNum2(navigationIndex === 2 ? 3 : 9);
    }
  }, [newActiveStep, isQuickBooking, guardianShipWill]);

  // Common function for enabling book appointment if all steps are completed
  const checkAllStepsCompleted = (completedSteps:number[],completedStepsList:number[]) => {
    const isAllStepsCompleted = completedSteps.every((step:number) => completedStepsList.includes(step));
    setIsShowBookAppointment(isAllStepsCompleted);
  };

  React.useEffect(() => {
    if (willTypeID === GUARDIANSHIP_WILL) {
      const completedSteps = [1,2,4,5,6];
      checkAllStepsCompleted(completedSteps,newCompletedSteps);
    } else if (willTypeID === FULL_WILL) {
      const completedSteps = [1,2,3,4,7,8];
      checkAllStepsCompleted(completedSteps,newCompletedSteps);
    } else {
      const completedSteps = [1,2,3,4,5,6,7,8];
      checkAllStepsCompleted(completedSteps,newCompletedSteps);
    }
  },[newCompletedSteps]);

  React.useEffect(() => {
    getCompletedSteps();
  },[isShowBookAppointment]);

  const handleBack = () => {
    const activeStepInBack = activeStep - 1;
    setActiveStep((prevActiveStep) => prevActiveStep - 1);
    setNum1((prevState) => prevState - 1);
    setNum2((prevState) => prevState - 1);
    if (
      activeStepInBack === 2
      || activeStepInBack === 5
      || activeStepInBack === 8
      || activeStepInBack === 11
    ) {
      setIconNum1((prevState) => prevState - 3);
      setIconNum2((prevState: any) => prevState - 3);
    }
  };

  const clearRealEstateShareOption = () => {
    dispatch(clearSelectedDistribution());
  };

  const getRealEstateOption = () => {
    if (willTypeID === 5 || willTypeID === 4) {
      // FAW && BOW
      return (
        <WillBySpecificRealEstate
          handleNext={handleNext}
          currentBtnStep={currentBtnStep}
          handleBack={clearRealEstateShareOption}
          // parameterGuid={parameterGuid}
          setNewCompletedSteps={setNewCompletedSteps}
          newCompletedSteps={newCompletedSteps}
        />
      );
    }

    if (willTypeID === 6) {
      // Templated Full Will
      return (
        <WillBySharesOfEstate
          handleNext={handleNext}
          currentBtnStep={currentBtnStep}
          handleBack={clearRealEstateShareOption}
          parameterGuid={parameterGuid}
          setNewCompletedSteps={setNewCompletedSteps}
          newCompletedSteps={newCompletedSteps}
        />
      );
    }

    if (!byShareCheck && !bySpecificCheck) {
      return (
        <WillRealEstateDistribution
          handleNext={handleNext}
          currentBtnStep={currentBtnStep}
          handleBack={handleBack}
          setNewCompletedSteps={setNewCompletedSteps}
          newCompletedSteps={newCompletedSteps}
        />
      );
    }
    if (byShareCheck) {
      return (
        <WillBySharesOfEstate
          handleNext={handleNext}
          currentBtnStep={currentBtnStep}
          handleBack={clearRealEstateShareOption}
          parameterGuid={parameterGuid}
          setNewCompletedSteps={setNewCompletedSteps}
          newCompletedSteps={newCompletedSteps}
        />
      );
    }
    if (bySpecificCheck) {
      return (
        <WillBySpecificRealEstate
          handleNext={handleNext}
          currentBtnStep={currentBtnStep}
          handleBack={clearRealEstateShareOption}
          // parameterGuid={parameterGuid}
          setNewCompletedSteps={setNewCompletedSteps}
          newCompletedSteps={newCompletedSteps}
        />
      );
    }
  };
  const getRealEstateOptionforfinancial = () => {
    if (willTypeID === 4) {
      // BOW
      return (
        <WillBySpecificRealEstateBusinessOwners
          handleNext={handleNext}
          currentBtnStep={currentBtnStep}
          handleBack={handleBack}
          parameterGuid={parameterGuid}
        />
      );
    }
    if (willTypeID === 5) {
      // FAW
      return (
        <WillBySpecificRealEstateFinancialAssets
          handleNext={handleNext}
          currentBtnStep={currentBtnStep}
          handleBack={handleBack}
          parameterGuid={parameterGuid}
        />
      );
    }
  };
  const getLocationType = () => {
    if (!isVirtual && !isInPerson) {
      return <WillLocationTypeSelection />;
    }
    if (isVirtual) {
      return (
        <WillBookAppointment
          handleNext={handleNext}
          currentBtnStep={currentBtnStep}
          handleBack={handleBack}
          willTypeID={willTypeID}
          setNewCompletedSteps={setNewCompletedSteps}
          newCompletedSteps={newCompletedSteps}
        />
      );
    }
  };

  React.useEffect(() => {
    getWillStep(currentStep);
    getRealEstateOption();
    getRealEstateOptionforfinancial();
  }, [byShareCheck, bySpecificCheck]);

  React.useEffect(() => {
    getWillStep(currentStep);
    getLocationType();
  }, [isVirtual, isInPerson]);
  const getWillStep = (step: number) => {
    let stepID;
    if (isDraft) {
      // Change responseSteps to incompleteSteps ahen using api
      stepID = responseSteps[step];
    } else {
      stepID = stepNumber[step];
    }
    // console.log('stepIndex', stepID);
    switch (newActiveStep !== 0 ? newActiveStep : stepID) {
      // switch (newActiveStep !== 0 ? newActiveStep : step + 1) {
      case 1:
        return <WillTypeSelection />;
      // return <WillLocationTypeSelection />;
      case 2:
        return (
          <WillPersonalInformation
            willTypeID={willTypeID}
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
            setNewCompletedSteps={setNewCompletedSteps}
            newCompletedSteps={newCompletedSteps}
          />
        );
      case 3:
        return (
          <WillRealEstateDetail
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
            setNewCompletedSteps={setNewCompletedSteps}
            newCompletedSteps={newCompletedSteps}
          />
          // <WillGuardianInformation
          //   handleNext={handleNext}
          //   currentBtnStep={currentBtnStep}
          //   handleBack={handleBack}
          // />
        );
      case 4:
        return (
          <WillExecutorDetail
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
            willTypeID={willTypeID}
            setNewCompletedSteps={setNewCompletedSteps}
            newCompletedSteps={newCompletedSteps}
            // setNewCompletedSteps={setNewCompletedSteps}
          />
        );
      case 5:
        return (
          <WillBeneficiaryDetail
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
            setNewCompletedSteps={setNewCompletedSteps}
            newCompletedSteps={newCompletedSteps}
            willTypeID={willTypeID}
          />
        );
      case 6:
        return getRealEstateOption();
      case 7:
        return (
          <WillWitnessDetails
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
            willTypeID={willTypeID}
            setNewCompletedSteps={setNewCompletedSteps}
            newCompletedSteps={newCompletedSteps}
          />
        );
      case 8:
        return (
          <DocumentManager
            willTypeID={willTypeID}
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
            setNewCompletedSteps={setNewCompletedSteps}
            newCompletedSteps={newCompletedSteps}
          />
        );
      case 9:
        return getLocationType();
      case 10:
        return (
          <WillPayment
            willTypeID={willTypeID}
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
          />
        );
      case 11:
        return (
          <WillGuardianInformation
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
            // willTypeID={parameterGuid}
            setNewCompletedSteps={setNewCompletedSteps}
            newCompletedSteps={newCompletedSteps}
          />
        );
      case 12:
        return (
          <WillsMinorChildren
            // willTypeGuid={parameterGuid}
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
            setNewCompletedSteps={setNewCompletedSteps}
            newCompletedSteps={newCompletedSteps}
          />
        );
      case 13:
        return (
          <WillDraftDetail
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
            willTypeID={willTypeID}
            setNewCompletedSteps={setNewCompletedSteps}
            newCompletedSteps={newCompletedSteps}
          />
        );
      case 15:
        return (
          <WillInterimGuardianDetail
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
            // willTypeID={parameterGuid}
            setNewCompletedSteps={setNewCompletedSteps}
            newCompletedSteps={newCompletedSteps}
          />
        );
      case 16:
        // Permanent Guardian Details
        return (
          <WillGuardianDetail
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
            // willTypeID={parameterGuid}
            setNewCompletedSteps={setNewCompletedSteps}
            newCompletedSteps={newCompletedSteps}
          />
        );

      case 17:
        return (
          <CompanyShareInfo
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
            setNewCompletedSteps={setNewCompletedSteps}
            newCompletedSteps={newCompletedSteps}
          />
        );
      case 18:
        return getRealEstateOption();
      case 19:
        return (
          <AccountsInformation
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
            setNewCompletedSteps={setNewCompletedSteps}
            newCompletedSteps={newCompletedSteps}
          />
        );
      case 20:
        return (
          <MovableAndImmovableProperty
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
            setNewCompletedSteps={setNewCompletedSteps}
            newCompletedSteps={newCompletedSteps}
          />
        );
      case 21:
        return (
          <WillPreview
            handleNext={handleNext}
            currentBtnStep={currentBtnStep}
            handleBack={handleBack}
            // parameterGuid={parameterGuid}
            handleShowIncompleteStepsModal={handleShowIncompleteStepsModal}
            handleCloseModal={handleCloseModal}
            setNewCompletedSteps={setNewCompletedSteps}
            newCompletedSteps={newCompletedSteps}
          />
        );

      default:
        break;
    }
  };

  // const recievedData = (single:any,mirror:any) => {
  //   console.log('data',single,mirror);
  // };

  return (
    <div className="main">
      <div className="case-details d-flex flex-column">
        <div className="row title-row ">
          <div className="col-lg-3 col-md-3 col-sm-12 col-xs-8 back-col-new">
            <RegistrationStepper
              activeStep={activeStep + 1}
              parameterGuid={parameterGuid}
              results={results}
              stepNumber={stepNumber}
              finishedSteps={finishedSteps}
              isDraft={isDraft}
              stepNumArray={stepNumArray}
              completedStepNumArray={newCompletedSteps.filter(
                (value, index, self) => self.indexOf(value) === index,
              )} // Remove Duplicates
              currentSelectedStep={currentSelectedStep}
              setCurrentSelectedStep={setCurrentSelectedStep}
              isShowBookAppointment={isShowBookAppointment}
              willTypeID={willTypeID}
              setNewCompletedSteps={setNewCompletedSteps}
            />
          </div>
          <div className="col-lg-9 col-md-9 col-sm-12 col-xs-12 title-col">
            <Stack sx={{ width: '100%' }} spacing={4}>
              <Stepper
                activeStep={activeStep}
                alternativeLabel
                connector={<ColorlibConnector />}
              >
                <div className="line" />
                <div className="scaffolding">
                  {results?.slice(iconNum1, iconNum2)?.map((label, index) => (
                    <ScaffoldingIcons
                      stepNumber={label?.stepNumber}
                      stepName={label?.stepName.toUpperCase()}
                      completed={newCompletedSteps.includes(
                        Number(label.stepNumber),
                      )}
                    />
                  ))}
                </div>
              </Stepper>
              {/* {getWillStep(newActiveStep !== 0 ? newActiveStep : currentStep)} */}
              <div className="stepsDiv">
                {(isUpgradeWill || isModifyWill)
                && (newActiveStep === 1 || newActiveStep === 0)
                  ? (
                    <WillPersonalInformation
                      willTypeID={willTypeID}
                      handleNext={handleNext}
                      currentBtnStep={currentBtnStep}
                      handleBack={handleBack}
                      setNewCompletedSteps={setNewCompletedSteps}
                      newCompletedSteps={newCompletedSteps}
                    />
                  ) : (
                    getWillStep(currentStep)
                  )}
              </div>
              {/* Revert back */}
              {newActiveStep === 1 && !isUpgradeWill && (
                <Box sx={{ display: 'flex', flexDirection: 'row', pt: 2 }}>
                  <button
                    type="button"
                    // Removed activeStep(state variable) from the parameter
                    onClick={() => handleNext(1, 'willTypeSelection', true)}
                    className={
                      !(mirrorWillCheck || singleWillCheck)
                        ? 'next-btn-disabled'
                        : 'next-btn'
                    }
                    disabled={!(mirrorWillCheck || singleWillCheck)}
                  >
                    Next Step
                  </button>
                </Box>
              )}
            </Stack>
          </div>
        </div>
      </div>
      {/* Modal for showing incomplete steps */}
      <IncompleteStepsModal
        showModal={showModal || showIncompleteStepsModal}
        handleCloseModal={handleCloseModal}
        steps={incompleteSteps}
        handleContinue={handleContinue}
      />

      {/* Modal if quickBooking is true */}
      <QuickBookingWarningModal
        showModal={showSkipToAppointmentModal}
        handleCloseModal={() => setShowSkipToAppointmentModal(false)}
      />

      <React.Suspense fallback={<div>Loading...</div>}>
        <DeleteConfirmationModal
          show={show}
          handleClose={() => {
            setShow(false);
            dispatch(setHighlightedSteps(5));
            dispatch(setNavigationIndex(5));
            dispatch(getNewActiveStep(5));
          }}
          handleContinue={() => {
            setShow(false);
            dispatch(setHighlightedSteps(5));
            dispatch(setNavigationIndex(5));
            dispatch(getNewActiveStep(5));
          }}
          type="Test"
          fromShares
        />
      </React.Suspense>
    </div>
  );
};

export default CustomizedSteppers;

/**
 * If navigation is enabled then we need to call a different function instead of handleNext(say:handleNavigateNext)
 * else we use the normal handleNext function and complete the navigation
 *
 */
  // Get husband information
  const getHusbandInformationByGuid = useCallback(async () => {
    const res = await trackPromise(api.getPersonalInformationByGuid(profileGuid));
    console.log('Profile information', res);
    setHusbandData(res?.data?.Output);
  }, [profileGuid, trackPromise, api, setHusbandData]);

  // Get spouse information
  const getSpouseInformationByGuid = useCallback(async () => {
    const res = await trackPromise(api.getPersonalInformationByGuid(spouseGuid));
    console.log('Spouse information', res);
    setSpouseData(res?.data?.Output);
  }, [spouseGuid, trackPromise, api, setSpouseData]);

  // Revert back to previous values after testing
  React.useEffect(() => {
    // if (spouseGuid && profileGuid) {
    if (profileGuid) getHusbandInformationByGuid();
    if (spouseGuid) getSpouseInformationByGuid();
    // }
  }, [profileGuid, spouseGuid]);
// ParentComponent.js:


import React, { useState } from 'react';
import ChildComponent from './ChildComponent';

const ParentComponent = () => {
  const [parameterFromChild, setParameterFromChild] = useState('');

  // Callback function to receive the parameter from the child
  const handleChildParameter = (parameter) => {
    setParameterFromChild(parameter);
  };

  return (
    <div>
      <h1>Parent Component</h1>
      
      {/* Render ChildComponent and pass the callback function as a prop */}
      <ChildComponent onParameterChange={handleChildParameter} />

      {/* Display the parameter received from the child */}
      {parameterFromChild && (
        <p>Parameter received from child: {parameterFromChild}</p>
      )}
    </div>
  );
};

export default ParentComponent;




//ChildComponent.js:
import React, { useState } from 'react';

const ChildComponent = ({ onParameterChange }) => {
  const [childParameter, setChildParameter] = useState('');

  const handleButtonClick = () => {
    // Update the childParameter state
    setChildParameter('Hello from ChildComponent!');
    
    // Invoke the callback function in the parent with the parameter
    onParameterChange('Hello from ChildComponent!');
  };

  return (
    <div>
      <h2>Child Component</h2>

      <button onClick={handleButtonClick} className="bg-blue-500 text-white px-4 py-2">
        Click me
      </button>
    </div>
  );
};

export default ChildComponent;
/* eslint-disable no-param-reassign */
/* eslint-disable no-underscore-dangle */
/* eslint-disable max-len */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable import/no-extraneous-dependencies */
import React, { FormEventHandler, useEffect, useState } from 'react';
import { useForm, Controller, SubmitHandler } from 'react-hook-form';
import { Autocomplete, Box, TextField } from '@mui/material';
import IconSave from '@assets/icon-save.svg';
import * as yup from 'yup';
import { yupResolver } from '@hookform/resolvers/yup';
import { Col, Row } from 'react-bootstrap';
import {
  fetchLitigantApplicationDetails,
  lawFirmRegistrationDetailSelector,
  setisValidRegistrationForm,
  submitLitigantApplicationDetails,
} from '@redux/slices/law-firm-registration';
import { useDispatch, useSelector } from 'react-redux';
import { trackPromise } from 'react-promise-tracker';
import api from '@api/index';
import {
  resetErrorState,
  setErrorInfo,
} from '@redux/slices/will-personal-information';
import { dropDownSelector, fetchCountryList } from '@redux/slices/dropDowns';
import './style.scss';
import useIsdCodesList from '@utils/hooks/useIsdCodesList';

interface LitigantProbonoApplicant {
  litigantGuid: string;
  applicantName: string;
  applicantAddress: string;
  applicantTelephone: string;
  applicantFax: string;
  applicantMobile: string;
  applicantEmail: string;
  isdCodeApplicantMobile: string;
}

interface Props {
  completed: { [k: number]: boolean };
  handleComplete: () => void;
  completedSteps: () => number;
  totalSteps: () => number;
  activeStep: number;
  handleBack: () => void;
  isLastStep: () => boolean;
}

const commonSchema = yup.object().shape({
  applicantName: yup.string().required('Applicant Name is required'),
  applicantEmail: yup
    .string()
    .email('Invalid email')
    .required('Applicant Email Address is required'),
  applicantAddress: yup.string().required('Address is required'),
  applicantTelephone: yup
    .string()
    .required('Telephone number is required')
    .matches(/^[0-9]{6,14}$/, 'Invalid telephone number'),
  applicantMobile: yup.string().required('Mobile number is required'),
  applicantFax: yup.string().required('Fax number is required'),
  isdCodeApplicantMobile: yup.string().required('Isd Code is required'),
});

const draftSchema = yup.object().shape({
  applicantName: yup.string().required('Applicant Name is required'),
  applicantEmail: yup
    .string()
    .email('Invalid email')
    .required('Applicant Email Address is required'),
});

function index({
  completed,
  handleComplete,
  completedSteps,
  totalSteps,
  activeStep,
  handleBack,
  isLastStep,
}: Props) {
  const [applicantMobile, setApplicantMobile] = useState<string>('');
  const [isdCodeLabel, setIsdCodeLabel] = useState<any>('');
  const [isdCode1, setIsdCode1] = useState<string>('');
  const [flagForLitigantApplicant, setFlagForLitigantApplicant] = useState<boolean>(false);
  const [isSubmitted, setIsSubmitted] = useState<boolean>(false);
  const [isDraft, setIsDraft] = useState<boolean>(false);
  const [submitBtn, setSubmitBtn] = useState(false);
  const [emailValidation, setEmailValidation] = useState(false);
  const [isNext, setIsNext] = useState<boolean | null>(null);
  const dispatch = useDispatch();

  const schema = isNext ? commonSchema : draftSchema;
  const {
    control,
    handleSubmit,
    reset,
    setValue,
    register,
    clearErrors,
    setError,
    trigger,
    formState: { errors },
  } = useForm<LitigantProbonoApplicant>({
    resolver: yupResolver(schema as yup.AnyObjectSchema),
    defaultValues: {
      // cityID: null, countryID: null, homeJurisdiction: null, phoneNo: '',
    },
  });

  console.log('litiganterrors', errors);

  console.log('isDraft', isDraft);

  const { litigantGuid, litigantDetails, isValidRegistrationForm } = useSelector(lawFirmRegistrationDetailSelector);

  const checkLitigantEmail = async (email: string) => {
    console.log('litigantGuid', litigantGuid);
    await dispatch(resetErrorState());
    try {
      // Make the API call here (e.g., using fetch or Axios)
      const response: any = await trackPromise(
        api.checkIfLitigantEmailRegistered(email, litigantGuid),
      );
      if (response?.data?.applicantEmalExists) {
        setFlagForLitigantApplicant(true);
        dispatch(setErrorInfo('Litigant Email already exists!'));
        dispatch<any>(setisValidRegistrationForm(false));
        // If the firm name already exists, set the error message for the Firm Name field
        setError('applicantEmail', {
          type: 'manual',
          message: 'Litigant Email already exists',
        });
      } else {
        dispatch<any>(setisValidRegistrationForm(true));
        setFlagForLitigantApplicant(false);
        // If the firm name is unique, clear the error message for the Firm Name field
        clearErrors('applicantEmail');
      }
    } catch (error) {
      console.error('Error making API call:', error);
    }
  };

  // Utility function to filter out all IDs from the list
  const filterList = (list: any[], condition: (item: any) => boolean) => list.filter((item: any) => {
    if (condition(item)) {
      return item;
    }
    return '';
  });

  // Get all dropdown lists from redux
  const { countryList } = useSelector(dropDownSelector);

  // Custom hooks for getting various list information
  const isdCodesList = useIsdCodesList(countryList);

  const onSubmit: SubmitHandler<LitigantProbonoApplicant> = async (
    data: LitigantProbonoApplicant,
  ) => {
    // setSubmitBtn(true);
    // await checkLitigantEmail(data.applicantEmail);
    await trigger(['applicantEmail']);
    if (Object.keys(errors).length === 0) {
      const formData: LitigantProbonoApplicant = {
        litigantGuid,
        applicantName: data.applicantName,
        applicantAddress: data.applicantAddress,
        applicantTelephone: data.applicantTelephone,
        applicantFax: data.applicantFax,
        applicantEmail: data.applicantEmail,
        applicantMobile,
        isdCodeApplicantMobile: isdCode1,
      };
      if (isValidRegistrationForm) {
        await dispatch<any>(
          submitLitigantApplicationDetails(formData, isDraft),
        );
        if (!isDraft) handleComplete();
        if (!isDraft) reset();
        window.scrollTo(0, 0);
      }
    }
  };

  const submitFromSave = async (data: any) => {
    console.log('Litigant Data', data);

    const litigantDraft:LitigantProbonoApplicant = {
      litigantGuid,
      applicantName: data.applicantName,
      applicantAddress: data.applicantAddress,
      applicantTelephone: data.applicantTelephone,
      applicantFax: data.applicantFax,
      applicantEmail: data.applicantEmail,
      applicantMobile,
      isdCodeApplicantMobile: isdCode1,
    };

    await dispatch<any>(
      submitLitigantApplicationDetails(litigantDraft, isDraft),
    );
  };

  const emailValidationRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

  React.useEffect(() => {
    window.scrollTo(0, 0);
    dispatch<any>(fetchCountryList());
  }, []);

  useEffect(() => {
    if (litigantGuid !== '') {
      dispatch<any>(fetchLitigantApplicationDetails(litigantGuid));
    }
  }, [litigantGuid]);

  const handleIsdCode1Change = (e: any, val: any) => {
    const isdCode1Value = val?.countryID;
    const isdCode1Label = val?.label;
    setIsdCode1(isdCode1Value);
    setIsdCodeLabel(isdCode1Label);
  };

  useEffect(() => {
    if (litigantDetails) {
      const isCode = filterList(
        isdCodesList,
        (item: any) => item.countryID === litigantDetails?.isdCodeApplicantMobile,
      );
      console.log('isdCode', isCode);
      setValue('applicantName', litigantDetails.applicantName);
      setValue('applicantAddress', litigantDetails.applicantAddress);
      setValue('applicantTelephone', litigantDetails.applicantTelephone);
      // setValue('iSDCodeApplicantTelephone', litigantDetails.isdCodeApplicantMobile);
      setValue('applicantFax', litigantDetails.applicantFax);
      setValue('applicantMobile', litigantDetails.applicantMobile);
      setValue('applicantEmail', litigantDetails.applicantEmail);
      setValue(
        'isdCodeApplicantMobile',
        litigantDetails.isdCodeApplicantMobile,
      );
      setApplicantMobile(litigantDetails.applicantMobile);
      setIsdCode1(isCode[0]?.countryID);
      setIsdCodeLabel(isCode[0]?.label);
    }
  }, [litigantDetails]);

  const handlePhoneNumber1Change = (e: any) => {
    const { value } = e.target;
    // eslint-disable-next-line no-param-reassign
    e.target.value = value.replace(/[^0-9]/g, '');
    setApplicantMobile(e.target.value);
  };
  const capitalizeWords = (text: string) => text
    .split(' ')
    .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
    .join(' ');

  const handleTelephoneChange = (e: any) => {
    const { value } = e.target;
    // eslint-disable-next-line no-param-reassign
    e.target.value = value.replace(/[^0-9]/g, '');
    setValue('applicantTelephone', e.target.value);
  };

  const handleFaxChange = (e: any) => {
    const { value } = e.target;
    // eslint-disable-next-line no-param-reassign
    e.target.value = value.replace(/[^0-9]/g, '');
    setValue('applicantFax', e.target.value);
  };
  const handleCursor: FormEventHandler<HTMLInputElement> = (e: {
    currentTarget: any;
  }) => {
    const input = e.currentTarget;
    const cursorPosition = input.selectionStart || 0;
    input.value = capitalizeWords(
      input.value
        .trimStart()
        .replace(/\s+/g, ' ')
        .replace(/[^a-zA-Z\W ]/g, ''),
    );
    input.setSelectionRange(cursorPosition, cursorPosition);
  };
  const handleInput: FormEventHandler<HTMLInputElement> = (e: {
    currentTarget: any;
  }) => {
    setSubmitBtn(false);
    if (emailValidationRegex.test(e.currentTarget.value)) {
      setEmailValidation(false);
    } else {
      setEmailValidation(true);
    }
    const input = e.currentTarget;
    const cursorPosition = input.selectionStart || 0;
    input.value = input.value.trim();
    input.setSelectionRange(cursorPosition, cursorPosition);
  };
  const handleInputForAddrress = (e: { currentTarget: any }) => {
    const input = e.currentTarget;
    const cursorPosition = input.selectionStart || 0;
    input.value = capitalizeWords(input.value.trimStart());
    input.setSelectionRange(cursorPosition, cursorPosition);
  };
  return (
    <form
      className="form"
      onSubmit={handleSubmit(isNext ? onSubmit : submitFromSave)}
    >
      <h1>Application Details</h1>
      <span className="mb-3">
        Please indicate whether you will be the claimant or respondent
      </span>
      <div className="row" style={{ paddingTop: '40px' }}>
        <div className="col-md-4">
          <div className="mb-3">
            <label htmlFor="name" className="form-label firmName-label w-100">
              Name*
            </label>
            <input
              type="text"
              className={`${
                errors?.applicantName
                  ? 'validate-field'
                  : 'form-control'
              } `}
              onInput={handleCursor}
              style={{ textTransform: 'capitalize' }}
              id="applicantName"
              placeholder="Enter Name"
              // onChange={(e) => setState(e.target.value)}
              {...register('applicantName', {
                required: true,
              })}
            />
          </div>
        </div>
        <div className="col-md-4">
          <div className="mb-3">
            <label htmlFor="name" className="form-label firmName-label w-100">
              Telephone*
            </label>
            <input
              type="text"
              max={15}
              className={`${
                errors?.applicantTelephone && isSubmitted
                  ? 'validate-field'
                  : 'form-control'
              } `}
              id="applicantTelephone"
              placeholder="Enter Telephone Number"
              {...register('applicantTelephone', {
                required: true,
              })}
              onChange={handleTelephoneChange}
            />
          </div>
        </div>
      </div>
      <div className="row">
        <div className="col-md-4">
          <div className="mb-3">
            <label
              htmlFor="applicantEmail"
              className="form-label applicantEmail-label w-100"
            >
              Email*
            </label>
            <Controller
              name="applicantEmail"
              control={control}
              render={({ field }) => (
                <input
                  type="text"
                  className={`${
                    errors.applicantEmail
                    || flagForLitigantApplicant
                    || (emailValidation && submitBtn)
                      ? 'validate-field'
                      : 'form-control'
                  }`}
                  {...field}
                  {...register('applicantEmail', {
                    required: true,
                    pattern: {
                      value: emailValidationRegex,
                      message: 'Please enter a valid email',
                    },
                  })}
                  id="applicantEmail"
                  aria-describedby="emailHelp"
                  placeholder="Enter Email Address"
                  onInput={handleInput}
                  onBlur={() => checkLitigantEmail(field.value)}
                />
              )}
              rules={{
                required: 'Firm Email is required',
                pattern: {
                  value: emailValidationRegex,
                  message: 'Please enter a valid email',
                },
              }}
            />
            {/* {errors.firmEmail && (
            <p className="error-message">{errors.firmEmail.message}</p>
            )} */}
          </div>
        </div>
        <div className="col-md-4">
          <div className="mb-3">
            <label htmlFor="phoneNumber" className="form-label w-100">
              Mobile*
            </label>
            <div className="d-flex">
              <Autocomplete
                id="country-select-demo"
                // sx={{ width: 1000 }}
                options={isdCodesList}
                autoHighlight
                // value={isdCodeLabel}
                value={
                  isdCodesList.find(
                    (option: any) => option.label === isdCodeLabel,
                  ) || null
                }
                disableClearable
                getOptionLabel={(option: any) => `${option.label} ${option.countryName}`}
                // getOptionLabel={(option: any) => option?.countryName}
                renderOption={(props, option) => (
                  <Box
                    component="li"
                    sx={{ '& > img': { mr: 2, flexShrink: 0 } }}
                    {...props}
                  >
                    <img
                      loading="lazy"
                      width="20"
                      src={`https://flagcdn.com/w20/${option?.countryCode?.toLowerCase()}.png`}
                      srcSet={`https://flagcdn.com/w40/${option?.countryCode?.toLowerCase()}.png 2x`}
                      alt=""
                    />
                    {option?.countryName}
                    {' '}
                    (
                    {option?.label}
                    )
                  </Box>
                )}
                renderInput={(params) => (
                  <TextField
                    {...params}
                    placeholder="+97"
                    // value={isdCodeLabel || ''}
                    inputProps={{
                      ...params.inputProps,
                      autoComplete: 'new-password', // disable autocomplete and autofill
                    }}
                    {...register('isdCodeApplicantMobile', {
                      required: true,
                    })}
                    error={
                      errors?.isdCodeApplicantMobile
                      && (isdCodeLabel === '' || isdCodeLabel === undefined)
                    }
                    className="isdcode-field"
                  />
                )}
                className="isdcode-box"
                onChange={(e, newVal: any) => handleIsdCode1Change(e, newVal)}
              />
              <input
                type="text"
                placeholder="Enter Phone Number"
                maxLength={15}
                // className={`${
                //   isSubmitted
                //   && (applicantMobile === '' || applicantMobile === undefined)
                //     ? 'phonenumber-input-error'
                //     : 'form-control-phonenumber'
                // } `}
                className={`${
                  errors?.applicantMobile && isSubmitted && (applicantMobile === '' || applicantMobile === undefined)
                    ? 'phonenumber-input-error'
                    : 'form-control-phonenumber'
                } `}
                id="applicantMobile"
                aria-describedby="applicantMobileHelp"
                {...register('applicantMobile', {
                  required: true,
                })}
                onChange={(e: any) => handlePhoneNumber1Change(e)}
              />
            </div>
          </div>
        </div>
      </div>
      <div className="row">
        <div className="col-md-4">
          <div className="mb-3">
            <label
              htmlFor="applicantFax"
              className="form-label applicantFax-label w-100"
            >
              Fax*
            </label>
            <input
              type="text"
              className={`${
                errors?.applicantFax && isSubmitted
                  ? 'validate-field'
                  : 'form-control'
              } `}
              id="applicantFax"
              placeholder="Enter Fax Number"
              {...register('applicantFax', {
                required: true,
              })}
              onChange={handleFaxChange}
            />
          </div>
        </div>
      </div>
      <div className="row">
        <div className="col-md-8">
          <div className="mb-3">
            <label
              htmlFor="applicantAddress"
              className="form-label firmName-label w-100"
            >
              Address*
            </label>
            <textarea
              className={`${
                errors?.applicantAddress
                  ? 'validate-field'
                  : 'form-control'
              } `}
              id="applicantAddress"
              placeholder="Enter Address*"
              onInput={handleInputForAddrress}
              {...register('applicantAddress', {
                required: true,
              })}
            />
          </div>
        </div>
      </div>

      <Row className="mb-3 pt-3">
        <Col md={8}>
          <button
            type="submit"
            className="next-button"
            onClick={() => {
              setIsSubmitted(true);
              setIsDraft(false);
              setSubmitBtn(true);
              setIsNext(true);
            }}
          >
            {isLastStep() ? 'Submit' : 'Next'}
          </button>
          <button
            type="submit"
            className="save-button"
            onClick={() => {
              setIsSubmitted(true);
              setIsDraft(true);
              setSubmitBtn(true);
              setIsNext(false);
            }}
          >
            <img src={IconSave} alt="" />
            Save
          </button>
        </Col>
        <Col className="mr-auto" md={4}>
          {activeStep !== 0 && (
            <button type="button" className="back-button" onClick={handleBack}>
              Back
            </button>
          )}
        </Col>
      </Row>
    </form>
  );
}

export default index;
import {
  Card,
  Center,
  VStack,
  Image,
  SimpleGrid,
  GridItem,
} from "@chakra-ui/react";
import { ViewHeader, ViewText } from "../../components/ViewStyle/ViewStyle";
import { GoogleMap, useJsApiLoader } from "@react-google-maps/api";
// import pinred from "../../features/OCVMap/pin/pinred.png";
import useCoordinates from "../../hooks/useCoordinates";

export default function ContactCard({
  manifestData,
  viewData,
  anchorID,
}: Record<string, any>): JSX.Element {
  const contactLine1 = viewData.contactLine1;
  const phoneNumber = viewData.phoneNumber;
  const emailAddress = viewData.emailAddress;
  const address = viewData.mailingAddress;
  const { isLoaded } = useJsApiLoader({
    id: "google-map-script",
    googleMapsApiKey: "AIzaSyAEOZZNm6jFVe3j3ISl_Ha9BeODMYrdqaY",
  });
  const addy = encodeURIComponent(address);
  const { data } = useCoordinates(addy);

  const options = {
    scrollwheel: true,
    gestureHandling: "auto",
  };
  // const coordinates = { lat: 37.783333, lng: -122.416667 };
  const coordinates = {
    lat: parseFloat(data.candidates[0].location.y),
    lng: parseFloat(data.candidates[0].location.x),
  };
  return (
    <section
      data-testid={"contactCard"}
      id={anchorID}
      style={{
        background: viewData.config.bgColor ? viewData.config.bgColor : "#eee",
        width: "100%",
        height: "100%",
        gap: "1rem",
        padding: "2rem 0rem",
      }}
    >
      <Center>
        <Card
          bg="white"
          width="1000px"
          py="2rem"
          px="1rem"
        >
          <VStack>
            <ViewHeader titleColor={viewData.config.titleColor}>
              {contactLine1}
            </ViewHeader>
            {isLoaded && (
              <GoogleMap
                options={options}
                mapContainerStyle={{
                  height: `30vh`,
                  width: `100%`,
                  marginTop: `2rem`,
                }}
                center={coordinates}
                zoom={15}
              ></GoogleMap>
            )}
            <SimpleGrid columns={[1, 1, 3]}>
              <GridItem>
                <Center>
                  <Image
                    src={
                      manifestData?.["stylesheet"]["images"]?.["titleImage"]?.[
                        "url"
                      ]
                    }
                    alt={
                      manifestData?.["stylesheet"]["images"]?.["titleImage"]?.[
                        "altText"
                      ]
                    }
                    verticalAlign="middle"
                    display="inline"
                    maxWidth="75px"
                  />
                </Center>
              </GridItem>
              <GridItem></GridItem>
              <GridItem>
                <ViewText textColor="black">{phoneNumber}</ViewText>
                <ViewText textColor="black">{emailAddress}</ViewText>
              </GridItem>
            </SimpleGrid>
          </VStack>
        </Card>
      </Center>
    </section>
  );
}
const handleNext = async (
    step: number,
    stepName?: any,
    completed?: boolean,
  ) => {
    console.log('STEPNUMBER', step);
    console.log('COMPLETED', completed);
    window.scrollTo(0, 0);
    setCurrentSelectedStep(step);
    // Revert Active Service Funtionalities back to initial state on first handleNext Step
    dispatch(setIsChangeService(false));
    // dispatch(setIsCompleteWillInfo(false));
    dispatch(setModifyAppointment(false));
    // dispatch(setIsUpgradeWill(false));
    dispatch(setIsModifyWill(false));

    // Set upgradeWill flag to false if next clicked from Personal Details
    if (stepName === 'personal') {
      dispatch(setIsUpgradeWill(false));
    }

    // Show selection option in Real Estate Distribution for Property Will up on next from beneficiary Details
    if (step === 5) {
      dispatch(clearSelectedDistribution());
    }

    // If quick booking is enabled
    if (isQuickBooking && stepName !== 'willTypeSelection') {
      setActiveStep(8);
      if (stepName === 'bookAppointment') {
        setActiveStep((prev) => prev + 1);
      }
    } else if (!isQuickBooking && stepName !== 'willTypeSelection') {
      // setActiveStep(3);
    }

    if (stepName === 'personal' && isQuickBooking) {
      setShowSkipToAppointmentModal(true);
    }

    // If upload documents is active and Book appointment is visible
    if (stepName === 'upload' && !isShowBookAppointment) {
      // Incomplete steps API called here
      try {
        const response = await trackPromise(
          api.validateWillSteps(
            profileGuid,
            spouseGuid,
            isSpouseSelected ? spouseGuid : profileGuid,
            serviceId,
          ),
        );
        // Save incomplete steps list in store (redux)
        dispatch(getIncompleteSteps(response?.data?.Output));
        const incompletedSteps = response?.data?.Output;
        const testatorIncompleteSteps = incompletedSteps.filter((step:any) => step.bookedForProfileGuid === profileGuid);
        const spouseIncompleteSteps = incompletedSteps.filter((step:any) => step.bookedForProfileGuid === spouseGuid);
        console.log('testatorIncompleteSteps', testatorIncompleteSteps);
        console.log('spouseIncompleteSteps', spouseIncompleteSteps);

        // Mirror Will && Testator
        if (mirrorWillCheck && !isSpouseSelected) {
          if (testatorIncompleteSteps.length !== 0) {
            handleShowIncompleteStepsModal();
          } else {
            // alert('go to next step');
            dispatch(setHighlightedSteps(9));
            dispatch(setNavigationIndex(9));
            dispatch(getNewActiveStep(13));
          }
        } else if (mirrorWillCheck && isSpouseSelected) { // Mirror Will && Spouse
          if (spouseIncompleteSteps.length !== 0) {
            handleShowIncompleteStepsModal();
          } else {
            dispatch(setHighlightedSteps(9));
            dispatch(setNavigationIndex(9));
            dispatch(getNewActiveStep(13));
          }
        }

        if (singleWillCheck) {
          // Show incomplete steps Modal only if the response is not empty
          if (incompletedSteps.length !== 0) {
            handleShowIncompleteStepsModal();
          } else {
          // Ask for confirmation on this functionality
            setIsShowBookAppointment(true);
            // Set View component, highlighted step in stepper and icon
            dispatch(setHighlightedSteps(9));
            dispatch(setNavigationIndex(9));
            dispatch(getNewActiveStep(21));
            setNewCompletedSteps((prev: any) => [...prev, 3, 4, 5, 6, 7, 8]);
          // dispatch(storeActiveStep(9));
          }
        }
      } catch (error) {
        console.log(error);
      }
    } else if (stepName === 'beneficiary-details' && willTypeID !== 1) {
      // Not needed for Full Will
      // If property and beneficiray is added then only we can navigate or go next to Real Estate Distribution
      if (propertyAdded && beneficiaryAdded) {
        dispatch(setHighlightedSteps(6));
        dispatch(getNewActiveStep(getStepIDFromBeneficiaryStep(willTypeID)));
        dispatch(setNavigationIndex(null));
        // // Highlighted step handled here
        // dispatch(setHighlightedSteps(step + 1));
        // // Set Current step number
        // dispatch(disableNavigation());
        // setCurrentSelectedStep(step);
        // // getWillStep(step);
        // const nextIndex = (currentIndex + 1) % stepNumber.length;
        // setCurrentIndex(nextIndex);

        // // setActiveStep((prevActiveStep) => prevActiveStep + 1);
        // // Need more testing here
        // setCurrentBtnStep(step + 1);
        // setActiveStep((prevActiveStep) => prevActiveStep + 1);
        // dispatch(storeActiveStep(step));
        // dispatch(getNewActiveStep(0));
        // dispatch(setNavigationIndex(null));
      } else {
        await dispatch<any>(resetErrorState());
        await dispatch<any>(setErrorInfo(`Please complete Beneficiary Details and ${getThirdStepName(willTypeID)}`));
      }
    } else {
      // ----------------------------------------------------------------
      // Highlighted step handled here
      // dispatch(setHighlightedSteps(step + 1));
      // // Test case
      // // getWillStep(step);
      // dispatch(disableNavigation());
      // const nextIndex = (currentIndex + 1) % stepNumber.length;
      // setCurrentIndex(nextIndex);
      // // dispatch(storeActiveStep(activeStep + 1));

      // // Get stepNumber list from the stepList array
      // const stepNumberList: any = results?.map((res) => Number(res?.stepNumber));

      // // // Handling ICONS navigation in handleNext()
      // if (step === 3) {
      //   setIconNum1(3);
      //   setIconNum2(6);
      // } else if (step === 6) {
      //   setIconNum1(6);
      //   setIconNum2(9);
      // } else if (step === 9) {
      //   if (willTypeID === 2) {
      //     // Guardianship Will
      //     setIconNum1(7);
      //     setIconNum2(10);
      //   } else {
      //     setIconNum1(8);
      //     setIconNum2(11);
      //   }
      // } else if (step > stepNumberList[stepNumberList.length - 2]) {
      //   // setIconNum1(8);
      //   // setIconNum2(11);
      //   navigate('/wills');
      // }

      // // Handle distribution of shares/Real estate distribution in ICONS
      // if (step === 7) {
      //   setIconNum1(6);
      //   setIconNum2(9);
      // }

      // // Set current step to pass as a prop to the further components to use
      // //  the handleNext method in those respective components
      // // NB:increment the step number by 1 to get correct list of completed steps
      // setCurrentBtnStep(step + 1);

      // let newSkipped = skipped;
      // if (isStepSkipped(activeStep)) {
      //   newSkipped = new Set(newSkipped.values());
      //   newSkipped.delete(activeStep);
      // }
      // // Increment activestep from state
      // setActiveStep((prevActiveStep) => prevActiveStep + 1);
      // // Increment currentStep from store state
      // dispatch(storeActiveStep(step));
      // dispatch(setStepFlow());
      // setSkipped(newSkipped);
      // dispatch(getNewActiveStep(0));
      // dispatch(setNavigationIndex(null));

      // if (navigationEnabled) {
      //   setNewCompletedSteps((prevSteps: any) => [
      //     ...prevSteps,
      //     completed ? navigationIndex : null,
      //   ]);
      //   dispatch(setCompletedStepList(completed ? navigationIndex : null));
      //   dispatch(storeActiveStep(navigationIndex));
      //   setActiveStep(navigationIndex);
      // } else {
      //   setNewCompletedSteps((prevStep: any) => [
      //     ...prevStep,
      //     completed ? step : null,
      //   ]);
      //   dispatch(setCompletedStepList(completed ? step : null));
      //   // setNewCompletedSteps((prevStep: any) => [...prevStep,step]);
      // }

      // ----------------------------------------------------------------

      // Stepper/Next Optimisations
      dispatch(setHighlightedSteps(step + 1));
      dispatch(storeActiveStep(step));
      dispatch(getNewActiveStep(0));
      dispatch(setNavigationIndex(step + 1));
      // dispatch(setNavigationIndex(null));

      setNewCompletedSteps((prev:any) => [...prev,completed ? step : null]);
    }
  };
// Handle Scaffolding icons navigation here (manual navigation)
  // React.useEffect(() => {
  //   if (navigationIndex !== null) {
  //     const view1 = [1, 2, 3];
  //     const view2 = [4, 5, 6];
  //     const view3 = [7, 8, 9];
  //     const view4 = [10, 11, 12];
  //     if (view1.includes(navigationIndex)) {
  //       setIconNum1(0);
  //       setIconNum2(3);
  //     } else if (view2.includes(navigationIndex)) {
  //       setIconNum1(3);
  //       setIconNum2(6);
  //     } else if (view3.includes(navigationIndex)) {
  //       setIconNum1(6);
  //       setIconNum2(9);
  //     } else if (view4.includes(navigationIndex)) {
  //       if (willTypeID === 2) {
  //         // Guardianship Will
  //         setIconNum1(7);
  //         setIconNum2(10);
  //       } else {
  //         // All other wills
  //         setIconNum1(8);
  //         setIconNum2(11);
  //       }
  //     }
  //   }
  // }, [navigationIndex, iconNum2, iconNum1]);
// Check condition for completed steps and navigation handling
  // React.useEffect(() => {
  //   if (willTypeID === 2) {
  //     // Guardianship Will
  //     if (
  //       newCompletedSteps.includes(1)
  //       && newCompletedSteps.includes(2)
  //       && newCompletedSteps.includes(4)
  //       && newCompletedSteps.includes(5)
  //       && newCompletedSteps.includes(6) // upload docs
  //     ) {
  //       setIsShowBookAppointment(true);
  //     } else {
  //       setIsShowBookAppointment(false);
  //     }
  //   } else if (willTypeID === 1) {
  //     // Full Will
  //     if (
  //       newCompletedSteps.includes(1)
  //       && newCompletedSteps.includes(2)
  //       && newCompletedSteps.includes(3)
  //       && newCompletedSteps.includes(4)
  //       && newCompletedSteps.includes(7)
  //       && newCompletedSteps.includes(8) // Upload Docs
  //       // && newCompletedSteps.includes(9) // Will Preview
  //     ) {
  //       setIsShowBookAppointment(true);
  //     } else {
  //       setIsShowBookAppointment(false);
  //     }
  //   } else if (
  //     willTypeID === 3 // Property Will
  //     || willTypeID === 5 // Financial Assets Will
  //     || willTypeID === 4 // Buisness Owners Will
  //     || willTypeID === 6 // Templated Full Will
  //   ) {
  //     if (
  //       newCompletedSteps.includes(1)
  //       && newCompletedSteps.includes(2)
  //       && newCompletedSteps.includes(3)
  //       && newCompletedSteps.includes(4)
  //       && newCompletedSteps.includes(5)
  //       && newCompletedSteps.includes(6)
  //       && newCompletedSteps.includes(7)
  //       && newCompletedSteps.includes(8) // Upload Docs
  //       // && newCompletedSteps.includes(9) // Will Preview
  //     ) {
  //       setIsShowBookAppointment(true);
  //     } else {
  //       setIsShowBookAppointment(false);
  //     }
  //   }
  // }, [newCompletedSteps]);
const handleNext = async (
    step: number,
    stepName?: any,
    completed?: boolean,
  ) => {
    console.log('STEPNUMBER', step);
    window.scrollTo(0, 0);
    setStepCompleted(completed);
    setCurrentSelectedStep(step);
    // Revert Active Service Funtionalities back to initial state on first handleNext Step
    dispatch(setIsChangeService(false));
    // dispatch(setIsCompleteWillInfo(false));
    dispatch(setModifyAppointment(false));
    // dispatch(setIsUpgradeWill(false));

    // Set upgradeWill flag to false if next clicked from Personal Details
    if (stepName === 'personal') {
      dispatch(setIsUpgradeWill(false));
    }

    // Completed Step handling --> remove after testing
    // if (completed === false) {
    //   const completedSteps = [...newCompletedSteps];
    //   const newSteps = completedSteps.filter((s: any) => s !== step);
    //   const unique = newSteps.filter(
    //     (item, index) => newSteps.indexOf(item) === index,
    //   );
    //   setNewCompletedSteps(newSteps);
    // }

    // Show selection option in Real Estate Distribution for Property Will up on next from beneficiary Details
    if (step === 5) {
      dispatch(clearSelectedDistribution());
    }

    // If quick booking is enabled
    if (isQuickBooking && stepName !== 'willTypeSelection') {
      setActiveStep(8);
      if (stepName === 'bookAppointment') {
        setActiveStep((prev) => prev + 1);
      }
    } else if (!isQuickBooking && stepName !== 'willTypeSelection') {
      // setActiveStep(3);
    }

    if (stepName === 'personal' && isQuickBooking) {
      setShowSkipToAppointmentModal(true);
    }

    // If upload documents is active and Book appointment is visible
    if (stepName === 'upload' && !isShowBookAppointment) {
      // Incomplete steps API called here
      try {
        const response = await trackPromise(
          api.validateWillSteps(
            profileGuid,
            spouseGuid,
            isSpouseSelected ? spouseGuid : profileGuid,
            serviceId,
          ),
        );
        // Save incomplete steps list in store (redux)
        dispatch(getIncompleteSteps(response?.data?.Output));
        const incompletedSteps = response?.data?.Output;
        const testatorIncompleteSteps = incompletedSteps.filter((step:any) => step.bookedForProfileGuid === profileGuid);
        const spouseIncompleteSteps = incompletedSteps.filter((step:any) => step.bookedForProfileGuid === spouseGuid);
        console.log('testatorIncompleteSteps', testatorIncompleteSteps);
        console.log('spouseIncompleteSteps', spouseIncompleteSteps);

        // Mirror Will && Testator
        if (mirrorWillCheck && !isSpouseSelected) {
          if (testatorIncompleteSteps.length !== 0) {
            handleShowIncompleteStepsModal();
          } else {
            // alert('go to next step');
            dispatch(setHighlightedSteps(9));
            dispatch(setNavigationIndex(9));
            dispatch(getNewActiveStep(13));
          }
        } else if (mirrorWillCheck && isSpouseSelected) { // Mirror Will && Spouse
          if (spouseIncompleteSteps.length !== 0) {
            handleShowIncompleteStepsModal();
          } else {
            dispatch(setHighlightedSteps(9));
            dispatch(setNavigationIndex(9));
            dispatch(getNewActiveStep(13));
          }
        }

        if (singleWillCheck) {
          // Show incomplete steps Modal only if the response is not empty
          if (incompletedSteps.length !== 0) {
            handleShowIncompleteStepsModal();
          } else {
          // Ask for confirmation on this functionality
            setIsShowBookAppointment(true);
            // Set View component, highlighted step in stepper and icon
            dispatch(setHighlightedSteps(9));
            dispatch(setNavigationIndex(9));
            dispatch(getNewActiveStep(21));
            setNewCompletedSteps((prev: any) => [...prev, 3, 4, 5, 6, 7, 8]);
          // dispatch(storeActiveStep(9));
          }
        }
      } catch (error) {
        console.log(error);
      }
    } else if (stepName === 'beneficiary-details' && willTypeID !== 1) {
      // Not needed for Full Will
      // If property and beneficiray is added then only we can navigate or go next to Real Estate Distribution
      if (propertyAdded && beneficiaryAdded) {
        dispatch(setHighlightedSteps(6));
        dispatch(getNewActiveStep(getStepIDFromBeneficiaryStep(willTypeID)));
        dispatch(setNavigationIndex(null));
        // // Highlighted step handled here
        // dispatch(setHighlightedSteps(step + 1));
        // // Set Current step number
        // dispatch(disableNavigation());
        // setCurrentSelectedStep(step);
        // // getWillStep(step);
        // const nextIndex = (currentIndex + 1) % stepNumber.length;
        // setCurrentIndex(nextIndex);

        // // setActiveStep((prevActiveStep) => prevActiveStep + 1);
        // // Need more testing here
        // setCurrentBtnStep(step + 1);
        // setActiveStep((prevActiveStep) => prevActiveStep + 1);
        // dispatch(storeActiveStep(step));
        // dispatch(getNewActiveStep(0));
        // dispatch(setNavigationIndex(null));
      } else {
        await dispatch<any>(resetErrorState());
        await dispatch<any>(setErrorInfo(`Please complete Beneficiary Details and ${getThirdStepName(willTypeID)}`));
      }
    } else {
      // ----------------------------------------------------------------
      // Highlighted step handled here
      // dispatch(setHighlightedSteps(step + 1));
      // // Test case
      // // getWillStep(step);
      // dispatch(disableNavigation());
      // const nextIndex = (currentIndex + 1) % stepNumber.length;
      // setCurrentIndex(nextIndex);
      // // dispatch(storeActiveStep(activeStep + 1));

      // // Get stepNumber list from the stepList array
      // const stepNumberList: any = results?.map((res) => Number(res?.stepNumber));

      // // // Handling ICONS navigation in handleNext()
      // if (step === 3) {
      //   setIconNum1(3);
      //   setIconNum2(6);
      // } else if (step === 6) {
      //   setIconNum1(6);
      //   setIconNum2(9);
      // } else if (step === 9) {
      //   if (willTypeID === 2) {
      //     // Guardianship Will
      //     setIconNum1(7);
      //     setIconNum2(10);
      //   } else {
      //     setIconNum1(8);
      //     setIconNum2(11);
      //   }
      // } else if (step > stepNumberList[stepNumberList.length - 2]) {
      //   // setIconNum1(8);
      //   // setIconNum2(11);
      //   navigate('/wills');
      // }

      // // Handle distribution of shares/Real estate distribution in ICONS
      // if (step === 7) {
      //   setIconNum1(6);
      //   setIconNum2(9);
      // }

      // // Set current step to pass as a prop to the further components to use
      // //  the handleNext method in those respective components
      // // NB:increment the step number by 1 to get correct list of completed steps
      // setCurrentBtnStep(step + 1);

      // let newSkipped = skipped;
      // if (isStepSkipped(activeStep)) {
      //   newSkipped = new Set(newSkipped.values());
      //   newSkipped.delete(activeStep);
      // }
      // // Increment activestep from state
      // setActiveStep((prevActiveStep) => prevActiveStep + 1);
      // // Increment currentStep from store state
      // dispatch(storeActiveStep(step));
      // dispatch(setStepFlow());
      // setSkipped(newSkipped);
      // dispatch(getNewActiveStep(0));

      // if (navigationEnabled) {
      //   setNewCompletedSteps((prevSteps: any) => [
      //     ...prevSteps,
      //     completed ? navigationIndex : null,
      //   ]);
      //   dispatch(setCompletedStepList(completed ? navigationIndex : null));
      //   dispatch(storeActiveStep(navigationIndex));
      //   setActiveStep(navigationIndex);
      // } else {
      //   setNewCompletedSteps((prevStep: any) => [
      //     ...prevStep,
      //     completed ? step : null,
      //   ]);
      //   dispatch(setCompletedStepList(completed ? step : null));
      //   // setNewCompletedSteps((prevStep: any) => [...prevStep,step]);
      // }

      // ----------------------------------------------------------------

      // Stepper/Next Optimisations
      dispatch(setHighlightedSteps(step + 1));
      dispatch(storeActiveStep(step));
      dispatch(getNewActiveStep(0));
      dispatch(setNavigationIndex(step + 1));
      // dispatch(setNavigationIndex(null));

      setNewCompletedSteps((prev:any) => [...prev,completed ? step : null]);
    }
  };
 // if (willPreviewCompleted && mirrorWillCheck) {
    //   // If modal handled from WillPreview
    //   if (fromWillPreview && !isSpouseSelected) {
    //     // From willPreview of Main Testator
    //     dispatch(setIsSpouseSelected(true));
    //     dispatch(setFromWillPreview(false));
    //   } else if (fromWillPreview && isSpouseSelected) {
    //     // From will Preview of Spouse
    //     dispatch(setIsSpouseSelected(false));
    //   }

    //   // If modal handled from UploadDocs ==> PS --> No need to check isSpouseSelected
    //   if (fromUploadDocs) {
    //     dispatch(setIsSpouseSelected(!!isSpouseSelected));
    //     dispatch(setFromUploadDocs(false));
    //   }
    //   try {
    //     const completedSteps = await trackPromise(
    //       api.getCompletedStepsListByGUID(
    //         isSpouseSelected ? spouseGuid : profileGuid,
    //       ),
    //     );
    //     const completedStepNumbers = completedSteps?.data?.Output;
    //     const steps = completedStepNumbers.map((stepNumber: any) => Number(stepNumber.stepNumber));
    //     console.log('willPreviewCompletedsteps', steps);
    //     setTimeout(() => {
    //       setNewCompletedSteps(steps);
    //     }, 100);
    //   } catch (error) {
    //     dispatch(resetErrorState());
    //     dispatch(setErrorInfo('Some Error occured !'));
    //   }
    // }

    // if (mirrorWillCheck && fromWillPreview) {
    //   dispatch(setFromWillPreview(false));
    //   if (!isSpouseSelected) { // Testator
    //     setIsSpouseSelected(!isSpouseSelected);
    //   } else if (isSpouseSelected) { // Spouse
    //     setIsSpouseSelected(false);
    //   }
    // }

    // setShowModal(false);
    // // setActiveStep(number);
    // // console.log('steplabelid', id);
    // dispatch(setNavigationIndex(id));
    // // // Handle highlighted step here
    // dispatch(setHighlightedSteps(id)); // PS:: This is stepNumber
    // // // setCurrentSelectedStep(number);
    // // // First incomplete stepID
    // // // Set willStep component here
    // dispatch(getNewActiveStep(number)); // PS:: This is stepID

    // Set scaffolding icons according to selection
    // if (willTypeID === 3) {
    //   // Property Will
    //   if (id === 3) {
    //     setIconNum1(0);
    //     setIconNum2(3);
    //     dispatch(setNavigationIndex(id));
    //   } else if (id === 4 || id === 5 || id === 6) {
    //     setIconNum1(3);
    //     setIconNum2(6);
    //     dispatch(setNavigationIndex(id));
    //   } else if (id === 7 || id === 8) {
    //     setIconNum1(6);
    //     setIconNum2(9);
    //     dispatch(setNavigationIndex(id));
    //   }
    // } else if (willTypeID === 2) {
    //   // Guardianship Will
    //   if (id === 2) {
    //     setIconNum1(0);
    //     setIconNum2(3);
    //     dispatch(setNavigationIndex(id));
    //   } else if (id === 3 || id === 4 || id === 5) {
    //     setIconNum1(3);
    //     setIconNum2(6);
    //     dispatch(setNavigationIndex(id));
    //   } else if (id === 6 || id === 7) {
    //     setIconNum1(6);
    //     setIconNum2(9);
    //     dispatch(setNavigationIndex(id));
    //   }
    // } else if (willTypeID === 6) {
    //   // Templated Full Will
    //   if (id === 3) {
    //     setIconNum1(0);
    //     setIconNum2(3);
    //     dispatch(setNavigationIndex(id));
    //   } else if (id === 4 || id === 5 || id === 6) {
    //     setIconNum1(3);
    //     setIconNum2(6);
    //     dispatch(setNavigationIndex(id));
    //   } else if (id === 7 || id === 8) {
    //     setIconNum1(6);
    //     setIconNum2(9);
    //     dispatch(setNavigationIndex(id));
    //   }
    // } else if (willTypeID === 4) {
    //   // Business Owners Will
    //   if (id === 3) {
    //     setIconNum1(0);
    //     setIconNum2(3);
    //     dispatch(setNavigationIndex(id));
    //   } else if (id === 4 || id === 5 || id === 6) {
    //     setIconNum1(3);
    //     setIconNum2(6);
    //     dispatch(setNavigationIndex(id));
    //   } else if (id === 7 || id === 8) {
    //     setIconNum1(6);
    //     setIconNum2(9);
    //     dispatch(setNavigationIndex(id));
    //   }
    // } else if (willTypeID === 5) {
    //   // Financial Assets Will
    //   if (id === 3) {
    //     setIconNum1(0);
    //     setIconNum2(3);
    //     dispatch(setNavigationIndex(id));
    //   } else if (id === 4 || id === 5 || id === 6) {
    //     setIconNum1(3);
    //     setIconNum2(6);
    //     dispatch(setNavigationIndex(id));
    //   } else if (id === 7 || id === 8) {
    //     setIconNum1(6);
    //     setIconNum2(9);
    //     dispatch(setNavigationIndex(id));
    //   }
    // } else if (willTypeID === 1) {
    //   // Full Will
    //   if (id === 3) {
    //     setIconNum1(0);
    //     setIconNum2(3);
    //     dispatch(setNavigationIndex(id));
    //   } else if (id === 4 || id === 5 || id === 6) {
    //     setIconNum1(3);
    //     setIconNum2(6);
    //     dispatch(setNavigationIndex(id));
    //   } else if (id === 7 || id === 8) {
    //     setIconNum1(6);
    //     setIconNum2(9);
    //     dispatch(setNavigationIndex(id));
    //   }
    // }
{
  "manifest": {
    "a": {
      "stylesheet": {
        "colors": {
          "primary": "black",
          "secondary": "#C89E56",
          "tertiary": "#C89E56"
        },
        "images": {
          "favicon": {
            "url": "https://cdn.myocv.com/ocvapps/a100879096/files/Badge-Icon@2x.png",
            "altText": ""
          },
          "titleImage": {
            "url": "https://cdn.myocv.com/ocvapps/a100879096/files/Badge-Icon@2x.png",
            "altText": ""
          }
        }
      },
      "homeOrder": [
        "slider",
        "featureBar",
        "welcome",
        "newsDigest",
        "jailInfo",
        "careerOp",
        "downloadOurApp"
      ],
      "baseLayout": [
        "{component}"
      ],
      "features": {
        "news": {
          "type": "newsDigestList",
          "url": "https://apps.myocv.com/feed/digest/a100879096/facebook",
          "title": "Social Media",
          "config": {
            "displayDate": true,
            "type": "newsDigestList",
            "limit": 10
          }
        },
        "contact": {
          "type": "contacts",
          "url": "https://cdn.myocv.com/ocvapps/a100879096/public/contact_contactUs.json",
          "title": "Contact Us",
          "limit": 10
        },
        "faq": {
          "type": "blogFAQ",
          "url": "https://cdn.myocv.com/ocvapps/a100879096/public/blog_fAQs.json",
          "title": "FAQ",
          "config": {
            "limit": 10
          }
        },
        "joinOurTeam": {
          "title": "Join Our Team",
          "type": "form",
          "url": "https://cdn.myocv.com/ocvapps/a100879096/public/form_joinOurTeam.json",
          "formID": "joinOurTeam"
        },
        "submitATip": {
          "title": "Submit A Tip",
          "type": "form",
          "url": "https://cdn.myocv.com/ocvapps/a100879096/public/form_submitATip.json",
          "formID": "submitATip"
        },
        "sexOffender": {
          "title": "Sex Offenders Map",
          "type": "sexOffendersMap",
          "url": "https://myocv.s3.amazonaws.com/ocvapps/a100879096/sexOffenders-TX.json",
          "config": {
            "zoom": 10,
            "clusterSize": 3
          }
        },
        "inmateSearch": {
          "title": "Inmate Search",
          "type": "feedList",
          "url": "https://apps.myocv.com/feed/rtjb/a100879096/inmates",
          "config": {
            "submitATipLink": true,
            "backgroundColor": "#eee",
            "showImage": "top",
            "blogKey": "inmates",
            "limit": 10,
            "appID": "a100879096",
            "type": "rtjb",
            "displayDate": false,
            "truncation": true,
            "sort": "nameAZ",
            "showSort": false,
            "showSearch": true
          }
        },
        "caseReport": {
          "title": "Case Report",
          "type": "form",
          "url": "https://cdn.myocv.com/ocvapps/a100879096/public/form_caseReport.json",
          "formID": "caseReport"
        },
        "closePatrolRequest": {
          "title": "Close Patrol Request",
          "type": "form",
          "url": "https://cdn.myocv.com/ocvapps/a100879096/public/form_closePatrolRequest.json",
          "formID": "closePatrolRequest"
        },
        "livestockOwnerLocation": {
          "title": "Livestock Owner/Location",
          "type": "form",
          "url": "https://cdn.myocv.com/ocvapps/a100879096/public/form_livestockOwnerLocation.json",
          "formID": "livestockOwnerLocation"
        },
        "crashReports": {
          "title": "Crash Reports",
          "type": "webview",
          "url": "https://cris.dot.state.tx.us/public/Purchase/app/home",
          "external": true
        },
        "backgroundCheck": {
          "title": "Background Check",
          "type": "webview",
          "url": "https://publicsite.dps.texas.gov/ConvictionNameSearch/",
          "external": true
        },
        "fingerprints": {
          "title": "Fingerprints",
          "type": "webview",
          "url": "https://www.identogo.com/services/live-scan-fingerprinting",
          "external": true
        },
        "civilServicesFees": {
          "title": "Civil Services Fees",
          "type": "page",
          "url": "https://cdn.myocv.com/ocvapps/a100879096/public/page_civilServiceFees.json"
        },
        "sheriffTaxSales": {
          "title": "Sheriff Tax Sales",
          "type": "page",
          "url": "https://cdn.myocv.com/ocvapps/a100879096/public/page_sheriffTaxSales.json"
        },
        "crimePrevention": {
          "title": "Crime Prevention",
          "type": "blogList",
          "url": "https://cdn.myocv.com/ocvapps/a100879096/public/blog_crimePrevention.json",
          "config": {
            "blogKey": "blog_crimePrevention",
            "limit": 4,
            "appID": "a100879096",
            "type": "blog",
            "displayDate": false,
            "truncation": false,
            "sort": "dateDesc",
            "showSort": false,
            "showSearch": false
          }
        },
        "payCitations": {
          "title": "Pay Citations",
          "type": "blogList",
          "url": "https://cdn.myocv.com/ocvapps/a100879096/public/blog_payCitations.json",
          "config": {
            "blogKey": "blog_payCitations",
            "limit": 4,
            "appID": "a100879096",
            "type": "blog",
            "displayDate": false,
            "truncation": false,
            "sort": "dateDesc",
            "showSort": false,
            "showSearch": false
          }
        },
        "jailInformation": {
          "title": "Jail Information",
          "type": "blogList",
          "url": "https://cdn.myocv.com/ocvapps/a100879096/public/blog_jailInformation.json",
          "config": {
            "blogKey": "blog_jailInformation",
            "limit": 10,
            "appID": "a100879096",
            "type": "blog",
            "displayDate": false,
            "truncation": false,
            "sort": "dateDesc",
            "showSort": false,
            "showSearch": false
          }
        },
        "recordsSubmenu": {
          "navHeader": "Records Request",
          "type": "submenu",
          "dropdown": [
            "caseReport",
            "crashReports",
            "backgroundCheck",
            "closePatrolRequest",
            "livestockOwnerLocation"
          ]
        },
        "resourcesSubmenu": {
          "navHeader": "Resources",
          "type": "submenu",
          "dropdown": [
            "crimePrevention",
            "civilServicesFees",
            "fingerprints",
            "payCitations",
            "sheriffTaxSales"
          ]
        }
      },
      "views": {
        "navbar": {
          "type": "navbar",
          "config": {
            "hideSearch": true,
            "title": "Wheeler County<br/> Sheriff's Office TX",
            "socialMedia": [
              {
                "icon": "facebook",
                "url": "https://www.facebook.com/WheelerCountySO/"
              }
            ],
            "items": [
              "contact",
              "recordsSubmenu",
              "faq",
              "resourcesSubmenu"
            ]
          }
        },
        "footer": {
          "type": "footer",
          "config": {
            "vertical": "sheriff",
            "title": "Wheeler County Sheriff's Office TX",
            "socialMedia": [
              {
                "icon": "facebook",
                "url": "https://www.facebook.com/WheelerCountySO/"
              }
            ],
            "item1": {
              "title": "CONTACT",
              "address": "7944 US-83,<br/> WHEELER, TX 79096",
              "phoneName": "Phone: ",
              "phone": "(806) 826-5537",
              "businessHours": "HOURS: 8:00 A.M. - 5:00 P.M. CST <br/>MONDAY THROUGH FRIDAY."
            },
            "item2": {
              "title": "RESOURCES",
              "options": [
                {
                  "feature": "joinOurTeam",
                  "featureText": "Join Our Team"
                }
              ]
            },
            "item3": {
              "buttonColor": "#C89E56",
              "buttonText": "DOWNLOAD OUR APP",
              "buttonTextColor": "#0F2445",
              "buttonBorderColor": "#C89E56",
              "buttonLink": "https://apps.myocv.com/share/a100879096"
            }
          }
        },
        "slider": {
          "type": "slider",
          "config": {
            "interval": 6000,
            "height": "600px",
            "media": [
              {
                "mediaURL": "https://cdn.myocv.com/ocvapps/a100879096/files/Header%203@2x.png",
                "mediaAlt": "Wheeler CSO Car"
              }
            ]
          }
        },
        "downloadOurApp": {
          "type": "slider",
          "config": {
            "interval": 6000,
            "externalURL": "https://apps.myocv.com/share/a100879096",
            "height": "600px",
            "media": [
              {
                "mediaURL": "https://cdn.myocv.com/ocvapps/a100879096/files/downloadourapp.png",
                "mediaAlt": "Download Our App"
              }
            ]
          }
        },
        "featureBar": {
          "title": "Quick Links",
          "type": "featureBar",
          "config": {
            "items": [
              {
                "title": "Submit A Tip",
                "feature": "submitATip",
                "icon": "submit"
              },
              {
                "title": "Sex Offender",
                "feature": "sexOffender",
                "icon": "personSearch"
              },
              {
                "title": "Inmate Search",
                "feature": "inmateSearch",
                "icon": "jail"
              },
              {
                "title": "Join Our Team",
                "feature": "joinOurTeam",
                "icon": "team"
              }
            ],
            "showVertical": false,
            "showHeading": true,
            "titleColor": "white",
            "headingColor": "white",
            "tileColor": "#C89E56",
            "bgColor": "#181818",
            "verticalColor": "#C89E56",
            "textColor": "white"
          }
        },
        "welcome": {
          "title": "Wheeler County Sheriff's Office TX",
          "type": "welcome",
          "characteristics": "Integrity | Professionalism | Commitment | Honesty | Trust | Respect",
          "subTitle": "As a Sheriff's Office, we value:",
          "imageCaption": "Sheriff Johnny Carter",
          "url": "https://cdn.myocv.com/ocvapps/a100879096/public/page_wEBWelcome.json",
          "config": {
            "showCaption": true,
            "titleColor": "black",
            "showSubTitle": true
          }
        },
        "newsDigest": {
          "title": "Social Media",
          "type": "newsDigest",
          "feature": "news",
          "config": {
            "titleColor": "white",
            "displayDate": true,
            "socialBar": false,
            "socialBarName": "socialBar",
            "bgColor": "black",
            "buttonTextColor": "black",
            "buttonBgColor": "#C89E56",
            "backgroundSize": "cover",
            "buttonText": "View More Posts",
            "buttonLink": "news"
          }
        },
        "jailInfo": {
          "title": "Jail Information",
          "type": "twoColumnButton",
          "url": "https://cdn.myocv.com/ocvapps/a100879096/public/page_jailInfo.json",
          "config": {
            "bgColor": "#eee",
            "textColor": "black",
            "titleColor": "black",
            "align": "center",
            "buttons": [
              {
                "buttonFeature": "jailInformation",
                "buttonText": "Learn More",
                "buttonTextColor": "black",
                "buttonColor": "#C89E56"
              }
            ]
          }
        },
        "careerOp": {
          "title": "Career Opportunities",
          "type": "twoColumnButton",
          "url": "https://cdn.myocv.com/ocvapps/a100879096/public/page_careerOpportunities.json",
          "config": {
            "row": "row-reverse",
            "bgColor": "#eee",
            "titleColor": "black",
            "align": "center",
            "buttons": [
              {
                "buttonFeature": "joinOurTeam",
                "buttonText": "Apply Now",
                "buttonTextColor": "black",
                "buttonColor": "#C89E56"
              }
            ]
          }
        }
      }
    }
  },
  "lookup": {
    "web": {
      "4.1.0": {
        "1": "a",
        "dev": "a",
        "prod": "a"
      }
    },
    "ios": [],
    "android": []
  }
}
<p><embed src="https://www.instagram.com/leecosheriffal/embed/?cr=1&amp;v=14&amp;wp=1080&amp;rd=https%3A%2F%2Fcdpn.io&amp;rp=%2Fcpe%2Fboomboom%2Findex.html%3Fkey%3Dindex.html-fcf10232-f752-7989-78a4-2f978a8ff956#%7B%22ci%22%3A0%2C%22os%22%3A228.39999999850988%2C%22ls%22%3A109.09999999962747%2C%22le%22%3A225.19999999925494%7D" /></p>
<p><embed src="https://www.facebook.com/plugins/page.php?href=https%3A%2F%2Ffacebook.com%2FleeCoSheriffAL&amp;tabs=timeline&amp;width=500&amp;height=500&amp;small_header=false&amp;adapt_container_width=true&amp;hide_cover=false&amp;show_facepile=false&amp;appId" width="500" height="500" /></p>
const beneficiaryArray = updatedBen.filter(
      (el: any) => el.parentProfileGUID === '',
    );
    console.log('beneficiaryArray', beneficiaryArray);

    // Substitute validation for all other willtypes (PW,FAW)
    // Get Array of all substitutes in the payload
    const substitutesArray = updatedBen.filter(
      (el: any) => el.parentProfileGUID !== '',
    ); // Filter out substitutes from payload
    console.log('substitutesArray', substitutesArray);
    // Check if the list of substitutes is updated for each iteration
    const substituteListForTest = checkSubstitutePresent(
      substitutesArray,
      beneficiaryList,
    );
    console.log('substituteListForTest', substituteListForTest);

    // New Method testing

    function filterPayloadByProperty(data:any) {
      const groups = data.reduce((result:any, item:any) => {
        const key = item.propertyGUID;
        if (!result[key]) {
          result[key] = [];
        }
        result[key].push(item);
        return result;
      }, {});

      return Object.values(groups);
    }

    function getSharesSum(arr:any) {
      return arr.map((subArray:any) => subArray.reduce((sum:any, num:any) => sum + num, 0));
    }

    const filteredData = filterPayloadByProperty(beneficiaryArray); // filter by propertyGUID
    console.log('filteredData', filteredData);

    const sharePercentages = filteredData.map((subArray:any) => subArray.map((obj:any) => obj.sharePercentage));

    console.log('sharePercentages', sharePercentages);

    const sums = getSharesSum(sharePercentages); // Sum of shares
    console.log('sums', sums);

    const validationTrue = sums.every((value:any) => value === 100); // Check if shares === 100
    console.log('valid', validationTrue);

    // if (validationTrue) {
    // dispatch<any>(submitshareDetails(isSpouseSelected ? spouseShares : husbandShares));
    // dispatch(setBySharesSubmitted(false));
    // handleNext(6, 'by-specific', isCompleted);
    // }

    // New Method testing end

    // Filter substitutes by property/account/company
    const filteredSubArrays = filterDataByPropertyGUID(substituteListForTest);
    console.log('filteredSubArrays', filteredSubArrays);
    // Calculate total sum of shares of the substitutes
    const substituteSharesTotalSum = calculateShareSum(filteredSubArrays);
    console.log('substituteSharesTotalSum', substituteSharesTotalSum);
    const substringsToRemove: string[] = ['undefined', 'null'];

    // Remove undefined and null values from the list
    const filteredObject = removeUndefinedAndNull(
      substituteSharesTotalSum,
      substringsToRemove,
    );
    console.log('filteredSubObject', filteredObject);

    // Remove Zeros from the list
    const removedZeros = removeZeroValues(filteredObject);
    console.log('removedZeros', removedZeros);

    // Condition to check substitute validation
    const subShareValidation = Object.values(removedZeros).every(
      (value) => value === 100,
    );

    // Substitute validation ends for all other WillTypes

    // Case 8 test ---
    // Normal Working case
    // const benCountList: any[] = updatedBenList1.filter(
    //   (ben: any) => ben.subBeneficiaryList.length !== 0 && ben.sharePercentage !== 0,
    // );
    const hus = updatedBenList1.filter(
      (ben: any) => ben.bookedForProfileGUID === profileGuid,
    );
    const spouse = updatedBenList1.filter(
      (ben: any) => ben.bookedForProfileGUID === spouseGuid,
    );
    const benCountList: any[] = (isSpouseSelected ? spouse : hus).filter(
      (ben: any) => ben.subBeneficiaryList?.length !== 0 && ben?.sharePercentage !== 0,
    );
    console.log('benCountList', benCountList);

    // Buisness Owners Will Substitute Validation

    // Check substitute validation in Buisness Owners Will
    // const substituteValidationBOW = checkSubstituteValidationBOW(
    //   subSharesBow,
    //   // benCountList,
    //   removedZeros,
    // );
    // console.log('substituteValidationBOW', substituteValidationBOW);

    // New test case --> Working but needs thorough testing
    // Add combined guids of propertyGUID and profileGUID
    const combinedArray = benCountList.map((obj: any) => ({
      ...obj,
      combinedGUID: `${obj.propertyGUID}-${obj.profileGUID}`,
    }));
    console.log('combinedArray', combinedArray);
    // Returns a list of shares and their corresponding combinedGUID's (propertyGUID + profileGUID)
    const subSharesList = getSharePercentages(combinedArray, removedZeros);
    console.log('subSharesArray', subSharesList);
    // Validate the substitute shares with the beneficiary shares
    const isSubstituteSharesValidBOW = validateShares(
      subSharesList,
      removedZeros,
    );
    console.log('isValid', isSubstituteSharesValidBOW);
    // Check if combinedGUID === key of substituteArray
    // const hasMatchingSharePercentage = checkSharePercentage(combinedArray, removedZeros);
    // console.log('hasMatchingSharePercentage', hasMatchingSharePercentage);

    // Check if substitute is present
    const isSubPresent = beneficiaryList.some(
      (el: any) => el.subBeneficiaryList.length !== 0,
    );

    const latestBenArray = updatedBen.filter((item1: any) => updatedBen.some(
      (item2: any) => item1.profileGUID === item2.parentProfileGUID,
    ));
    // console.log('latestBenArray', latestBenArray);
    const filteredLatestBenList = latestBenArray.filter(
      (e: any) => e.propertyGUID !== null,
    );
    console.log('filteredLatestBenList', filteredLatestBenList);
    const removeZeroFromBen = filteredLatestBenList.filter(
      (e: any) => e.sharePercentage !== 0,
    );
    console.log('removeZeroFromBen', removeZeroFromBen);

    // Substitute validation ends ---------------------------------------------------------------

    // Beneficiary Validation 2.0 (current version)
    // Get the total count of beneficiaries with substitutes
    // Check if the list of beneficiaries is updated for each iteration
    const beneficiaryListForTest = checkBeneficiaryPresent(
      beneficiaryArray,
      beneficiaryList,
    );
    console.log('beneficiaryListForTest', beneficiaryListForTest);

    // Filter beneficiaries by Property/Account/Company
    const filteredBenArrays = filterDataByPropertyGUID(beneficiaryListForTest);
    console.log('filteredBenArrays', filteredBenArrays);

    // Calculate total sum of shares of the beneficiaries of each property/account/company
    const benSharesTotalSum = calculateShareSum(filteredBenArrays);
    console.log('benSharesTotalSum', benSharesTotalSum);

    // Filter each beneficiary by property/account/company (Remove undefined and null values)
    const filteredObj = removeUndefinedAndNullForBen(benSharesTotalSum);
    console.log('filteredBenObj', filteredObj);

    // Condition to check beneficiary validation (Total shares === 100)
    const benShareValidation = Object.values(filteredObj).every(
      (value) => value === 100,
    );
    console.log('benShareValidation', benShareValidation);

    // Buisness Owners Will Beneficiary Validation
    const sharesForbow = getSharesForBOW(filteredObj);
    const sharesIterator = sharesForbow[Symbol.iterator]();
    console.log('sharesIterator', sharesIterator);

    // Beneficiary Validation for BOW
    const benShareValidationBOW = Object.values(filteredObj).every(
      (value) => value === sharesIterator.next().value,
    );
    console.log('benShareValidationBOW', benShareValidationBOW);

    const getListType = () => {
      if (willTypeID === 3) return propertyList;
      if (willTypeID === 5) return accountList;
      if (willTypeID === 4) return companyShareInformationList;
      return null;
    };

    const list = getListType();
    console.log('listType', list);

    // Check property/account/company list length
    const propertySharesObject = filterByPropertyList(
      filteredObj,
      list,
      willTypeID,
    );
    console.log('propertySharesObject', propertySharesObject);
    // propertyList || accountList || companyShareInformationList

    // Check if all properties/accounts/companies are allocated shares
    let checkLength: boolean;
    if (
      (accountList.length
        || propertyList.length
        || companyShareInformationList.length)
      === Object.keys(propertySharesObject).length
    ) {
      // Add Company List when working on BOW
      checkLength = true;
    }

    // Allow submission only if the shares have been allocated
    if (updatedBen.length !== 0 && checkLength) {
      // Property Will && Financial Assets Will
      if (willTypeID === 5 || willTypeID === 3) {
        // Financial Assets Will && Property Will
        if (isSubPresent) {
          // IF  substitute is present check validation for beneficiaries & substitutes
          const checkSubLength = benCountList.length === Object.keys(removedZeros).length;
          // const checkSubLength = benCountList.length === subCount * accountList.length;
          console.log('checkSubLength', checkSubLength);

          // if (substituteSharesList.length !== 0) {
          // Check beneficiary && substitute validation here
          if (
            benShareValidation
            && subShareValidation
            && checkSubLength
            // && filteredLatestBenList.length !== 0
          ) {
            // dispatch<any>(submitshareDetails(updatedBen));
            dispatch<any>(
              submitshareDetails(
                isSpouseSelected ? spouseShares : husbandShares,
              ),
            );
            dispatch(setBySharesSubmitted(false));
            handleNext(6, 'by-specific', isCompleted);
          } else {
            await dispatch(resetErrorState());
            await dispatch(
              setErrorInfo('Please enter shares for all substitutes'),
            );
          }
          // }
        } else if (!isSubPresent) {
          // Working smoothly -- Beneficiary Validation working with single & multiple accounts/properties
          // Beneficiary validation only
          if (benShareValidation) {
            dispatch<any>(
              submitshareDetails(
                isSpouseSelected ? spouseShares : husbandShares,
              ),
            );
            dispatch(clearUpdatedBenList());
            dispatch(setBySharesSubmitted(false));
            handleNext(6, 'by-specific', isCompleted);
          } else {
            await dispatch(resetErrorState());
            await dispatch(
              setErrorInfo('Please enter shares for all beneficiaries'),
            );
          }
        }
      } else {
        // Buisness Owners Will
        if (!isSubPresent) {
          if (benShareValidationBOW) {
            dispatch<any>(
              submitshareDetails(
                isSpouseSelected ? spouseShares : husbandShares,
              ),
            );
            dispatch(setBySharesSubmitted(false));
            handleNext(6, 'by-specific', isCompleted);
          } else {
            await dispatch(resetErrorState());
            await dispatch(
              setErrorInfo('Please enter shares for all beneficiaries'),
            );
          }
        } else if (isSubPresent) {
          // Substitute is present
          console.log('Substitute Present');
          const checkSubLength = benCountList.length === Object.keys(removedZeros).length;
          if (
            benShareValidationBOW
            // && substituteValidationBOW
            && isSubstituteSharesValidBOW
            && checkSubLength
            // && filteredLatestBenList.length !== 0
          ) {
            dispatch<any>(
              submitshareDetails(
                isSpouseSelected ? spouseShares : husbandShares,
              ),
            );
            dispatch(setBySharesSubmitted(false));
            handleNext(6, 'by-specific', isCompleted);
          } else {
            await dispatch(resetErrorState());
            await dispatch(
              setErrorInfo('Please enter shares for all substitutes'),
            );
          }
        }
      }
    } else {
      await dispatch(resetErrorState());
      await dispatch(setErrorInfo('Please assign the shares'));
    }
    // -----
const beneficiaryArray = updatedBen.filter(
      (el: any) => el.parentProfileGUID === '',
    );
    console.log('beneficiaryArray', beneficiaryArray);

    // Substitute validation for all other willtypes (PW,FAW)
    // Get Array of all substitutes in the payload
    const substitutesArray = updatedBen.filter(
      (el: any) => el.parentProfileGUID !== '',
    ); // Filter out substitutes from payload
    console.log('substitutesArray', substitutesArray);
    // Check if the list of substitutes is updated for each iteration
    const substituteListForTest = checkSubstitutePresent(
      substitutesArray,
      beneficiaryList,
    );
    console.log('substituteListForTest', substituteListForTest);

    // New Method testing

    function filterPayloadByProperty(data:any) {
      const groups = data.reduce((result:any, item:any) => {
        const key = item.propertyGUID;
        if (!result[key]) {
          result[key] = [];
        }
        result[key].push(item);
        return result;
      }, {});

      return Object.values(groups);
    }

    function getSharesSum(arr:any) {
      return arr.map((subArray:any) => subArray.reduce((sum:any, num:any) => sum + num, 0));
    }

    const filteredData = filterPayloadByProperty(beneficiaryArray); // filter by propertyGUID
    console.log('filteredData', filteredData);

    const sharePercentages = filteredData.map((subArray:any) => subArray.map((obj:any) => obj.sharePercentage));

    console.log('sharePercentages', sharePercentages);

    const sums = getSharesSum(sharePercentages); // Sum of shares
    console.log('sums', sums);

    const validationTrue = sums.every((value:any) => value === 100); // Check if shares === 100
    console.log('valid', validationTrue);

    // if (validationTrue) {
    // dispatch<any>(submitshareDetails(isSpouseSelected ? spouseShares : husbandShares));
    // dispatch(setBySharesSubmitted(false));
    // handleNext(6, 'by-specific', isCompleted);
    // }

    // New Method testing end

    // Filter substitutes by property/account/company
    const filteredSubArrays = filterDataByPropertyGUID(substituteListForTest);
    console.log('filteredSubArrays', filteredSubArrays);
    // Calculate total sum of shares of the substitutes
    const substituteSharesTotalSum = calculateShareSum(filteredSubArrays);
    console.log('substituteSharesTotalSum', substituteSharesTotalSum);
    const substringsToRemove: string[] = ['undefined', 'null'];

    // Remove undefined and null values from the list
    const filteredObject = removeUndefinedAndNull(
      substituteSharesTotalSum,
      substringsToRemove,
    );
    console.log('filteredSubObject', filteredObject);

    // Remove Zeros from the list
    const removedZeros = removeZeroValues(filteredObject);
    console.log('removedZeros', removedZeros);

    // Condition to check substitute validation
    const subShareValidation = Object.values(removedZeros).every(
      (value) => value === 100,
    );

    // Substitute validation ends for all other WillTypes

    // Case 8 test ---
    // Normal Working case
    // const benCountList: any[] = updatedBenList1.filter(
    //   (ben: any) => ben.subBeneficiaryList.length !== 0 && ben.sharePercentage !== 0,
    // );
    const hus = updatedBenList1.filter(
      (ben: any) => ben.bookedForProfileGUID === profileGuid,
    );
    const spouse = updatedBenList1.filter(
      (ben: any) => ben.bookedForProfileGUID === spouseGuid,
    );
    const benCountList: any[] = (isSpouseSelected ? spouse : hus).filter(
      (ben: any) => ben.subBeneficiaryList?.length !== 0 && ben?.sharePercentage !== 0,
    );
    console.log('benCountList', benCountList);

    // Buisness Owners Will Substitute Validation

    // Check substitute validation in Buisness Owners Will
    // const substituteValidationBOW = checkSubstituteValidationBOW(
    //   subSharesBow,
    //   // benCountList,
    //   removedZeros,
    // );
    // console.log('substituteValidationBOW', substituteValidationBOW);

    // New test case --> Working but needs thorough testing
    // Add combined guids of propertyGUID and profileGUID
    const combinedArray = benCountList.map((obj: any) => ({
      ...obj,
      combinedGUID: `${obj.propertyGUID}-${obj.profileGUID}`,
    }));
    console.log('combinedArray', combinedArray);
    // Returns a list of shares and their corresponding combinedGUID's (propertyGUID + profileGUID)
    const subSharesList = getSharePercentages(combinedArray, removedZeros);
    console.log('subSharesArray', subSharesList);
    // Validate the substitute shares with the beneficiary shares
    const isSubstituteSharesValidBOW = validateShares(
      subSharesList,
      removedZeros,
    );
    console.log('isValid', isSubstituteSharesValidBOW);
    // Check if combinedGUID === key of substituteArray
    // const hasMatchingSharePercentage = checkSharePercentage(combinedArray, removedZeros);
    // console.log('hasMatchingSharePercentage', hasMatchingSharePercentage);

    // Check if substitute is present
    const isSubPresent = beneficiaryList.some(
      (el: any) => el.subBeneficiaryList.length !== 0,
    );

    const latestBenArray = updatedBen.filter((item1: any) => updatedBen.some(
      (item2: any) => item1.profileGUID === item2.parentProfileGUID,
    ));
    // console.log('latestBenArray', latestBenArray);
    const filteredLatestBenList = latestBenArray.filter(
      (e: any) => e.propertyGUID !== null,
    );
    console.log('filteredLatestBenList', filteredLatestBenList);
    const removeZeroFromBen = filteredLatestBenList.filter(
      (e: any) => e.sharePercentage !== 0,
    );
    console.log('removeZeroFromBen', removeZeroFromBen);

    // Substitute validation ends ---------------------------------------------------------------

    // Beneficiary Validation 2.0 (current version)
    // Get the total count of beneficiaries with substitutes
    // Check if the list of beneficiaries is updated for each iteration
    const beneficiaryListForTest = checkBeneficiaryPresent(
      beneficiaryArray,
      beneficiaryList,
    );
    console.log('beneficiaryListForTest', beneficiaryListForTest);

    // Filter beneficiaries by Property/Account/Company
    const filteredBenArrays = filterDataByPropertyGUID(beneficiaryListForTest);
    console.log('filteredBenArrays', filteredBenArrays);

    // Calculate total sum of shares of the beneficiaries of each property/account/company
    const benSharesTotalSum = calculateShareSum(filteredBenArrays);
    console.log('benSharesTotalSum', benSharesTotalSum);

    // Filter each beneficiary by property/account/company (Remove undefined and null values)
    const filteredObj = removeUndefinedAndNullForBen(benSharesTotalSum);
    console.log('filteredBenObj', filteredObj);

    // Condition to check beneficiary validation (Total shares === 100)
    const benShareValidation = Object.values(filteredObj).every(
      (value) => value === 100,
    );
    console.log('benShareValidation', benShareValidation);

    // Buisness Owners Will Beneficiary Validation
    const sharesForbow = getSharesForBOW(filteredObj);
    const sharesIterator = sharesForbow[Symbol.iterator]();
    console.log('sharesIterator', sharesIterator);

    // Beneficiary Validation for BOW
    const benShareValidationBOW = Object.values(filteredObj).every(
      (value) => value === sharesIterator.next().value,
    );
    console.log('benShareValidationBOW', benShareValidationBOW);

    const getListType = () => {
      if (willTypeID === 3) return propertyList;
      if (willTypeID === 5) return accountList;
      if (willTypeID === 4) return companyShareInformationList;
      return null;
    };

    const list = getListType();
    console.log('listType', list);

    // Check property/account/company list length
    const propertySharesObject = filterByPropertyList(
      filteredObj,
      list,
      willTypeID,
    );
    console.log('propertySharesObject', propertySharesObject);
    // propertyList || accountList || companyShareInformationList

    // Check if all properties/accounts/companies are allocated shares
    let checkLength: boolean;
    if (
      (accountList.length
        || propertyList.length
        || companyShareInformationList.length)
      === Object.keys(propertySharesObject).length
    ) {
      // Add Company List when working on BOW
      checkLength = true;
    }

    // Allow submission only if the shares have been allocated
    if (updatedBen.length !== 0 && checkLength) {
      // Property Will && Financial Assets Will
      if (willTypeID === 5 || willTypeID === 3) {
        // Financial Assets Will && Property Will
        if (isSubPresent) {
          // IF  substitute is present check validation for beneficiaries & substitutes
          const checkSubLength = benCountList.length === Object.keys(removedZeros).length;
          // const checkSubLength = benCountList.length === subCount * accountList.length;
          console.log('checkSubLength', checkSubLength);

          // if (substituteSharesList.length !== 0) {
          // Check beneficiary && substitute validation here
          if (
            benShareValidation
            && subShareValidation
            && checkSubLength
            // && filteredLatestBenList.length !== 0
          ) {
            // dispatch<any>(submitshareDetails(updatedBen));
            dispatch<any>(
              submitshareDetails(
                isSpouseSelected ? spouseShares : husbandShares,
              ),
            );
            dispatch(setBySharesSubmitted(false));
            handleNext(6, 'by-specific', isCompleted);
          } else {
            await dispatch(resetErrorState());
            await dispatch(
              setErrorInfo('Please enter shares for all substitutes'),
            );
          }
          // }
        } else if (!isSubPresent) {
          // Working smoothly -- Beneficiary Validation working with single & multiple accounts/properties
          // Beneficiary validation only
          if (benShareValidation) {
            dispatch<any>(
              submitshareDetails(
                isSpouseSelected ? spouseShares : husbandShares,
              ),
            );
            dispatch(clearUpdatedBenList());
            dispatch(setBySharesSubmitted(false));
            handleNext(6, 'by-specific', isCompleted);
          } else {
            await dispatch(resetErrorState());
            await dispatch(
              setErrorInfo('Please enter shares for all beneficiaries'),
            );
          }
        }
      } else {
        // Buisness Owners Will
        if (!isSubPresent) {
          if (benShareValidationBOW) {
            dispatch<any>(
              submitshareDetails(
                isSpouseSelected ? spouseShares : husbandShares,
              ),
            );
            dispatch(setBySharesSubmitted(false));
            handleNext(6, 'by-specific', isCompleted);
          } else {
            await dispatch(resetErrorState());
            await dispatch(
              setErrorInfo('Please enter shares for all beneficiaries'),
            );
          }
        } else if (isSubPresent) {
          // Substitute is present
          console.log('Substitute Present');
          const checkSubLength = benCountList.length === Object.keys(removedZeros).length;
          if (
            benShareValidationBOW
            // && substituteValidationBOW
            && isSubstituteSharesValidBOW
            && checkSubLength
            // && filteredLatestBenList.length !== 0
          ) {
            dispatch<any>(
              submitshareDetails(
                isSpouseSelected ? spouseShares : husbandShares,
              ),
            );
            dispatch(setBySharesSubmitted(false));
            handleNext(6, 'by-specific', isCompleted);
          } else {
            await dispatch(resetErrorState());
            await dispatch(
              setErrorInfo('Please enter shares for all substitutes'),
            );
          }
        }
      }
    } else {
      await dispatch(resetErrorState());
      await dispatch(setErrorInfo('Please assign the shares'));
    }
    // -----
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<alert
    xmlns="urn:oasis:names:tc:emergency:cap:1.2">
    <identifier>8a78b202447e4fdb84be3917b4d97a55_120170</identifier>
    <sender>ocv_ipaws@120170</sender>
    <sent>2023-12-04T17:04:09-00:00</sent>
    <status>Actual</status>
    <msgType>Alert</msgType>
    <scope>Public</scope>
    <code>IPAWSv1.0</code>
    <info>
        <language>en-US</language>
        <category>Security</category>
        <event>Test</event>
        <urgency>Immediate</urgency>
        <severity>Extreme</severity>
        <certainty>Observed</certainty>
        <eventCode>
            <valueName>SAME</valueName>
            <value>SPW</value>
        </eventCode>
        <expires>2023-12-04T19:04:09-00:00</expires>
        <senderName>OCV</senderName>
        <headline>Test</headline>
        <description>Testing with polygon</description>
        <parameter>
            <valueName>EAS-ORG</valueName>
            <value>CIV</value>
        </parameter>
        <parameter>
            <valueName>timezone</valueName>
            <value>UTC</value>
        </parameter>
        <parameter>
            <valueName>BLOCKCHANNEL</valueName>
            <value>EAS</value>
        </parameter>
        <parameter>
            <valueName>BLOCKCHANNEL</valueName>
            <value>NWEM</value>
        </parameter>
        <parameter>
            <valueName>WEAHandling</valueName>
            <value>Imminent Threat</value>
        </parameter>
        <parameter>
            <valueName>CMAMtext</valueName>
            <value>Test</value>
        </parameter>
        <parameter>
            <valueName>CMAMlongtext</valueName>
            <value></value>
        </parameter>
        <area>
            <areaDesc>Lee County Alabama</areaDesc>
            <polygon>32.635521121840846,-85.47122246840102 32.62295827375514,-85.46861804344758 32.63268636190215,-85.48836848952871 32.635521121840846,-85.47122246840102</polygon>
            <geocode>
                <valueName>SAME</valueName>
                <value>001081</value>
            </geocode>
        </area>
    </info>
    <capsig:Signature
        xmlns:capsig="http://www.w3.org/2000/09/xmldsig#">
        <capsig:SignedInfo>
            <capsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            <capsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
            <capsig:Reference URI="">
                <capsig:Transforms>
                    <capsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                </capsig:Transforms>
                <capsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                <capsig:DigestValue>HPUxsg+gTfYuvAV3rpYJHJrJW+1RSnDtyeK3IIM9/2E=</capsig:DigestValue>
            </capsig:Reference>
        </capsig:SignedInfo>
        <capsig:SignatureValue>bW2/NitHRMdaABZTLRHSyQjSzT05fyGDJsXTZ1v4r1HwGlAZM0PhRbd70QnTZ4FiKUg28m1EY3Xbuh/ULqyQjShoafLezlRLxroPpLC9EGziqzdwlHHirc+a6cRdxCM97swKTiomQDRBq9BE7QmGLgPWTRuL28mY1vWaaOnVrZHCfuiSZF6p24uwvqbNNQWRVQT9b8j65YYWkXIiuk7XFrkNt11OSFW11GIhprE43VUfuModNJxMEc7KRWsbgNV7X1BjSmmo2BG2jb+jlXavoPLLBakv1SWSh5byvWkhU5sttdXKf/YN8zhdMvoOlGdlxP+4UWzYDiuzy2Ylspn4cw==</capsig:SignatureValue>
        <capsig:KeyInfo>
            <capsig:X509Data>
                <capsig:X509SubjectName>CN=IPAWSOPEN120170,OU=A01413300000177FF30EA1D00000F72,OU=Devices IPAWS,OU=National Continuity Programs,O=FEMA IPAWS,C=US</capsig:X509SubjectName>
                <capsig:X509Certificate>MIIGXTCCBUWgAwIBAgIQQAF3/zDqODPHxIFwMGdk6zANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJVUzEfMB0GA1UECgwWSWRlblRydXN0IFNlcnZpY2VzIExMQzEgMB4GA1UECwwXSWRlblRydXN0IEdsb2JhbCBDb21tb24xHDAaBgNVBAMME1BURSBJR0MgU2VydmVyIENBIDEwHhcNMjEwMzA0MjE0MjExWhcNMjQwMzAzMjE0MjExWjCBpTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkZFTUEgSVBBV1MxJTAjBgNVBAsTHE5hdGlvbmFsIENvbnRpbnVpdHkgUHJvZ3JhbXMxFjAUBgNVBAsTDURldmljZXMgSVBBV1MxKDAmBgNVBAsTH0EwMTQxMzMwMDAwMDE3N0ZGMzBFQTFEMDAwMDBGNzIxGDAWBgNVBAMTD0lQQVdTT1BFTjEyMDE3MDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALdJ3mt9MzmNZ29Nd++wjnGHFoNYuHmt/Ukjl92SI2xChKxuE+rm6sPBIUp+nh5SGtBbh9iGTs0MFxTS2KMqn9kViYb6THKb1wabPucrw8/Us6N9GC/8HKjz5pDXcUQo3Q2UCxDA58Vyf1eiAXSb0EYe5aDzXjk5vjdeNF69zcDDchCSHVmi2xPzRVt3BLJgmCdCUByP1o75+EoBW2n7LDJ+JPhtJ31iLqEDF1xEKw2R91R8PHOz/C9fFG+VaOmDXBoLrQSWNgDWnRpedV02jx6P5HwOMHwkfbeAZD4kRck1vUTxAI+iaXUEG+r4LXMBoNbunGUUCI5OLiRtv4IeWHUCAwEAAaOCAr0wggK5MA4GA1UdDwEB/wQEAwIFoDCBgQYIKwYBBQUHAQEEdTBzMC8GCCsGAQUFBzABhiNodHRwOi8vSUdDQ0ExUFRFLm9jc3AuaWRlbnRydXN0LmNvbTBABggrBgEFBQcwAoY0aHR0cDovL2FwcHMtc3RnLmlkZW50cnVzdC5jb20vcm9vdHMvaWdjc2VydmVyY2ExLnA3YzAfBgNVHSMEGDAWgBSc1H9L+MIO/N90WoUgnp8Zm7yF+zCCAVIGA1UdIASCAUkwggFFMIIBQQYLYIZIAYb5LwBkJQIwggEwMEsGCCsGAQUFBwIBFj9odHRwczovL3NlY3VyZS5pZGVudHJ1c3QuY29tL2NlcnRpZmljYXRlcy9wb2xpY3kvSUdDL2luZGV4Lmh0bWwwgeAGCCsGAQUFBwICMIHTDIHQVGVzdCBDZXJ0aWZpY2F0ZS4gRG8gTm8gUmVseS4gQ2VydGlmaWNhdGUgdXNlIHJlc3RyaWN0ZWQgdG8gUmVseWluZyBQYXJ0eShzKSBpbiBhY2NvcmRhbmNlIHdpdGggSUdDLUNQIChzZWUgaHR0cHM6Ly9zZWN1cmUuaWRlbnRydXN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0lHQy9pbmRleC5odG1sKS4gSUdDLUNQUyBpbmNvcnBvcmF0ZWQgYnkgcmVmZXJlbmNlLjA+BgNVHR8ENzA1MDOgMaAvhi1odHRwOi8vY3JsLXB0ZS5pZGVudHJ1c3QuY29tL2lnY3NlcnZlcmNhMS5jcmwwGgYDVR0RBBMwEYIPSVBBV1NPUEVOMTIwMTcwMB0GA1UdDgQWBBTlJOOlXTZyj0pwFBw/9wrb6z1yMjAxBgNVHSUEKjAoBggrBgEFBQcDAgYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQsFAAOCAQEAu2kFWsaQAFYOSUAfct6PESE9dRNg8iamKy4mhkGTAHwnLMVtu6wNiA+YQVA4U30xlqKLUMqqp1HdnfN+YgYi2Xsj2LD03HnTCyspAyPaDJd6+IqwR8lPmN3mSwU0Yft3uuhHQwwh0eh7fJsb/rjDg7JDY0eYyJGqKJqFsjY23omv8SApmndS9jsChZIxApg46O81o1zn9S1F7cSyAqRJiyC5B+IQF2ySrybAH5fe4oknIC1YtNgF1Tt0+K0/MzKO7Sl9//SBAqGT9y3Xccc8UrETjY7pKFWNwQQFJxO0EtUVPEg2CgEJgZo0+40Mao+01clSNZuUEMcpJjguTLXvZw==</capsig:X509Certificate>
            </capsig:X509Data>
        </capsig:KeyInfo>
    </capsig:Signature>
</alert>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<alert
    xmlns="urn:oasis:names:tc:emergency:cap:1.2">
    <identifier>9af7517bd0a64adf88c06945fdce7206_120170</identifier>
    <sender>ocv_ipaws@120170</sender>
    <sent>2023-12-04T16:52:12-00:00</sent>
    <status>Actual</status>
    <msgType>Alert</msgType>
    <scope>Public</scope>
    <code>IPAWSv1.0</code>
    <info>
        <language>en-US</language>
        <category>Security</category>
        <event>Test</event>
        <urgency>Immediate</urgency>
        <severity>Extreme</severity>
        <certainty>Observed</certainty>
        <eventCode>
            <valueName>SAME</valueName>
            <value>SPW</value>
        </eventCode>
        <expires>2023-12-04T18:52:12-00:00</expires>
        <senderName>OCV</senderName>
        <headline>Test</headline>
        <description>Testing of no polygon</description>
        <parameter>
            <valueName>EAS-ORG</valueName>
            <value>CIV</value>
        </parameter>
        <parameter>
            <valueName>timezone</valueName>
            <value>UTC</value>
        </parameter>
        <parameter>
            <valueName>BLOCKCHANNEL</valueName>
            <value>EAS</value>
        </parameter>
        <parameter>
            <valueName>BLOCKCHANNEL</valueName>
            <value>NWEM</value>
        </parameter>
        <parameter>
            <valueName>WEAHandling</valueName>
            <value>Imminent Threat</value>
        </parameter>
        <parameter>
            <valueName>CMAMtext</valueName>
            <value>Test</value>
        </parameter>
        <parameter>
            <valueName>CMAMlongtext</valueName>
            <value></value>
        </parameter>
        <area>
            <areaDesc>Lee County Alabama</areaDesc>
            <geocode>
                <valueName>SAME</valueName>
                <value>001081</value>
            </geocode>
        </area>
    </info>
    <capsig:Signature
        xmlns:capsig="http://www.w3.org/2000/09/xmldsig#">
        <capsig:SignedInfo>
            <capsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            <capsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
            <capsig:Reference URI="">
                <capsig:Transforms>
                    <capsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                </capsig:Transforms>
                <capsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                <capsig:DigestValue>JOLKhVgTuGbk2tzbvfY4WSu3/tRkyVlbZw9NewqYc7A=</capsig:DigestValue>
            </capsig:Reference>
        </capsig:SignedInfo>
        <capsig:SignatureValue>p2aNcvd5khGq4U9+ty1SoxW29bSQf48oWOCAhjRYQ05di9aOifY8cxm3BKs/dinPINfy9uLEn311ve/Z7vAPl3rsJM68ruWiU5rWCaDbY8gqn/B+Rzc6AOEYR3sUDyFqZfHk+D2CuZXjusnNbxHjW4EIqhezqboBOrwVIFaQOkPhDY3WptQkDvK/uCAg9eV9mwJ4PX3ANttn3wiMHB+9EROmlTPm4eronhJQcDE5U0sdg4XT+gW45TAocw4DeeUbYihhm44n7jnilmVIXgpPIvPQ8SbYa7hr5U2bTp0H4b3Wl2TXXDheRIZ5s89QbYjS6gqoaYO94+ZaQqaaAg9pog==</capsig:SignatureValue>
        <capsig:KeyInfo>
            <capsig:X509Data>
                <capsig:X509SubjectName>CN=IPAWSOPEN120170,OU=A01413300000177FF30EA1D00000F72,OU=Devices IPAWS,OU=National Continuity Programs,O=FEMA IPAWS,C=US</capsig:X509SubjectName>
                <capsig:X509Certificate>MIIGXTCCBUWgAwIBAgIQQAF3/zDqODPHxIFwMGdk6zANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJVUzEfMB0GA1UECgwWSWRlblRydXN0IFNlcnZpY2VzIExMQzEgMB4GA1UECwwXSWRlblRydXN0IEdsb2JhbCBDb21tb24xHDAaBgNVBAMME1BURSBJR0MgU2VydmVyIENBIDEwHhcNMjEwMzA0MjE0MjExWhcNMjQwMzAzMjE0MjExWjCBpTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkZFTUEgSVBBV1MxJTAjBgNVBAsTHE5hdGlvbmFsIENvbnRpbnVpdHkgUHJvZ3JhbXMxFjAUBgNVBAsTDURldmljZXMgSVBBV1MxKDAmBgNVBAsTH0EwMTQxMzMwMDAwMDE3N0ZGMzBFQTFEMDAwMDBGNzIxGDAWBgNVBAMTD0lQQVdTT1BFTjEyMDE3MDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALdJ3mt9MzmNZ29Nd++wjnGHFoNYuHmt/Ukjl92SI2xChKxuE+rm6sPBIUp+nh5SGtBbh9iGTs0MFxTS2KMqn9kViYb6THKb1wabPucrw8/Us6N9GC/8HKjz5pDXcUQo3Q2UCxDA58Vyf1eiAXSb0EYe5aDzXjk5vjdeNF69zcDDchCSHVmi2xPzRVt3BLJgmCdCUByP1o75+EoBW2n7LDJ+JPhtJ31iLqEDF1xEKw2R91R8PHOz/C9fFG+VaOmDXBoLrQSWNgDWnRpedV02jx6P5HwOMHwkfbeAZD4kRck1vUTxAI+iaXUEG+r4LXMBoNbunGUUCI5OLiRtv4IeWHUCAwEAAaOCAr0wggK5MA4GA1UdDwEB/wQEAwIFoDCBgQYIKwYBBQUHAQEEdTBzMC8GCCsGAQUFBzABhiNodHRwOi8vSUdDQ0ExUFRFLm9jc3AuaWRlbnRydXN0LmNvbTBABggrBgEFBQcwAoY0aHR0cDovL2FwcHMtc3RnLmlkZW50cnVzdC5jb20vcm9vdHMvaWdjc2VydmVyY2ExLnA3YzAfBgNVHSMEGDAWgBSc1H9L+MIO/N90WoUgnp8Zm7yF+zCCAVIGA1UdIASCAUkwggFFMIIBQQYLYIZIAYb5LwBkJQIwggEwMEsGCCsGAQUFBwIBFj9odHRwczovL3NlY3VyZS5pZGVudHJ1c3QuY29tL2NlcnRpZmljYXRlcy9wb2xpY3kvSUdDL2luZGV4Lmh0bWwwgeAGCCsGAQUFBwICMIHTDIHQVGVzdCBDZXJ0aWZpY2F0ZS4gRG8gTm8gUmVseS4gQ2VydGlmaWNhdGUgdXNlIHJlc3RyaWN0ZWQgdG8gUmVseWluZyBQYXJ0eShzKSBpbiBhY2NvcmRhbmNlIHdpdGggSUdDLUNQIChzZWUgaHR0cHM6Ly9zZWN1cmUuaWRlbnRydXN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0lHQy9pbmRleC5odG1sKS4gSUdDLUNQUyBpbmNvcnBvcmF0ZWQgYnkgcmVmZXJlbmNlLjA+BgNVHR8ENzA1MDOgMaAvhi1odHRwOi8vY3JsLXB0ZS5pZGVudHJ1c3QuY29tL2lnY3NlcnZlcmNhMS5jcmwwGgYDVR0RBBMwEYIPSVBBV1NPUEVOMTIwMTcwMB0GA1UdDgQWBBTlJOOlXTZyj0pwFBw/9wrb6z1yMjAxBgNVHSUEKjAoBggrBgEFBQcDAgYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQsFAAOCAQEAu2kFWsaQAFYOSUAfct6PESE9dRNg8iamKy4mhkGTAHwnLMVtu6wNiA+YQVA4U30xlqKLUMqqp1HdnfN+YgYi2Xsj2LD03HnTCyspAyPaDJd6+IqwR8lPmN3mSwU0Yft3uuhHQwwh0eh7fJsb/rjDg7JDY0eYyJGqKJqFsjY23omv8SApmndS9jsChZIxApg46O81o1zn9S1F7cSyAqRJiyC5B+IQF2ySrybAH5fe4oknIC1YtNgF1Tt0+K0/MzKO7Sl9//SBAqGT9y3Xccc8UrETjY7pKFWNwQQFJxO0EtUVPEg2CgEJgZo0+40Mao+01clSNZuUEMcpJjguTLXvZw==</capsig:X509Certificate>
            </capsig:X509Data>
        </capsig:KeyInfo>
    </capsig:Signature>
</alert>
step1-node -v to see the version of nodejs
step2-npx create-react-app nisthaapp
step3-cd nisthaapp
step4-npm run start
step5-delete those files which are not in work
setuptest.js in src,reportwebvitals in src,logo.svg in src,apptest in src,app.css in src
step6-go in index.js and remove delete files from include section
step7-same for app.js
step8-new app.js

function App() {
  return (
   <div>
    <h1>
      chai or react
    </h1>
    </div>
  );
}

export default App;


jo bhi project hum npx create-react-app se bnate h vo bhut jyada bulky hote h.isliye ab hum vite use krte h.vite ek bundler h
step1-npm create vite@latest
step2-set configuration 
step3-cd projectname
step4-iss process mai node modules nhi hote isliye alag se install krne pdenge
command-npm i
step5-delete those files which are not in work
step6-go in index.js and remove delete files from include section
step7-same for app.js
step8-new app.js
import { createContext, useReducer, ReactNode } from 'react';

type State = {
  user: any | null;
};

const initialState: State = {
  user: null,
};

enum ActionType {
  SET_USER = 'SET_USER',
}

export const reducer = (
  state: State,
  action: {
    type: keyof typeof ActionType;
    payload: any;
  },
) => {
  switch (action.type) {
    case ActionType.SET_USER:
      return {
        ...state,
        user: action.payload,
      };
    default:
      return state;
  }
};

type GlobalContextType = {
  user: State['user'];
  setUser: (newUser: State['user']) => void;
};

export const GlobalContext = createContext<GlobalContextType>(
  {} as GlobalContextType,
);

const GlobalProvider = ({ children }: { children: ReactNode }) => {
  const [state, dispatch] = useReducer(reducer, initialState);

  const contextValue: GlobalContextType = {
    ...state,

    //* mutations
    setUser: (newUser: State['user']) => {
      dispatch({ type: ActionType.SET_USER, payload: newUser });
    },
  };

  return (
    <GlobalContext.Provider value={contextValue}>
      {children}
    </GlobalContext.Provider>
  );
};

export default GlobalProvider;
// import FullReviewDetail from "@/components/reviews/FullReviewDetail";
// import { ReviewInterface } from "@/models";
// import { MongoClient, ObjectId } from "mongodb";
// import Head from "next/head";

// function FullReviewDetails(props: ReviewInterface) {
//   return (
//     <>
//       <Head>
//         <title>{props.reviewData.title}</title>
//         <meta name="description" content={props.reviewData.comment} />
//       </Head>

//       <FullReviewDetail
//         title={props.reviewData.title}
//         name={props.reviewData.name}
//         date={props.reviewData.date}
//         comment={props.reviewData.comment}
//       />
//     </>
//   );
// }

// export async function getStaticPaths() {
//   const client = await MongoClient.connect(
//     "mongodb+srv://ktanzyl:1234@reviewdata.dqz2kqn.mongodb.net/?retryWrites=true&w=majority"
//   );
//   const db = client.db();

//   const reviewsCollection = db.collection("reviews");

//   // If wanting to find all , can pass in an empty object, which means there's no filter criteria. Second argument can be passed which defines which fields should be extracted for every document.
//   // In this case, we only want the id, so add in the params like below
//   const reviews = await reviewsCollection
//     .find({}, { projection: { _id: 1 } })
//     .toArray();

//   client.close();

//   return {
//     fallback: "blocking",
//     paths: reviews.map((review) => ({
//       params: { reviewId: review._id.toString() },
//     })),
//   };
// }

// export async function getStaticProps(context: {
//   params: { reviewId: string };
// }) {
//   //fetch data for a single review
//   const reviewId = context.params.reviewId;

//   const client = await MongoClient.connect(
//     "mongodb+srv://ktanzyl:1234@reviewdata.dqz2kqn.mongodb.net/?retryWrites=true&w=majority&ssl=true"
//   );
//   const db = client.db();

//   const reviewsCollection = db.collection("reviews");

//   const selectedReview = await reviewsCollection.findOne({
//     _id: ObjectId(reviewId),
//   });

//   client.close();

//   // Check if the review was not found
//   if (!selectedReview) {
//     return {
//       notFound: true,
//     };
//   }

//   return {
//     props: {
//       reviewData: {
//         id: selectedReview._id.toString(),
//         title: selectedReview.title,
//         name: selectedReview.name,
//         date: selectedReview.date,
//         comment: selectedReview.comment,
//       },
//     },
//   };
// }

// export default FullReviewDetails;
  // Check the validity of uploaded files
  const checkFileValidity = useCallback(async (files: any[], documentTypeID: number) => {
    const maxFileSize = 20 * 1024 * 1024;
    const passportSizePhotoValidDocTypes = ['jpeg', 'png', 'jpg', 'bmp'];

    const docPresent = draftsmanUploadedDocumentList.filter((doc:any) => {
      if (doc.documentTypeID === 4) return doc;
    });

    console.log('docPresent', docPresent);

    let isMaxSize = true;

    // Filter valid files based on extension and file size
    const validFiles = files.filter((file: { name: string; size: number; }) => {
      console.log('validFile', file);
      const validExt = file.name.split('.').pop();
      if (file.size <= maxFileSize) isMaxSize = false;
      const checkValidityCondition = passportSizePhotoValidDocTypes.includes(validExt);
      if (documentTypeID === 4) {
        if (checkValidityCondition) return file;
        setShowInvalidFilesModal(true);
      } else {
        return file;
      }
    });

    console.log('validFiles', validFiles);
    if (documentTypeID === 4) {
      if (docPresent.length === 0) {
        saveValidFiles(validFiles, documentTypeID);
      } else {
        await dispatch(resetErrorState());
        await dispatch(setErrorInfo('You can only add one passport size photo'));
      }
    } else if (documentTypeID !== 4) {
      saveValidFiles(validFiles, documentTypeID);
    }

    // Filter invalid files
    const invalidFiles = files.filter((file: any) => !validFiles.includes(file));

    if (invalidFiles.length > 0) {
      setShowInvalidFilesModal(true);
    } else if (validFiles.length > 0) {
      saveValidFiles(validFiles, documentTypeID);

      //   // Update the documentTypeArray state with the new file name
      const updatedDocumentTypeArray = documentTypeArray?.map((docType) => {
        if (docType.documentTypeID === documentTypeID) {
          return { ...docType, documentName: validFiles[0]?.name };
        }
        return docType;
      });

      setDocumentTypeArray(updatedDocumentTypeArray);
      console.log('Updated Document Array:', updatedDocumentTypeArray);
    }
  }, [saveValidFiles, documentTypeArray, setShowInvalidFilesModal, setDocumentTypeArray]);
 const isValidExtension = validExtensions.some((ext) => file.name.toLowerCase().endsWith(ext));
      const isWithinMaxSize = file.size <= maxFileSize;
      return isValidExtension && isWithinMaxSize;
setDraftsmanUploadedDocumentList: (state, { payload }) => {
      state.loading = false;
      if (state.draftsmanGUID !== '') {
        if (payload[0]?.documentTypeID === 409) {
          payload.forEach((item: any) => {
            state.draftsmanUploadedDocumentList.push(item);
          });
        } else {
          state.draftsmanUploadedDocumentList = state.draftsmanUploadedDocumentList.filter((item: any) => item.documentTypeID !== payload[0]?.documentTypeID);
          state.draftsmanUploadedDocumentList.push(payload[0]);
        }
      } else {
        payload.forEach((item: any) => {
          // Replace passport size photo
          if (item?.documentTypeID !== 4) {
            state.draftsmanUploadedDocumentList.push(item);
          }
        });
        if (payload[0]?.documentTypeID === 4) {
          state.draftsmanUploadedDocumentList = state.draftsmanUploadedDocumentList.filter((doc: any) => doc.documentTypeID !== payload?.documentTypeID);
          const fileExtension = payload[0].name.split('.').pop();
          const passportSizePhotoValidDocTypes = ['jpeg', 'png', 'jpg', 'bmp'];
          const isValid = passportSizePhotoValidDocTypes.includes(fileExtension);
          if (isValid) state.draftsmanUploadedDocumentList.push(payload[0]);
        }
      }
      state.isDocumentsChanged = !state.isDocumentsChanged;
    },
import React, { useState, useEffect } from "react";

const ExampleComponent = () => {
  const [input, setInput] = useState("");

  useEffect(() => {
    // This effect will be re-executed on every render
  }, []);

  return (
    <div>
      <input
        type="text"
        value={input}
        onChange={(e) => setInput(e.target.value)}
      />
    </div>
  );
};
https://github.com/chronark/highstorm

https://github.com/idurar/idurar-erp-crm

https://github.com/nz-m/SocialEcho

//react-google-maps-api documentation LINK
https://web.archive.org/web/20230701010714mp_/https://react-google-maps-api-docs.netlify.app/#googlemap

import { useState } from "react";
import ReactDOM from "react-dom/client";

function Car() {
  const [car, setCar] = useState({
    brand: "Ford",
    model: "Mustang",
    year: "1964",
    color: "red"
  });

  const updateColor = () => {
    setCar(previousState => {
      return { ...previousState, color: "blue" }
    });
  }

  return (
    <>
      <h1>My {car.brand}</h1>
      <p>
        It is a {car.color} {car.model} from {car.year}.
      </p>
      <button
        type="button"
        onClick={updateColor}
      >Blue</button>
    </>
  )
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Car />);
import { Modal, ModalCustom, Tabs, Tab, Badge, useToast, Checkbox } from '@ocv-web/ui'
import {
  categoryMap,
  certaintyMap,
  weaCertaintyMap,
  eventCodes,
  eventResponseMap,
  severityMap,
  weaSeverityMap,
  urgencyMap,
  weaUrgencyMap,
  weaHandlingMap,
  NotificationFormData,
} from '../../config'
import React from 'react'
import { DetailMap } from '../DetailTabs/DetailMap'
import {
  useNotificationMutation,
  useNotificationsMutation,
} from '../../api/notifications'
import { useTemplateMutation, useTemplatesMutation } from '../../api/templates'
import { useParams } from 'react-router-dom'
import { OCVRouteParams } from '../../../core/types'
import { useUserSelection } from '../../../core/context/UserSelectionContext'
import { useUser } from '../../../administration/api/users'
export interface SubmissionModalProps {
  show: boolean
  showAction: () => void
  formData: NotificationFormData
  templateEdit: boolean
  template: boolean
  newNotification: boolean
  setSubmitStatus?: React.Dispatch<React.SetStateAction<string>>
}

const alertMapping = {
  GeoPhysical: 'Geo',
  Meteorological: 'Met',
  Safety: 'Safety',
  Security: 'Security',
  Rescue: 'Rescue',
  Fire: 'Fire',
  Health: 'Health',
  'Environmental (Env)': 'Env',
  Transport: 'Transport',
  'Infrastructure (Infra)': 'Infra',
  CBRNE: 'CBRNE',
  Other: 'Other',
}

export const SubmissionModal: React.FC<SubmissionModalProps> = ({
  show,
  showAction,
  formData,
  templateEdit,
  template,
  setSubmitStatus,
  newNotification,
}) => {
  const { id } = useParams<OCVRouteParams>()
  const [disabled, toggleDisabled] = React.useState(true)
  const { userEmail } = useUserSelection()
  const { data } = useUser(userEmail)
  const userName = data?.Results[0]?.Name
  const [selectedTab, setTabSelected] = React.useState(0)
  const [mutate] = useNotificationsMutation()
  const [mutatePatch] = useNotificationMutation(id)
  const [templateMutate] = useTemplatesMutation()
  const [mutateTemplatePatch] = useTemplateMutation(id)
  const { dispatch } = useToast()
  const handleTabChange = React.useCallback(
    newSelectedTab => setTabSelected(newSelectedTab),
    []
  )
  const localStorageData = JSON.parse(localStorage.getItem('formObject'))
  React.useEffect(() => {
    console.log(template)
  }, [template])
  const handleSend = () => {
    if (localStorageData && Object.keys(localStorageData).length > 0) {
      localStorage.setItem('formObject', JSON.stringify({}))
      window.location.reload()
    }

    if (template === true) {
      try {
        templateMutate({
          Name: formData.Title,
          Type: formData.Type,
<<<<<<< HEAD
          CreatedBy: { Name: userName, Email: userEmail },
=======
          CreatedBy: { Name: 'Rob Beaty', Email: 'rob@myocv.com' },
>>>>>>> master
          Template: {
            Title: formData.Title,
            Description: formData.Description,
            Type: formData.Type,
            Locations: JSON.parse(formData.Locations),
<<<<<<< HEAD
            SentBy: { Name: userName, Email: userEmail },
=======
            SentBy: { Name: 'Rob Beaty', Email: 'rob@myocv.com' },
>>>>>>> master
            Groups: [formData.Groups],
            IPAWSInfo: {
              DisseminationChannels: {
                EAS: formData.EAS,
                WEA: formData.WEA,
                NWEM: formData.NWEM,
              },
              Instructions: formData.Instructions,
              Severity: formData.Severity,
              Urgency: formData.Urgency,
              Certainty: formData.Certainty,
              AlertCategory: formData.AlertCategory,
              EventCode: formData.EventCode,
              EventResponse: formData.EventResponse,
              CountyFIPS: parseInt(formData.CountyFIPS),
              WEAShortText: formData.WEAShortText,
              WEALongText: formData.WEALongText,
              WEAHandling: formData.WEAHandling,
              WEASpanish: formData.WEASpanish,
              WEAShortTextSpanish: formData.WEAShortTextSpanish,
              WEALongTextSpanish: formData.WEALongTextSpanish,
              IPAWSKey: formData.IPAWSKey,
            },
            Expires: {
              Hours: formData.ExpiresInHours,
              Minutes: formData.ExpiresInMinutes,
            },
            SchedulingInfo: {
              Schedule: formData.ScheduleNotification,
              Hide: formData.ScheduleHide,
              SendDate: formData.ScheduleDate,
              HideDate: formData.ScheduleHideDate,
              Recurring: formData.ScheduleRecurring,
              Frequency: formData.Frequency,
            },
            SocialMedia: {
              Instagram: formData.Instagram,
              Facebook: formData.Facebook,
              Twitter: formData.Twitter,
            },
            FeatureToOpen: formData.FeatureToOpen,
<<<<<<< HEAD
            LastUpdated: new Date().toLocaleString(),
=======
            Response: {
              body: {
                alertId: '',
                sender: '',
                sentOn: '',
              },
            },
>>>>>>> master
          },
        })
        dispatch({
          type: 'add',
          payload: {
            title: 'Template Added Successfully.',
            status: 'success',
            message: 'You successfully added this Template.',
          },
        })
        setSubmitStatus && setSubmitStatus('success')
        showAction()
      } catch {
        dispatch({
          type: 'add',
          payload: {
            title: 'Adding Template Failed.',
            status: 'error',
            message: 'You failed to add this Template.',
          },
        })
        setSubmitStatus && setSubmitStatus('failed')
        showAction()
      }
    } else if (formData.IPAWSTemplate === true) {
      try {
        mutate({
          Title: formData.Title,
          Description: formData.Description,
          Type: formData.Type,
          Locations: JSON.parse(formData.Locations),
<<<<<<< HEAD
          SentBy: { Name: userName, Email: userEmail },
=======
          SentBy: { Name: 'Rob Beaty', Email: 'rob@myocv.com' },
>>>>>>> master
          Groups: [formData.Groups],
          IPAWSInfo: {
            DisseminationChannels: {
              EAS: formData.EAS,
              WEA: formData.WEA,
              NWEM: formData.NWEM,
            },
            Instructions: formData.Instructions,
            Severity: formData.Severity,
            Urgency: formData.Urgency,
            Certainty: formData.Certainty,
            AlertCategory: formData.AlertCategory,
            EventCode: formData.EventCode,
            EventResponse: formData.EventResponse,
            CountyFIPS: parseInt(formData.CountyFIPS),
            WEAShortText: formData.WEAShortText,
            WEALongText: formData.WEALongText,
            WEAHandling: formData.WEAHandling,
            WEASpanish: formData.WEASpanish,
            WEAShortTextSpanish: formData.WEAShortTextSpanish,
            WEALongTextSpanish: formData.WEALongTextSpanish,
            IPAWSKey: formData.IPAWSKey,
          },
          Expires: { Hours: formData.ExpiresInHours, Minutes: formData.ExpiresInMinutes },
          SchedulingInfo: {
            Schedule: formData.ScheduleNotification,
            Hide: formData.ScheduleHide,
            SendDate: formData.ScheduleDate,
            HideDate: formData.ScheduleHideDate,
            Recurring: formData.ScheduleRecurring,
            Frequency: formData.Frequency,
          },
          SocialMedia: {
            Instagram: formData.Instagram,
            Facebook: formData.Facebook,
            Twitter: formData.Twitter,
          },
          FeatureToOpen: formData.FeatureToOpen,
<<<<<<< HEAD
          LastUpdated: new Date().toLocaleString(),
=======
          Response: {
            body: {
              alertId: '',
              sender: '',
              sentOn: '',
            },
          },
>>>>>>> master
        }).then(() => {
          templateMutate({
            Name: formData.Title,
            Type: formData.Type,
<<<<<<< HEAD
            CreatedBy: { Name: userName, Email: userEmail },
=======
            CreatedBy: { Name: 'Rob Beaty', Email: 'rob@myocv.com' },
>>>>>>> master
            Template: {
              Title: formData.Title,
              Description: formData.Description,
              Type: formData.Type,
              Locations: JSON.parse(formData.Locations),
<<<<<<< HEAD
              SentBy: { Name: userName, Email: userEmail },
=======
              SentBy: { Name: 'Rob Beaty', Email: 'rob@myocv.com' },
>>>>>>> master
              Groups: [formData.Groups],
              IPAWSInfo: {
                DisseminationChannels: {
                  EAS: formData.EAS,
                  WEA: formData.WEA,
                  NWEM: formData.NWEM,
                },
                Instructions: formData.Instructions,
                Severity: formData.Severity,
                Urgency: formData.Urgency,
                Certainty: formData.Certainty,
                AlertCategory: formData.AlertCategory,
                EventCode: formData.EventCode,
                EventResponse: formData.EventResponse,
                CountyFIPS: parseInt(formData.CountyFIPS),
                WEAShortText: formData.WEAShortText,
                WEALongText: formData.WEALongText,
                WEAHandling: formData.WEAHandling,
                WEASpanish: formData.WEASpanish,
                WEAShortTextSpanish: formData.WEAShortTextSpanish,
                WEALongTextSpanish: formData.WEALongTextSpanish,
                IPAWSKey: formData.IPAWSKey,
              },
              Expires: {
                Hours: formData.ExpiresInHours,
                Minutes: formData.ExpiresInMinutes,
              },
              SchedulingInfo: {
                Schedule: formData.ScheduleNotification,
                Hide: formData.ScheduleHide,
                SendDate: formData.ScheduleDate,
                HideDate: formData.ScheduleHideDate,
                Recurring: formData.ScheduleRecurring,
                Frequency: formData.Frequency,
              },
              SocialMedia: {
                Instagram: formData.Instagram,
                Facebook: formData.Facebook,
                Twitter: formData.Twitter,
              },
              FeatureToOpen: formData.FeatureToOpen,
<<<<<<< HEAD
              LastUpdated: new Date().toLocaleString(),
=======
              Response: {
                body: {
                  alertId: '',
                  sender: '',
                  sentOn: '',
                },
              },
>>>>>>> master
            },
          })
        })

        dispatch({
          type: 'add',
          payload: {
            title: 'Notification Sent Successfully.',
            status: 'success',
            message: 'You successfully sent this MAXX Notification.',
          },
        })
        setSubmitStatus && setSubmitStatus('success')
        showAction()
      } catch {
        dispatch({
          type: 'add',
          payload: {
            title: 'Sending Notification Failed.',
            status: 'error',
            message: 'You failed to send this MAXX Notification.',
          },
        })
        setSubmitStatus && setSubmitStatus('failed')
        showAction()
      }
    } else {
      try {
        mutate({
          Title: formData.Title,
          Description: formData.Description,
          Type: formData.Type,
          Locations: JSON.parse(formData.Locations),
<<<<<<< HEAD
          SentBy: { Name: userName, Email: userEmail },
=======
          SentBy: { Name: 'Rob Beaty', Email: 'rob@myocv.com' },
>>>>>>> master
          Groups: [formData.Groups],
          IPAWSInfo: {
            DisseminationChannels: {
              EAS: formData.EAS,
              WEA: formData.WEA,
              NWEM: formData.NWEM,
            },
            Instructions: formData.Instructions,
            Severity: formData.Severity,
            Urgency: formData.Urgency,
            Certainty: formData.Certainty,
            AlertCategory: formData.AlertCategory,
            EventCode: formData.EventCode,
            EventResponse: formData.EventResponse,
            CountyFIPS: parseInt(formData.CountyFIPS),
            WEAShortText: formData.WEAShortText,
            WEALongText: formData.WEALongText,
            WEAHandling: formData.WEAHandling,
            WEASpanish: formData.WEASpanish,
            WEAShortTextSpanish: formData.WEAShortTextSpanish,
            WEALongTextSpanish: formData.WEALongTextSpanish,
            IPAWSKey: formData.IPAWSKey,
          },
          Expires: { Hours: formData.ExpiresInHours, Minutes: formData.ExpiresInMinutes },
          SchedulingInfo: {
            Schedule: formData.ScheduleNotification,
            Hide: formData.ScheduleHide,
            SendDate: formData.ScheduleDate,
            HideDate: formData.ScheduleHideDate,
            Recurring: formData.ScheduleRecurring,
            Frequency: formData.Frequency,
          },
          SocialMedia: {
            Instagram: formData.Instagram,
            Facebook: formData.Facebook,
            Twitter: formData.Twitter,
          },
          FeatureToOpen: formData.FeatureToOpen,
<<<<<<< HEAD
          LastUpdated: new Date().toLocaleString(),
=======
          Response: {
            body: {
              alertId: '',
              sender: '',
              sentOn: '',
            },
          },
>>>>>>> master
        })
        dispatch({
          type: 'add',
          payload: {
            title: 'Notification Sent Successfully.',
            status: 'success',
            message: 'You successfully sent this MAXX Notification.',
          },
        })
        setSubmitStatus && setSubmitStatus('success')
        showAction()
      } catch {
        dispatch({
          type: 'add',
          payload: {
            title: 'Sending Notification Failed.',
            status: 'error',
            message: 'You failed to send this MAXX Notification.',
          },
        })
        setSubmitStatus && setSubmitStatus('failed')
        showAction()
      }
    }
  }
  const handleNotificationUpdate = () => {
    try {
      mutatePatch({
        Title: formData.Title,
        Description: formData.Description,
        Type: formData.Type,
        Locations: JSON.parse(formData.Locations),
<<<<<<< HEAD
        SentBy: { Name: userName, Email: userEmail },
=======
        SentBy: { Name: 'Rob Beaty', Email: 'rob@myocv.com' },
>>>>>>> master
        Groups: [formData.Groups],
        IPAWSInfo: {
          DisseminationChannels: {
            EAS: formData.EAS,
            WEA: formData.WEA,
            NWEM: formData.NWEM,
          },
          Instructions: formData.Instructions,
          Severity: formData.Severity,
          Urgency: formData.Urgency,
          Certainty: formData.Certainty,
          AlertCategory: formData.AlertCategory,
          EventCode: formData.EventCode,
          EventResponse: formData.EventResponse,
          CountyFIPS: parseInt(formData.CountyFIPS),
          WEAShortText: formData.WEAShortText,
          WEALongText: formData.WEALongText,
          WEAHandling: formData.WEAHandling,
          WEASpanish: formData.WEASpanish,
          WEAShortTextSpanish: formData.WEAShortTextSpanish,
          WEALongTextSpanish: formData.WEALongTextSpanish,
          IPAWSKey: formData.IPAWSKey,
        },
        Expires: { Hours: formData.ExpiresInHours, Minutes: formData.ExpiresInMinutes },
        SchedulingInfo: {
          Schedule: formData.ScheduleNotification,
          Hide: formData.ScheduleHide,
          SendDate: formData.ScheduleDate,
          HideDate: formData.ScheduleHideDate,
          Recurring: formData.ScheduleRecurring,
          Frequency: formData.Frequency,
        },
        SocialMedia: {
          Instagram: formData.Instagram,
          Facebook: formData.Facebook,
          Twitter: formData.Twitter,
        },
        FeatureToOpen: formData.FeatureToOpen,
<<<<<<< HEAD
        LastUpdated: new Date().toLocaleString(),
=======
        Response: {
          body: {
            alertId: '',
            sender: '',
            sentOn: '',
          },
        },
>>>>>>> master
      })
      dispatch({
        type: 'add',
        payload: {
          title: 'Notification Updated Successfully.',
          status: 'success',
          message: 'You successfully updated this MAXX Notification.',
        },
      })
      showAction()
    } catch {
      dispatch({
        type: 'add',
        payload: {
          title: 'Updating Notification Failed.',
          status: 'error',
          message: 'You failed to update this MAXX Notification.',
        },
      })
      showAction()
    }
  }
  const handleTemplatePatch = () => {
    try {
      mutateTemplatePatch({
        Name: formData.Title,
        Type: formData.Type,
<<<<<<< HEAD
        CreatedBy: { Name: userName, Email: userEmail },
=======
        CreatedBy: { Name: 'Rob Beaty', Email: 'rob@myocv.com' },
>>>>>>> master
        Template: {
          Title: formData.Title,
          Description: formData.Description,
          Type: formData.Type,
          Locations: JSON.parse(formData.Locations),
<<<<<<< HEAD
          SentBy: { Name: userName, Email: userEmail },
=======
          SentBy: { Name: 'Rob Beaty', Email: 'rob@myocv.com' },
>>>>>>> master
          Groups: [formData.Groups],
          IPAWSInfo: {
            DisseminationChannels: {
              EAS: formData.EAS,
              WEA: formData.WEA,
              NWEM: formData.NWEM,
            },
            Instructions: formData.Instructions,
            Severity: formData.Severity,
            Urgency: formData.Urgency,
            Certainty: formData.Certainty,
            AlertCategory: formData.AlertCategory,
            EventCode: formData.EventCode,
            EventResponse: formData.EventResponse,
            CountyFIPS: parseInt(formData.CountyFIPS),
            WEAShortText: formData.WEAShortText,
            WEALongText: formData.WEALongText,
            WEAHandling: formData.WEAHandling,
            WEASpanish: formData.WEASpanish,
            WEAShortTextSpanish: formData.WEAShortTextSpanish,
            WEALongTextSpanish: formData.WEALongTextSpanish,
            IPAWSKey: formData.IPAWSKey,
          },
          Expires: {
            Hours: formData.ExpiresInHours,
            Minutes: formData.ExpiresInMinutes,
          },
          SchedulingInfo: {
            Schedule: formData.ScheduleNotification,
            Hide: formData.ScheduleHide,
            SendDate: formData.ScheduleDate,
            HideDate: formData.ScheduleHideDate,
            Recurring: formData.ScheduleRecurring,
            Frequency: formData.Frequency,
          },
          SocialMedia: {
            Instagram: formData.Instagram,
            Facebook: formData.Facebook,
            Twitter: formData.Twitter,
          },
          FeatureToOpen: formData.FeatureToOpen,
<<<<<<< HEAD
          LastUpdated: new Date().toLocaleString(),
=======
          Response: {
            body: {
              alertId: '',
              sender: '',
              sentOn: '',
            },
          },
>>>>>>> master
        },
      })
      showAction()
      dispatch({
        type: 'add',
        payload: {
          title: 'Template Updated Successfully.',
          status: 'success',
          message: 'You successfully updated this Template.',
        },
      })
    } catch {
      dispatch({
        type: 'add',
        payload: {
          title: 'Updating Template Failed.',
          status: 'error',
          message: 'You failed to update this Template.',
        },
      })
      showAction()
    }
  }
  const disseminationChannels = []
  if (formData.EAS) disseminationChannels.push('EAS')
  if (formData.WEA) disseminationChannels.push('WEA/CMAS')
  if (formData.NWEM) disseminationChannels.push('NWEM')
  return (
    show && (
      <Modal
        disabled={disabled}
        buttons
        width="xxl"
        buttonColor={disabled ? 'gray' : 'green'}
        show={show}
        onCancel={() => showAction()}
        onClick={
          templateEdit
            ? handleTemplatePatch
            : newNotification
            ? handleSend
            : handleNotificationUpdate
        }
        buttonTitle="Send Notification"
      >
        <ModalCustom>
          <div className="flex-1 overflow-y-hidden">
            <div className="h-full py-8 xl:py-10">
              <div className="flex flex-col px-2 mx-auto sm:px-6 lg:px-8 xl:h-full">
                <div className="xl:col-span-2 xl:pr-8">
                  {formData.IPAWSKey === 'Test' ? (
                    <div className="flex flex-col h-10 rounded-md mb-4 space-x-0 space-y-4 md:flex-row md:space-x-4 md:space-y-0 bg-green-600">
                      <p className="pl-px text-2xl">
                        IPAWS Environment: {formData.IPAWSKey} - Lab
                      </p>
                    </div>
                  ) : (
                    <div className="flex flex-col h-10 rounded-md mb-4 space-x-0 space-y-4 md:flex-row md:space-x-4 md:space-y-0 bg-red-600">
                      <p className="pl-px text-2xl">
                        IPAWS Environment: {formData.IPAWSKey} - WARNING LIVE ENVIRONMENT
                      </p>
                    </div>
                  )}
                  <h2 className="font-semibold text-gray-300 ">Headline (Title)</h2>
                  <h1 className="text-2xl font-bold text-gray-900 dark:text-gray-50">
                    {formData.Title ? formData.Title : 'No Value Provided'}
                  </h1>
                  <div className="py-3 xl:pt-3 xl:pb-0">
                    <Tabs selected={selectedTab} onSelect={handleTabChange}>
                      <Tab title="General">
                        <div className="grid grid-cols-1 overflow-y-auto xl:grid-cols-3 xl:gap-4">
                          <div className="col-span-1 pt-4 xl:col-span-3">
                            <h2 className="text-lg font-semibold text-gray-200">
                              Description
                            </h2>
                            <div className="mb-8 prose dark:text-gray-200 max-w-none">
                              <p>
                                {formData.Description
                                  ? formData.Description
                                  : 'No Value Provided'}
                              </p>
                            </div>
                          </div>
                          <div className="">
                            <h2 className="font-semibold text-gray-200 ">County FIPS</h2>
                            <div className="prose dark:text-gray-200 max-w-none">
                              <p>
                                {formData['CountyFIPS']
                                  ? formData['CountyFIPS']
                                  : 'No Value Provided'}
                              </p>
                            </div>
                          </div>
                          <div className="">
                            <h2 className="font-semibold text-gray-200 ">Expires in: </h2>
                            <div className="prose dark:text-gray-200 max-w-none">
                              <p>
                                {formData.ExpiresInHours +
                                  ' Hour(s), ' +
                                  formData.ExpiresInMinutes +
                                  ' Minute(s)'}
                              </p>
                            </div>
                          </div>
                          {formData.WEA && (
                            <>
                              <div className="py-4">
                                <h2 className="font-semibold text-gray-300 ">
                                  WEA Short Text
                                </h2>
                                <div className="prose dark:text-gray-200 max-w-none">
                                  <p>
                                    {formData.WEAShortText
                                      ? formData.WEAShortText
                                      : 'No Value Provided'}
                                  </p>
                                </div>
                              </div>
                              <div className="py-4">
                                <h2 className="font-semibold text-gray-200 ">
                                  WEA Long Text
                                </h2>
                                <div className="prose dark:text-gray-200 max-w-none">
                                  <p>
                                    {formData.WEALongText
                                      ? formData.WEALongText
                                      : 'No Value Provided'}
                                  </p>
                                </div>
                              </div>
                              {formData.WEASpanish && (
                                <>
                                  <div className="py-4">
                                    <h2 className="font-semibold text-gray-200 ">
                                      WEA Short Text (Spanish)
                                    </h2>
                                    <div className="prose dark:text-gray-200 max-w-none">
                                      <p>
                                        {formData.WEAShortTextSpanish
                                          ? formData.WEAShortTextSpanish
                                          : 'No Value Provided'}
                                      </p>
                                    </div>
                                  </div>
                                  <div className="py-4">
                                    <h2 className="font-semibold text-gray-200 ">
                                      WEA Long Text (Spanish)
                                    </h2>
                                    <div className="prose dark:text-gray-200 max-w-none">
                                      <p>
                                        {formData.WEALongTextSpanish
                                          ? formData.WEALongTextSpanish
                                          : 'No Value Provided'}
                                      </p>
                                    </div>
                                  </div>
                                </>
                              )}
                            </>
                          )}
                        </div>
                      </Tab>
                      {formData.Type === 'IPAWS' && (
                        <Tab title="IPAWS">
                          <div className="h-auto overflow-y-auto">
                            <div className="grid grid-cols-3 py-4 border-gray-200 gap-y-6">
                              <div className="col-span-3">
                                <h2 className="text-sm font-semibold text-gray-300">
                                  Instructions
                                </h2>
                                <div className="prose dark:text-gray-200 max-w-none">
                                  <p>
                                    {formData.Instructions
                                      ? formData.Instructions
                                      : 'No Value Provided'}
                                  </p>
                                </div>
                              </div>
                              <div>
                                <h2 className="text-sm font-semibold text-gray-300">
                                  Distribution Channels
                                </h2>
                                <div className="prose dark:text-gray-200 max-w-none">
                                  <p>{disseminationChannels.join(', ')}</p>
                                </div>
                              </div>
                              <div>
                                <h2 className="text-sm font-semibold text-gray-300">
                                  Event Code
                                </h2>
                                <div className="prose dark:text-gray-200 max-w-none">
                                  <p>{eventCodes[formData['EventCode']]?.name}</p>
                                </div>
                              </div>
                              <div>
                                <h2 className="text-sm font-semibold text-gray-300">
                                  Event Response
                                </h2>
                                <div className="m-1">
                                  <Badge
                                    color={
                                      eventResponseMap[formData['EventResponse']]?.color
                                    }
                                  >
                                    {eventResponseMap[formData['EventResponse']]?.name}
                                  </Badge>
                                </div>
                              </div>
                              <div>
                                <h2 className="text-sm font-semibold text-gray-300">
                                  Alert Category
                                </h2>
                                <div className="m-1">
                                  <Badge
                                    color={categoryMap[formData['AlertCategory']]?.color}
                                  >
                                    {categoryMap[formData['AlertCategory']]?.name}
                                  </Badge>
                                </div>
                              </div>
                              <div>
                                <h2 className="text-sm font-semibold text-gray-300">
                                  Severity
                                </h2>
                                <div className="m-1">
                                  {formData.WEA ? (
                                    <Badge
                                      color={weaSeverityMap[formData.Severity]?.color}
                                    >
                                      {weaSeverityMap[formData.Severity]?.name}
                                    </Badge>
                                  ) : (
                                    <Badge color={severityMap[formData.Severity]?.color}>
                                      {severityMap[formData.Severity]?.name}
                                    </Badge>
                                  )}
                                </div>
                              </div>
                              <div>
                                <h2 className="text-sm font-semibold text-gray-300">
                                  Urgency
                                </h2>
                                <div className="m-1">
                                  {formData.WEA ? (
                                    <Badge color={weaUrgencyMap[formData.Urgency]?.color}>
                                      {weaUrgencyMap[formData.Urgency]?.name}
                                    </Badge>
                                  ) : (
                                    <Badge color={urgencyMap[formData.Urgency]?.color}>
                                      {urgencyMap[formData.Urgency]?.name}
                                    </Badge>
                                  )}
                                </div>
                              </div>
                              <div>
                                <h2 className="text-sm font-semibold text-gray-300">
                                  Certainty
                                </h2>
                                <div className="m-1">
                                  {formData.WEA ? (
                                    <Badge
                                      color={weaCertaintyMap[formData.Certainty]?.color}
                                    >
                                      {weaCertaintyMap[formData.Certainty]?.name}
                                    </Badge>
                                  ) : (
                                    <Badge
                                      color={certaintyMap[formData.Certainty]?.color}
                                    >
                                      {certaintyMap[formData.Certainty]?.name}
                                    </Badge>
                                  )}
                                </div>
                              </div>
                              {formData['WEA Handling'] && (
                                <div>
                                  <h2 className="text-sm font-semibold text-gray-300">
                                    WEA Handling
                                  </h2>
                                  <div className="m-1">
                                    <Badge
                                      color={
                                        weaHandlingMap[formData['WEAHandling']]?.color
                                      }
                                    >
                                      {weaHandlingMap[formData['WEAHandling']]?.name}
                                    </Badge>
                                  </div>
                                </div>
                              )}
                            </div>
                          </div>
                        </Tab>
                      )}
                      <Tab title="Locations">
                        <DetailMap locations={JSON.parse(formData.Locations)} />
                      </Tab>
                    </Tabs>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </ModalCustom>
        <div className="px-6 py-6 bg-gray-200 dark:bg-gray-800 sm:px-6 ">
          <h2 className="text-lg font-semibold text-red-400">
            You are sending as {userName}.
          </h2>
          <Checkbox onChange={() => toggleDisabled(false)}>
            I, {userName}, by checking this box do hereby accept responsibility for
            sending out this notification in ensuring public safety and emergency
            preparedness.
          </Checkbox>
        </div>
      </Modal>
    )
  )
}

export default SubmissionModal
import { Modal, ModalText, useToast } from '@ocv-web/ui'
import Portal from '../../../portal/portal'
import { useNotificationStatus } from '../../api/notifications'
import { useHistory, useLocation } from 'react-router-dom'
import React from 'react'
<<<<<<< HEAD
import { useUser } from '../../../administration/api/users'
import { useUserSelection } from '../../../core/context/UserSelectionContext'

=======
import { useHistory, useParams } from 'react-router-dom'
import { OCVRouteParams } from '../../../core/types'
import { useNotification } from '../../api/notifications'
import AWS from 'aws-sdk'
import { Auth } from 'aws-amplify'
>>>>>>> master
export interface IIPAWSCancelModal {
  show: boolean
  showAction: () => void
  cancelItem: any
}

<<<<<<< HEAD
export const IPAWSCancelModal: React.FC<IIPAWSCancelModal> = ({
  show,
  showAction,
  cancelItem,
}) => {
  const { userEmail } = useUserSelection()
  const { data } = useUser(userEmail)
  const userName = data?.Results[0]?.Name
  const cancelItemId = cancelItem?.SK?.split('#')[1]
  const history = useHistory()
  const location = useLocation()
  const [mutatePatch] = useNotificationStatus(cancelItemId)
=======
async function invokeLambda(params) {
  Auth.currentCredentials().then(async credentials => {
    const lambda = new AWS.Lambda({
      region: 'us-east-2',
      credentials: Auth.essentialCredentials(credentials),
    })
    const lambdaParams = {
      FunctionName:
        'arn:aws:lambda:us-east-2:730987745435:function:ipawsCancelAlert' /* required */,
      InvocationType: 'RequestResponse',
      Payload: JSON.stringify({
        sender: params.sender,
        messageId: params.messageId,
        sentOn: params.sentOn,
      }),
    }
    try {
      console.log('calling lambda')
      const resp = await lambda.invoke(lambdaParams).promise()
      console.log(resp)
    } catch (err) {
      console.log(err)
    }
  })
}

export const IPAWSCancelModal: React.FC<IIPAWSCancelModal> = ({ show, showAction }) => {
  const { id } = useParams<OCVRouteParams>()
  const { data } = useNotification(id)
  React.useEffect(() => {
    console.log(data?.Results[0])
  }, [data])
>>>>>>> master
  const { dispatch } = useToast()
  const handleCancel = () => {
    console.log('cancel')
    invokeLambda({
      sender: data.Results[0].Response.body.sender,
      messageId: data.Results[0].Response.body.alertId,
      sentOn: data.Results[0].Response.body.sentOn,
    })
    // // add cancel api call here
    // const lambdaParams = {
    //   FunctionName:
    //     'arn:aws:lambda:us-east-2:730987745435:function:ipawsCancelAlert' /* required */,
    //   InvocationType: 'RequestResponse',
    //   Payload: {
    //     sender: data.Results[0].Response.body.sender,
    //     messageId: data.Results[0].Response.body.alertId,
    //     sentOn: data.Results[0].Response.body.sentOn,
    //   },
    // }
    // try {
    //   console.log('calling lambda')
    //   const resp = lambda.invoke(lambdaParams)
    //   console.log(resp)
    // } catch (err) {
    //   console.log(err)
    // }
    try {
      mutatePatch({
        Status: 'Inactive',
        Title: cancelItem.Title,
        Description: cancelItem.Description,
        Type: cancelItem.Type,
        SentBy: { Name: userName, Email: userEmail },
        Locations: cancelItem.Locations,
        Expires: {
          Hours: 0,
          Minutes: 0,
        },
        SocialMedia: {
          Facebook: false,
          Twitter: false,
          Instagram: false,
        },
        FeatureToOpen: '',
        Groups: [],
        LastUpdated: new Date().toLocaleString(),
      })
      dispatch({
        type: 'add',
        payload: {
          title: 'Notification Cancelled Successfully.',
          status: 'success',
          message: 'You successfully cancelled this MAXX Notification.',
        },
      })
      showAction()
      if (location.pathname === '/maxx/history') {
        setTimeout(() => {
          window.location.reload()
        }, 1000)
      } else {
        history.push('/maxx/history')
        setTimeout(() => {
          window.location.reload()
        }, 1000)
      }
    } catch {
      dispatch({
        type: 'add',
        payload: {
          title: 'Failed to Cancel Notification.',
          status: 'error',
          message: 'You failed to cancel this notification.',
        },
      })
      showAction()
    }
  }
  return (
    show && (
      <Portal id="root">
        <Modal
          buttons
          width="lg"
          buttonColor="red"
          show={show}
          onCancel={() => showAction()}
          onClick={() => {
            handleCancel()
          }}
          buttonTitle="Cancel Notification"
        >
          <ModalText
            icon="exclamation-triangle"
            iconColor="red"
            title="Cancel Notification"
            subtitle="Are you sure you want to cancel this notification? This action cannot be undone."
          />
        </Modal>
      </Portal>
    )
  )
}

export default IPAWSCancelModal
for (int index = 0; index < array.length; index++){
  
}
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend
} from 'chart.js';
import { Line } from 'react-chartjs-2';       


function HraHero() {
  return (
    <Line
      className='bg-white h-3/4 w-full'
      options={{
        responsive: true,
        plugins: {
          legend: false
        },
        scales: {
          x: {
            ticks: {
              color: 'orange'
            },
            title: {
              display: true,
              text: 'Years of Growth',
              color: '#00aeef',
              font: {
                size: 14
              }
            }
          },
          y: {
            ticks: {
              callback: function (value, i) {
                if (i == 0) {
                  return value + ' k';
                }

                return value + ' Lakhs';
              }
            },
            title: {
              display: true,
              text: 'Amount Invested',
              color: '#154d83',
              font: {
                size: 14
              }
            },
            border: {
              dash: [6, 4]
            }
          }
        }
      }}
      data={{
        labels: [
          2022, 2024, 2026, 2028, 2030, 2032, 2034, 2036, 2038, 2040, 2042
        ],
        datasets: [
          {
            data: [0, 2, 3, 5, 10, 15, 20, 25, 30, 35],
            borderColor: '#f47920',
            tension: 0.1,
            pointRadius: '6',
            pointHoverRadius: '6',
            pointBackgroundColor: '#00aeef',
            pointHoverBackgroundColor: '#f47920'
          }
        ]
      }}
    />
  );
}

export default HraHero
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend
} from 'chart.js';
import { Line } from 'react-chartjs-2';       


function HraHero() {
   ChartJS.register(
    CategoryScale,
    LinearScale,
    PointElement,
    LineElement,
    Title,
    Tooltip,
    Legend
  );
  
  return (
    <Line
      className='bg-white h-3/4 w-full'
      options={{
        responsive: true,
        plugins: {
          legend: false
        },
        scales: {
          x: {
            ticks: {
              color: 'orange'
            },
            title: {
              display: true,
              text: 'Years of Growth',
              color: '#00aeef',
              font: {
                size: 14
              }
            }
          },
          y: {
            ticks: {
              callback: function (value, i) {
                if (i == 0) {
                  return value + ' k';
                }

                return value + ' Lakhs';
              }
            },
            title: {
              display: true,
              text: 'Amount Invested',
              color: '#154d83',
              font: {
                size: 14
              }
            },
            border: {
              dash: [6, 4]
            }
          }
        }
      }}
      data={{
        labels: [
          2022, 2024, 2026, 2028, 2030, 2032, 2034, 2036, 2038, 2040, 2042
        ],
        datasets: [
          {
            data: [0, 2, 3, 5, 10, 15, 20, 25, 30, 35],
            borderColor: '#f47920',
            tension: 0.1,
            pointRadius: '6',
            pointHoverRadius: '6',
            pointBackgroundColor: '#00aeef',
            pointHoverBackgroundColor: '#f47920'
          }
        ]
      }}
    />
  );
}

export default HraHero
1.To check which Git credentials are configured in your system, you can use the following command in the terminal:

```bash
git config --list
```

2. To permanently remove the user.email and user.name settings from your Git configuration, you can use the following commands in the terminal:

```bash
git config --global --unset user.email
git config --global --unset user.name
```

3. Then run the git config --list command to check your Git configuration, the output will not include the user.email and user.name settings.

<style>
    .parent>*{
    grid-area:1/1;
    }
</style>
<div class="parent grid max-w-[350px] rounded-md outline">
    <img class="aspect-square w-full object-contain" src="https://www.picsum.photos/id/233/1080/920" />
    <div class="h-full w-full bg-gradient-to-b from-transparent to-black/50"></div>
    <h1 class="mb-4 self-end text-center text-4xl text-white">Lorem, ipsum dolor</h1>
</div>
<style>
    .parent>*{
    grid-area:1/1;
    }
</style>
<div class="parent grid max-w-[350px] rounded-md outline">
    <img class="aspect-square w-full object-contain" src="https://www.picsum.photos/id/233/1080/920" />
    <div class="h-full w-full bg-gradient-to-b from-transparent to-black/50"></div>
    <h1 class="mb-4 self-end text-center text-4xl text-white">Lorem, ipsum dolor</h1>
</div>
const polygonVertices = item.shape.points[0].map(point =>
  webMercatorUtils.lngLatToXY(point[0], point[1])
);

// Calculate the center point of the polygon
const centerX = polygonVertices.reduce((sum, point) => sum + point[0], 0) / polygonVertices.length;
const centerY = polygonVertices.reduce((sum, point) => sum + point[1], 0) / polygonVertices.length;

// Create a center point graphic
const centerPointGraphic = new Graphic({
  geometry: new Point({
    x: centerX,
    y: centerY,
    spatialReference: {
      latestWkid: 3857,
      wkid: 102100
    }
  }),
  symbol: {
    type: 'simple-marker',
    style: 'circle',
    color: [255, 0, 0],  // Red color for the center point
    size: 10  // Adjust the size of the center point as needed
  }
});

// Create the polygon graphic
const polygonGraphic = new Graphic({
  geometry: new Polygon({
    rings: polygonVertices,
    spatialReference: {
      latestWkid: 3857,
      wkid: 102100,
    },
  }),
  symbol: {
    type: 'simple-fill',
    style: 'solid',
    color: [105, 105, 105, 0.5],
    outline: {
      color: [255, 255, 255],
      width: 2,
    },
  },
});

// Add both the polygon and center point graphics to the map
graphicsLayer.addMany([polygonGraphic, centerPointGraphic]);
<div>
    <div class="sticky top-0 flex h-12 w-full items-center bg-black">
        <input type="checkbox" class="peer hidden" id="a" />
        <label for="a" class="select-none border px-4 py-2 text-white"> ☰ </label>

        <!-- Sidebar -->
        <div class="fixed inset-y-0 left-0 mt-12 w-64 -translate-x-full transform bg-gray-800 px-4 transition-transform duration-300 ease-in-out peer-checked:translate-x-0">
            <div class="flex h-full flex-col justify-between gap-4">
                <div class="border border-emerald-500">
                    <h1 class="text-2xl leading-loose text-white">Logo</h1>
                </div>
                <div class="overflow-y-auto border border-orange-500">
                    <!-- Links -->
                    <a href="#" class="block py-2 text-white hover:bg-gray-700">Link 1</a>
                    <a href="#" class="block py-2 text-white hover:bg-gray-700">Link 2</a>
                    <div class="group">
                        <div class="relative">
                            <a href="#" class="group block py-2 text-white hover:bg-gray-700">
                                Link 3
                                <span class="absolute right-4 top-1/2 -translate-y-1/2 transform text-white transition-transform group-hover:rotate-180">▼</span>
                            </a>
                        </div>
                        <div class="mt-2 hidden space-y-2 pl-4 group-hover:flex group-hover:flex-col">
                            <a href="#" class="text-white">Link 3.1</a>
                            <a href="#" class="text-white">Link 3.2</a>
                        </div>
                    </div>
                    <a href="#" class="block py-2 text-white hover:bg-gray-700">Link 4</a>
                    <a href="#" class="hover-bg-gray-700 block py-2 text-white">Link 5</a>
                    <a href="#" class="block py-2 text-white hover:bg-gray-700">Link 6</a>
                    <a href="#" class="block py-2 text-white hover:bg-gray-700">Link 4</a>
                    <a href="#" class="hover-bg-gray-700 block py-2 text-white">Link 5</a>
                    <a href="#" class="block py-2 text-white hover:bg-gray-700">Link 6</a>
                    <a href="#" class="block py-2 text-white hover:bg-gray-700">Link 4</a>
                    <a href="#" class="hover-bg-gray-700 block py-2 text-white">Link 5</a>
                    <a href="#" class="block py-2 text-white hover:bg-gray-700">Link 6</a>
                    <a href="#" class="block py-2 text-white hover:bg-gray-700">Link 4</a>
                    <a href="#" class="hover-bg-gray-700 block py-2 text-white">Link 5</a>
                    <a href="#" class="block py-2 text-white hover:bg-gray-700">Link 6</a>
                </div>
                <!-- Settings -->
                <div class="border border-lime-500"><button class="block py-2 text-white hover:bg-gray-700">Settings</button></div>
            </div>
        </div>
    </div>
    <!-- Main Content -->
    <div class="flex-grow bg-gray-100 p-4">
        <!-- Your Main Content Goes Here -->
        <p>....</p>
    </div>
</div>
// copy paste react
return (
<>
<style>
{`
.animated-text {
            position: relative;
            display: inline-block;
            text-decoration: none;}

.animated-text::after {
            content: '';
            position: absolute;
            left: 0;
            bottom: 0;
            width: 100%;
            height: 2px;
            background-color: white;
            transform-origin: 0% 50%;
            transform: scaleX(0);
            transition: transform 0.3s ease;}

.wrapper:hover .animated-text::after, .wrapper:hover .animated-text {
            transform: scaleX(1);}

//or (removing redundant, see if it works)
.wrapper:hover .animated-text1::after{
            transform: scaleX(1);}
 `}
<style>
<button className="wrapper">
<p className="animated-text">click</p>
</button>
</>
)
// copy paste for react 
return (
<>
    <style>{`
        .animated-text {
            position: relative;
            display: inline-block;
            text-decoration: none;
        }

        .animated-text::after {
            content: '';
            position: absolute;
            left: 0;
            bottom: 0;
            width: 100%;
            height: 2px;
            background-color: blue;
            transform-origin: 0% 50%;
            transform: scaleX(0);
            transition: transform 0.3s ease;
        }

        .animated-text:hover::after {
            transform: scaleX(1);
        }
    `}
</style>

    <p class="animated-text">Hover over this text to animate the underline.</p>

</>
)
const [formErrors, setFormErrors] = useState<Partial<UserRegistrationFormAddressInfoDetails>>({
  address: '',
  countryName: '',
  nationalityName: '',
  cityName: '',
  passportNo: '',
  passportExpiryDate: '',
  // nationality: '',
  resident: '',
  companyAdd: '',
});


handleEmptyField('passportNo', userData.passportNumber || passportNo, 'Passport No is required');


useEffect(() => {
  if (passportNo) {
    setFormErrors((prevErrors) => ({ ...prevErrors, passportNo: '' }));
  }
}, [passportNo]);

<input
      type="text"
      className={`form-control passport-number-input ${formErrors.passportNo ? 'input-error' : ''}`}
      id="passportNumber"
      placeholder="Enter Your Passport Number"
      defaultValue={userData.passportNumber}
      maxLength={12}
      onChange={(e) => {
        setPassportNo(e.target.value);
        if (e.target.value) {
        setFormErrors((prevErrors) => ({ ...prevErrors, passportNo: '' }));
        }
        }}
      onInput={(e) => {
        const input = e.target as HTMLInputElement;
        input.value = input.value.replace(/[^a-zA-Z0-9 ]/g, '');
        setPassportNo(input.value);
        }}
      {...register('passportNo', {
      required: true,
      })}
/>





  props,
  ref,
) => <MuiAlert elevation={6} ref={ref} variant="filled" {...props} />);

export default function PhoneOTPVerification() {
  const [inputValue, setInputValue] = useState(['', '', '', '', '', '']);
  const [isVerified, setIsVerified] = useState(false);
  const [showInvalidOTPModal, setShowInvalidOTPModal] = useState(false);
  const [open, setOpen] = React.useState(false);
  const [errorMessage, setErrorMessage] = React.useState('');
  const [phoneNumber, setPhoneNumber] = useState('');
  const [snackbarSeverity, setSnackbarSeverity] = React.useState('success');
  const [snackbarOpen, setSnackbarOpen] = React.useState(false);
  const [snackbarMessage, setSnackbarMessage] = React.useState('');

  const navigate = useNavigate();

  const handleClose = (event?: React.SyntheticEvent | Event, reason?: string) => {
    if (reason === 'clickaway') {
      return;
    }

    setOpen(false);
  };

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>, index: number) => {
    // Only allow digit characters
    const value = e.target.value.replace(/\D/g, '');
    // Create a new array with the updated value
    const newValue = [...inputValue];
    newValue[index] = value;
    setInputValue(newValue);
  };

  const handleKeyDown = (e: { key: string; }) => {
    if (e.key === 'Backspace') {
      setInputValue(inputValue.slice(0, -1)); // Remove the last character from the input value
    }
  };
  const { userGuid } = useParams();
  const verifyPhoneNumber = async () => {
    // Join the inputValue array into a single string
    const userOtp = inputValue.join('');
    // Check if the length is 6 (since we have 6 input fields)
    if (userOtp.length === 6) {
      const response = await trackPromise(api.verifyOtp(userOtp, userGuid));
      if (response?.data?.Output?.phoneVerified) {
        setIsVerified(true);
        navigate(`/accounts/signup/identity-verification/${userGuid}`);
      } else {
        setOpen(true);
        setErrorMessage('Invalid OTP');
      }
    } else {
      setIsVerified(false);
    }
  };

  const resentOtp = async () => {
    const response = await trackPromise(api.resendOtp(userGuid));
    console.log('otp resend response:', response);
    // show success sbackbart nessga if otp resend successfully
    if (response?.data?.Output?.phoneNumber) {
      setPhoneNumber(response?.data?.Output?.phoneNumber);
      setSnackbarSeverity('success');
      setSnackbarMessage('OTP resend successfully');
      setSnackbarOpen(true);
    } else {
      setSnackbarSeverity('error');
      setSnackbarMessage('OTP resend failed. Try again.');
      setSnackbarOpen(true);
    }
  };

  // useEffect(() => {
  //   resentOtp();
  // }, []);

  return (
    <>
      <main className="otp-verify-container">
        <header className="header">
          <img src={Headericon} alt="Header Image" />
        </header>
        <section className="verification-section">
          <h1 className="verification-title">Phone Number Verification</h1>
          <article className="verification-content">
            <div className="verification-icon">
              <img src={SMSIcon} alt="SMS Icon" />
            </div>
            <div className="verification-subtitle">Enter 6 Digit OTP</div>
            <div className="verification-message">
              <span className="verification-message-text">
                We have sent an OTP on
                {' '}
                <span className="verification-message-phone">{phoneNumber}</span>
              </span>
              <button
                onClick={resentOtp}
                className="resend-link"
              >
                Resend OTP
              </button>
            </div>
            <div className="verification-input mb-5">
              {[...Array(6)].map((_, index) => (
                <input
                  key={index}
                  type="text"
                  maxLength={1}
                  className="otp-input"
                  value={inputValue[index] || ''}
                  onChange={(e) => handleChange(e, index)}
                />
              ))}
              <button type="button" onClick={verifyPhoneNumber}>
                Verify
              </button>
            </div>
          </article>
        </section>
        <InvalidOTPModal
          show={showInvalidOTPModal}
          handleClose={() => setShowInvalidOTPModal(false)}
        />

      </main>
      <Snackbar
        open={open}
        autoHideDuration={3000}
        onClose={handleClose}
        anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
      >
        <Alert onClose={handleClose} severity="error" sx={{ width: '100%', backgroundColor: '#C13254' }}>
          {/* Oops! Something went wrong. Please try again later. */}
          {errorMessage}
        </Alert>
      </Snackbar>

      {/* snacbar for otp resend */}
      <Snackbar
        open={snackbarOpen}
        autoHideDuration={3000}
        onClose={() => setSnackbarOpen(false)}
        anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
      >
        <MuiAlert
          onClose={() => setSnackbarOpen(false)}
          variant="filled"
          elevation={6}
          severity={snackbarSeverity as MuiAlertProps['severity']}
          sx={{ width: '100%' }}
        >
          {snackbarMessage}
        </MuiAlert>
      </Snackbar>

    </>
  );
}
  useEffect(() => {
    
    // Begin here.
    
  }, []);
// src/components/RadixSlider.jsx
import * as Slider from "@radix-ui/react-slider";
import { useState } from "react";

const RadixSlider = () => {
  const [values, setValues] = useState([20, 80]);
  console.log(values);
  return (
    <div className="bg-gray-200 ">
      <label
        htmlFor="slider"
        className="text-center text-sm font-medium text-gray-700"
      >
        range: {values.toString()}
      </label>
      <Slider.Root
        id="slider"
        className="outline outline-1 mx-auto relative flex items-center select-none touch-none w-[300px] h-5"
        defaultValue={values}
        // onValueChange={(values) => setValues(values)}
        onValueCommit={(values) => setValues(values)}
        max={100}
        step={1}
        minStepsBetweenThumbs={10}
      >
        <Slider.Track className="bg-blue-400 relative grow rounded-full h-[3px]">
          <Slider.Range className="absolute bg-red-400 rounded-full h-full" />
        </Slider.Track>
        <Slider.Thumb
          className="block bg-white shadow-[0_2px_10px] shadow-black rounded-full hover:bg-violet-300 focus:outline "
          aria-label="Volume"
          asChild
        >
          <p className=" px-1"> {values[0]}</p>
        </Slider.Thumb>
        <Slider.Thumb
          className="block   bg-white shadow-[0_2px_10px] shadow-black rounded-full hover:bg-violet-300 focus:outline "
          aria-label="Volume"
          asChild
        >
          <p className=" px-1"> {values[1]}</p>
        </Slider.Thumb>
      </Slider.Root>
    </div>
  );
};

export default RadixSlider;

// src/App.jsx
const App = () => (
  <div>

      <RadixSlider />
     
    </div>
  </div>
);
// for india currency ruppes
  commaSeparatedNumber: (number) => {
    return (
      number
        ?.toString()
        ?.replaceAll(",", "")
        // ?.replace(/(\.\d{2})\d*/, "$1,")
        ?.replace(/(\d)(?=(\d\d)+\d$)/g, "$1,")
    );
  },

// for us currency ruppes 
  commaSeparatedNumber: (number) => {
    return (
      number
        ?.toString()
        ?.replaceAll(",", "")
        // ?.replace(/(\.\d{2})\d*/, "$1,")
           ?.replace(/(\d)(?=(\d{3})+\b)/g, "$1,")

    );
import { zodResolver } from "@hookform/resolvers/zod";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";

const signUpSchema = z
  .object({
    email: z
      .string()
      .nonempty("email is required")
      .email("Invalid email address"),
    password: z.string().min(8, "Password must be at least 8 characters"),
    confirmPassword: z.string(),
  })
  // we can use zod to validate using refine method
  .refine((data) => data.password === data.confirmPassword, {
    message: "Passwords do not match",
    path: ["confirmPassword"], // it will show error in confirmPassword field
  });

type ISignUpSchema = z.infer<typeof signUpSchema>; // create type from schema

const ReactHookFormWithZod = () => {
  const [show, setShow] = useState(false);
  const [show1, setShow1] = useState(false);
  const { register, handleSubmit, formState, reset } = useForm<ISignUpSchema>({
    resolver: zodResolver(signUpSchema), //tell which schema to resolve
  });
  const { errors, isSubmitting } = formState;

  const onSubmit = async (data: ISignUpSchema) => {
    console.log(data);
    //-------send data to server----------//
    await new Promise((resolve) => setTimeout(resolve, 1000));
    //------
    reset(); // clear form
  };
  return (
    <form
      onSubmit={handleSubmit(onSubmit)}
      className="flex flex-col gap-y-4 [&>div>input]:w-full"
    >
      <label className="-mb-3 text-sm text-gray-500" htmlFor="email">
        email
      </label>
      <div className="">
        <input
          {...register("email")}
          type="text"
          placeholder="email"
          className="rounded border px-4 py-2"
        />
        {
          // granular show errors
          errors.email && (
            <p className="text-sm text-red-500">{`${errors.email.message}`}</p>
          )
        }
      </div>
      <label className="-mb-3 text-sm text-gray-500" htmlFor="password">
        password
      </label>
      <div className="relative ">
        <input
          {...register("password")}
          type={show ? "text" : "password"}
          id="password"
          placeholder="password"
          className=" block rounded border py-2 pl-2 pr-12"
        ></input>
        <p
          className="absolute  right-2 top-0 block cursor-pointer select-none py-2 "
          onClick={() => setShow((show) => !show)}
        >
          👁️
        </p>
        {
          // granular show errors
          errors.password && (
            <p className="text-sm text-red-500">{`${errors.password.message}`}</p>
          )
        }
      </div>
      <label className="-mb-3 text-sm text-gray-500" htmlFor="confirmPassword ">
        confirm password
      </label>
      <div className="relative">
        <input
          {...register("confirmPassword")}
          id="confirmPassword"
          type={show1 ? "text" : "password"}
          placeholder="confirm password"
          className="rounded border py-2 pl-2 pr-10 "
        />
        <p
          className="absolute  right-2 top-0 block cursor-pointer select-none py-2 "
          onClick={() => setShow1((show) => !show)}
        >
          👁️
        </p>
        {
          // granular show errors
          errors.confirmPassword && (
            <p className="text-sm text-red-500">{`${errors.confirmPassword.message}`}</p>
          )
        }
      </div>

      <button
        type="submit"
        className="rounded bg-blue-500 py-2 text-white disabled:cursor-no-drop disabled:bg-gray-500"
        disabled={isSubmitting}
      >
        {isSubmitting ? "loading..." : "Submit"}
      </button>
    </form>
  );
};

export default ReactHookFormWithZod;
import React, { useState } from "react";
import { useForm } from "react-hook-form";
import type { FieldValues } from "react-hook-form";

const ReactHookForm = () => {
  const [show, setShow] = useState(false);
  const [show1, setShow1] = useState(false);
  const { register, handleSubmit, formState, reset, getValues } = useForm();
  const { errors, isSubmitting } = formState;

  const onSubmit = async (data: FieldValues) => {
    // (data:FieldValues) type is -> {[x:string] : any} //we would need zod for more typesafety
    console.log(data);
    //-------send data to server----------//
    await new Promise((resolve) => setTimeout(resolve, 1000));
    //------
    reset(); // clear form
  };
  return (
    <form
      onSubmit={handleSubmit(onSubmit)}
      className="flex flex-col gap-y-4 [&>div>input]:w-full"
    >
      <label className="-mb-3 text-sm text-gray-500" htmlFor="email">
        email
      </label>
      <div className="border">
        <input
          {...register("email", {
            required: "Email is required",
            pattern: {
              value: /\S+@\S+\.\S+/,
              message: "invaid email format",
            },
          })}
          type="email"
          placeholder="email"
          className="rounded px-4 py-2"
        />
        {
          // granular show errors
          errors.email && (
            <p className="text-sm text-red-500">{`${errors.email.message}`}</p>
          )
        }
      </div>
      <label className="-mb-3 text-sm text-gray-500" htmlFor="password">
        password
      </label>
      <div className="relative border ">
        <input
          {...register("password", {
            required: "Password is required",
            minLength: {
              value: 8,
              message: "Password must be at least 8 characters",
            },
          })}
          type={show ? "text" : "password"}
          id="password"
          placeholder="password"
          className="  block rounded py-2 pl-2 pr-12"
        ></input>
        <p
          className="absolute  right-2 top-0 block cursor-pointer select-none py-2 "
          onClick={() => setShow((show) => !show)}
        >
          👁️
        </p>
        {
          // granular show errors
          errors.password && (
            <p className="text-sm text-red-500">{`${errors.password.message}`}</p>
          )
        }
      </div>
      <label className="-mb-3 text-sm text-gray-500" htmlFor="confirmPassword ">
        confirm password
      </label>
      <div className="relative border">
        <input
          {...register("confirmPassword", {
            required: "Confirm Password is required",
            validate: (value) => {
              return (
                // getValues from "password" input
                value === getValues("password") || "Passwords do not match"
              );
            },
          })}
          id="confirmPassword"
          type={show1 ? "text" : "password"}
          placeholder="confirm password"
          className="rounded py-2 pl-2 pr-10 "
        />
        <p
          className="absolute  right-2 top-0 block cursor-pointer select-none py-2 "
          onClick={() => setShow1((show) => !show)}
        >
          👁️
        </p>
        {
          // granular show errors
          errors.confirmPassword && (
            <p className="text-sm text-red-500">{`${errors.confirmPassword.message}`}</p>
          )
        }
      </div>

      <button
        type="submit"
        className="rounded bg-blue-500 py-2 text-white disabled:cursor-no-drop disabled:bg-gray-500"
        disabled={isSubmitting}
      >
        {isSubmitting ? "loading..." : "Submit"}
      </button>
    </form>
  );
};

export default ReactHookForm;
import { useState } from "react";

const initialFormData = {
  email: "",
  password: "",
  confirmPassword: "",
};
const FormWithoutReactHookForm = () => {
  const [show, setShow] = useState(false);
  const [show1, setShow1] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [errors, setErrors] = useState<string[]>([""]); // errors are array of strings
  const [formData, setFormData] = useState(initialFormData);

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    setErrors([]); // clear errors
    //-------validate data ----------//
    if (formData.password !== formData.confirmPassword) {
      setErrors((prev) => [...prev, "passwords do not match"]);
      return;
    }

    console.log(formData);
    setIsSubmitting(true); // show loading or disable submit button
    //-------send data to Server ----------//
    await new Promise((resolve) => setTimeout(resolve, 1000));
    //....
    setFormData(initialFormData); // clear form
    setIsSubmitting(false);
  };
  return (
    <form
      className="flex flex-col gap-y-4 [&>div>input]:w-full"
      onSubmit={handleSubmit}
    >
      <label className="-mb-3 text-sm text-gray-500" htmlFor="email">
        email
      </label>
      <div className="border">
        <input
          type="email"
          id="email"
          required={true}
          placeholder="email"
          className="rounded px-4 py-2"
          value={formData.email}
          onChange={(e) =>
            setFormData((prev) => ({ ...prev, email: e.target.value }))
          }
        />
      </div>
      <label className="-mb-3 text-sm text-gray-500" htmlFor="password">
        password
      </label>
      <div className="relative border ">
        <input
          type={show ? "text" : "password"}
          id="password"
          placeholder="password"
          className="  block rounded py-2 pl-2 pr-12"
          required={true}
          minLength={8}
          value={formData.password}
          onChange={(e) =>
            setFormData((prev) => ({ ...prev, password: e.target.value }))
          }
        ></input>
        <p
          className="absolute  right-2 top-0 block cursor-pointer select-none py-2 "
          onClick={() => setShow((show) => !show)}
        >
          👁️
        </p>
      </div>
      <label className="-mb-3 text-sm text-gray-500" htmlFor="confirmPassword ">
        confirm password
      </label>
      <div className="relative border">
        <input
          id="confirmPassword"
          required={true}
          type={show1 ? "text" : "password"}
          placeholder="confirm password"
          className="rounded py-2 pl-2 pr-10 "
          value={formData.confirmPassword}
          onChange={(e) =>
            setFormData((prev) => ({
              ...prev,
              confirmPassword: e.target.value,
            }))
          }
        />
        <p
          className="absolute  right-2 top-0 block cursor-pointer select-none py-2 "
          onClick={() => setShow1((show) => !show)}
        >
          👁️
        </p>
      </div>
      {
        // show errors
        errors.length > 0 && (
          <div className=" text-center text-red-500">
            {errors.map((error, i) => (
              <p key={i} className="text-sm">
                {error}
              </p>
            ))}
          </div>
        )
      }
      <button
        type="submit"
        className="rounded bg-blue-500 py-2 text-white disabled:cursor-no-drop disabled:bg-gray-500"
        disabled={isSubmitting}
      >
        {isSubmitting ? "loading..." : "Submit"}
      </button>
    </form>
  );
};

export default FormWithoutReactHookForm;
import { useRef, useState } from "react";

const Modal = () => {
  const contentRef = useRef(null);
  const [isOpen, setIsOpen] = useState(false);

  const handleClickOutside = (event) => {
    if (contentRef.current && !contentRef.current.contains(event.target)) {
      console.log(`object`);
      setIsOpen(false);
    }
  };

  const toggleModal = () => {
    setIsOpen(!isOpen);
  };
  

  return (
    <div>
      <style>
        {`
/* Modal container */
.modal-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent overlay */
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Modal content */
.modal-content {
  background-color: #fff;
  padding: 20px;
  border-radius: 4px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
  max-width: 400px;
  text-align: center;
}
	`}
      </style>
      <button
        className="px-2 bg-blue-300 py-1 rounded-lg"
        onClick={toggleModal}
      >
        Toggle Modal
      </button>
      {isOpen && (
        <div
          className="modal-container border border-pink-600 select-none"
          onClick={handleClickOutside}
        >
          <div className="modal-content" ref={contentRef}>
            <h2>Click outside to close</h2>
            <p>This is a modal. Click outside to close.</p>
            <button
              className="px-3 py-1 mt-3 rounded-md bg-teal-300"
              onClick={() => setIsOpen(false)}
            >
              ok
            </button>
          </div>
        </div>
      )}
    </div>
  );
};

export default Modal;
import {userRef,UseEffect} from "react"
function App()=>{
  const refOne = useRef(null);
  
  useEffect(() => {
    document.addEventListener("click", handleClickOutside, true);
  }, []);
  
  const handleClickOutside = (e) => {
    if (refOne.current && !refOne.current.contains(e.target)) {
      console.log("clicked outside");
    } else {
      console.log(`clicked inside div`);
    }
  };
 return(
 <div style={{width:"10rem",height:"10rem", backGround:"red"}}>
 </div>) 
}
//THIS IS FASTER

const initialUserInput = {
  "current-savings": 10000,
  "yearly-contribution": 1200,
  "expected-return": 7,
  duration: 10
};
 

function inputChangeHandler(input, value) {
    setUserInput((prevInput) => {
      return {
        ...prevInput,
        [input]: +value
      };
    });
  }

//**NOTE: The +value expression is used to convert the value to a number (i.e., a numeric data type). The unary + operator in JavaScript is used for type conversion, and when applied to a non-number value, it attempts to convert it to a numeric value.

//The +value expression is used to ensure that the value stored in the state object (prevInput) is of numeric data type, regardless of the data type of the value being passed into the inputChangeHandler function.




//THIS IS SLOWER

  // const [enteredCurrentSavings, setEnteredCurrentSavings] = useState(0);
  // const [enteredYearlyContributions, setEnteredYearlyContributions] = useState(
  //   0
  // );
  // const [enteredExpectedReturn, setEnteredExpectedReturn] = useState(0);
  // const [enteredDuration, setEnteredDuration] = useState(0);
  // const [userInput, setUserInput] = useState({
  //   "current-savings": "",
  //   "yearly-contribution": "",
  //   "expected-return": "",
  //   duration: ""
  // });

  // function currentSavingsChangeHandler(e) {
  //   setEnteredCurrentSavings(e.target.value);
  // }

  // function yearlyContributionsChangeHandler(e) {
  //   setEnteredYearlyContributions(e.target.value);
  // }
  // function expectedReturnChangeHandler(e) {
  //   setEnteredExpectedReturn(e.target.value);
  // }
  // function enteredDurationChangeHandler(e) {
  //   setEnteredDuration(e.target.value);
  // }

  // function submitHandler(e) {
  //   e.preventDefault();

  //   setUserInput({
  //     "current-savings": enteredCurrentSavings,
  //     "yearly-contribution": enteredYearlyContributions,
  //     "expected-return": enteredExpectedReturn,
  //     duration: enteredDuration
  //   });

  //   calculateHandler(userInput);
  // }
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/deploying_different_types_of_servers/setting-apache-http-server_deploying-different-types-of-servers

Install ModSecurity on CentOS 7

1. Enter the following into a terminal window:
sudo yum install mod_security

If prompted, pres y and hit Enter to allow the process to complete.
2. Restart the Apache service:

sudo systemctl restart httpd.service
3. Check the software version (should be 2.8.0 or later):

yum info mod_security
Step: 3 Configure ModSecurity

Upon installation, ModSecurity is set to log events according to default rules. You’ll need to edit the configuration file to adjust the rules to detect and block traffic.

The default configuration file is /etc/modsecurity/modsecurity.conf-recommended.
1. Copy and rename the file:
sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf

2. Next, change the ModSecurity detection mode. First, move into the /etc/modsecurity folder:
sudo cd /etc/modsecurity

3. Open the configuration file in a text editor (we will be using nano):
sudo nano modsecurity.conf
___________________________________________________________________________________________________
Now after installation 

Add this line in httpd.conf (full path-> /etc/httpd/conf/httpd.conf)
SecRuleEngine on
SecServerSignature " "
ServerSignature On
ServerTokens Prod

function ListingCard({listings}) {
  return (
    <div className="listing-container">
    <div className="listing-card">
        <img src={listings.image} />
        <a href="#"><p>{listings.title}</p></a>
        <div className="description">
            <p>{listings.category}</p>
        </div>
        <div>
        <p>{listings.price}€</p>
        </div>
    </div>
    </div>
  )
}
<div className="home-container">
        <div className="listings-container" key={listings.id}>
          {listings.title}
          
        </div>
      {/* 
          //listings.map(item=><ListingCard listing={item}
            //key={item.id} />)

          // listings.map(item=><p key={item.id}>{item.title}</p>)
        */}
        
      </div>
 <div className="row form-row mb-5">
            {/* Country Col */}
            <div className="col-md-6">
              <label
                htmlFor="country"
                className="form-label w-100 country-label"
              >
                Country*
              </label>
              <Autocomplete
                disablePortal
                id="country"
                defaultValue={userData?.countryName ?? ''}
                options={countriesList}
                isOptionEqualToValue={(option: any, value: any) => option.label === value.label}
                renderInput={(params) => (
                  <TextField
                    {...params}
                    {...register('countryName', {
                      required: true,
                    })}
                    sx={{
                      '& .MuiOutlinedInput-root': {
                        '& fieldset': {
                          borderColor: (countryID || !submitAttempted) ? 'grey' : 'red',
                        },
                        '&:hover fieldset': {
                          borderColor: (countryID || !submitAttempted) ? 'grey' : 'red',
                        },
                        '&.Mui-focused fieldset': {
                          borderColor: (countryID || !submitAttempted) ? 'grey' : 'red',
                        },
                      },
                    }}
                    className="country-input"
                    placeholder="Select Country"
                  />
                )}
                // onchange event handler to set the countryName state
                onChange={(e: any, newVal: any) => {
                  setCountryID(newVal.countryID);
                  setCountrySelected(true);
                  setCityID(0); // Clear the city ID
                  // Also clear any other city-related states if you have them
                }}
              />
            </div>

            {/* City Col */}
            {countrySelected && (
            <div className="col-md-6">
              <label
                htmlFor="city"
                className="form-label w-100 city-label"
              >
                City*
              </label>
              <Autocomplete
                disablePortal
                id="city"
                value={cityID ? citiesListBycountry.find((city: { cityID: number; }) => city.cityID === cityID) : null} // Use the cityID state to control the value
                options={citiesListBycountry}
                isOptionEqualToValue={(option: any, value: any) => option.label === value.label}
                renderInput={(params) => (
                  <TextField
                    {...params}
                    {...register('cityName', {
                      required: true,
                    })}
                    sx={{
                      '& .MuiOutlinedInput-root': {
                        '& fieldset': {
                          borderColor: (cityID || !submitAttempted) ? 'grey' : 'red',
                        },
                        '&:hover fieldset': {
                          borderColor: (cityID || !submitAttempted) ? 'grey' : 'red',
                        },
                        '&.Mui-focused fieldset': {
                          borderColor: (cityID || !submitAttempted) ? 'grey' : 'red',
                        },
                      },
                    }}
                    className="city-input"
                    placeholder="Choose City*"
                  />
                )}
                onChange={(e, value: any) => setCityID(
                  value?.cityID,
                )}
              />
              {/* handle errors */}
              {/* {formErrors.cityName && (
              <span className="error-message">{formErrors.cityName}</span>
              )} */}
            </div>
            )}
          </div>
import { createContext, useState } from "react";

export const ThemeContext = createContext();

// pass the prop children; a provider is needed here
export default function ThemeContextProvider({ children }) {
  
  // boolean for default setting
  const [darkMode, setDarkMode] = useState(true);
  return (
    // allows darkMode and setDarkMode to be used
    <ThemeContext.Provider value={{ darkMode, setDarkMode }}>
      {children}
    </ThemeContext.Provider>
  );
}
<DatePicker
                onChange={handleDatePicker}
                value={userData.passportExpiryDate || null || passportExpiryDate}
                minDate={new Date().toISOString().split('T')[0].split('-').join('/')}
                renderInput={(params: any) => (
                  <TextField
                    {...params}
                    inputProps={{
                      ...params.inputProps,
                      // readonly
                      readOnly: true,
                      placeholder: 'Select Date of Expiry',
                    }}
                    {...register('passportExpiryDate', {
                      required: true,
                    })}
                    // className="date-picker date-picker-input"
                    error={
                      (errors?.passportExpiryDate?.type === 'required' && passportExpiryDate === '')
                    }
                    sx={{
                      '& .MuiOutlinedInput-root': {
                        '& fieldset': {
                          borderColor: (passportExpiryDate || !submitAttempted) ? 'grey' : 'red',
                        },
                        '&:hover fieldset': {
                          borderColor: (passportExpiryDate || !submitAttempted) ? 'grey' : 'red',
                        },
                        '&.Mui-focused fieldset': {
                          borderColor: (passportExpiryDate || !submitAttempted) ? 'grey' : 'red',
                        },
                      },
                    }}
                  />
                )}
              />
<section id="cv-section-3" style="overflow: auto;" data-visibility="all">
<div data-visibility="all">
<div>
<p style="text-align: center;"><span style="font-size: 18pt;"><strong><img src="https://cdn.myocv.com/ocvapps/a7736801/files/LCSO-JoinOurTeamHeader.png" alt="Join Our Team" width="1920" height="650" /></strong></span></p>
<p style="text-align: center;">&nbsp;</p>
<p style="text-align: center;">&nbsp;</p>
<p style="text-align: center;"><span style="font-size: 18pt;"><strong>Thank you for your interest in employment with the Lee County Sheriff's Office.&nbsp;</strong></span></p>
</div>
<div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table style="border-collapse: collapse; width: 100%;" border="1">
<tbody>
<tr>
<td style="width: 54.181818%; text-align: center; vertical-align: top;">
<h2 style="text-align: left;"><span style="font-size: 18pt; color: #e1b047;"><strong>Employment&nbsp;Opportunities</strong></span></h2>
<p style="text-align: left;">&nbsp;</p>
<p style="text-align: left;">&nbsp;</p>
<p style="text-align: left;"><span style="font-size: 14pt;"><strong>Correction Nurse &ndash; Detention Center Division</strong></span></p>
<ul style="text-align: left;" type="disc">
<li><strong>Full-Time</strong></li>
<li><strong>Pay Range: $47,335.39 - $71,472.62&nbsp;<br /></strong></li>
<li><strong>Division: Detention Center - Lee County Sheriff's Office</strong></li>
</ul>
<div title="Page 1">
<div>
<div>
<p style="text-align: left;">This position is responsible for providing quality nursing care for the inmate population.</p>
</div>
</div>
</div>
<p style="text-align: left;">Successful applicants must pass a criminal background check and will be subject to a pre-employment drug screen.&nbsp;</p>
<p style="text-align: left;">&nbsp;</p>
<p style="text-align: left;"><strong><a href="https://cdn.myocv.com/ocvapps/a7736801/files/LCSO-CorrectionNurse1022.pdf" target="_blank" rel="noopener"><em>Complete Correction Nurse position Announcement, Duties, and Qualifications</em></a><br /></strong><em>(Opens PDF in another window)</em></p>
<p style="text-align: left;">&nbsp;</p>
<p style="text-align: left;">&nbsp;</p>
<p style="text-align: left;"><span style="font-size: 14pt;"><strong>Correction Deputy &ndash; Detention Center Division</strong></span></p>
<ul style="text-align: left;" type="disc">
<li><strong>Full-Time</strong></li>
<li><strong>Pay Range: $40,890.56 - $61,740.71&nbsp;<br /></strong></li>
<li><strong>Division: Detention Center - Lee County Sheriff's Office</strong></li>
</ul>
<p style="text-align: left;">This position is responsible for the safety and security of detention center inmates, personnel, and facilities.</p>
<p style="text-align: left;">Successful applicants must pass a criminal background check and will be subject to a pre-employment drug screen.&nbsp;</p>
<p style="text-align: left;">&nbsp;</p>
<p style="text-align: left;"><strong><a href="https://cdn.myocv.com/ocvapps/a7736801/files/LCSO-CorrectionDeputy1022.pdf" target="_blank" rel="noopener"><em>Complete Correction Deputy position Announcement, Duties, and Qualifications</em></a><br /></strong><em>(Opens PDF in another window)</em></p>
<p style="text-align: left;">&nbsp;</p>
<p style="text-align: left;">&nbsp;</p>
<p style="text-align: left;"><span style="font-size: 14pt;"><strong>Deputy Sheriff &ndash; Patrol Division</strong></span></p>
<ul style="text-align: left;" type="disc">
<li><strong>Full-Time</strong></li>
<li><strong>Pay Range: $47,335.39 - $71,472.62&nbsp;<br /></strong></li>
<li><strong>Division: Patrol - Lee County Sheriff's Office</strong></li>
</ul>
<p style="text-align: left;">This position is responsible for the enforcement of local, state, and federal laws.</p>
<p style="text-align: left;">Successful applicants must pass&nbsp;a criminal background check and will be subject to a pre-employment drug screen.&nbsp;</p>
<p style="text-align: left;">&nbsp;</p>
<p style="text-align: left;"><em><strong><a href="https://cdn.myocv.com/ocvapps/a7736801/files/LCSO-DeputySheriff1022.pdf" target="_blank" rel="noopener">Complete Deputy Sheriff position Announcement, Duties, and Qualifications</a><br /></strong>(Opens PDF in another window)</em></p>
<p style="text-align: left;">&nbsp;</p>
<p style="text-align: left;">&nbsp;</p>
<p style="text-align: left;"><em>&nbsp;</em></p>
</td>
<td style="width: 4.817108%; text-align: center; vertical-align: top;">
<h2><span style="color: #236fa1;"><span style="font-size: 18pt;"><strong><span style="color: #e1b047;">&nbsp;</span></strong></span></span></h2>
</td>
<td style="width: 41.001073%; text-align: center; vertical-align: top;">
<h2><span style="color: #236fa1;"><a style="color: #236fa1;" href="https://cdn.myocv.com/ocvapps/a7736801/files/LCSO-Updated-Benefits-Summary-Feb2022.pdf" target="_blank" rel="noopener"><span style="font-size: 18pt;"><strong><span style="color: #e1b047;">Summary of Benefits</span></strong></span></a></span></h2>
<p><span style="font-size: 10pt;"><em>(Opens PDF in another window)</em></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2><span style="color: #236fa1;"><a style="color: #236fa1;" href="https://cdn.myocv.com/ocvapps/a7736801/files/LCSO%20Application%20-%20Fillable%20Form.pdf" target="_blank" rel="noopener"><span style="font-size: 18pt;"><strong><span style="color: #e1b047;">Download an Application</span></strong></span></a></span></h2>
<p><span style="font-size: 10pt;"><em>(Opens PDF in another window)</em></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p style="text-align: left;"><strong><em>IMPORTANT GUIDELINES FOR COMPLETING YOUR APPLICATION:</em></strong></p>
<ul>
<li style="list-style-type: none;">
<ul>
<li style="text-align: left;">Resumes may be attached in addition to, but not in place of, any portion of the application.&nbsp;&nbsp;<strong>When completing your work history, DO NOT use "See Resume" as your response.</strong>&nbsp; Only the information you provide under&nbsp;WORK EXPERIENCE&nbsp;will be considered in determining if you meet the minimum experience requirements.&nbsp;</li>
<li style="text-align: left;"><strong>Be thorough.</strong>&nbsp;Your application is the primary tool used to evaluate your job qualifications.&nbsp; You must complete all sections of the application, including education and work experience. Additional proof may be requested.</li>
<li style="text-align: left;"><strong>Please read all questions carefully.</strong>&nbsp;Answer honestly and provide correct information, dates, etc.&nbsp; Background and reference check findings that are contradictory&nbsp;to the information provided on the&nbsp;application will result in disqualification or&nbsp;the retraction&nbsp;of any and all&nbsp;job offers.</li>
<li style="text-align: left;">Applicants should ensure that completed applications are submitted prior to the published closing date. <strong>Applications will not be accepted after the published closing date.</strong></li>
</ul>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
<div data-visibility="all">
<p>&nbsp;</p>
<p>&nbsp;</p>
<hr />
<p style="text-align: center;">&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p style="text-align: center;"><span style="font-size: 18pt;"><strong>If you would like to be a part of the Lee County Sheriff&rsquo;s Office team, there are several ways to submit a completed application...</strong></span></p>
<p style="text-align: center;">&nbsp;</p>
<table style="border-collapse: collapse; width: 87.67441860465117%; margin-left: auto; margin-right: auto;" border="1">
<tbody>
<tr>
<td style="width: 33.731739707835324%; text-align: left; vertical-align: top;">
<p><strong>In Person</strong></p>
<p>Lee County Sheriff's Office</p>
<p>1900 Frederick Rd.</p>
<p>Opelika, AL 36801</p>
</td>
<td style="width: 33.731739707835324%; text-align: left; vertical-align: top;">
<p><strong>Email</strong></p>
<p>lcso@leecountysheriff.org</p>
</td>
<td style="width: 32.536520584329345%; text-align: left; vertical-align: top;">
<p><strong>Fax</strong></p>
<p>(334) 737-7118</p>
</td>
</tr>
</tbody>
</table>
<p style="text-align: center;">&nbsp;</p>
<p style="text-align: center;"><strong>Applications will only be accepted for posted positions and must be received by the closing date.</strong></p>
<p style="text-align: center;"><strong>Resumes will not be accepted unless accompanied by an application.</strong></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<hr />
<h2>&nbsp;</h2>
<h2>&nbsp;</h2>
<h2><span style="color: #e1b047;"><strong>Interested in becoming a Deputy Sheriff or Corrections Deputy?</strong></span></h2>
<p>&nbsp;</p>
<p style="text-align: center;"><strong>If you want to learn more about our Deputy Sheriff and Correction Deputy positions contact:</strong></p>
<p style="text-align: center;">Deputy Sheriff Recruiter at (334) 737-7207 or <a href="mailto:jdaley@leecountysheriff.org">jdaley@leecountysheriff.org</a></p>
<p style="text-align: center;">Corrections Deputy Recruiter at (334) 737-7083 or <a href="mailto:sthreat@leecountysheriff.org">sthreat@leecountysheriff.org</a></p>
<p style="text-align: center;">&nbsp;</p>
<p style="text-align: center;">&nbsp;</p>
<table style="border-collapse: collapse; width: 100%; border-color: #CED4D9; border-style: solid;" border="1">
<tbody>
<tr>
<td style="width: 48.8374%; text-align: left; vertical-align: top;">
<p><strong>Deputy Sheriff Requirements</strong></p>
<ul>
<li>21 years of age or older</li>
<li>Valid Alabama Driver&rsquo;s License</li>
<li>High School Diploma or GED</li>
<li>Must pass a BAT (Basic Abilities Test) if you do not have an Associate&rsquo;s Degree or Higher</li>
<li>Pass a Criminal Background Check</li>
<li>Pass a Background Investigation</li>
<li>Pass a Drug Screening</li>
<li>Pass a Physical Exam</li>
<li>Pass a Physical Agility/Ability Test</li>
</ul>
<p>Must be available to work shift hours/weekends/holidays</p>
</td>
<td style="width: 48.8374%; text-align: left; vertical-align: top;">
<p><strong>Correction Deputy Requirements</strong></p>
<ul>
<li>19 years of age or older</li>
<li>High School Diploma or GED</li>
<li>Valid Driver&rsquo;s License</li>
<li>Pass a Background Investigation</li>
<li>Pass a Criminal Background Check</li>
<li>Pass a Drug Screening</li>
<li>Pass a Physical Agility Test</li>
</ul>
<p>Must be available to work shift hours/weekends/holidays</p>
</td>
</tr>
<tr>
<td style="width: 48.8374%; text-align: left; vertical-align: top;">
<p><strong>Physical Agility/Ability Test</strong></p>
<ul>
<li>Push Car 15 feet</li>
<li>Climb 6-foot fence</li>
<li>Crawl<strong> </strong>through window</li>
<li>Walk balance beam</li>
<li>Pull 165 lb. dummy 15 feet</li>
<li>22 push-ups in 1 minute</li>
<li>25 sit-ups in 1 minute</li>
<li>Run 1.5 miles in 15 minutes/28 seconds</li>
</ul>
</td>
<td style="width: 48.8374%; text-align: left; vertical-align: top;">
<p><strong>Physical Agility Test</strong></p>
<ul>
<li>Push Car 15 feet</li>
<li>Ren short distance then climb 6-foot wall or chain link fence</li>
<li>Crawl through window</li>
<li>Walk balance beam</li>
<li>Pull 165 lb. dummy 15 feet</li>
</ul>
<p>Each applicant will have 2 attempts to complete each obstacle. Test must be completed in 2 minutes</p>
</td>
</tr>
<tr>
<td style="width: 48.8374%; text-align: left; vertical-align: top;">
<p><strong>Benefits of Becoming a Deputy Sheriff</strong></p>
<ul>
<li>Competitive Salary</li>
<li>Educational Reimbursement for Approved Courses of Study</li>
<li>Advancement Opportunities</li>
<li>Retirement Investment Program</li>
<li>Health and Life Insurance</li>
<li>Paid Holidays</li>
<li>Paid Annual and Sick Leave</li>
<li>Take Home Vehicle</li>
<li>In-House Fitness Room</li>
<li>Training Opportunities</li>
</ul>
</td>
<td style="width: 48.8374%; text-align: left; vertical-align: top;">
<p><strong>Benefits of Becoming a Correction Deputy</strong></p>
<ul>
<li>Competitive Salary</li>
<li>Educational Reimbursement for Approved Courses of Study</li>
<li>Advancement Opportunities</li>
<li>Retirement Investment Program</li>
<li>Health and Life Insurance</li>
<li>Paid Holidays</li>
<li>Paid Annual and Sick Leave</li>
<li>In-House Fitness Room</li>
<li>Training Opportunities</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<div data-visibility="all">
<p><img src="https://cdn.myocv.com/ocvapps/a7736801/files/fitnessheader.jpg" alt="" width="1920" height="650" /></p>
<p>&nbsp;</p>
<hr />
<p>&nbsp;</p>
<p>&nbsp;</p>
</div>
<p>&nbsp;</p>
<h2 style="text-align: left;"><span style="font-size: 18pt; color: #e1b047;"><strong>Frequently Asked Questions</strong></span></h2>
<ul>
<li><strong>How do I find current job openings for the Sheriff&rsquo;s Office?</strong></li>
</ul>
<p style="padding-left: 80px;">You may find a listing of current job openings on the <u>Employment Opportunity</u> Section.</p>
<ul>
<li><strong>Do you accept resumes?</strong></li>
</ul>
<p style="padding-left: 80px;">We do accept resumes but they must be submitted alongside the required employment application.</p>
<ul>
<li><strong>Will I be notified if the position I applied for has been filled?</strong></li>
</ul>
<p style="padding-left: 80px;">Applicants not selected for a position will be notified via email or letter that another candidate was selected.</p>
<ul>
<li><strong>I have submitted my application. Now what?</strong></li>
</ul>
<p style="padding-left: 80px;">Your application will be reviewed and Human Resources will notify you if you are selected to interview.</p>
<ul>
<li><strong>What if I am interested in a job that is not currently posted?</strong></li>
</ul>
<p style="padding-left: 80px;">Applications are <em><u>only </u></em>accepted for positions that are currently available. You can periodically check the website to find out what positions are currently available.</p>
<ul>
<li><strong>What benefits are offered to Sheriff&rsquo;s Office employees?</strong></li>
</ul>
<p style="padding-left: 80px;">You can find a listing of benefits available in the benefits section.</p>
<ul>
<li><strong>What are the qualifications for a Deputy Sheriff?</strong></li>
</ul>
<p style="padding-left: 80px;">Minimum age 21; must have a high school diploma or GED; must have a valid driver&rsquo;s license; must meet the <a href="https://www.apostc.alabama.gov/wp-content/uploads/2021/06/Chapter-2-June-2021.pdf" target="_blank" rel="noopener">physical requirements of APOST</a>.</p>
<p style="padding-left: 80px;">All applicants must pass an oral interview, computer voice stress test, drug screening, psychological exam and background investigation as conditions of employment. Must be willing to work 12 hour rotating shifts, nights, weekends, and holidays; must be willing to work overtime and non-standard hours. Applicants who are not APOST certified or have an associate&rsquo;s degree or higher, must pass the Basic Abilities Test (BAT). As of October 1, 2017, all Deputy Sheriff candidates must possess a valid High School or GED and must pass the Basic Abilities Test (BAT) before hire. The BAT test can be scheduled at a participating Alabama Community College.&nbsp; The candidate is responsible for scheduling the test, as well as, the $45 testing fee.&nbsp;</p>
<ul>
<li><strong>What are the qualifications for a Correction Deputy?</strong></li>
</ul>
<p style="padding-left: 80px;">Minimum age of 19; must have a high school diploma or GED, must have a valid driver&rsquo;s license; all applicants must pass an oral interview, must meet the physical requirements and drug screen as conditions of employment; must be willing to work 12 hour rotating shifts, nights, weekends, and holidays; must be willing to work overtime and non-standard hours.</p>
<ul>
<li><strong>Where can I find more information on APOST requirements?</strong></li>
</ul>
<p style="padding-left: 80px;">Please visit the <a href="https://www.apostc.alabama.gov/apostc-rule-book/" target="_blank" rel="noopener">Alabama Peace Officer Standards and Training website and rule book.</a></p>
<ul>
<li><strong>I&rsquo;m already certified as a law enforcement officer in another state; what are the lateral entry requirements for employment with your agency?</strong></li>
</ul>
<p style="padding-left: 80px;">Please see <a href="https://www.apostc.alabama.gov/wp-content/uploads/2020/08/Chapter-4.pdf" target="_blank" rel="noopener">RULE 650-X-4-.03 of the APOSTC Administrative Code</a>.</p>
<ul>
<li><strong>What documentation do you require verifying law enforcement experience for a deputy position?</strong></li>
</ul>
<p style="padding-left: 80px;">To verify law enforcement experience, you should provide your POST Certification, along with your training certificates. Make sure you list all agencies that you previously worked for on your application.</p>
<ul>
<li><strong>Do you offer Reserve Deputy positions?</strong></li>
</ul>
<p style="padding-left: 80px;"><strong>We are currently accepting applications for reserve deputy.</strong> We encourage anyone interested in volunteering to apply. The physical requirements are the same for reserve deputies as they are for patrol deputies, and many of our current employees started off as reserve deputies before deciding to become full-time deputies. For more information, contact Lieutenant McLeroy at lmcleroy@leecountysheriff.org or (334) 737-7081.</p>
<ul>
<li><strong>Can I request a tour of the jail?</strong></li>
</ul>
<p style="padding-left: 80px;">Jail tours are not offered to the public. Applicants who are selected for testing and potential employment as a Correction Deputy are given a jail tour before taking the fitness test and will receive prior notification of the date and time of the tour.</p>
<div data-visibility="all">
<p style="text-align: center; line-height: 1.4;">&nbsp;</p>
<p style="text-align: center; line-height: 1.4;">&nbsp;</p>
</div>
</div>
</div>
</section>
import { jsPDF } from "jspdf";
import "jspdf/dist/polyfills.es.js";
import { regex } from "./constant";

const htmlPdfConverter = (basicDetails, inputs) => {
  
  const pdfHeading = `
  <div class="h-full w-full text-dream_vacation block justify-center items-end">
  <div class="w-full flex justify-end h-full">
    <img
     src=${window.location.origin + "/indiafirst-color.png"}
      alt=""
      class="h-[110px] w-[130px]"
    />
  </div>
  <div class="w-full mb-4 mt-2 h-20 font-semibold text-[38px] text-center">
    Future Wealth Creation Report
  </div>
</div>
  `;

  const date = new Date();
  const doc = new jsPDF();
  doc.setFontSize(12);
  doc.setProperties({
    title: "Future Wealth Creation Report",
    subject: "Future Wealth Creation Report",
    author: "India first life",
    keywords: "generated, javascript, web 2.0, ajax",
    creator: "India first life"
  });

  doc.html(pdfHeading, {
    useCORS: true,
    pageSplit: true,
    callback: function (pdf) {
      pdf.save(
        `Wealth Creation Calculator Report_${
          date.getDate() +
          "-" +
          (date.getMonth() + 1) +
          "-" +
          date.getFullYear() 
        }.pdf`
      );
    },
    margin: [10, 10, 10, 10],
    autoPaging: "text",
    x: 0,
    y: 0,
    width: 195,
    windowWidth: 900
  });
  return true;
};

export default htmlPdfConverter;
For react build deployment - put buli in (/var/www/html) folder
PORT 80 - is for http ip access link (comment it out in httpd.conf file)
PORT 443 is for HTTPS ip access link 

For redirection reload "404 error" issues-

1) Change httpd.conf file in (/etc/httpd/conf)and in .htaccess build folder (/var/www/html). 

2) Note: This two files should contain the same below code i.e.-> 

RewriteEngine On
RewriteBase / 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule ^ index.html [QSA,L]

3) Note:  in document root "/var/www/html" change AllowOverride to All.

After this re-run the Apache server command - apachectl restart
  const handleFileDrop = (acceptedFiles: any) => {
    console.log('Accepted Files:', acceptedFiles);
    checkFileValidity(acceptedFiles, documentTypeID);

    // Accept same file again
    if (dropzoneInputRef.current) {
      dropzoneInputRef.current.value = '';
    }
  };
copy build to var/www/html

/usr/share/httpd/noindex  .... 


local -> fpts to srv.arcosunix (buil import)

cd in build folder (cmd prmpt) -> command -[    cp -rv * /var/www/html/     ]  (this will override/copy new build)
 

*-------------------------------------*

if on restart if apache didn't restart then 

delete  indiafirstlife-ssl.conf     (path -  /etc/httpd/conf.d)

then apache will work 


commentd on line 87 on  vi /etc/httpd/conf.d/ssl.conf
import { ChevronRightIcon } from "@chakra-ui/icons";
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbSeparator,
} from "@chakra-ui/react";
import { useNavigate, useLocation } from "react-router-dom";

export default function BreadcrumbNavigation({
  title,
}: Record<string, any>): JSX.Element {
  const navigate = useNavigate();
  const { pathname } = useLocation();
  const pathnames = pathname.split("/").filter(Boolean);
  const blogName = pathnames[1]?.replace(/%20/g, " ");
  // check the pathName for numbers, upper and lower case.
  //return new path name with spaces, no numbers, and first letter capital
  // function UpdatePathName(input: string) {
  //   console.log(input);
  //   const result = input.match(/[A-Z]?[a-z]+|\d+|[A-Z]+(?![a-z])/g);
  //   // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  //   // @ts-ignore: Object is possibly 'null'
  //   const newPathName = result.slice(0, 1).join(" ");

  //   return newPathName.charAt(0).toUpperCase() + newPathName.slice(1);
  // }

  return (
    <Breadcrumb
      spacing="8px"
      separator={<ChevronRightIcon color="gray.500" />}
    >
      {/* home button */}
      <BreadcrumbItem key={"home"}>
        <BreadcrumbLink href="/">Home</BreadcrumbLink>
      </BreadcrumbItem>
      if(pathnames.length === 1)
      {
        <BreadcrumbItem
          key={title}
          id={title}
          isCurrentPage
        >
          <BreadcrumbLink href="#">{title}</BreadcrumbLink>
        </BreadcrumbItem>
      }
      else
      {
        <BreadcrumbItem
          key={pathnames[1]}
          id={pathnames[1]}
          isCurrentPage
        >
          <BreadcrumbSeparator />
          <BreadcrumbLink onClick={() => navigate(pathnames[1])}>
            {blogName}
          </BreadcrumbLink>
        </BreadcrumbItem>
      }
    </Breadcrumb>
  );
}
import { ChevronRightIcon } from "@chakra-ui/icons";
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink } from "@chakra-ui/react";
import { useNavigate, useLocation } from "react-router-dom";

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export default function BreadcrumbNavigation({ title }: any): JSX.Element {
  const navigate = useNavigate();
  const { pathname } = useLocation();
  const pathnames = pathname.split("/").filter(Boolean);

  // check the pathName for numbers, upper and lower case.
  //return new path name with spaces, no numbers, and first letter capital
  // function UpdatePathName(input: string) {
  //   console.log(input);
  //   const result = input.match(/[A-Z]?[a-z]+|\d+|[A-Z]+(?![a-z])/g);
  //   // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  //   // @ts-ignore: Object is possibly 'null'
  //   const newPathName = result.slice(0, 1).join(" ");

  //   return newPathName.charAt(0).toUpperCase() + newPathName.slice(1);
  // }

  return (
    <Breadcrumb
      spacing="8px"
      separator={<ChevronRightIcon color="gray.500" />}
    >
      <BreadcrumbItem key={"home"}>
        <BreadcrumbLink href="/">Home</BreadcrumbLink>
      </BreadcrumbItem>
      {pathnames.map((name, index) => {
        const routeTo = `/${pathnames.slice(0, index + 1).join("/")}`;
        // const isLast = index === pathnames.length - 1;
        // const newPathName = UpdatePathName(name);
        return pathnames.length === 1 ? (
          <BreadcrumbItem
            key={title}
            id={title}
            isCurrentPage
          >
            <BreadcrumbLink href="#">{title}</BreadcrumbLink>
          </BreadcrumbItem>
        ) : (
          <BreadcrumbItem
            key={name}
            id={name}
            isCurrentPage
          >
            <BreadcrumbLink onClick={() => navigate(routeTo)}>
              {name.replace(/%20/g, " ")}
            </BreadcrumbLink>
          </BreadcrumbItem>
        );
      })}
    </Breadcrumb>
  );
}
export function calculateAge(dob) {
  const userDob = dob.split("/");
  const birthDate = new Date(userDob[2], userDob[1]-1, userDob[0]);

  const today = new Date();
  const yyyy = today.getFullYear();
  let mm = today.getMonth();
  let dd = today.getDate();
  if (dd < 10) dd = "0" + dd;
  if (mm < 10) mm = "0" + mm;
  const formattedTodayDate = new Date(yyyy, mm, dd);

  let year_difference =
    formattedTodayDate.getFullYear() - birthDate.getFullYear(); // 2001 - 2000 = 1
  let one_or_zero =
    formattedTodayDate.getMonth() < birthDate.getMonth() ||
    (formattedTodayDate.getMonth() === birthDate.getMonth() &&
      formattedTodayDate.getDate() < birthDate.getDate())
      ? 1
      : 0;
  let age = year_difference - one_or_zero;

  return age;
}
const whereIsMyCoffeeOrder = function(orderId) {
  return new Promise((resolve, reject) => {
    coffeeApi.checkStatus(orderId, (error, coffeeStatus) => {
      if (error) {
        // Promise fails
        reject(error)
      } else {
        // Promise is fulfilled
        resolve(coffeeStatus)
      }
    })
  })
}
useEffect(
  () => {
   axios.get(``)
    .then(res => {
     console.log(res)
   })
    .catch(err => console.log(err))
  }
)
const TikTok = () => {
  useEffect(() => {
    const anchor = document.createElement("a");
    anchor.setAttribute("class", "twitter-timeline");
    anchor.setAttribute("data-theme", "dark");
    anchor.setAttribute("data-tweet-limit", "5");
    anchor.setAttribute("data-chrome", "noheader nofooter noborders");
    anchor.setAttribute("href", "https://www.tiktok.com/@leecosheriffal");
    document.getElementsByClassName("twitter-embed")[0].appendChild(anchor);
    const script = document.createElement("script");
    script.setAttribute("src", "https://www.tiktok.com/embed.js");
    document.getElementsByClassName("twitter-embed")[0].appendChild(script);
  }, []);
  return (
    <section className="twitterContainer">
      <div className="twitter-embed"></div>
    </section>
  );
};
export default TikTok;
// vvv--- shown to aide explanation

// const Library = (props) => {
//  const books = [
//  "The Adventures of Herlock Sholmes",
//  "The Life and Lessons of Manny Mole",
//  "My Brother's Book"
//  ];

const response = (books.indexOf(props.request) > -1)
 ? <p>We have that book!</p>
 : <p>Sorry, we don't have that book.</p>

// vvv--- shown to aide explanation of props.request, don't include it

// ReactDOM.render(
// <Library // request={"The Adventures of Herlock Sholmes"} // />,
//  document.getElementById("root")
// );
<Autocomplete
  id="google-map-demo"
  defaultValue={userData.addressLine1 || ''}
  freeSolo // <-- Add this line
  clearOnEscape={false}
  clearIcon={null}
  // ...rest of your props
/>

onChange={(event: any, newValue: PlaceType | string | null) => {
  if (typeof newValue === 'string') {
    // The user entered a new address manually
    setAddress(newValue);
    console.log('Manual input:', newValue);
  } else if (newValue) {
    // The user selected an address from the dropdown
    setAddress(newValue.description);
    console.log('Selected Value:', newValue.description);
  }
}}

    
    
.catch(err => {
  console.log(err.response.status)
  if (err.response.status === 404) {
    alert(`No results matching ${query}`)
  }
  else {
    console.log(err)
  }
})
    // Check if primaryEmail and secondaryEmail are same
    if (primaryEmail === secondaryEmail && primaryEmail !== '' && secondaryEmail !== '') {
      errors.primaryEmail = 'Primary and Secondary email cannot be the same';
      errors.secondaryEmail = 'Primary and Secondary email cannot be the same';
    }

  // Check if primaryMobileNumber and secondaryMobileNumber are same
    if (primaryMobileNumber === secondaryMobileNumber && primaryMobileNumber !== '' && secondaryMobileNumber !== '') {
      errors.primaryMobileNumber = 'Primary and Secondary mobile number cannot be the same';
      errors.secondaryMobileNumber = 'Primary and Secondary mobile number cannot be the same';
    }

<div className="col-md-6">
              <label htmlFor="email" className="form-label w-100 email-label">
                Primary Email*
              </label>
              
// primary email

<input
                type="email"
                className={`form-control email-input ${formErrors.primaryEmail ? 'input-error' : ''}`}
                id="email"
                placeholder="abc@babc.com"
                defaultValue={userData.primaryEmail}
                onChange={(e) => setPrimaryEmail(e.target.value)}
                {...register('primaryEmail', {
                  required: true,
                })}
              />
              {
                primaryEmail === secondaryEmail
                && primaryEmail !== ''
                && secondaryEmail !== ''
                  && (
                  <div className="error-message">
                    {formErrors.primaryEmail}
                  </div>
                  )
              }
            </div>

 // secondary email

<input
                    type="email"
                    className={`form-control secondary-email-input ${formErrors.secondaryEmail ? 'input-error' : ''}`}
                    id="secondary-email"
                    placeholder="secondary@abc.com"
                    defaultValue={userData.secondaryEmail}
                    // onchange
                    onChange={(e) => setSecondaryEmail(e.target.value)}
                    // register
                    {...register('secondaryEmail', {
                      required: true,
                    })}
                  />
                  {formErrors.secondaryEmail && <div className="error-message mt-1">{formErrors.secondaryEmail}</div>}


// primary mobile number

<input
                  type="text"
                  className={`form-control mobile-input ${formErrors.primaryMobileNumber ? 'input-error' : ''}`}
                  id="mobile"
                  placeholder="XXXXXXXXXXXXXX"
                  defaultValue={userData.primaryMobileNumber}
                  onInput={(e) => {
                    const input = e.target as HTMLInputElement;
                    input.value = input.value.slice(0, 15).replace(/[^0-9 ]/g, ''); // Limit the input to 15 characters and Allow only digits and spaces
                    setPrimaryMobileNumber(input.value);
                  }}
                  {...register('primaryMobileNumber', {
                    required: true,
                  })}
                />


// secondary mobile number

                    <input
                      type="text"
                      className={`form-control secondary-mobile-input ${formErrors.secondaryMobileNumber ? 'input-error' : ''}`}
                      id="secondary-mobile"
                      placeholder="XXXXXXXXXXX"
                      defaultValue={userData.secondaryMobileNumber}
                      onInput={(e) => {
                        const input = e.target as HTMLInputElement;
                        const value = input.value.slice(0, 15).replace(/[^0-9 ]/g, ''); // Limit the input to 15 characters and Allow only digits and spaces
                        input.value = value;
                        setSecondaryMobileNumber(value);
                      }}
                      {...register('secondaryMobileNumber', {
                        required: true,
                      })}
                    />
                    {/* {
                      primaryMobileNumber === secondaryMobileNumber
                      && primaryMobileNumber !== ''
                      && secondaryMobileNumber !== ''
                        && (
                        <div className="error-message mt-1">
                          {formErrors.primaryMobileNumber}
                        </div>
                        )
                    } */}
                  </div>
                  {
                      formErrors.secondaryMobileNumber
                      && (
                      <div
                        className="error-message mt-1"
                      >
                        {formErrors.secondaryMobileNumber}
                      </div>
                      )
                    }


import {useState, createContext, useEffect} from 'react'

export const FavoritesContext = createContext();

export default function FavoritesContextProvider(props){
    //create the global state
    const [favorites, setFavorites] = useState([])

    //get inital state from localStorage when page loads
    useEffect(
        ()=>{
            console.log('context loaded', favorites)
            //is there a value in localStorage
            const storedFavs = localStorage.getItem('favoritesList')
            //check if something was there
            if (storedFavs){
                console.log('use localstorage')
                //console.log('datatype is ', typeof(storedDarkMode))
                //setDarkMode(storedDarkMode)
                //parse converts from string to its datatype
                setFavorites(JSON.parse(storedFavs))
            }
            //otherwise will use default state value

        }, []
    )

    //save to localStorage whenever it changes
    useEffect(
        ()=>{
            console.log('favorites updated', favorites)
            //save current state to localStorage when it changes
            //stringify converts to JSON string format
            localStorage.setItem('favoritesList', JSON.stringify(favorites))

        }, [favorites]
    )

    const addCharacter = (charToAdd) =>{
        console.log('adding', charToAdd)
        let newFavorites;
        newFavorites = [...favorites, charToAdd]
        setFavorites(newFavorites)
        // localStorage.setItem('favoritesList', JSON.stringify(newFavorites))
    }

    const removeCharacter = (charId) =>{
        console.log("remove", charId)
        let newFavorites;
        newFavorites = favorites.filter(item => item.id !== charId)
        setFavorites(newFavorites)
        // localStorage.setItem('favoritesList', JSON.stringify(newFavorites))
    }

    return(
        <FavoritesContext.Provider value={{ favorites, addCharacter, removeCharacter }} >
            {props.children}
        </FavoritesContext.Provider>
    )


}
import {useState, createContext, useEffect} from 'react'

export const ThemeContext = createContext();

export default function ThemeContextProvider(props){
    //create the global state
    const [darkMode, setDarkMode] = useState(false)

    //get inital state from localStorage when page loads
    useEffect(
        ()=>{
            //is there a value in localStorage
            const storedDarkMode = localStorage.getItem('darkMode')
            
            // if (storedDarkMode){
            //     //console.log('datatype is ', typeof(storedDarkMode))
            //     //setDarkMode(storedDarkMode)
            //     //parse converts from string to its datatype
            //     setDarkMode(JSON.parse(storedDarkMode))
            // }

            setDarkMode(storedDarkMode?JSON.parse(storedDarkMode):false)          
            //otherwise will use default state value

        }, []
    )

    //save to localStorage whenever it changes
    useEffect(
        ()=>{
            //save current state to localStorage when it changes
            //stringify converts to JSON string format
            localStorage.setItem('darkMode', JSON.stringify(darkMode))
            //localStorage.setItem('darkMode', darkMode)

        }, [darkMode]
    )

    return(
        <ThemeContext.Provider value={{ darkMode, setDarkMode }} >
            {props.children}
        </ThemeContext.Provider>
    )


}
  // Scroll to top of page on component mount
  React.useEffect(() => {
    window.scrollTo(0, 0);
  }, []);
/* eslint-disable no-restricted-syntax */
/* eslint-disable array-callback-return */
/* eslint-disable @typescript-eslint/no-shadow */
/* eslint-disable react/no-array-index-key */
/* eslint-disable @typescript-eslint/no-use-before-define */
/* eslint-disable no-plusplus */
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-alert */
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable jsx-a11y/control-has-associated-label */
/* eslint-disable react/button-has-type */
/* eslint-disable max-len */
import React, { useState, useEffect, useCallback } from 'react';
import { useDropzone } from 'react-dropzone';
import { AiOutlineClose } from 'react-icons/ai';
import FileUploadIcon from '@assets/FileUploadIcon.svg';
import FileListIcon from '@assets/FileListIcon.svg';
import FileUploadIconDark from '@assets/FileUploadIconDark.svg';
import TickMarkIconGreen from '@assets/TickMarkIconGreen.svg';
import TickMarkIconGrey from '@assets/TickMarkIconGrey.svg';
import FileArrowIcon from '@assets/FileArrowIcon.svg';

import './style.scss';
import Box from '@mui/material/Box/Box';
import Button from '@mui/material/Button/Button';
import { useForm } from 'react-hook-form';
import {
  fetchDocumentTypeList,
  fetchDocumentsList,
  deleteDocument,
  willDocumentUploadSelector,
  saveDocument,
} from '@redux/slices/will-documents-upload';
import { useSelector, useDispatch } from 'react-redux';
import { DocumentTypeList } from '@api/models';
import axios from 'axios';
import { willPersonalInformationSelector } from '@redux/slices/will-personal-information';
import { willsValidatorSelector } from '@redux/slices/willsValidator';
import MirrorWillSwitcher from '@components/MirrorWillSwitcher';
// import custom hook useDocumentsList
import useDocumentsList from '@utils/hooks/useDocumentsList';
import DeleteConfirmationModal from '@components/DeleteConfirmationModal';
import { useLocation } from 'react-router';
import DocumentManagerModal from '@components/DocumentManagerModal';
import { fetchAppointmentDetail } from '@redux/slices/wills-book-appointment';
import { Alert, AlertColor, Snackbar } from '@mui/material';
import MuiAlert from '@mui/material/Alert';

import { trackPromise } from 'react-promise-tracker';
import { getAppointmentDetail } from '../../redux/slices/wills-book-appointment';
import api from '../../api';

interface Props {
  handleNext: (step: number, stepName?: string) => void;
  currentBtnStep: number;
  handleBack: () => void;
  willTypeID: number;
}

function DocumentManager({
  handleNext, currentBtnStep, handleBack, willTypeID,
}: Props) {
  // const [documentTypeID, setDocumentTypeID] = useState<string>('');
  const [documentTypeArray, setDocumentTypeArray] = useState([]);
  const [documentTypeID, setDocumentTypeID] = useState();
  const [uniqueDocumentId, setUniqueDocumentId] = useState();
  const [witnessProfileGUID, setWitnessProfileGUID] = useState();
  const [willDocGuid, setWillDocGuid] = useState<string>('');
  // const bookedForProfileGUID = 'ba125f2d-8c78-41ce-b576-6aaef9b57c2a';
  const [uploadedFiles, setUploadedFiles] = useState([]);
  const [showModal, setShowModal] = useState(false);
  const { state } = useLocation();
  const [showBookAppointnentModal, setShowBookAppointnentModal] = useState(false);
  // State for managing snackbar
  const [snackbarOpen, setSnackbarOpen] = useState(false);
  const [snackbarSeverity, setSnackbarSeverity] = useState<AlertColor>('error'); // You can change 'error' to 'warning' or other values if needed

  // Snackbar message to display
  const snackbarMessage = 'Please upload all required documents before proceeding to the next step.';

  const [documentIsRequired, setDocumentIsRequired] = useState<boolean>(false);

  // check document is required or not and
  useEffect(() => {
    const isRequiredDocumentsExist = documentTypeArray.some((d) => d.isRequired);
    setDocumentIsRequired(isRequiredDocumentsExist);
  }, [documentTypeArray]);

  // profile guid
  const { isSpouseSelected, spouseGuid, profileGuid } = useSelector(willPersonalInformationSelector);

  const dispatch = useDispatch();

  const handleOpenModal = () => {
    setShowModal(true);
  };
  const handleCloseModal = () => {
    setShowModal(false);
  };

  const handleBookAppointmentModalOpen = () => {
    setShowBookAppointnentModal(true);
  };

  const handleBookAppointmentModalClose = () => {
    setShowBookAppointnentModal(false);
  };

  const handleBookAppointmentModalContinue = () => {
    setShowBookAppointnentModal(false);
    // handleNext(currentBtnStep, 'upload');
  };

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await trackPromise(api.getAppointmentDetail(profileGuid));
        console.log('fetch AppointmentDetail Result', response?.data?.Output);
        // log the timeSlotID
        console.log('timeSlotID:', response?.data?.Output?.timeSlotID);
        if (response?.data?.Output?.timeSlotID === 0) {
          console.log('No appointment details found! Opening modal');
          handleBookAppointmentModalOpen();
        } else {
          const appointmentDetails = response.data.Output;
          console.log('Appointment details:', appointmentDetails);
        }
      } catch (error) {
        console.error('Error fetching appointment detail:', error);
      }
    };
    fetchData();
  }, []);

  // API results from Redux
  const {
    bookedforprofileguid,
    docType,
    documentTypeList,
    documentsList,
    docTypeID,
    isDocumentsChanged,
  } = useSelector(willDocumentUploadSelector);
  const { mirrorWillCheck } = useSelector(willsValidatorSelector);
  // custom hook for document list
  const uploadedDocumentsList = useDocumentsList(documentsList);

  /**
   * Retrieves the list of document types and sets it to the document type array.
   *
   * @return {void} No return value.
   */
  const getDocumentTypeList = () => {
    const documentTypes: any = [];
    documentTypeList.forEach((d: DocumentTypeList) => {
      documentTypes.push({
        documentTypeID: d.docTypeID,
        documentTypeName: d.fileName,
        witnessProfileGUID: d.witnessProfileGUID,
        isRequired: d.isRequired,
      });
    });
    setDocumentTypeArray(documentTypes);
  };

  // API calls inside useEffects -------
  useEffect(() => {
    // dispatch<any>(fetchDocumentTypeList(bookedForProfileGUID));
    dispatch<any>(fetchDocumentTypeList(isSpouseSelected ? spouseGuid : profileGuid));
  }, [dispatch, isSpouseSelected]);

  useEffect(() => {
    // Dispatch the fetchDocumentsList action when documentTypeID changes
    dispatch<any>(fetchDocumentsList(isSpouseSelected ? spouseGuid : profileGuid, documentTypeID, witnessProfileGUID));
  }, [uniqueDocumentId, documentTypeID, isDocumentsChanged, isSpouseSelected]);

  // Result transformation for UI
  useEffect(() => {
    getDocumentTypeList();
  }, [documentTypeList]);

  const { handleSubmit } = useForm();
  /**
   * Sets the active element to the given element string.
   *
   * @param {string} element - The string representing the active element to set.
   */
  const handleElementClick = (docTypeId: any, witnessProfileGUID: any) => {
    const uniqueDocumentId: any = `${docTypeId}-${witnessProfileGUID}`;
    setUniqueDocumentId(uniqueDocumentId);
    setDocumentTypeID(docTypeId);
    setWitnessProfileGUID(witnessProfileGUID);
  };
  /**
   * Returns the background color style object for a given element.
   *
   * @param {string} element - The element to get background style for.
   * @return {Object} The background color style object for the given element.
   */
  const getBackgroundStyle = (element: any) => ({
    backgroundColor: uniqueDocumentId === element ? '#023979' : '#F4F4F4',
  });

  /**
   * Returns an object representing the style to be applied to the title element.
   *
   * @param {string} element - The element to apply the style to.
   * @return {Object} An object containing the color property to be applied to the title element.
   */
  const getTitleStyle = (element: any) => ({
    color: uniqueDocumentId === element ? '#FFFFFF' : '#1B202D',
  });

  const getFileUploadIcon = (element: any) => (uniqueDocumentId === element ? FileUploadIcon : FileUploadIconDark);

  const getTickMarkicon = (element: any) => (uniqueDocumentId === element ? TickMarkIconGreen : TickMarkIconGrey);

  /**
   * Handles click event on "Add File" button.
   *
   * @param {any} e - The event object.
   * @return {void} Nothing is returned by this function.
   */

  const handleAddFileClick = (e: any) => {
    e.preventDefault();
    if (e.target !== e.currentTarget) {
      return;
    }
    document.getElementById('file-upload-input')?.click();
  };

  /**
   * Handles the file input change event.
   *
   * @param {any} e - the event object
   * @return {void}
   */
  const handleFileInputChange = (e: any) => {
    const newFiles = Array.from(e.target.files);
    checkFileValidity(newFiles);
  };

  /**
   * Updates the document type array by setting the 'isRequired' property to false for the document type
   * with the specified 'documentTypeID'. Returns the updated document type array.
   *
   * @param {any} documentTypeID - The ID of the document type to update
   * @return {void}
   */
  const updateDocumentTypeArray = (documentTypeID: any): void => {
    const updatedDocumentTypeArray = documentTypeArray.map((doc) => (doc.documentTypeID === documentTypeID ? { ...doc, isRequired: false } : doc));
    setDocumentTypeArray(updatedDocumentTypeArray);
  };

  /**
   * Handles the file drop event by checking the validity of the accepted files.
   *
   * @param {any} acceptedFiles - the files that have been accepted for upload
   */
  const handleFileDrop = (acceptedFiles: any) => {
    checkFileValidity(acceptedFiles);
  };

  /**
   * Prevents the click event from propagating and executing other click events.
   *
   * @param {any} e - the click event to be stopped from propagating
   */
  const handleRowItemClick = (e: any) => {
    e.stopPropagation();
  };

  /**
   * Filters files by their extension and size, and adds the valid files to the uploadedFiles state.
   *
   * @param {Array} files - The array of files to be checked.
   * @return {void} Returns nothing.
   */

  // Check the validity of uploaded files
  const checkFileValidity = async (files: any[]) => {
    const validExtensions = ['.pdf', '.jpeg', '.jpg', '.bmp', '.doc', '.docx'];
    const maxFileSize = 20 * 1024 * 1024;

    // Filter valid files based on extension and file size
    const validFiles = files.filter((file: { name: string; size: number; }) => {
      // Check if the file extension is valid
      const isValidExtension = validExtensions.some((ext) => file.name.toLowerCase().endsWith(ext));
      // Check if the file size is within the allowed limit
      const isWithinMaxSize = file.size <= maxFileSize;
      return isValidExtension && isWithinMaxSize;
    });

    // Filter invalid files
    const invalidFiles = files.filter(
      (file: any) => !validFiles.includes(file),
    );
    if (invalidFiles.length > 0) {
      // Display an alert message for invalid files
      const invalidFileNames = invalidFiles
        .map((file: { name: any; }) => file.name)
        .join(', ');
      alert(
        `Invalid files: ${invalidFileNames}. Please use A4-size PDF, JPEG, BMP, DOC, or DOCX files that are within 20MB.`,
      );
    } else {
      // Add valid files to the uploaded files list
      const updatedUploadedFiles = [...uploadedFiles, ...validFiles];
      setUploadedFiles(updatedUploadedFiles);

      // Update the document type array with the document type ID.
      updateDocumentTypeArray(documentTypeID);

      const formData = new FormData();
      for (let i = 0; i < validFiles.length; i++) {
        const file = validFiles[i];
        formData.append('FileDoc', file, file.name);
      }

      dispatch<any>(
        saveDocument(
          isSpouseSelected ? spouseGuid : profileGuid,
          documentTypeID,
          witnessProfileGUID,
          formData,
        ),
      );
    }
  };

  const handleNextStepClick = () => {
    if (!documentIsRequired) {
      // Handle Next Step click logic here
      handleNext(state === 'Guardianship Will' ? 6 : currentBtnStep, 'upload');
    } else {
      // Show the snackbar with an error message
      setSnackbarSeverity('error'); // You can change 'error' to 'warning' or other values if needed
      setSnackbarOpen(true);
    }
  };

  /**
   * Removes a file from the system.
   *
   * @param {string} willDocGuid - the unique identifier of the file to be removed
   * @return {any} the result of the delete operation
   */
  const removeFile = (willDocGuid: string) => {
    setWillDocGuid(willDocGuid);
    handleOpenModal();
  };

  const deleteFile = () => {
    console.log(`Delete the doc with GUID: ${willDocGuid}`);
    dispatch<any>(deleteDocument(willDocGuid));
    // log the result of the delete operation
    console.log('File removed successfully!');
    setShowModal(false);
  };

  const handleUploadDocument = (data: any) => {
    console.log(data);
    // handle document upload
    handleNext(currentBtnStep, 'upload');
  };

  const {
    getRootProps, // Props for the file drop zone element
    getInputProps, // Props for the file input element
  } = useDropzone({
    onDrop: handleFileDrop, // Callback function for handling dropped or selected files
  });

  return (
    <main>
      <section>
        {mirrorWillCheck && <MirrorWillSwitcher />}
        <header className="header mt-4">Upload Documents</header>
        <p className="description">
          Upload the documents in PDF or JPEG format. Click on Next Step to save
          the files once all the documents have been uploaded
        </p>
      </section>
      <div className="row document-upload-container">
        <div className="col-lg-6 content-wrapper">
          {documentTypeArray?.map((type) => (
            <div
              className={`top${
                uniqueDocumentId === `${type?.documentTypeID}-${type?.witnessProfileGUID}` ? ' active' : ''
              }`}
              style={getBackgroundStyle(`${type?.documentTypeID}-${type?.witnessProfileGUID}`)}
              onClick={() => handleElementClick(type?.documentTypeID, type?.witnessProfileGUID)}
            >
              <div className="left-container">
                <div className="file-upload-icon">
                  <img
                    src={getFileUploadIcon(`${type?.documentTypeID}-${type?.witnessProfileGUID}`)}
                    alt="File Uploader Icon"
                  />
                </div>
                <div
                  className="document-title"
                  style={getTitleStyle(`${type?.documentTypeID}-${type?.witnessProfileGUID}`)}
                >
                  {type.documentTypeName}
                </div>
              </div>
              <div className="tick-icon">
                <img
                  src={getTickMarkicon(`${type?.documentTypeID}-${type?.witnessProfileGUID}`)}
                  alt="Tick Mark"
                />
              </div>
            </div>
          ))}
        </div>

        <div
          className="col-lg-6 row-item"
          {...getRootProps()}
          onClick={handleRowItemClick}
        >
          <div className="file-upload-arrow">
            <img src={FileArrowIcon} alt="File Upload Arrow Icon" />
          </div>
          <div className="file-upload-text">
            Drag and drop document here to upload
          </div>
          <div className="file-attach-instructions">
            Please attach the file(s) below (use the Add button). We recommend
            using A4-size PDF, BMP, PNG, DOC, DOCX, JPG and JPEG files. File
            size cannot be more than 20 megabytes (MB). Your files will be
            uploaded when you submit your form.
          </div>
          <div className="file-add-button">
            <button className="add-file-btn" onClick={handleAddFileClick}>
              Add File
            </button>
            <input
              type="file"
              id="file-upload-input"
              name="file-upload-input"
              accept=".pdf, .bmp, .png, .doc, .docx, .jpg, .jpeg"
              multiple
              onChange={handleFileInputChange}
              style={{ display: 'none' }}
              {...getInputProps()}
            />
          </div>
          {uploadedDocumentsList.length > 0
            && uploadedDocumentsList.map((file: any, index) => (
              <div className="file-list-item" key={index}>
                <div className="file-info">
                  <div className="file-icon">
                    <img src={FileListIcon} alt="File List Icon" />
                  </div>
                  <div className="file-name">{file.fileName}</div>
                </div>
                <div className="close-icon" onClick={() => removeFile(file.willDocGuid)}>
                  <span className="close-icon-text">Remove</span>
                </div>
              </div>
            ))}
        </div>
      </div>
      {/* log documentIsRequired on template */}
      {/* {documentIsRequired && <div>Document is required</div>} */}
      <Box sx={{ display: 'flex', flexDirection: 'row', pt: 2 }}>
        <button
          type="button"
          className="next-btn"
          onClick={handleNextStepClick}
        >
          Next Step
        </button>
      </Box>
      {/* Snackbar */}
      <Snackbar open={snackbarOpen} autoHideDuration={3000} onClose={() => setSnackbarOpen(false)}>
        <MuiAlert
          elevation={6}
          variant="filled"
          severity={snackbarSeverity}
          onClose={() => setSnackbarOpen(false)}
        >
          {snackbarMessage}
        </MuiAlert>
      </Snackbar>
      <span className="next-btn-text mt-4">
        *Before clicking next, please make sure the details provided here are
        correct.
      </span>
      <DeleteConfirmationModal
        show={showModal}
        handleClose={handleCloseModal}
        handleContinue={deleteFile}
        type="Document"
      />
      {
          (willTypeID === 1 || willTypeID === 2) && (
            <DocumentManagerModal
              showBookAppointnentModal={showBookAppointnentModal}
              handleBookAppointmentModalClose={handleBookAppointmentModalClose}
              handleBookAppointmentModalContinue={handleBookAppointmentModalContinue}
              handleNext={handleNext}
              currentBtnStep={currentBtnStep}
              handleBack={handleBack}
            />
          )
        }

    </main>
  );
}

export default DocumentManager;
import Snackbar from '@mui/material/Snackbar';
import MuiAlert, { AlertProps as MuiAlertProps } from '@mui/material/Alert';


// snackbar states
  const [snackbarSeverity, setSnackbarSeverity] = React.useState('success');
  const [snackbarOpen, setSnackbarOpen] = React.useState(false);
  const [snackbarMessage, setSnackbarMessage] = React.useState('');



  const handleSnackbarClose = () => {
    // Handle the closing here
    setSnackbarOpen(false);
  };


 	try {
        const response = await trackPromise(api.saveUserRegistrationInformation(formData));
        // console.log('user reg response:', response?.data?.itemGUID);
        if (response?.data?.Output?.isAlreadyExists) {
          setSnackbarMessage('User already exists');
          setSnackbarSeverity('error');
          setSnackbarOpen(true);
        } else {
          dispatch(setUserInfo(response?.data?.Output?.itemGUID));
          setSnackbarMessage('User registered successfully');
          setSnackbarSeverity('success');
          setSnackbarOpen(true);
          setShowModal(true);
        }
      } catch (error) {
        setSnackbarMessage('An error occurred while submitting user registration');
        setSnackbarSeverity('error');
        setSnackbarOpen(true);
      }

// place snackbar at end of root jsx element. for example if parent jsx element is <main>,
 // place snackbar at the end of <main> element.
 
	  <Snackbar
        open={snackbarOpen}
        autoHideDuration={2000}
        onClose={handleSnackbarClose}
        anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
      >
        <MuiAlert
          onClose={handleSnackbarClose}
          variant="filled"
          elevation={6}
          severity={snackbarSeverity as MuiAlertProps['severity']}
          sx={{ width: '100%' }}
        >
          {snackbarMessage}
        </MuiAlert>
      </Snackbar>
You can even jumpstart your project with the thousands of components shared by the React open source community like Chakra UI (https://chakra-ui.com/) and Material UI (https://material-ui.com/).
yes it is working, our client needs further upadates here.

when user uploads all the required files and then moves to other component and return back to DocumentManager component. isRequired property is true in which userhas to upload the requried files again. 

i want to keep documentTypeArray in redux or any state management technique. so when user returns back it should be available. or you can try any other methods. 

ie once reuiqred docs are updated and when we move to documentmanager component, next step button should be disabled. 

below attaching code for your reference:

"""
function DocumentManager({
  handleNext, currentBtnStep, handleBack, willTypeID,
}: Props) {
  // const [documentTypeID, setDocumentTypeID] = useState<string>('');
  const [documentTypeArray, setDocumentTypeArray] = useState([]);
  const [documentTypeID, setDocumentTypeID] = useState();
  const [uniqueDocumentId, setUniqueDocumentId] = useState();
  const [witnessProfileGUID, setWitnessProfileGUID] = useState();
  const [willDocGuid, setWillDocGuid] = useState<string>('');
  // const bookedForProfileGUID = 'ba125f2d-8c78-41ce-b576-6aaef9b57c2a';
  const [uploadedFiles, setUploadedFiles] = useState([]);
  const [showModal, setShowModal] = useState(false);
  const { state } = useLocation();
  const [showBookAppointnentModal, setShowBookAppointnentModal] = useState(false);

  const [documentIsRequired, setDocumentIsRequired] = useState<boolean>(false);

  // check document is required or not and
  useEffect(() => {
    const isRequiredDocumentsExist = documentTypeArray.some((d) => d.isRequired);
    setDocumentIsRequired(isRequiredDocumentsExist);
  }, [documentTypeArray]);

  // profile guid
  const { isSpouseSelected, spouseGuid, profileGuid } = useSelector(willPersonalInformationSelector);

  const dispatch = useDispatch();

  const handleOpenModal = () => {
    setShowModal(true);
  };
  const handleCloseModal = () => {
    setShowModal(false);
  };

  const handleBookAppointmentModalOpen = () => {
    setShowBookAppointnentModal(true);
  };

  const handleBookAppointmentModalClose = () => {
    setShowBookAppointnentModal(false);
  };

  const handleBookAppointmentModalContinue = () => {
    setShowBookAppointnentModal(false);
    // handleNext(currentBtnStep, 'upload');
  };

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await trackPromise(api.getAppointmentDetail(profileGuid));
        console.log('fetch AppointmentDetail Result', response?.data?.Output);
        // log the timeSlotID
        console.log('timeSlotID:', response?.data?.Output?.timeSlotID);
        if (response?.data?.Output?.timeSlotID === 0) {
          console.log('No appointment details found! Opening modal');
          handleBookAppointmentModalOpen();
        } else {
          const appointmentDetails = response.data.Output;
          console.log('Appointment details:', appointmentDetails);
        }
      } catch (error) {
        console.error('Error fetching appointment detail:', error);
      }
    };
    fetchData();
  }, []);

  // API results from Redux
  const {
    bookedforprofileguid,
    docType,
    documentTypeList,
    documentsList,
    docTypeID,
    isDocumentsChanged,
  } = useSelector(willDocumentUploadSelector);
  const { mirrorWillCheck } = useSelector(willsValidatorSelector);
  // custom hook for document list
  const uploadedDocumentsList = useDocumentsList(documentsList);

  /**
   * Retrieves the list of document types and sets it to the document type array.
   *
   * @return {void} No return value.
   */
  const getDocumentTypeList = () => {
    const documentTypes: any = [];
    documentTypeList.forEach((d: DocumentTypeList) => {
      documentTypes.push({
        documentTypeID: d.docTypeID,
        documentTypeName: d.fileName,
        witnessProfileGUID: d.witnessProfileGUID,
        isRequired: d.isRequired,
      });
    });
    setDocumentTypeArray(documentTypes);
  };

  // API calls inside useEffects -------
  useEffect(() => {
    // dispatch<any>(fetchDocumentTypeList(bookedForProfileGUID));
    dispatch<any>(fetchDocumentTypeList(isSpouseSelected ? spouseGuid : profileGuid));
  }, [dispatch, isSpouseSelected]);

  useEffect(() => {
    // Dispatch the fetchDocumentsList action when documentTypeID changes
    dispatch<any>(fetchDocumentsList(isSpouseSelected ? spouseGuid : profileGuid, documentTypeID, witnessProfileGUID));
  }, [uniqueDocumentId, documentTypeID, isDocumentsChanged, isSpouseSelected]);

  // Result transformation for UI
  useEffect(() => {
    getDocumentTypeList();
  }, [documentTypeList]);

  const { handleSubmit } = useForm();
  /**
   * Sets the active element to the given element string.
   *
   * @param {string} element - The string representing the active element to set.
   */
  const handleElementClick = (docTypeId: any, witnessProfileGUID: any) => {
    const uniqueDocumentId: any = `${docTypeId}-${witnessProfileGUID}`;
    setUniqueDocumentId(uniqueDocumentId);
    setDocumentTypeID(docTypeId);
    setWitnessProfileGUID(witnessProfileGUID);
  };
  /**
   * Returns the background color style object for a given element.
   *
   * @param {string} element - The element to get background style for.
   * @return {Object} The background color style object for the given element.
   */
  const getBackgroundStyle = (element: any) => ({
    backgroundColor: uniqueDocumentId === element ? '#023979' : '#F4F4F4',
  });

  /**
   * Returns an object representing the style to be applied to the title element.
   *
   * @param {string} element - The element to apply the style to.
   * @return {Object} An object containing the color property to be applied to the title element.
   */
  const getTitleStyle = (element: any) => ({
    color: uniqueDocumentId === element ? '#FFFFFF' : '#1B202D',
  });

  const getFileUploadIcon = (element: any) => (uniqueDocumentId === element ? FileUploadIcon : FileUploadIconDark);

  const getTickMarkicon = (element: any) => (uniqueDocumentId === element ? TickMarkIconGreen : TickMarkIconGrey);

  /**
   * Handles click event on "Add File" button.
   *
   * @param {any} e - The event object.
   * @return {void} Nothing is returned by this function.
   */

  const handleAddFileClick = (e: any) => {
    e.preventDefault();
    if (e.target !== e.currentTarget) {
      return;
    }
    document.getElementById('file-upload-input')?.click();
  };

  /**
   * Handles the file input change event.
   *
   * @param {any} e - the event object
   * @return {void}
   */
  const handleFileInputChange = (e: any) => {
    const newFiles = Array.from(e.target.files);
    checkFileValidity(newFiles);
  };

  /**
   * Updates the document type array by setting the 'isRequired' property to false for the document type
   * with the specified 'documentTypeID'. Returns the updated document type array.
   *
   * @param {any} documentTypeID - The ID of the document type to update
   * @return {void}
   */
  const updateDocumentTypeArray = (documentTypeID: any): void => {
    const updatedDocumentTypeArray = documentTypeArray.map((doc) => (doc.documentTypeID === documentTypeID ? { ...doc, isRequired: false } : doc));
    setDocumentTypeArray(updatedDocumentTypeArray);
  };

  /**
   * Handles the file drop event by checking the validity of the accepted files.
   *
   * @param {any} acceptedFiles - the files that have been accepted for upload
   */
  const handleFileDrop = (acceptedFiles: any) => {
    checkFileValidity(acceptedFiles);
  };

  /**
   * Prevents the click event from propagating and executing other click events.
   *
   * @param {any} e - the click event to be stopped from propagating
   */
  const handleRowItemClick = (e: any) => {
    e.stopPropagation();
  };

  /**
   * Filters files by their extension and size, and adds the valid files to the uploadedFiles state.
   *
   * @param {Array} files - The array of files to be checked.
   * @return {void} Returns nothing.
   */

  // Check the validity of uploaded files
  const checkFileValidity = async (files: any[]) => {
    const validExtensions = ['.pdf', '.jpeg', '.jpg', '.bmp', '.doc', '.docx'];
    const maxFileSize = 20 * 1024 * 1024;

    // Filter valid files based on extension and file size
    const validFiles = files.filter((file: { name: string; size: number; }) => {
      // Check if the file extension is valid
      const isValidExtension = validExtensions.some((ext) => file.name.toLowerCase().endsWith(ext));
      // Check if the file size is within the allowed limit
      const isWithinMaxSize = file.size <= maxFileSize;
      return isValidExtension && isWithinMaxSize;
    });

    // Filter invalid files
    const invalidFiles = files.filter(
      (file: any) => !validFiles.includes(file),
    );
    if (invalidFiles.length > 0) {
      // Display an alert message for invalid files
      const invalidFileNames = invalidFiles
        .map((file: { name: any; }) => file.name)
        .join(', ');
      alert(
        `Invalid files: ${invalidFileNames}. Please use A4-size PDF, JPEG, BMP, DOC, or DOCX files that are within 20MB.`,
      );
    } else {
      // Add valid files to the uploaded files list
      const updatedUploadedFiles = [...uploadedFiles, ...validFiles];
      setUploadedFiles(updatedUploadedFiles);

      // Update the document type array with the document type ID.
      updateDocumentTypeArray(documentTypeID);

      const formData = new FormData();
      for (let i = 0; i < validFiles.length; i++) {
        const file = validFiles[i];
        formData.append('FileDoc', file, file.name);
      }

      dispatch<any>(
        saveDocument(
          isSpouseSelected ? spouseGuid : profileGuid,
          documentTypeID,
          witnessProfileGUID,
          formData,
        ),
      );
    }
  };

  /**
   * Removes a file from the system.
   *
   * @param {string} willDocGuid - the unique identifier of the file to be removed
   * @return {any} the result of the delete operation
   */
  const removeFile = (willDocGuid: string) => {
    setWillDocGuid(willDocGuid);
    handleOpenModal();
  };

  const deleteFile = () => {
    console.log(`Delete the doc with GUID: ${willDocGuid}`);
    dispatch<any>(deleteDocument(willDocGuid));
    // log the result of the delete operation
    console.log('File removed successfully!');
    setShowModal(false);
  };

  const handleUploadDocument = (data: any) => {
    console.log(data);
    // handle document upload
    handleNext(currentBtnStep, 'upload');
  };

  const {
    getRootProps, // Props for the file drop zone element
    getInputProps, // Props for the file input element
  } = useDropzone({
    onDrop: handleFileDrop, // Callback function for handling dropped or selected files
  });

  return (
    <main>
      <section>
        {mirrorWillCheck && <MirrorWillSwitcher />}
        <header className="header mt-4">Upload Documents</header>
        <p className="description">
          Upload the documents in PDF or JPEG format. Click on Next Step to save
          the files once all the documents have been uploaded
        </p>
      </section>
      <div className="row document-upload-container">
        <div className="col-lg-6 content-wrapper">
          {documentTypeArray?.map((type) => (
            <div
              className={`top${
                uniqueDocumentId === `${type?.documentTypeID}-${type?.witnessProfileGUID}` ? ' active' : ''
              }`}
              style={getBackgroundStyle(`${type?.documentTypeID}-${type?.witnessProfileGUID}`)}
              onClick={() => handleElementClick(type?.documentTypeID, type?.witnessProfileGUID)}
            >
              <div className="left-container">
                <div className="file-upload-icon">
                  <img
                    src={getFileUploadIcon(`${type?.documentTypeID}-${type?.witnessProfileGUID}`)}
                    alt="File Uploader Icon"
                  />
                </div>
                <div
                  className="document-title"
                  style={getTitleStyle(`${type?.documentTypeID}-${type?.witnessProfileGUID}`)}
                >
                  {type.documentTypeName}
                </div>
              </div>
              <div className="tick-icon">
                <img
                  src={getTickMarkicon(`${type?.documentTypeID}-${type?.witnessProfileGUID}`)}
                  alt="Tick Mark"
                />
              </div>
            </div>
          ))}
        </div>

        <div
          className="col-lg-6 row-item"
          {...getRootProps()}
          onClick={handleRowItemClick}
        >
          <div className="file-upload-arrow">
            <img src={FileArrowIcon} alt="File Upload Arrow Icon" />
          </div>
          <div className="file-upload-text">
            Drag and drop document here to upload
          </div>
          <div className="file-attach-instructions">
            Please attach the file(s) below (use the Add button). We recommend
            using A4-size PDF, BMP, PNG, DOC, DOCX, JPG and JPEG files. File
            size cannot be more than 20 megabytes (MB). Your files will be
            uploaded when you submit your form.
          </div>
          <div className="file-add-button">
            <button className="add-file-btn" onClick={handleAddFileClick}>
              Add File
            </button>
            <input
              type="file"
              id="file-upload-input"
              name="file-upload-input"
              accept=".pdf, .bmp, .png, .doc, .docx, .jpg, .jpeg"
              multiple
              onChange={handleFileInputChange}
              style={{ display: 'none' }}
              {...getInputProps()}
            />
          </div>
          {uploadedDocumentsList.length > 0
            && uploadedDocumentsList.map((file: any, index) => (
              <div className="file-list-item" key={index}>
                <div className="file-info">
                  <div className="file-icon">
                    <img src={FileListIcon} alt="File List Icon" />
                  </div>
                  <div className="file-name">{file.fileName}</div>
                </div>
                <div className="close-icon" onClick={() => removeFile(file.willDocGuid)}>
                  <span className="close-icon-text">Remove</span>
                </div>
              </div>
            ))}
        </div>
      </div>
      {/* log documentIsRequired on template */}
      {/* {documentIsRequired && <div>Document is required</div>} */}
      <Box sx={{ display: 'flex', flexDirection: 'row', pt: 2 }}>
        <button
          type="button"
          className="next-btn"
          onClick={() => handleNext(state === 'Guardianship Will' ? 6 : currentBtnStep, 'upload')}
          disabled={documentIsRequired}
        >
          Next Step
        </button>
      </Box>
      <span className="next-btn-text mt-4">
        *Before clicking next, please make sure the details provided here are
        correct.
      </span>
      <DeleteConfirmationModal
        show={showModal}
        handleClose={handleCloseModal}
        handleContinue={deleteFile}
        type="Document"
      />
      {
          (willTypeID === 1 || willTypeID === 2) && (
            <DocumentManagerModal
              showBookAppointnentModal={showBookAppointnentModal}
              handleBookAppointmentModalClose={handleBookAppointmentModalClose}
              handleBookAppointmentModalContinue={handleBookAppointmentModalContinue}
              handleNext={handleNext}
              currentBtnStep={currentBtnStep}
              handleBack={handleBack}
            />
          )
        }

    </main>
  );
}

"""
<AccordionDetails>
                <div
                  className="row"
                  style={{
                    marginLeft: '0px', marginRight: '0px',
                  }}
                >
                  <div className="col" style={{ paddingRight: '0px', borderRight: '1px solid', paddingTop: '40px' }}>
                    <div className="row" style={{ paddingBottom: '24px' }}>
                      <div className="col" style={{ maxWidth: '52px', paddingTop: '10px' }}>
                        <img src={sharePercentage} alt="" width="42px" height="39px" />
                      </div>
                      <div className="col">
                        <Typography sx={{ fontWeight: '500', fontSize: '24px', lineHeight: '45px' }}>
                          {/* {calculateTotalShare()} */}
                          %
                        </Typography>
                        <Typography sx={{ fontWeight: '300', fontSize: '14px', lineHeight: '18px' }}>
                          Total Assigned to This Property
                        </Typography>
                      </div>
                    </div>
                    <div className="row">
                      <ul className="beneficiary-list">
                        {beneficiaryList1.length !== 0 && beneficiaryList1.map((b: any, i: number) => (
                          <li
                            onClick={(e) => handleSelectedBeneficiary(b.profileGUID, i, b.surName, b.sharePercentage)}
                            className={(activeBeneficiary === b.profileGUID) ? 'beneficiary-selected-byshare' : 'beneficiary-li'}
                          >
                            {b.foreName}
                            &nbsp;
                            {b.surName}
                            <button className="shareBtn" type="button">
                              {/* {b.sharePercentage} */}
                              {shareValue}
                              {' '}
                              %
                            </button>
                          </li>
                        ))}
                      </ul>
                    </div>
                  </div>
                  <div className="col" style={{ padding: '40px' }}>
                    <div className="row">
                      <div className="col">
                        <Box>
                          <Typography id="input-slider" gutterBottom sx={{ fontWeight: '500', fontSize: '14px', lineHeight: '18px' }}>
                            Share of This Property (%)
                          </Typography>
                          <Typography sx={{ fontWeight: '300', fontSize: '14px', lineHeight: '18px' }}>
                            Seek The Bar To Increase Or Decrease Share for Aron Matew
                          </Typography>
                          <Grid container spacing={2} alignItems="center">
                            <Grid item xs>
                              <Slider
                                // value={typeof shareValues[n] === 'number' ? shareValues[n] : 0}
                                // onChange={(event, newValue) => handleSliderChange(event, newValue, n)}
                                value={shareValue}
                                onChange={handleSliderChange}
                                aria-labelledby="input-slider"
                                max={totalShare}
                                sx={{ width: '501px', paddingTop: '33px' }}
                              />
                              <Typography
                                sx={{
                                  display: 'inline-block',
                                  fontWeight: '500',
                                  fontSize: '18px',
                                }}
                              >
                                {/* {typeof shareValues[n] === 'number' ? shareValues[n] : 0} */}
                                {shareValue}
                                % Share for
                                {' '}
                                {shareListusername}
                              </Typography>
                            </Grid>
                          </Grid>
                        </Box>
                      </div>
                    </div>
                    <div className="row">
                      <div className="col">
                        <div className="mb-3">
                          <label style={{ paddingTop: '24px' }} htmlFor="propertyShare" className="form-label w-100">
                            Or Enter Percentage Here
                          </label>
                          {/* <Input
                            className="form-control"
                            value={shareValue}
                            size="small"
                            onChange={handleInputChange}
                            onBlur={handleBlur}
                            name="propertyShare"
                            inputProps={{
                              step: 0,
                              min: 0,
                              max: { totalShare },
                              type: 'number',
                              'aria-labelledby': 'input-slider',
                            }}
                            placeholder="0.0%"
                            sx={{ maxWidth: '287px' }}
                          /> */}

                          <input
                            type="number"
                            placeholder="0.0%"
                            maxLength={3}
                            value={shareValue}
                            // onBlur={handleBlur}
                            // className={`${
                            //   value < 1 ? 'validate-field' : 'form-control'
                            // } `}
                            onChange={handleInputChange}
                          />
                          <br />
                        </div>
                      </div>
                      <div className="col" />
                    </div>
                    <div className="row">
                      <div className="col">
                        <span className="helper">
                          If you have decimal no, enter % here (Eg:13.33%)
                        </span>
                      </div>
                    </div>
                    <div className="row">
                      <div className="col">
                        <Typography
                          id="input-slider"
                          gutterBottom
                          sx={{
                            fontWeight: '500', fontSize: '14px', lineHeight: '18px', paddingTop: '40px',
                          }}
                        >
                          Substitute Share (%)
                        </Typography>
                        <Typography sx={{ fontWeight: '300', fontSize: '14px', lineHeight: '18px' }}>
                          You can divide
                          {' '}
                          {shareListusername}
                          {' '}
                          share  to substitute
                        </Typography>
                      </div>
                    </div>
                    <div className="row" style={{ paddingTop: '24px' }}>

                      {filteredArray.map((item) => (
                        <div className="col">
                          <div className="mb-3">
                            <label htmlFor="substitute" className="form-label w-100">
                              {item.foreName}
                            </label>
                            <input
                              type="text"
                              id="substitute"
                              className="form-control"
                              placeholder="0%"
                              value={substituteValues[item.profileGUID] || item.sharePercentage}
                              onChange={(event) => handleInputChangesubstitute(event, item.profileGUID)}
                            />
                          </div>
                        </div>
                      ))}
                      <div className="col" />
                      {totalSubstituteValue !== 100
                        ? <p className="totalShare">Total substitute share percentage must be 100.</p> : <p /> }
                      {totalSubstituteValue !== 0 && shareValue === 0
                        ? <p className="totalShare">Assign share to the main beneficiary before assigning it to the substitute.</p> : <p /> }
                      <Box sx={{ flex: '1 1 auto' }} />
                    </div>
                  </div>
                </div>
              </AccordionDetails>
/* eslint-disable array-callback-return */
/* eslint-disable @typescript-eslint/no-shadow */
/* eslint-disable react/no-array-index-key */
/* eslint-disable @typescript-eslint/no-use-before-define */
/* eslint-disable no-plusplus */
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-alert */
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable jsx-a11y/control-has-associated-label */
/* eslint-disable react/button-has-type */
/* eslint-disable max-len */
import React, { useState, useEffect } from 'react';
import { useDropzone } from 'react-dropzone';
import { AiOutlineClose } from 'react-icons/ai';
import FileUploadIcon from '@assets/FileUploadIcon.svg';
import FileListIcon from '@assets/FileListIcon.svg';
import FileUploadIconDark from '@assets/FileUploadIconDark.svg';
import TickMarkIconGreen from '@assets/TickMarkIconGreen.svg';
import TickMarkIconGrey from '@assets/TickMarkIconGrey.svg';
import FileArrowIcon from '@assets/FileArrowIcon.svg';

import './style.scss';
import Box from '@mui/material/Box/Box';
import Button from '@mui/material/Button/Button';
import { useForm } from 'react-hook-form';
import {
  fetchDocumentTypeList,
  fetchDocumentsList,
  deleteDocument,
  willDocumentUploadSelector,
  saveDocument,
} from '@redux/slices/will-documents-upload';
import { useSelector, useDispatch } from 'react-redux';
import { DocumentTypeList } from '@api/models';
import axios from 'axios';
import { willPersonalInformationSelector } from '@redux/slices/will-personal-information';
import { willsValidatorSelector } from '@redux/slices/willsValidator';
import MirrorWillSwitcher from '@components/MirrorWillSwitcher';
// import custom hook useDocumentsList
import useDocumentsList from '@utils/hooks/useDocumentsList';
import DeleteConfirmationModal from '@components/DeleteConfirmationModal';
import { useLocation } from 'react-router';
import DocumentManagerModal from '@components/DocumentManagerModal';
import { fetchAppointmentDetail } from '@redux/slices/wills-book-appointment';

import { trackPromise } from 'react-promise-tracker';
import { getAppointmentDetail } from '../../redux/slices/wills-book-appointment';
import api from '../../api';

interface Props {
  handleNext: (step: number, stepName?: string) => void;
  currentBtnStep: number;
  handleBack: () => void;
  willTypeID: number;
}

function DocumentManager({
  handleNext, currentBtnStep, handleBack, willTypeID,
}: Props) {
  // const [documentTypeID, setDocumentTypeID] = useState<string>('');
  const [documentTypeArray, setDocumentTypeArray] = useState([]);
  const [documentTypeID, setDocumentTypeID] = useState();
  const [uniqueDocumentId, setUniqueDocumentId] = useState();
  const [witnessProfileGUID, setWitnessProfileGUID] = useState();
  const [willDocGuid, setWillDocGuid] = useState<string>('');
  // const bookedForProfileGUID = 'ba125f2d-8c78-41ce-b576-6aaef9b57c2a';
  const [uploadedFiles, setUploadedFiles] = useState([]);
  const [showModal, setShowModal] = useState(false);
  const { state } = useLocation();
  const [showBookAppointnentModal, setShowBookAppointnentModal] = useState(false);
  // state for documentIsRequired with boolean type

  // profile guid
  const { isSpouseSelected, spouseGuid, profileGuid } = useSelector(willPersonalInformationSelector);

  const dispatch = useDispatch();

  const handleOpenModal = () => {
    setShowModal(true);
  };
  const handleCloseModal = () => {
    setShowModal(false);
  };

  const handleBookAppointmentModalOpen = () => {
    setShowBookAppointnentModal(true);
  };

  const handleBookAppointmentModalClose = () => {
    setShowBookAppointnentModal(false);
  };

  const handleBookAppointmentModalContinue = () => {
    setShowBookAppointnentModal(false);
    // handleNext(currentBtnStep, 'upload');
  };

  // Show a modal on load
  // useEffect(() => {
  //   dispatch<any>(fetchAppointmentDetail(profileGuid))
  //     .then((response: any) => {
  //       console.log('fetchAppointmentDetailResult', response);
  //       // log the response status
  //       if (!response) {
  //         handleBookAppointmentModalOpen();
  //       }
  //     });
  // }, []);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await trackPromise(api.getAppointmentDetail(profileGuid));
        console.log('fetch AppointmentDetail Result', response?.data?.Output);
        // log the timeSlotID
        console.log('timeSlotID:', response?.data?.Output?.timeSlotID);
        if (response?.data?.Output?.timeSlotID === 0) {
          console.log('No appointment details found! Opening modal');
          handleBookAppointmentModalOpen();
        } else {
          const appointmentDetails = response.data.Output;
          console.log('Appointment details:', appointmentDetails);
        }
      } catch (error) {
        console.error('Error fetching appointment detail:', error);
      }
    };
    fetchData();
  }, []);

  // API results from Redux
  const {
    bookedforprofileguid,
    docType,
    documentTypeList,
    documentsList,
    docTypeID,
    isDocumentsChanged,
  } = useSelector(willDocumentUploadSelector);
  const { mirrorWillCheck } = useSelector(willsValidatorSelector);
  // custom hook for document list
  const uploadedDocumentsList = useDocumentsList(documentsList);

  /**
   * Retrieves the list of document types and sets it to the document type array.
   *
   * @return {void} No return value.
   */
  const getDocumentTypeList = () => {
    const documentTypes: any = [];
    documentTypeList.forEach((d: DocumentTypeList) => {
      documentTypes.push({
        documentTypeID: d.docTypeID,
        documentTypeName: d.fileName,
        witnessProfileGUID: d.witnessProfileGUID,
        isRequired: d.isRequired,
      });
    });
    setDocumentTypeArray(documentTypes);
    // log the document type array with a message
    console.log('Document types array:', documentTypeArray);
  };

  const [documentIsRequired, setDocumentIsRequired] = useState<boolean>(
    documentTypeArray.some((d) => d.isRequired),
  );

  // Check for Document Required or not
  // if (documentTypeArray.some((d) => d.isRequired)) {
  //   // list reuiqred documents
  //   const requiredDocuments = documentTypeArray.filter((d) => d.isRequired);
  //   console.log('Required documents:', requiredDocuments);
  // }

  // API calls inside useEffects -------
  useEffect(() => {
    // dispatch<any>(fetchDocumentTypeList(bookedForProfileGUID));
    dispatch<any>(fetchDocumentTypeList(isSpouseSelected ? spouseGuid : profileGuid));
  }, [dispatch, isSpouseSelected]);

  useEffect(() => {
    // Dispatch the fetchDocumentsList action when documentTypeID changes
    dispatch<any>(fetchDocumentsList(isSpouseSelected ? spouseGuid : profileGuid, documentTypeID, witnessProfileGUID));
  }, [uniqueDocumentId, documentTypeID, isDocumentsChanged, isSpouseSelected]);

  // Result transformation for UI
  useEffect(() => {
    getDocumentTypeList();
  }, [documentTypeList]);

  const { handleSubmit } = useForm();
  /**
   * Sets the active element to the given element string.
   *
   * @param {string} element - The string representing the active element to set.
   */
  const handleElementClick = (docTypeId: any, witnessProfileGUID: any) => {
    const uniqueDocumentId: any = `${docTypeId}-${witnessProfileGUID}`;
    setUniqueDocumentId(uniqueDocumentId);
    setDocumentTypeID(docTypeId);
    setWitnessProfileGUID(witnessProfileGUID);
    console.log(witnessProfileGUID, uniqueDocumentId);
  };

  /**
   * Returns the background color style object for a given element.
   *
   * @param {string} element - The element to get background style for.
   * @return {Object} The background color style object for the given element.
   */
  const getBackgroundStyle = (element: any) => ({
    backgroundColor: uniqueDocumentId === element ? '#023979' : '#F4F4F4',
  });

  /**
   * Returns an object representing the style to be applied to the title element.
   *
   * @param {string} element - The element to apply the style to.
   * @return {Object} An object containing the color property to be applied to the title element.
   */
  const getTitleStyle = (element: any) => ({
    color: uniqueDocumentId === element ? '#FFFFFF' : '#1B202D',
  });

  const getFileUploadIcon = (element: any) => (uniqueDocumentId === element ? FileUploadIcon : FileUploadIconDark);

  const getTickMarkicon = (element: any) => (uniqueDocumentId === element ? TickMarkIconGreen : TickMarkIconGrey);

  /**
   * Handles click event on "Add File" button.
   *
   * @param {any} e - The event object.
   * @return {void} Nothing is returned by this function.
   */
  const [documentTypeArrayCopy, setDocumentTypeArrayCopy] = useState([...documentTypeArray]);

  const handleAddFileClick = (e: any) => {
    e.preventDefault();
    documentTypeArrayCopy.forEach((d) => {
      if (d.isRequired) {
        setDocumentIsRequired(true);
        // update the documentTypeArrayCopy with the new value of documentIsRequired
        documentTypeArrayCopy.push({ ...d, isRequired: false });
        // log the updated documentTypeArrayCopy
        console.log('documentTypeArrayCopy:', documentTypeArrayCopy);
        setDocumentTypeArrayCopy(documentTypeArrayCopy);
      }
      setDocumentIsRequired(false);
    });
    if (e.target !== e.currentTarget) {
      return;
    }
    document.getElementById('file-upload-input')?.click();
    // store documentTypeArray to a new array
    // check if any of the documents is required, if yes, set documentIsRequired to true

    // const isRequiredDocumentsExist = documentTypeArray.some((d) => d.isRequired);
    // // log the result of the check
    // console.log('isRequiredDocumentsExist:', isRequiredDocumentsExist);
    // setDocumentIsRequired(isRequiredDocumentsExist);
  };

  /**
   * Handles the file input change event.
   *
   * @param {any} e - the event object
   * @return {void}
   */
  const handleFileInputChange = (e: any) => {
    const newFiles = Array.from(e.target.files);
    checkFileValidity(newFiles);
  };

  /**
   * Handles the file drop event by checking the validity of the accepted files.
   *
   * @param {any} acceptedFiles - the files that have been accepted for upload
   */
  const handleFileDrop = (acceptedFiles: any) => {
    checkFileValidity(acceptedFiles);
  };

  /**
   * Prevents the click event from propagating and executing other click events.
   *
   * @param {any} e - the click event to be stopped from propagating
   */
  const handleRowItemClick = (e: any) => {
    e.stopPropagation();
  };

  /**
   * Filters files by their extension and size, and adds the valid files to the uploadedFiles state.
   *
   * @param {Array} files - The array of files to be checked.
   * @return {void} Returns nothing.
   */

  // Check the validity of uploaded files
  const checkFileValidity = async (files: any) => {
    const validExtensions = ['.pdf', '.jpeg', '.jpg', '.bmp', '.doc', '.docx'];
    const maxFileSize = 20 * 1024 * 1024;

    // Filter valid files based on extension and file size
    const validFiles = files.filter((file: any) => {
      // Check if the file extension is valid
      const isValidExtension = validExtensions.some((ext) => file.name.toLowerCase().endsWith(ext));
      // Check if the file size is within the allowed limit
      const isWithinMaxSize = file.size <= maxFileSize;
      return isValidExtension && isWithinMaxSize;
    });

    // Filter invalid files
    const invalidFiles = files.filter(
      (file: any) => !validFiles.includes(file),
    );
    if (invalidFiles.length > 0) {
      // Display an alert message for invalid files
      const invalidFileNames = invalidFiles
        .map((file: any) => file.name)
        .join(', ');
      alert(
        `Invalid files: ${invalidFileNames}. Please use A4-size PDF, JPEG, BMP, DOC, or DOCX files that are within 20MB.`,
      );
    } else {
      // Add valid files to the uploaded files list
      setUploadedFiles((prevFiles) => [...prevFiles, ...validFiles]);
      if (uploadedFiles) {
        const formData = new FormData();
        for (let i = 0; i < validFiles.length; i++) {
          const file = validFiles[i];
          formData.append('FileDoc', file, file.name);
        }

        dispatch<any>(saveDocument(isSpouseSelected ? spouseGuid : profileGuid, documentTypeID, witnessProfileGUID, formData));
      }
    }
  };

  /**
   * Removes a file from the system.
   *
   * @param {string} willDocGuid - the unique identifier of the file to be removed
   * @return {any} the result of the delete operation
   */
  const removeFile = (willDocGuid: string) => {
    setWillDocGuid(willDocGuid);
    handleOpenModal();
  };

  const deleteFile = () => {
    console.log(`Delete the doc with GUID: ${willDocGuid}`);
    dispatch<any>(deleteDocument(willDocGuid));
    // log the result of the delete operation
    console.log('File removed successfully!');
    setShowModal(false);
  };

  const handleUploadDocument = (data: any) => {
    console.log(data);
    // handle document upload
    handleNext(currentBtnStep, 'upload');
  };

  const {
    getRootProps, // Props for the file drop zone element
    getInputProps, // Props for the file input element
  } = useDropzone({
    onDrop: handleFileDrop, // Callback function for handling dropped or selected files
  });

  return (
    <main>
      <section>
        {mirrorWillCheck && <MirrorWillSwitcher />}
        <header className="header mt-4">Upload Documents</header>
        <p className="description">
          Upload the documents in PDF or JPEG format. Click on Next Step to save
          the files once all the documents have been uploaded
        </p>
      </section>
      <div className="row document-upload-container">
        <div className="col-lg-6 content-wrapper">
          {documentTypeArray?.map((type) => (
            <div
              className={`top${
                uniqueDocumentId === `${type?.documentTypeID}-${type?.witnessProfileGUID}` ? ' active' : ''
              }`}
              style={getBackgroundStyle(`${type?.documentTypeID}-${type?.witnessProfileGUID}`)}
              onClick={() => handleElementClick(type?.documentTypeID, type?.witnessProfileGUID)}
            >
              <div className="left-container">
                <div className="file-upload-icon">
                  <img
                    src={getFileUploadIcon(`${type?.documentTypeID}-${type?.witnessProfileGUID}`)}
                    alt="File Uploader Icon"
                  />
                </div>
                <div
                  className="document-title"
                  style={getTitleStyle(`${type?.documentTypeID}-${type?.witnessProfileGUID}`)}
                >
                  {type.documentTypeName}
                </div>
              </div>
              <div className="tick-icon">
                <img
                  src={getTickMarkicon(`${type?.documentTypeID}-${type?.witnessProfileGUID}`)}
                  alt="Tick Mark"
                />
              </div>
            </div>
          ))}
        </div>

        <div
          className="col-lg-6 row-item"
          {...getRootProps()}
          onClick={handleRowItemClick}
        >
          <div className="file-upload-arrow">
            <img src={FileArrowIcon} alt="File Upload Arrow Icon" />
          </div>
          <div className="file-upload-text">
            Drag and drop document here to upload
          </div>
          <div className="file-attach-instructions">
            Please attach the file(s) below (use the Add button). We recommend
            using A4-size PDF, BMP, PNG, DOC, DOCX, JPG and JPEG files. File
            size cannot be more than 20 megabytes (MB). Your files will be
            uploaded when you submit your form.
          </div>
          <div className="file-add-button">
            <button className="add-file-btn" onClick={handleAddFileClick}>
              Add File
            </button>
            <input
              type="file"
              id="file-upload-input"
              name="file-upload-input"
              accept=".pdf, .bmp, .png, .doc, .docx, .jpg, .jpeg"
              multiple
              onChange={handleFileInputChange}
              style={{ display: 'none' }}
              {...getInputProps()}
            />
          </div>
          {uploadedDocumentsList.length > 0
            && uploadedDocumentsList.map((file: any, index) => (
              <div className="file-list-item" key={index}>
                <div className="file-info">
                  <div className="file-icon">
                    <img src={FileListIcon} alt="File List Icon" />
                  </div>
                  <div className="file-name">{file.fileName}</div>
                </div>
                <div className="close-icon" onClick={() => removeFile(file.willDocGuid)}>
                  <span className="close-icon-text">Remove</span>
                </div>
              </div>
            ))}
        </div>
      </div>
      <Box sx={{ display: 'flex', flexDirection: 'row', pt: 2 }}>
        {documentIsRequired}
        <button
          type="button"
          className="next-btn"
          onClick={() => handleNext(state === 'Guardianship Will' ? 6 : currentBtnStep, 'upload')}
          disabled={documentIsRequired}
        >
          Next Step
        </button>
      </Box>
      <span className="next-btn-text mt-4">
        *Before clicking next, please make sure the details provided here are
        correct.
      </span>
      <DeleteConfirmationModal
        show={showModal}
        handleClose={handleCloseModal}
        handleContinue={deleteFile}
        type="Document"
      />
      {/* render DocumentManagerModal */}
      {
          (willTypeID === 1 || willTypeID === 2) && (
            <DocumentManagerModal
              showBookAppointnentModal={showBookAppointnentModal}
              handleBookAppointmentModalClose={handleBookAppointmentModalClose}
              handleBookAppointmentModalContinue={handleBookAppointmentModalContinue}
              handleNext={handleNext}
              currentBtnStep={currentBtnStep}
              handleBack={handleBack}
            />
          )
        }

    </main>
  );
}

export default DocumentManager;
<DesktopDatePicker 
    value={dateOfBirth} 
    disableFuture 
    onChange={(e:any, newVal:any)=> handleDate(e, newVal)}
    renderInput={(params:any) =>
        <TextField {...params} error={false} />}
    />
 
HandleChange Function
    const handleDate = (e: any, newVal: any) => {
      console.log('formatted date', moment(e?._d).format());
      const formattedDate = moment(e?._d).format();
      setDateOfBirth(formattedDate);
    };
 
State variable and datatype
    const [dateOfBirth, setDateOfBirth] = useState<string>(null);
 
Repopulating value
    setDateOfBirth(selectedBeneficiary?.dateOfBirth?.slice(0, 10));
Desktop DatePicker Code (From MUI)
<DesktopDatePicker 
	value={dateOfBirth} 
	disableFuture 
    onChange={(e:any, newVal:any)=> handleDate(e, newVal)}
    renderInput={(params:any) =>
    	<TextField {...params} error={false} />}
    />

HandleChange Function
    const handleDate = (e: any, newVal: any) => {
      console.log('formatted date', moment(e?._d).format());
      const formattedDate = moment(e?._d).format();
      setDateOfBirth(formattedDate);
    };

State variable and datatype
	const [dateOfBirth, setDateOfBirth] = useState<string>(null);

Repopulating value
	setDateOfBirth(selectedBeneficiary?.dateOfBirth?.slice(0, 10));
"""
function ChooseMethodModal({ showModal, handleModalClose, handleContinue }: ChooseMethodModalProps) {
  const [activeCard, setActiveCard] = useState('draftWill');
  const [selectedWillCard, setSelectedWillCard] = React.useState({
    willTypeName: 'Templated Full Will',
    willTypeID: '6',
  });
  const { results } = useSelector(willsListSelector);

  const dispatch = useDispatch();

  React.useEffect(() => {
    // dispatch<any>(fetchWillsList());
  }, []);

  /**
 * Handles the click event on the card and sets the active card name.
 *
 * @param {string} cardName - The name of the card that was clicked.
 * @return {void} This function does not return anything.
 */
  const handleCardClick = (cardName: string) => {
    setActiveCard(cardName);
    const { willTypeName, willTypeID } = results.find((will: any) => {
      if (cardName === 'draftWill') return will.willTypeName === 'Templated Full Will';
      if (cardName === 'willCopyUpload') return will.willTypeName === 'Full Will';
      return false;
    }) || { willTypeName: '', willTypeID: '' };
    setSelectedWillCard({ willTypeName, willTypeID });
  };

  const isAnyWillCardSelected = selectedWillCard.willTypeName !== '' && selectedWillCard.willTypeID !== '';

  return (
    <Modal show={showModal} onHide={handleModalClose} dialogClassName="modal-dialog-centered" size="lg">
      <Modal.Header closeButton>
        <Modal.Title className="modal-title">Choose Method</Modal.Title>
      </Modal.Header>
      <Modal.Body>
        <div>
          <div className="modal-choose-method-subtitle mb-3">
            List your Substitute Beneficiaries below and click on Add Substitute to add them to your List
          </div>
        </div>
        <div className="d-flex flex-row">
          <div
            className={`card-container-draft-will d-flex flex-column align-items-center ${activeCard === 'draftWill' ? 'active' : ''}`}
            style={{ width: '50%', marginRight: '10px', position: 'relative' }}
            onClick={() => handleCardClick('draftWill')}
          >
            {activeCard === 'draftWill' && (
            <div
              className="check-icon"
            >
              <img src={FillCheckRoundIcon} alt="Fill Check Icon" />
            </div>
            )}
            <div className="choose-method-draft-will-icon-container" style={{ marginBottom: '20px', marginTop: '20px' }}>
              <img src={DraftWillIcon} alt="Will Copy Upload Icon" />
            </div>
            <div className="text-center choose-method-draft-will-title" style={{ marginTop: '10px', marginBottom: '10px', textAlign: 'center' }}>
              Draft Will Using the System
            </div>
            <div
              className="text-center choose-method-draft-will-desc"
              style={{ marginTop: '10px', marginBottom: '10px' }}
            >
              It is a long established fact that a reader will be distracted by the readable content.
            </div>
          </div>
          <div
            className={`card-container-will-copy-upload d-flex flex-column align-items-center ${activeCard === 'willCopyUpload' ? 'active' : ''}`}
            style={{ width: '50%', marginRight: '10px', position: 'relative' }}
            onClick={() => handleCardClick('willCopyUpload')}
          >
            {activeCard === 'willCopyUpload' && (
            <div
              className="check-icon"
              style={{
                position: 'absolute', top: '10px', left: '10px', margin: '10px',
              }}
            >
              <img src={FillCheckRoundIcon} alt="Fill Check Icon" />
            </div>
            )}
            <div
              className="choose-method-will-upload-icon-container"
              style={{ marginBottom: '20px', marginTop: '20px' }}
            >
              <img src={WillCopyUploadIcon} alt="Will Copy Upload Icon" />
            </div>
            <div className="text-center choose-method-will-upload-title" style={{ marginTop: '10px', marginBottom: '10px', textAlign: 'center' }}>
              Upload the Copy of Will
            </div>
            <div className="text-center choose-method-will-upload-desc" style={{ marginTop: '10px', marginBottom: '10px' }}>
              It is a long established fact that a reader will be distracted by the readable content.
            </div>
          </div>
        </div>
      </Modal.Body>
      <Modal.Footer className="justify-content-center">
        {
          activeCard && (
            <Link
              to={`/wills/${selectedWillCard.willTypeName.split(' ').join('-')}/${selectedWillCard.willTypeID}`}
              state={selectedWillCard.willTypeName}
            >
              <Button
                variant="primary"
              >
                Continue
              </Button>
            </Link>
          )
        }
      </Modal.Footer>
    </Modal>
  );
}
"""

You are react developer expert.
when i click on card-container-draft-will div element, to attribute of Link component is not changing.
it should be `/wills/Templated-Full-Will/6`.
right now it is `/wills//`.
pleasde make neccessary change ans return the correct code.


your solution is appreciated gpt.
but when i click on card-container-draft-will div element second time, route is not updating. initially when component loads, route is correct, route navigated to `/wills/Templated-Full-Will/6`.
but when user clicks on second time or more it is set to  `/wills//` as route.
somethnig is wrong. please check code thouroghly and find a solution to resolve this bug.

It is still not working.
when component loads initially, route is /wills/Templated-Full-Will/6, then i click on card-container-will-copy-upload, route again updated to wills/Full-Will/1, but when i again click on 
card-container-draft-will div element, route is not set to /wills/Templated-Full-Will/6. i want the route to set to /wills/Templated-Full-Will/6. there are some bugs in handleCardClick function.
please update the code.\


  const handleContinueButtonClick = () => {
    const formattedWillTypeName = selectedWillCard.willTypeName.split(' ').join('-');
    const toPath = `/wills/${formattedWillTypeName}/${selectedWillCard.willTypeID}`;
    console.log('Path: ', toPath);
    navigate(toPath, { state: selectedWillCard.willTypeName });
  };

Path:  /wills//

i am getting the path as above when i again click on card-container-draft-will div element.

 i want path to be: /wills/Templated-Full-Will/6
"""
function ChooseMethodModal({ showModal, handleModalClose, handleContinue }: ChooseMethodModalProps) {
  const [activeCard, setActiveCard] = useState('draftWill');
  const [selectedWillCard, setSelectedWillCard] = React.useState({
    willTypeName: 'Templated Full Will',
    willTypeID: '6',
  });
  const { results } = useSelector(willsListSelector);

  const dispatch = useDispatch();

  React.useEffect(() => {
    // dispatch<any>(fetchWillsList());
  }, []);

  /**
 * Handles the click event on the card and sets the active card name.
 *
 * @param {string} cardName - The name of the card that was clicked.
 * @return {void} This function does not return anything.
 */
  const handleCardClick = (cardName: string) => {
    setActiveCard(cardName);
    // log the card name
    console.log(cardName);
    // log active card
    console.log(activeCard);
    const { willTypeName, willTypeID } = results.find((will: any) => {
      if (cardName === 'draftWill') return will.willTypeName === 'Templated Full Will';
      if (cardName === 'willCopyUpload') return will.willTypeName === 'Full Will';
      return false;
    }) || { willTypeName: '', willTypeID: '' };
    setSelectedWillCard({ willTypeName, willTypeID });
  };

  const isAnyWillCardSelected = selectedWillCard.willTypeName !== '' && selectedWillCard.willTypeID !== '';

  return (
    <Modal show={showModal} onHide={handleModalClose} dialogClassName="modal-dialog-centered" size="lg">
      <Modal.Header closeButton>
        <Modal.Title className="modal-title">Choose Method</Modal.Title>
      </Modal.Header>
      <Modal.Body>
        <div>
          <div className="modal-choose-method-subtitle mb-3">
            List your Substitute Beneficiaries below and click on Add Substitute to add them to your List
          </div>
        </div>
        <div className="d-flex flex-row">
          <div
            className={`card-container-draft-will d-flex flex-column align-items-center ${activeCard === 'draftWill' ? 'active' : ''}`}
            style={{ width: '50%', marginRight: '10px', position: 'relative' }}
            onClick={() => handleCardClick('draftWill')}
          >
            {activeCard === 'draftWill' && (
            <div
              className="check-icon"
            >
              <img src={FillCheckRoundIcon} alt="Fill Check Icon" />
            </div>
            )}
            <div className="choose-method-draft-will-icon-container" style={{ marginBottom: '20px', marginTop: '20px' }}>
              <img src={DraftWillIcon} alt="Will Copy Upload Icon" />
            </div>
            <div className="text-center choose-method-draft-will-title" style={{ marginTop: '10px', marginBottom: '10px', textAlign: 'center' }}>
              Draft Will Using the System
            </div>
            <div
              className="text-center choose-method-draft-will-desc"
              style={{ marginTop: '10px', marginBottom: '10px' }}
            >
              It is a long established fact that a reader will be distracted by the readable content.
            </div>
          </div>
          <div
            className={`card-container-will-copy-upload d-flex flex-column align-items-center ${activeCard === 'willCopyUpload' ? 'active' : ''}`}
            style={{ width: '50%', marginRight: '10px', position: 'relative' }}
            onClick={() => handleCardClick('willCopyUpload')}
          >
            {activeCard === 'willCopyUpload' && (
            <div
              className="check-icon"
              style={{
                position: 'absolute', top: '10px', left: '10px', margin: '10px',
              }}
            >
              <img src={FillCheckRoundIcon} alt="Fill Check Icon" />
            </div>
            )}
            <div
              className="choose-method-will-upload-icon-container"
              style={{ marginBottom: '20px', marginTop: '20px' }}
            >
              <img src={WillCopyUploadIcon} alt="Will Copy Upload Icon" />
            </div>
            <div className="text-center choose-method-will-upload-title" style={{ marginTop: '10px', marginBottom: '10px', textAlign: 'center' }}>
              Upload the Copy of Will
            </div>
            <div className="text-center choose-method-will-upload-desc" style={{ marginTop: '10px', marginBottom: '10px' }}>
              It is a long established fact that a reader will be distracted by the readable content.
            </div>
          </div>
        </div>
      </Modal.Body>
      <Modal.Footer className="justify-content-center">
        {
          activeCard && (
            <Link
              to={`/wills/${selectedWillCard.willTypeName.split(' ').join('-')}/${selectedWillCard.willTypeID}`}
              state={selectedWillCard.willTypeName}
            >
              <Button
                variant="primary"
              >
                Continue
              </Button>
            </Link>
          )
        }
      </Modal.Footer>
    </Modal>
  );
}
"""

when component loads, card-container-draft-will is selected by default. when user clicks on card-container-will-copy-upload, that element is selected. But when user clicks on card-container-draft-will again after clickin will-copy-upload, problem is when clicking continue button, Link is not naviating to the indented component/page. it is not moving to indented page.
please update the code. and make it correct.
but now when i click on card-container-draft-will element, COnitnue button not showing. please fix this bug.
-------- APP Page ---------------
  import React, { useState } from "react";
import Header from "./Header";
import Footer from "./Footer";
import Note from "./Note";
import CreateArea from "./CreateArea";

function App() {
  ------------  see -------------
  const [notes, setNotes] = useState([]);
  

  function addNote(newNote) {
    setNotes((prevValue) => {
      return [...prevValue, newNote];
    });
  }
------------ end see --------------
  function onDelete(id) {
    setNotes((prevValue) => {
      return prevValue.filter((item, index) => {
        return index !== id;
      });
    });
  }

  return (
    <div>
      <Header />
      <CreateArea addNote={addNote} />
      {notes.map((noteItem, index) => {
        return (
          <Note
            key={index}
            id={index}
            title={noteItem.title}
            content={noteItem.content}
            deleteFunction={onDelete}
          />
        );
      })}

      <Footer />
    </div>
  );
}

export default App;

  
  
  
  ----------------- content area page ------------
import React, { useState } from "react";
import AddToPhotosIcon from "@material-ui/icons/AddToPhotos";
import Fab from "@material-ui/core/Fab";
import Zoom from "@material-ui/core/Zoom";

function CreateArea(params) {
  ------------  see --------------
  const [input, setInput] = useState({
    title: "",
    content: ""
  });

  function handleInput(event) {
    const { name, value } = event.target;
    setInput((prevValue) => {
      return {
        ...prevValue,
        [name]: value
      };
    });
  }

  function SubmitButton(event) {
    event.preventDefault();
    params.addNote(input);
    setInput({
      title: "",
      content: ""
    });
  }
  ------------ end see --------------

  const [condition_check, setCondition_check] = useState(false);

  function onCondition() {
    setCondition_check(true);
  }

  function noCondition() {
    setCondition_check(false);
  }

  return (
    <div>
      <form className="create-note" onBlur={noCondition}>
        {condition_check && (
          <input
            name="title"
            placeholder="Title"
            value={input.title}
            onChange={handleInput}
          />
        )}
        <textarea
          name="content"
          placeholder="Take a note..."
          rows={condition_check ? 3 : 1}
          value={input.content}
          onChange={handleInput}
          onClick={onCondition}
        />
------------  see --------------
        <Zoom in={condition_check}>
          <Fab onClick={SubmitButton}>
            <AddToPhotosIcon />
          </Fab>
        </Zoom>
------------ end see --------------
      </form>
    </div>
  );
}

export default CreateArea;
"""
<div className="col-md-6">
              <label
                htmlFor="companyContactNumber"
                className="form-label w-100 company-contact-number-label"
              >
                Company Contact Number*
              </label>
              <div className="d-flex">
                {/* autocomlete field for isdcodelist */}
                <Autocomplete
                  ref={autocompleteRef}
                  disablePortal
                  id="isdcodelist"
                  options={isdCodesList}
                  isOptionEqualToValue={(option: any, value: any) => option.label === value.label}
                  renderInput={(params) => (
                    <TextField
                      {...params}
                      {...register('isdCode', {
                        required: true,
                      })}
                      className="isd-code-input"
                      placeholder="+971"
                    />
                  )}
                  renderOption={(props, option) => (
                    <span
                      className="phone-number-option"
                      {...props}
                    >
                      {option.countryName}
                    </span>
                  )}
                            // onchange event handler to set the isdCode state
                  onChange={(e, value: any) => setIsdCode(
                    value?.label,
                  )}
                />
                {/* handle errors */}
                {formErrors.isdCode && (
                <span className="error-message">{formErrors.isdCode}</span>
                )}
                {/* company contact input */}
                <input
                  type="text"
                  className="form-control company-contact-number-input"
                  id="companyContactNumber"
                  placeholder="XXXXXXXXXXXXXX"
                  onInput={(e) => {
                    const input = e.target as HTMLInputElement;
                    input.value = input.value.slice(0, 15).replace(/[^0-9 ]/g, ''); // Limit the input to 15 characters and Allow only digits and spaces
                    setCompanyContactNumber(input.value);
                  }}
                  {...register('companyContactNumber', {
                    required: true,
                  })}
                />
                {/* handle errors */}
                {formErrors.companyContactNumber && (
                <span className="error-message">{formErrors.companyContactNumber}</span>
                )}
              </div>
</div>
"""

consider you are react developer.
client wants to achieve below changes in the form.

1. You have to display isdCode error below that particular autocomplete field. currently it is shown right to the field. Show it under field.

2. You have to display company contact number error below that particular field. currently it is shown right to the field. Show it under field.

3. make appropriate changes in the code and return the code.



""" 
<div className="row form-row mb-4 align-items-center">
            <div className="col-md-6">
              <label
                htmlFor="resident"
                className="form-label w-100 resident-label"
              >
                Are you a Resident of the UAE?
              </label>
            </div>
            <div className="col-md-6 d-flex justify-content-between align-items-center">
              <OptionButtons
                options={residentOrNotOptions}
                selectedOption={resident}
                onOptionSelected={handleResidentOptionSelect}
              />
            </div>
          </div>

          {/* row with columns for emirates id */}
          <div className="row form-row mb-5">
            {/* Emirates ID Col */}
            <div className="col-md-6">
              <label
                htmlFor="emiratesId"
                className="form-label w-100 emirates-id-label"
              >
                Emirates ID*
              </label>
              <input
                type="text"
                className="form-control emirates-id-input"
                id="emiratesId"
                placeholder="XXXX XXXX XXXX"
                defaultValue={userData.emiratesID}
                maxLength={15}
                onChange={(e) => setEmiratesID(e.target.value)}
                onInput={(e) => {
                  const input = e.target as HTMLInputElement;
                  input.value = input.value.replace(/\D/g, '');
                  setEmiratesID(input.value);
                }}
                {...register('emiratesID', {
                  required: true,
                })}
              />

              {/* handle errors */}
              {/* {formErrors.emiratesID && (
              <span className="error-message">{formErrors.emiratesID}</span>
              )} */}
            </div>
            {/* passport expiry date col */}
            <div className="col-md-6">
              <label
                htmlFor="emiratesIdExpiryDate"
                className="form-label w-100 emiratesId-expiry-date-label"
              >
                Emirates ID Expiry Date*
              </label>
              {/* Date Picker to handle emirates id expiry */}
              <DatePicker
                onChange={handleEmiratesExpiryDatePicker}
                value={emiratesIDExpiryDate}
                minDate={new Date().toISOString().split('T')[0].split('-').join('/')}
                renderInput={(params: any) => (
                  <TextField
                    {...params}
                    inputProps={{
                      ...params.inputProps,
                      // readonly
                      readOnly: true,
                      placeholder: 'Choose Date',
                    }}
                    {...register('emiratesIDExpiryDate', {
                      required: true,
                    })}
                    className="date-picker date-picker-input"
                  />
                )}
                className="date-picker-field"
              />
              {/* handle errors */}
              {formErrors.emiratesIDExpiryDate && (
              <span className="error-message">{formErrors.emiratesIDExpiryDate}</span>
              )}
            </div>
          </div>

"""

You are an experienced react developer.
Client want some changes in form. Details were given in below bullet points:

1. When the value of resident props of OptionButtons is No, emiratesid and emirates expiry date datepicker should be disabled.
Ie user should  not be able to input or select any data in both fields.
2. if the value is Yes, both emiratesid and emirates expiry date datepicker are enabled. 
3. Initialy when component is loaded, both were enabled.
4. It is disable only when user choose resident as No, else both the inputs were enabled.

please update the code as per my above requirements.


---------------- App Page ---------------
  
  import React, { useState } from "react";
import ListItem from "./ListItem";

function App() {
  const [input, setInput] = useState("");
  const [task, setTask] = useState([]);

  function handleChange(event) {
    const newTask = event.target.value;
    setInput(newTask);
  }
  function deleteItem(id) {
    console.log("Delete this", id);
    setTask((prevTask) => {
      return prevTask.filter((item, index) => {
        return index !== id;
      });
    });
  }

  const listTasks = [...task];
  function addTasks() {
    setTask((prevTask) => [...prevTask, input]);
  }

  return (
    <div className="container">
      <div className="heading">
        <h1>To-Do List</h1>
      </div>
      <div className="form">
        <input type="text" name="tasksName" onChange={handleChange} />
        <button onClick={addTasks}>
          <span>Add</span>
        </button>
      </div>
      <div>
        <ul>
          {listTasks.map((items, index) => (
            <ListItem key={index} id={index} text={items} delete={deleteItem} />
          ))}
        </ul>
      </div>
    </div>
  );
}

export default App;
  
 ------------------ Input List Page -------------
   
   import React, { useState } from "react";

function ListItem(props) {
  const [conditionLine, setLine] = useState(false);

  function HandleChange() {
    setLine((prevValue) => {
      return !prevValue;
    });
  }

  return (
    <div onClick={HandleChange}>
      <li style={{ textDecoration: conditionLine && "line-through" }}>
        {props.text}
        <button className="button_list" onClick={()=>props.delete(props.id)}>
          <span>Delete</span>
        </button>
      </li>
    </div>
  );
}

export default ListItem;
To populate the form fields of the previous step when the "Back" button is clicked, you can store the form data in the parent component and pass it as props to the child components. Here's an updated example:

UserOnBoardingMain component:

```jsx
import React, { useState } from 'react';
import UserRegistrationForm from './UserRegistrationForm';
import UserRegistrationFormAddressInfo from './UserRegistrationFormAddressInfo';
import UserRegistrationFormCompanyInfo from './UserRegistrationFormCompanyInfo';

const UserOnBoardingMain = () => {
  const [step, setStep] = useState(1);
  const [userData, setUserData] = useState({});

  const handleNextStep = (data) => {
    setUserData((prevData) => ({ ...prevData, ...data }));
    setStep((prevStep) => prevStep + 1);
  };

  const handleBackStep = () => {
    setStep((prevStep) => prevStep - 1);
  };

  return (
    <>
      {step === 1 && (
        <UserRegistrationForm onNextStep={handleNextStep} userData={userData} />
      )}
      {step === 2 && (
        <UserRegistrationFormAddressInfo
          onNextStep={handleNextStep}
          onBackStep={handleBackStep}
          userData={userData}
        />
      )}
      {step === 3 && (
        <UserRegistrationFormCompanyInfo
          onNextStep={handleNextStep}
          onBackStep={handleBackStep}
          userData={userData}
        />
      )}
    </>
  );
};

export default UserOnBoardingMain;
```

UserRegistrationForm component:

```jsx
import React from 'react';
import { useForm } from 'react-hook-form';

const UserRegistrationForm = ({ onNextStep, userData }) => {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm();

  const onSubmit = (data) => {
    onNextStep(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {/* Form fields */}
      <input {...register('fieldName')} defaultValue={userData.fieldName} />
      {/* Other form fields */}
      <button type="submit">Next</button>
    </form>
  );
};

export default UserRegistrationForm;
```

UserRegistrationFormAddressInfo and UserRegistrationFormCompanyInfo components would have similar implementations.

In the above code, the `userData` state is updated whenever the `handleNextStep` function is called, which is triggered when the "Next" button is clicked in each form step. The `userData` is then passed as props to the child components. When the "Back" button is clicked, the `handleBackStep` function is called, which reduces the `step` value by 1, allowing you to navigate back to the previous step.

By providing the `defaultValue` prop to each form field in the `UserRegistrationForm` component, the fields will be populated with the corresponding values from the `userData` object. This way, when you navigate back to the previous step, the form fields will be prepopulated with the previously entered values.

Make sure to adjust the form field names and structure according to your specific requirements.
To create a Google Maps API, follow these steps:

1. Go to the Google Cloud Console: https://console.cloud.google.com.
2. Sign in with your Google account or create a new account if you don't have one.
3. Create a new project by clicking on the project dropdown at the top of the page and selecting "New Project." Enter a name for your project and click "Create."
4. Once your project is created, you will be redirected to the project dashboard.
5. Enable the Google Maps JavaScript API:
   - Click on the menu icon (☰) in the upper-left corner of the Cloud Console.
   - In the sidebar, click on "APIs & Services" > "Library."
   - Search for "Google Maps JavaScript API" and select it from the results.
   - Click on the "Enable" button.
6. Set up API credentials:
   - Click on the menu icon (☰) in the upper-left corner of the Cloud Console.
   - In the sidebar, click on "APIs & Services" > "Credentials."
   - Click on the "Create credentials" button and select "API key."
   - Copy the generated API key.
7. Restrict your API key (optional, but recommended for security):
   - On the credentials page, click on the API key you created.
   - Under "Key restriction," select the option that best fits your use case (e.g., HTTP referrers, IP addresses).
   - Configure the allowed referrers or IP addresses as needed.
8. Use your API key in your code:
   - Replace `YOUR_API_KEY` in your code with the API key obtained in the previous step.

Make sure to follow any additional usage limits and terms of service specified by Google. It's also important to secure and protect your API key to prevent unauthorized usage.

Please note that creating and using the Google Maps API may involve costs depending on your usage and the services used. Refer to the Google Cloud Console for pricing information and billing details.
Error:
Google Maps JavaScript API error: ApiNotActivatedMapError
https://developers.google.com/maps/documentation/javascript/error-messages#api-not-activated-map-error

https://www.youtube.com/watch?v=n1UorU1PALk&t=47s

The "ApiNotActivatedMapError" error typically occurs when the Google Maps JavaScript API is not activated or enabled for your project. Here are some steps you can follow to resolve this error:

1. Go to the Google Cloud Console (https://console.cloud.google.com).
2. Select your project or create a new project if needed.
3. Make sure you have a billing account associated with your project. The Google Maps JavaScript API requires a billing account to be set up.
4. Enable the Google Maps JavaScript API for your project. You can do this by following these steps:
   - Click on the menu icon (☰) in the upper-left corner of the Cloud Console.
   - In the sidebar, click on "APIs & Services" > "Library".
   - Search for "Google Maps JavaScript API" and select it from the results.
   - Click on the "Enable" button.
5. Set up the required API credentials. You need to create an API key and configure it to be used in your code.
   - Click on the menu icon (☰) in the upper-left corner of the Cloud Console.
   - In the sidebar, click on "APIs & Services" > "Credentials".
   - Click on the "Create credentials" button and select "API key".
   - Copy the generated API key.
6. Update your code with the API key.
   - Replace `GOOGLE_MAPS_API_KEY` in your code with the API key obtained in the previous step.

After completing these steps, the Google Maps JavaScript API should be activated and the "ApiNotActivatedMapError" should no longer occur.
-------------- List Item page --------------------
import React, { useState } from "react";

function ListItem(props) {
  const [conditionLine, setLine] = useState(false);

  function HandleChange() {
    setLine((prevValue) => {
      return !prevValue;
    });
  }

  return (
    <div onClick={HandleChange}>
      <li style={{ textDecoration: conditionLine && "line-through" }}>
        {props.text}
      </li>
    </div>
  );
}

export default ListItem;

-------------- App page --------------------

import React, { useState } from "react";
import ListItem from "./ListItem";

function App() {
  const [input, setInput] = useState("");
  const [task, setTask] = useState([]);

  function handleChange(event) {
    const newTask = event.target.value;
    setInput(newTask);
  }

  const listTasks = [...task];
  function addTasks() {
    setTask((prevTask) => [...prevTask, input]);
  }

  return (
    <div className="container">
      <div className="heading">
        <h1>To-Do List</h1>
      </div>
      <div className="form">
        <input type="text" name="tasksName" onChange={handleChange} />
        <button onClick={addTasks}>
          <span>Add</span>
        </button>
      </div>
      <div>
        <ul>
          {listTasks.map((items) => (
            <ListItem text={items} />
          ))}
        </ul>
      </div>
    </div>
  );
}

export default App;

Sure, here is an email you can send to your HR:

Subject: Sick Leave Request

Dear Sony R,

I am writing to request a sick leave for today, June 28, 2023, due to fever and cold. I woke up this morning with a fever of 102 degrees Fahrenheit and a sore throat. I have also been feeling congested and have a runny nose.

I have already made an appointment with my doctor and will be going to see them later today. I will keep you updated on my condition and let you know when I expect to be back in the office.

In the meantime, I have already informed my team of my absence and have asked [colleague's name] to cover my workload.

I apologize for any inconvenience this may cause.

Thank you for your understanding.

Sincerely,

Jissmon Jose
Software Developer
8921762662
  const handleMobileNumberValidation = (phone: string) => {
    // const mobileNumberRegex = /^[+0-9\s]*$/;
    // const mobileNumberRegex = /^\+(?:[0-9] ?){6,14}[0-9]$/;
    const mobileNumberRegex = /^(?:[0-9] ?){6,14}[0-9]$/;
    return mobileNumberRegex.test(phone);
  };


    if (primaryMobileNumber.trim() !== '') {
      if (!handleMobileNumberValidation(primaryMobileNumber)) {
        errors.primaryMobileNumber = 'Invalid mobile number';
      }
    }


    <div className="col-md-6">
              <label htmlFor="mobile" className="form-label w-100 mobile-label">
                Primary Mobile Number*
              </label>
              <div className="d-flex">
                {/* autocomlete field for isdcodelist */}
                <Autocomplete
                  disablePortal
                  id="isdcodelist"
                  options={isdCodesList}
                  isOptionEqualToValue={(option: any, value: any) => option.label === value.label}
                  renderInput={(params) => (
                    <TextField
                      {...params}
                      {...register('isdCode', {
                        required: true,
                      })}
                      className="isd-code-input"
                      placeholder="+971"
                    />
                  )}
                  renderOption={(props, option) => (
                    <span
                      className="phone-number-option"
                      {...props}
                    >
                      {option.countryName}
                    </span>
                  )}
                            // onchange event handler to set the isdCode state
                  onChange={(e, value: any) => setIsdCode(
                    value?.label,
                  )}
                />
                <input
                  type="text"
                  className="form-control mobile-input"
                  id="mobile"
                  placeholder="XXX XXX XXXX"
                // onchange
                  onChange={(e) => setPrimaryMobileNumber(e.target.value)}
                  {...register('primaryMobileNumber', {
                    required: true,
                  })}
                />
              </div>
              {/* handle errors */}
              {formErrors.primaryMobileNumber && (
              <span className="error-message">{formErrors.primaryMobileNumber}</span>
              )}
            </div>

const [formErrors, setFormErrors] = useState<UserRegistrationDetails>({
    firstName: '',
    lastName: '',
    gender: '',
    dateOfBirth: '',
    primaryEmail: '',
    secondaryEmail: '',
    primaryMobileNumber: '',
    secondaryMobileNumber: '',
    service: '',
  });

  const validateEmail = (email: string) => {
    const emailRegex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/;
    return emailRegex.test(email);
  };

 const handleUserRegistrationForm = () => {
   
  const handleEmptyField = (fieldName: string, fieldValue: string, errorMessage: string) => {
      if (!fieldValue) {
        errors[fieldName] = errorMessage;
      }
    };

    handleEmptyField('firstName', firstName, 'First name is required');
    handleEmptyField('lastName', lastName, 'Last name is required');
    handleEmptyField('primaryEmail', primaryEmail, 'Primary email is required');
    handleEmptyField('primaryMobileNumber', primaryMobileNumber, 'Primary mobile number is required');
    handleEmptyField('dateOfBirth', dateOfBirth, 'Date of birth is required');

    if (primaryEmail.trim() !== '') {
      if (!validateEmail(primaryEmail)) {
        errors.primaryEmail = 'Invalid email';
      }
    }

    setFormErrors(errors);

 }
 
<input
                type="email"
                className="form-control email-input"
                id="email"
                placeholder="abc@babc.com"
                // onchange
                onChange={(e) => setPrimaryEmail(e.target.value)}
                {...register('primaryEmail', {
                  required: true,
                })}
              />




<DatePicker
                onChange={handleDatePicker}
                value={dateOfBirth}
                disableFuture
                maxDate={subYears(new Date(), 21)}
                renderInput={(params: any) => (
                  <TextField
                    {...params}
                    inputProps={{
                      ...params.inputProps,
                      readOnly: true,
                      placeholder: 'Select Date of Birth',
                    }}
                    {...register('dateOfBirth', {
                      required: true,
                      validate: {
                        ageVerification: (dateString) => {
                          const date = new Date(dateString);
                          return isAfter(subYears(new Date(), 21), date);
                        },
                      },
                    })}
                    className="date-picker date-picker-input"
                  />
                )}
                className="date-picker-field"
              />
<input
  type="text"
  className="form-control firstname-input"
  id="firstname"
  placeholder="John"
  onInput={(e) => {
    const input = e.target as HTMLInputElement;
    input.value = input.value.replace(/[^a-zA-Z ]/g, '');
    setFirstName(input.value);
  }}
  {...register('firstName', {
    required: true,
  })}
/>
<input
  type="text"
  className="form-control firstname-input"
  id="firstname"
  placeholder="John"
  onInput={(e) => {
    const input = e.target as HTMLInputElement;
    input.value = input.value.replace(/[^a-zA-Z ]/g, '');
    setFirstName(input.value);
  }}
  {...register('firstName', {
    required: true,
  })}
/>
import React, { useState } from "react";

function App() {
  const [input, setInput] = useState("");
  const [task, setTask] = useState([]);

  function handleChange(event) {
    const newTask = event.target.value;
    setInput(newTask);
  }

  const listTasks = [...task];
  function addTasks() {
    setTask((prevTask) => [...prevTask, input]);
  }

  return (
    <div className="container">
      <div className="heading">
        <h1>To-Do List</h1>
      </div>
      <div className="form">
        <input type="text" name="tasksName" onChange={handleChange} />
        <button onClick={addTasks}>
          <span>Add</span>
        </button>
      </div>
      <div>
        <ul>
          {listTasks.map((items) => (
            <li>{items}</li>
          ))}
        </ul>
      </div>
    </div>
  );
}

export default App;
-------------- Form Page --------------------
import React, { useState } from "react";
import FormInput from "./FormInputs";

function Form(params) {

  function getfullname(event) {
    const { name, value } = event.target; // DESTRUCTURING CONCEPT

    params.setFullName((prevName) => {
      return {
        ...prevName,
        [name]: value
      };
    });

    //params.setFullname(event.target.value);
  }

  return (
    <form className="form">
      <FormInput
        type="text"
        name="fname"
        placeholder="Username"
        onchange={getfullname}
      />
      <FormInput
        type="text"
        name="lname"
        placeholder="Lastname"
        onchange={getfullname}
      />
    </form>
  );
}

export default Form;

---------------------  App Page -----------------------
  
  import React, { useState } from "react";
import Form from "./Form";



function App() {
  //setInterval(getTime,1000);

  const [fullName, setFullName] = useState({
    fname: "f",
    lname: "n"
  });

  return (
    <div className="container">
      {isLoggedIn === true ? (
        <h1>Hola {fullName.fname + " " + fullName.lname}</h1>
      ) : (
        <div>
          <h1>Hola {fullName.fname + " " + fullName.lname}</h1>
          <Form setFullName={setFullName} />
        </div>
      )}
      <h1 className="timer">{time}</h1>

      <button className="timer" onClick={getTime}>
        Get Time
      </button>
    </div>
  );
}

export default App;

const array1 = ["elemento 1","elemento 2","elemento 3"];
const array2 = ["elemento 4","elemento 5","elemento 6", ...array1];

console.log(array2);

const fullname = {
  fname: "sarfraz".
  lname: "sheth"
}
const miembros = {
  miembro1: "alguien",
  ...fullname
}

console.log(miembros)
---------------------  App Page --------------------
import React, { useState } from "react";
import Form from "./Form";

function App() {
  const [fullName, setFullName] = useState({
    fname: "f",
    lname: "n"
  });

  return (
    <div className="container">
        <div>
          <h1>Hola {fullName.fname + " " + fullName.lname}</h1>
          <Form setFullName={setFullName} />
        </div>
    </div>
  );
}

export default App;


---------------------  Form Page --------------------

import React, { useState } from "react";
import FormInput from "./FormInputs";

function Form(params) {
  
  function getfullname(event) {
    const newValue = event.target.value;
    const inputName = event.target.name;


    params.setFullName((prevName) => {
      if (inputName === "fname") {
        return { fname: newValue, lname: prevName.fname };
      } else if (inputName === "lname") {
        return { fname: prevName.lname, lname: newValue };
      }
    });
    // --------- laternative by using desturcturing code
      function getfullname(event) {
    	const { name, value } = event.target;
    	params.setFullName((prevName) => {
      	if (name === "fname") {
        	return { fname: value, lname: prevName.fname };
      	} else if (name === "lname") {
        	return { fname: prevName.lname, lname: value };
     	 }
    	});

    //params.setFullname(event.target.value);
  }
    
    
    //-------------- final of destructuring code

    //params.setFullname(event.target.value);
  }

  return (
    <form className="form">
      <FormInput
        type="text"
        name="fname"
        placeholder="Username"
        onchange={getfullname}
      />
      <FormInput
        type="text"
        name="lname"
        placeholder="Lastname"
        onchange={getfullname}
      />
      <FormInput type="password" placeholder="Password" />
    </form>
  );
}

export default Form;

----------------- app pages ---------------------------
  import React, { useState } from "react";
import Form from "./Form";

var isLoggedIn = false;

const NEWDATE = new Date();
const nowDate = NEWDATE.toLocaleTimeString();

function App() {
  //setInterval(getTime,1000);

  const [time, nextTime] = useState(nowDate);

  function getTime() {
    console.log("clicked");
    console.log(new Date().toLocaleTimeString());
    return nextTime(new Date().toLocaleTimeString());
  }
  const [fname, setfname] = useState(" ");
  const [lname, setlname] = useState(" ");

  return (
    <div className="container">
      {isLoggedIn === true ? (
        <h1>Hola {fname + " " + lname}</h1>
      ) : (
        <div>
          <h1>Hola {fname + " " + lname}</h1>
          <Form fname={setfname} lname={setlname} />
        </div>
      )}
      <h1 className="timer">{time}</h1>

      <button className="timer" onClick={getTime}>
        Get Time
      </button>
    </div>
  );
}

export default App;

  import React, { useState } from "react";
import FormInput from "./FormInputs";

function Form(params) {
  const [conditionButton, setCondition] = useState(false);

  function getStateOver() {
    setCondition(true);
  }
  function getStateOut() {
    setCondition(false);
  }
  function getfname(event) {
    params.fname(event.target.value);
  }
  function getlname(event) {
    params.lname(event.target.value);
  }

  return (
    <form className="form">
      <FormInput type="text" placeholder="Username" onchange={getfname} />
      <FormInput type="text" placeholder="Lastname" onchange={getlname} />
      <FormInput type="password" placeholder="Password" />
      <button
        type="submit"
        style={
          conditionButton ? { background: "black" } : { background: "white" }
        }
        onMouseOver={getStateOver}
        onMouseOut={getStateOut}
        onClick={getfname}
      >
        Login
      </button>
    </form>
  );
}

export default Form;

  
  
----------------- form pages ---------------------------
<html>
  <head>
    <title>My Extension Popup</title>
  </head>
  <body>
    <div id="popup-root"></div>
    <script src="popup.js"></script>
  </body>
</html>
"""
Problem Description
Given a number N, you have to find the largest Fibonacci number which is less than N.

Input Format
First line contains an integer T - Number of test cases.

Next T lines each have a given number N

Output Format
Print the answer for each test case in a separate line.

Sample Input 1
2

6

13

Sample Output 1
5

8

Explanation 1
In the first test case the largest Fibonacci number less than 6 is 5.

In the second test case the largest Fibonacci number less than 13 is 8 (the next Fibonacci number after 8 is 13 which is equal to the number N i.e. 13)

Constraints
T <= 10^4

0 < N <= 10^9
"""

Please help me to debug the below code based on details given above and return the updated full version of code.

"""
'use strict';

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(string => {
        return string.replace(/\s+/g, " ").trim();
    });
    main();
});

function readLine() {
    return inputString[currentLine++];
}

function readIntArr() {
    let str = readLine();
    str = str.split(" ");
    let arr = [];
    for ( let i = 0; i < str.length; i++ ) {
        arr.push(parseInt(str[i], 10));
    }
    return arr;
}

function print(x) {
    process.stdout.write(x + "");
}

function largestFibonacciNumber(n) {
    let a = 0;
    let b = 1;
    while (b <= n)
    {
        a = b;
        b = a + b;
    }
    return a;
}

function main() {
    let t=parseInt(readLine(),10);
    while(t--){
    let n=parseInt(readLine(),10)

    let result=largestFibonacciNumber(n);
    console.log(result);
    }
}
"""
-------------- APP Page ----------------------
import React, { useState } from "react";
import Form from "./Form";

var isLoggedIn = false;

const NEWDATE = new Date();
const nowDate = NEWDATE.toLocaleTimeString();

function App() {
  //setInterval(getTime,1000);

  const [time, nextTime] = useState(nowDate);

  function getTime() {
    console.log("clicked");
    console.log(new Date().toLocaleTimeString());
    return nextTime(new Date().toLocaleTimeString());
  }
  const [heading, setHeading] = useState("Hola mundo heading");



  return (
    <div className="container">
      {isLoggedIn === true ? (
        <h1>{heading}</h1>
      ) : (
        <div>
          <h1>{heading}</h1>
          <Form heading={heading} setHeading={setHeading}/>
        </div>
      )}
      <h1 className="timer">{time}</h1>

      <button className="timer" onClick={getTime}>
        Get Time
      </button>
    </div>
  );
}

export default App;


----------------- Form Page --------------------------

import React, { useState } from "react";
import FormInput from "./FormInputs";

function Form(params) {
  const [name, setName] = useState(params.heading);

  console.log(params.heading);
  console.log(name);

  const [conditionButton, setCondition] = useState(false);

  function getStateOver() {
    setCondition(true);
  }
  function getStateOut() {
    setCondition(false);
  }
  function getHeading(event) {
    setName(event.target.value);
    params.setHeading(event.target.value);
  }

  return (
    <form className="form">
      <FormInput type="text" placeholder="Username" onchange={getHeading} />
      <FormInput type="password" placeholder="Password" />
      <button
        type="submit"
        style={
          conditionButton ? { background: "black" } : { background: "white" }
        }
        onMouseOver={getStateOver}
        onMouseOut={getStateOut}
        onClick={getHeading}
      >
        Login
      </button>
    </form>
  );
}

export default Form;



-------------------------- Input Page -------------------------------
  
  
  import React, { useState } from "react";

function FormInput(params) {
  const [name, setName] = useState("Input Value");
  
 // function onChangeEvent(event) {
    //console.log(element.target.value);
   // console.log(event.target.placeholder);
   // console.log(event.target.type);
  //  setName(event.target.value);
  //}

  return (
    <div>
      <input
        type={params.type}
        placeholder={params.placeholder}
        onChange={params.onchange}
      />
      {name}
    </div>
  );
}

export default FormInput;
import React, { useState } from "react";

function FormInput(params) {
  const [name, setName] = useState("Input Value");
  function onChangeEvent(element) {
    //console.log(element.target.value);
    console.log(element.target.placeholder);
    console.log(element.target.type);
    setName(element.target.value);
  }

  return (
    <div>
      <input
        type={params.type}
        placeholder={params.placeholder}
        onChange={onChangeEvent}
      />
      {name}
    </div>
  );
}

export default FormInput;
import React, { useState } from "react";
import FormInput from "./FormInputs";

function Form() {
  const [conditionButton, setCondition] = useState(false);

  function getStateOver() {
    setCondition(true);
  }
  function getStateOut() {
    setCondition(false);
  }

  return (
    <form className="form">
      <FormInput type="text" placeholder="Username" />
      <FormInput type="password" placeholder="Password" />
      <button
        type="submit"
        style={
          conditionButton ? { background: "black" } : { background: "white" }
        }
        onMouseOver={getStateOver}
        onMouseOut={getStateOut}
      >
        Login
      </button>
    </form>
  );
}

export default Form;
const cars = [
  {
    model: "Honda Civic",
    coloursByPopularity: ["black", "silver"],
    speedStats: {
      topSpeed: 140,
      zeroToSixty: 8.5
    }
  },
  {
    model: "Tesla Model 3",
    coloursByPopularity: ["red", "white"],
    speedStats: {
      topSpeed: 150,
      zeroToSixty: 3.2
    }
  }
];

export default cars;


------- App Page --------------


import React from "react";
import ReactDOM from "react-dom";
import cars from "./practice";

const [honda, tesla] = cars;

const {speedStats: { topSpeed: hondaTopSpeed }} = honda;
const {speedStats: { topSpeed: teslaTopSpeed }} = tesla;

const {coloursByPopularity: [hondaTopColour]} = honda; // access to item object and set variable name to the item of the nested object.
const {coloursByPopularity: [teslaTopColour]} = tesla;

ReactDOM.render(
  <table>
    <tr>
      <th>Brand</th>
      <th>Top Speed</th>
      <th>Top Colour</th>
    </tr>
    <tr>
      <td>{tesla.model}</td>
      <td>{teslaTopSpeed}</td>
      <td>{teslaTopColour}</td>
    </tr>
    <tr>
      <td>{honda.model}</td>
      <td>{hondaTopSpeed}</td>
      <td>{hondaTopColour}</td>
    </tr>
  </table>,
  document.getElementById("root")
);
const animals = [
  { name: "cat", sound: "meow" },
  { name: "dog", sound: "woof" }
];

function useAnimal(animal) {
  return [animal.name, function() {
      console.log(animal.sound);
    }
  ];
}

export default animals;
export { useAnimal };


------- App Page ------------
mport React from "react";
import ReactDOM from "react-dom";
import animals, { useAnimal } from "./data";

const [catName, dogName] = animals;

const { name, sound } = catName;

console.log(useAnimal(catName));

const [animal, makeSound] = useAnimal(catName);

console.log(makeSound());
console.log(makeSound());
makeSound();
const animals = [
  { name: "cat", sound: "meow", foodRequierements: {
    food: 2,
    water: 3
  } },
  { name: "dog", sound: "woof" }
];

const [catName, dogName] = animals // is taking the animal array and assign a variable name for each item

const {name, sound} = catName // is going deeper and is taking the value of the name key of the first item of the array which is catName NOTE: is importante that the varibale name must be equal to the key names of the array.

const {name: catName, sound: catSound} = catName // rename the keys to be used individually of each item

const {name = "Fluffy", sound = "Purr"} = catName // define a default value incase the value is null or empty

const {name, sound, foodRequierements} = catName // get the keys of the object. but bring the foodRequierements as object, to acces its value you will need to use dot . and call the property

const {name, sound, foodRequierements: {food, water} } = catName // to call the key of the nested object this is the bes method

console.log(sound)
import React, { useState } from "react";
var ReactDOM = require("react-dom");

import Form from "./Form";

var isLoggedIn = false;

const NEWDATE = new Date();
const nowDate = NEWDATE.toLocaleTimeString();



function App() {

  setInterval(getTime,1000);
  
  const [time, nextTime] = useState(nowDate);

  function getTime() {
    console.log("clicked");
    console.log(new Date().toLocaleTimeString())
    return nextTime(new Date().toLocaleTimeString());
  }

  return (
    <div className="container">
      {isLoggedIn === true ? <h1>Hello Men</h1> : <Form />}
      <h1 className="timer">{time}</h1>
      <button className="timer" onClick={getTime}>
        Get Time
      </button>
    </div>
  );
}

export default App;

"""
<main className="main-container">
      <section className="image-section">
        <div className="image-container">
          <img
            src={WelcomeImageUserOnBoarding}
            alt="Welcome User On Boarding Image"
            sizes=""
          />
          <div className="image-overlay">
            <h2 className="image-title">Welcome</h2>
            <p className="image-content">The DIFC Courts is an independent common law judiciary based in the Dubai International Financial Centre (DIFC) with jurisdiction governing civil and commercial disputes.</p>
          </div>
        </div>
      </section>
      <section className="registration-section">
        <Typography className="question" sx={{ mt: 2, mb: 1 }}>
          Register Now
        </Typography>
        <Typography className="question-helper">
          Enter Below Details to Continue
        </Typography>
        <div className="button-wrapper">
          <button
            type="button"
          >
            <img
              src={FingerPrintIcon}
              className="finger-print-icon"
              alt="Finger Print Icon"
              sizes=""
            />
            Signup with UAE Pass

          </button>
        </div>
        <Typography
          className="question-helper sub-text"
          sx={{ mt: 3 }}
        >
          Or Enter Details Below
        </Typography>
        <form className="form mt-3">
          <div className="row form-row mb-4">
            {/* FirstName Col */}
            <div className="col-md-6">
              <label
                htmlFor="firstname"
                className="form-label w-100 firstname-label"
              >
                FirstName*
              </label>
              <input
                type="text"
                className="form-control firstname-input"
                id="firstname"
                placeholder="John"
              />
            </div>
            {/* LastName Col */}
            <div className="col-md-6">
              <label
                htmlFor="lastname"
                className="form-label w-100 lastname-label"
              >
                LastName*
              </label>
              <input
                type="text"
                className="form-control lastname-input"
                id="lastname"
                placeholder="Doe"
              />
            </div>
          </div>
          <div className="row form-row mb-4">
            {/* gender selection buttons */}
            <div className="col-md-6">
              <label
                htmlFor="gender"
                className="form-label w-100 gender-label"
              >
                Gender
              </label>
              <OptionButtons />
            </div>
            {/* Date of Birth Col */}
            <div className="col-md-6">
              <label
                htmlFor="dob"
                className="form-label w-100 dob-label"
              >
                Date of Birth*
              </label>
              <DatePicker
                onChange={handleDatePicker}
                value={dateOfBirth}
                renderInput={(params: any) => (
                  <TextField
                    {...params}
                    inputProps={{
                      ...params.inputProps,
                      placeholder: 'Select Date of Birth',
                    }}
                    // {...register('dateOfBirth', {
                    //   required: true,
                    // })}
                    className="date-picker date-picker-input"
                  />
                )}
                className="date-picker-field"
              />
            </div>
          </div>
          <div className="row form-row mb-2">
            {/* Email Col */}
            <div className="col-md-6">
              <label
                htmlFor="email"
                className="form-label w-100 email-label"
              >
                Primary Email*
              </label>
              <input
                type="email"
                className="form-control email-input"
                id="email"
                placeholder="abc@babc.com"
              />
            </div>
            {/* Mobile Number Col */}
            <div className="col-md-6">
              <label
                htmlFor="mobile"
                className="form-label w-100 mobile-label"
              >
                Primary Mobile Number*
              </label>
              <input
                type="text"
                className="form-control mobile-input"
                id="mobile"
                placeholder="+971 50 123 4567"
              />
            </div>
          </div>
          <div className="row form-row mb-4">
            {/* Secondary Email Col */}
            <div className="col-md-6">
              <div className="secondary-email">
                <span>
                  Add Secondary Email
                </span>
                {/* increase the size of below AiOutlinePlusCircle icon */}
                <AiOutlinePlusCircle
                  className="secondary-email-icon"
                  // increase the size
                  size={30}
                />
              </div>
            </div>
            {/* Secondary Mobile Number Col */}
            <div className="col-md-6">
              <div className="secondary-mobile">
                <span>
                  Add Secondary Mobile
                </span>
                <AiOutlinePlusCircle
                  className="secondary-mobile-icon"
                  // increase the size
                  size={30}
                />
              </div>
            </div>
          </div>

          {/* Select Services from dropdown list */}
          <div className="row form-row mb-4">
            <div className="col-md-12">
              <label
                htmlFor="services"
                className="form-label w-100 services-label"
              >
                How did you know about this service?
              </label>
              {/* add autocomplete to select */}
              <Autocomplete
                disablePortal
                id="combo-box-demo"
                options={services}
                isOptionEqualToValue={(option, value) => option.label === value.label}
                renderInput={(params) => (
                  <TextField
                    {...params}
                    placeholder="Social Media - LinkedIn / Twitter / Instagram"
                    className="services-input"
                  />
                )}
              />
            </div>
          </div>

          {/* add new row */}
          <div className="row form-row mb-4">
            <div className="col-md-4">
              {/* add a next step button that follows default styles */}
              <button
                type="button"
                className="next-step-button"
              >
                Next
              </button>
            </div>
          </div>

          {/* add new row below */}
          <div className="row form-row mb-4">
            <div className="col-md-6">
              {/* add a text 'Already have an account? Login ' */}
              <span className="already-have-account">
                Already have an account?
              </span>
              {/* wrap login by Link component */}
              <Link
                to="/accounts/login"
                className="login-link"
              >
                Login
              </Link>

            </div>
          </div>

        </form>
      </section>
    </main>
"""

SASS
--------
"""
/* stylelint-disable */ 
.main-container {
    display: flex;
    width: 100%;
    justify-content: center;
    margin-top: 112px;
    background: #FFFFFF;
    border-radius: 20px;
}

.image-section {
    position: relative;
    flex: 1;
  }
  
  .image-section img {
    width: 100%; /* Set the desired width */
    height: auto; /* Maintain aspect ratio */
  }

  .registration-section {
    flex: 1;
    padding: 20px;
    margin: 30px;
    box-sizing: border-box; 
    overflow: hidden; 
  }
  
  .image-container {
    position: relative;
    display: inline-block;
  }
  
  .image-overlay {
    position: absolute;
    bottom: 0;
    left: 0;
    padding: 20px;
    margin-bottom: 130px;
  }
  
  .image-title {
    font-family: 'Basis Grotesque Arabic Pro';
    font-style: normal;
    font-weight: 700;
    font-size: 70px;
    line-height: 64px;
    letter-spacing: -0.04em;
    text-transform: capitalize;
    color: #FFFFFF;
  }
  
  .image-content {
    color: #FFFFFF;
    text-align: left;
    font-family: 'Basis Grotesque Arabic Pro';
    font-style: normal;
    font-weight: 500;
    font-size: 16px;
    line-height: 19px;
  }
  
  .question {
    font-family: "Basis Grotesque Arabic Pro" !important;
    font-style: normal !important;
    font-weight: 500 !important;
    font-size: 40px !important;
    line-height: 45px !important;
    letter-spacing: -0.04em !important;
    color: #1b202d !important;
  }
  
.question-helper {
    font-family: "Basis Grotesque Arabic Pro" !important;
    font-style: normal !important;
    font-weight: 300 !important;
    font-size: 14px !important;
    line-height: 18px !important;
    color: #1b202d !important;
}

.button-wrapper {
    margin-top: 40px;
  }
  
  .button-wrapper button {
    width: 100%;
    background: #000000;
    border-radius: 5px;
    font-family: 'Inter';
    font-style: normal;
    font-weight: 600;
    font-size: 14px;
    line-height: 17px;
    color: #F5F5F5;
    padding: 16px 50px;
  }

  .finger-print-icon {
    margin-right: 14px;
  }
  
  .firstname-label,
  .lastname-label,
  .gender-label,
  .email-label,
  .mobile-label,
  .services-label
  {
    font-family: 'Basis Grotesque Arabic Pro';
    font-style: 'normal';
    font-weight: 500;
    font-size: 0.75rem;
    line-height: 18px;
    color: #1b202d;
    margin-top: 0px !important;
  }

  .firstname-input,
  .lastname-input,
  .email-input,
  .mobile-input,
  .services-input
    {
    font-family: 'Basis Grotesque Arabic Pro' !important;
    font-style: 'normal' !important;
    font-weight: 500 !important;
    font-size: 0.75rem !important;
    line-height: 18px !important;
    color: #1b202d !important;
    height: 2.5rem !important;
  }

  .date-picker-field .date-picker-input {
    font-family: 'Basis Grotesque Arabic Pro';
    font-style: normal;
    font-weight: 500;
    font-size: 0.75rem;
    line-height: 18px;
  }

  // right align secondary-email and secondary-mobile
  .secondary-email,
  .secondary-mobile {
    text-align: right;
  }

  // add left spacing between secondary-email and secondary-email-icon
  .secondary-email-icon {
    margin-left: 10px;
  }

  // add left spacing between secondary-mobile and secondary-mobile-icon
  .secondary-mobile-icon {
    margin-left: 10px;
  }

  // add background: #023979;
// border-radius: 10px; to next-step-button
.next-step-button {
  background: #023979;
  border-radius: 10px;
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-size: 14px;
  line-height: 17px;
  color: #F5F5F5;
  padding: 16px 50px;
  border: none;
}

// add below style to already-have-account
.already-have-account {
  font-family: 'Basis Grotesque Arabic Pro';
  font-style: normal;
  font-weight: 500;
  font-size: 16px;
  line-height: 16px;
  color: #494A53;
}

// add below style to login-text
.login-link {
  font-family: 'Basis Grotesque Arabic Pro';
  font-style: normal;
  font-weight: 500;
  font-size: 16px;
  line-height: 16px;
  color: #1B202D;
  margin-left: 5px;
  text-decoration: underline;
  text-underline-offset: 4px;
}

"""


You are a CSS expert.

Client wanrs to Auto Update the WelcomeImageUserOnBoarding image height when main container height increments. image height should be in sync
with the height change of main container div element.
So when main container height updates image height also auto update with same. Thus it wont leave any spacing at bottom.
I have given the jsx and sass file for your reference.
If you have any questions you can ask.


Solutions:

To achieve the desired effect of the `WelcomeImageUserOnBoarding` image height being in sync with the height change of the `main-container` div element, you can use CSS to make the image responsive and adjust its height accordingly.

Here's an updated version of the SASS code with modifications to make the image height responsive:

```sass
.main-container {
  display: flex;
  width: 100%;
  justify-content: center;
  margin-top: 112px;
  background: #FFFFFF;
  border-radius: 20px;
  position: relative; /* Add position relative to main-container */
}

.image-section {
  position: relative;
  flex: 1;
}

.image-section img {
  width: 100%;
  height: 100%; /* Set the image height to 100% of the parent container */
  object-fit: cover; /* Maintain aspect ratio and cover the entire container */
}

.registration-section {
  flex: 1;
  padding: 20px;
  margin: 30px;
  box-sizing: border-box;
  overflow: hidden;
}

.image-container {
  position: relative;
  display: inline-block;
  width: 100%; /* Set the image container width to 100% */
  height: 100%; /* Set the image container height to 100% */
}

.image-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  padding: 20px;
  margin-bottom: 130px;
}

/* Rest of the styles remain the same */
```

In this code, I've added `position: relative` to the `main-container` to establish a positioning context for its child elements. Then, I've modified the styles for the `image-section`, `image-container`, and `image-section img` to make the image responsive. By setting the image height to `100%` of the parent container and using `object-fit: cover`, the image will automatically adjust its height to match the height of the `main-container`.

Please ensure you include this updated SASS code in your project and recompile it to generate the CSS styles.
  <Link
                to="/accounts/login"
                className="login-link"
              >
                Login
              </Link>


.login-link {
  font-family: 'Basis Grotesque Arabic Pro';
  font-style: normal;
  font-weight: 500;
  font-size: 16px;
  line-height: 16px;
  /* identical to box height */
  color: #1B202D;
  // assign left margin to login-text
  margin-left: 5px;
  // add an underline to login-link
  text-decoration: underline;
}

You are a front end developer
I have applied underline to login link. but letter 'g'  of login text has no underline. i dont how to resolve this. You can apply any styling to put the underline for whole text.

Solution:

It sounds like the g in the word "login" is not being underlined along with the rest of the text, which can happen if the text is not aligned properly with the underline.

To fix this issue, you can try adding the text-underline-offset property to the .login-link class, with a value of 3px or 4px. This property will adjust the position of the underline so that it lines up correctly with the text.



.login-link {
  font-family: 'Basis Grotesque Arabic Pro';
  font-style: normal;
  font-weight: 500;
  font-size: 16px;
  line-height: 16px;
  color: #1B202D;
  margin-left: 5px;
  text-decoration: underline;
  text-underline-offset: 3px; /* Adjust value as needed */
}


With this change, the underline should now cover the entire text, including the g. You can adjust the value of text-underline-offset as needed to ensure that the underline lines up properly with the text.
import React, {useState} from "react";
import Form from "./Form";
var isLoggedIn = false;

// the function use state is compose by a value and function that will update the value
// in the below code it is used the destructuring concept which is assign a name to eache array value so you can call the exact value by calling just the name example 
// const [name1, name2] = [value1, value2]
/// when you call or consle.log(name1) will show you the value1 as result
function App() {
  const [myCount, nextState] = useState(0) // useState need to be in a function
  
  function increase(){
    nextState(myCount + 1)
  }
  function decrease(){
    nextState(myCount - 1)
  }
  return <div className="container">
  {isLoggedIn === true ? <h1>Hello Men</h1> : <Form />}
  <br />
  <h1>{myCount}</h1>

  <button onClick={increase}>+</button>
  <button onClick={decrease}>-</button>

  </div>;
}

export default App;
import React from "react";
import Form from "./Form";
var isLoggedIn = false;



function App() {
return <div className="container">
{isLoggedIn === true ? <h1>Hello Men</h1> : <Form />} // one option
{isLoggedIn ? <h1>Hello Men</h1> : <Form />}  // second option due the condition is already a boolean
{isLoggedIn ? <h1>Hello Men</h1> : null} // // third option you can set the false as nothing
{isLoggedIn && <h1>Hello Men</h1>  } // // fourth option exact as above null set but the condition is a double check expresion. Condition && Expresion => False && omit or True && render the expresion
</div>;
}
// alternative method of using this is by applying styles
var condition = true;
const customStyle = {color: "red"};
<p style={condition ? customStyle : nill} show the color if true or not </P

export default App;
JSX
"""
<Modal show={showModal} onHide={handleModalClose} dialogClassName="modal-dialog-centered" size="lg">
      <Modal.Header closeButton>
        <Modal.Title className="modal-title">Choose Method</Modal.Title>
      </Modal.Header>
      <Modal.Body>
        <div>
          <div className="modal-choose-method-subtitle mb-3">
            List your Substitute Beneficiaries below and click on Add Substitute to add them to your List
          </div>
        </div>
        <div className="d-flex flex-row">
          <div
            className={`card-container-draft-will d-flex flex-column align-items-center ${activeCard === 'draftWill' ? 'active' : ''}`}
            onClick={() => handleCardClick('draftWill')}
          >
            {activeCard === 'draftWill' && (
            <div
              className="check-icon"
            >
              <img src={FillCheckRoundIcon} alt="Fill Check Icon" />
            </div>
            )}
            <div className="choose-method-draft-will-icon-container" style={{ marginBottom: '20px', marginTop: '20px' }}>
              <img src={DraftWillIcon} alt="Will Copy Upload Icon" />
            </div>
            <div className="text-center choose-method-draft-will-title" style={{ marginTop: '10px', marginBottom: '10px' }}>
              Draft Will Using the System
            </div>
            <div className="text-center choose-method-draft-will-desc" style={{ marginTop: '10px', marginBottom: '10px' }}>
              It is a long established fact that a reader will be distracted by the readable content.
            </div>
          </div>
          <div
            className={`card-container-will-copy-upload d-flex flex-column align-items-center ${activeCard === 'willCopyUpload' ? 'active' : ''}`}
            style={{ width: '50%', marginRight: '10px', position: 'relative' }}
            onClick={() => handleCardClick('willCopyUpload')}
          >
            {activeCard === 'willCopyUpload' && (
            <div
              className="check-icon"
              style={{
                position: 'absolute', top: '10px', left: '10px', margin: '10px',
              }}
            >
              <img src={FillCheckRoundIcon} alt="Fill Check Icon" />
            </div>
            )}
            <div className="choose-method-will-upload-icon-container">
              <img src={WillCopyUploadIcon} alt="Will Copy Upload Icon" />
            </div>
            <div className="text-center choose-method-will-upload-title" style={{ marginTop: '10px', marginBottom: '10px' }}>
              Upload the Copy of Will
            </div>
            <div className="text-center choose-method-will-upload-desc" style={{ marginTop: '10px', marginBottom: '10px' }}>
              It is a long established fact that a reader will be distracted by the readable content.
            </div>
          </div>
        </div>
      </Modal.Body>
      <Modal.Footer className="justify-content-center">
        {
          activeCard && isAnyWillCardSelected && (
            <Link
              to={`/wills/${selectedWillCard.willTypeName.split(' ').join('-')}/${selectedWillCard.willTypeGUID}`}
              state={selectedWillCard.willTypeName}
            >
              <Button
                variant="primary"
              >
                Continue
              </Button>
            </Link>
          )
        }
      </Modal.Footer>
    </Modal>
    
   """
   
   css
   ------
   """
   /* stylelint-disable */ 

.card-container-draft-will.active, .card-container-will-copy-upload.active  {
    background-color: #E4FDFF;
    border-radius: 20px;
    padding: 28px;
}
.card-container-draft-will {
    width: 50%;
    margin-right: 10px;
    position: relative;
}
.modal-choose-method-subtitle {
    font-family: 'Basis Grotesque Arabic Pro';
    font-style: normal;
    font-weight: 300;
    font-size: 0.875rem;
    line-height: 18px;
    color: #1B202D;
}

.modal-title {
    font-family: 'Basis Grotesque Arabic Pro';
    font-style: normal;
    font-weight: 500;
    font-size: 2.5rem;
    line-height: 45px;
    letter-spacing: -0.04em;
    color: #1B202D;
}

.btn-close {
    color: #494A53 !important;
    font-size: 10px !important;
    position: absolute !important;
    top: 20px !important;
    right: 20px !important;
}

.btn-close:before {
    background-color: #f1f1f1 !important;
    border-radius: 50px !important;
  }

  .check-icon {
    position: absolute;
    top: 10px;
    left: 10px;
    margin: 10px;
  }
  
  .choose-method-draft-will-icon-container {
    margin-bottom: 20px;
    margin-top: 20px;
  }
  
  .choose-method-will-upload-title {
    margin-top: 10px;
    margin-bottom: 10px;
    text-align: center;
  }
  """
  
  You are expert in css to sass conversion.
  Client want the above css to be converted in to sass format.
  it should follow sass styling conventions.
  you have to convert it as per the requirement of client.
  for your reference, i have given the respective JSX content for the above styles.
  you can check the css selectors and make sure current styles wont break.
  Return the converted sass 
import React from "react";

var isLoggedIn = true;

function renderconditionally (){
  if (isLoggedIn === true){
    return <h1>Hello Men </h1>
  }else{
    return(<form className="form">
        <input type="text" placeholder="Username" />
        <input type="password" placeholder="Password" />
        <button type="submit">Login</button>
      </form>)
  }
}

function App() {
  return (
    <div className="container">
      {renderconditionally()}
    </div>
  );
}

export default App;
// option 1
const newVariable = (input1,input2) => {
  return input1 * input2;
}

// option 2
const newVariable = input1=> input1 * 2;

// example
var number = [1,2,4,50,62,45]
const newNumbers = number.map(input => input*2)
console.log(newNumbers)
import emojipedia from "./emojipedia";

const newEmojipedia = emojipedia.map(function(emojiEntry) {
  return emojiEntry.meaning.substring(0, 100);
});

console.log(newEmojipedia);
var numbers = [12,15,12,13,50,46,50,25,1,3,7,64,125,25]

------------------ map formula --------------------------
//Map -Create a new array by doing something with each item in an array.
// function namedouble(varibale) {
//   return varibale * 2;
// }
// const newNumbers = numbers.map(namedouble);

const newNumbers = numbers.map(function (varibale) {
  return varibale * 2;
}) // anonymus function because it does not have any name

// var newNumbers = [];
// numbers.forEach(function (varibale) {
//   newNumbers.push(varibale * 2);
// });
console.log(newNumbers);
------------------ filter formula --------------------------
/Filter - Create a new array by keeping the items that return true.

const newNumbers = numbers.filter(function(num) {
  return num < 10;
});

// var newNumbers = [];
// numbers.forEach(function(num) {
//   if (num < 10) {
//     newNumbers.push(num);
//   }
// })
console.log(newNumbers);
------------------ reduce formula --------------------------
//Reduce - Accumulate a value by doing something to each item in an array.

var newNumber = numbers.reduce(function (accumulator, currentNumber) {
  console.log("accumulator = " + accumulator);
  console.log("currentNumber = " + currentNumber);
  return accumulator + currentNumber;
 });

// var newNumber = 0;
// numbers.forEach(function (currentNumber) {
//   newNumber += currentNumber
// })
------------------ find formula --------------------------
//Find - find the first item that matches from an array.

const newNumber = numbers.find(function (num) {
  return num > 10;
 })

console.log(newNumber);
------------------ findindex formula --------------------------
//FindIndex - find the index of the first item that matches.

const newNumber = numbers.findIndex(function (num) {
  return num > 10;
 })

console.log(newNumber);
import React from "react";
import ReactDom from "react-dom";
import Header from "./Header"
import Footer from "./Footer"
import Note from "./Note"
import NoteList from "../noteArray"

function createNote(note){
    return (<Note
    id = {note.id}
    key = {note.id} // it is mandatory to use it
    title = {note.title}
    detail = {note.detail}
    img = {note.img}
     />);
}

function App(){
    return (
    <div> 
    <Header />
    <Note
    title = "The first note"
    detail = "note Detail"
    img = {NoteList[0].img}
     />
     {NoteList.map(createNote)}
   

    <Footer />
    </div>
    )
}
--------------------- App page -----------------------
  
  function App(){
    return (
    <div>
    <Header />
    <Note
    title = "The first note"
    detail = "note Detail"
    img = {NoteList[0].img}
     />
    <Note
    title = {NoteList[1].title}
    detail = {NoteList[1].detail}
    img = {NoteList[1].img}
     />
    <Note
    title = {NoteList[2].title}
    detail = {NoteList[2].detail}
    img = {NoteList[2].img}
     />
    <Footer />
    </div>
    )
}

 ----------------- Note page ----------------------
function Note(props){
    return (
    <div className="note">
        <Detail info={props.title}/>
        <Detail info={props.detail}/>
        <Avatar img={props.img} />
    </div>
    )
}

--------------------- Avatar Page ----------------
function Avatar(props) {
  return <img className="circle-img" src={props.img} alt="avatar_img" />;
}
--------------------Details page -------------------
function Detail(props) {
  return <p>{props.info}</p>;
}

  
import { useDispatch, useSelector } from 'react-redux';
import fetchWillsList, { willsListSelector } from '@redux/slices/wills-list';


  const { results } = useSelector(willsListSelector);

  const dispatch = useDispatch();

  React.useEffect(() => {
    dispatch<any>(fetchWillsList());
  }, []);


  const handleCardClick = (cardName: string) => {
    let willTypeName: string = '';
    let willTypeGUID: string = '';
    setActiveCard(cardName);
    results.forEach((will: any) => {
      if (cardName === 'draftWill' && will.willTypeName === 'Templated Full Will') {
        willTypeName = will.willTypeName;
        willTypeGUID = will.willTypeGUID;
      } else if (cardName === 'willCopyUpload' && will.willTypeName === 'Full Will') {
        willTypeName = will.willTypeName;
        willTypeGUID = will.willTypeGUID;
      }
    });

    setSelectedWillCard({ willTypeName, willTypeGUID });
  };
--------------- APP page ----------------
// custo tag by the programmer in React -- are not html tag
    <Note
    title = "The first note"
    detail = "note Detail"
     />
    <Note
    title = "The second note"
    detail = "note Detail"
     />

---------------- Note Page html page ------------


function Note(props){
    return (
    <div className="note">
        <h1>{props.title}</h1>
        <p>{props.detail}</p>
    </div>
    )
}

      
Choosing the proper AI Crypto trading bot can be a game-changer, assisting to automate trading in crypto, manage portfolios, set stop losses, and much more., They learn from new information and data, can adjust trading techniques, and detect patterns that may not be obvious to humans. These AI Crypto trading bots make trading transactions quite easier and more efficient for people by analyzing large amounts of data and adapting to market changes. Interested to start your own AI-based Crypto trading bot, then maticz can assist you with their enthralling blockchain development solutions. Check out their website and get an instant demo!

> https://maticz.com/ai-crypto-trading-bot
---------------- App page ------------------------------------
import Heading, { SubHeading, SubHeading2 } from "./Heading"
// optional you can use import * as NameYouWant from "./root"
// when using the  when call the function use NameYouWant.NamOfFunction

------------------- Heading Page -------------------------
 function Heading() {
  return (
    <div>
      <h1>This is My Componente Heading</h1>
      <h2 style={customStyle}>{greeting}</h2>
    </div>
  );
}
  function SubHeading() {
  return (
    <ul>
      <li>This is the Subheading 1</li>
    </ul>
  );
}

function SubHeading2() {
  return (
    <ul>
      <li>This is the second Subheading 2</li>
    </ul>
  );
}

export default Heading;
export { SubHeading, SubHeading2 };
-------- Heading.jsx page -------------

import React from "react";
import ReactDOM from "react-dom";

function Heading(){
  return <h1>This is My Componente Heading</h1>
}

export default Heading;

---------  main page ----------

import ReactDOM from "react-dom";
import Heading from "./Heading.jsx"; // is optional the .jsx
import Ulist from "./Ulist";

ReactDOM.render(
  <div>
    <Heading />
    <Ulist />
  </div>,
  document.getElementById("root")
);
var React = require("react");
var ReactDOM = require("react-dom");

const CURRENT_DATE = new Date();
console.log(CURRENT_DATE);
const CURRENT_YEAR = CURRENT_DATE.getFullYear();
const CURRENT_TIME = CURRENT_DATE.getHours();
console.log(CURRENT_TIME);

let greeting;
const greetingColor = {
  color: "Black"
};

if (CURRENT_TIME < 12) {
  greeting = "Good Morning";
  greetingColor.color = "red";
} else if (CURRENT_TIME < 18) {
  greeting = "Good Afternoon";
  greetingColor.color = "green";
} else {
  greeting = "Good Night";
  greetingColor.color = "blue";
}


ReactDOM.render(
  <div>
    <h1 className="heading" style={greetingColor}>
      {greeting}
    </h1>
  </div>,
  document.getElementById("root")
const customStyle = {
  color: "red",
  fontSize: "20px",
  border: "1px solid black"
}  

customStyle.color = "blue";

ReactDOM.render(
  <div>
	<h1 style={customStyle}> inline stly css practice </h1>
// alternative method not recomended
	<h1 style={
      color: "red",
      fontSize: "20px",
      border: "1px solid black"}> 
      inline stly css practice </h1>
  </div>,
  document.getElementById("root"))
var React = require("react");
var ReactDOM = require("react-dom");

const fname = "@Sarfraz";
const lname = "Sheth";

const CURRENT_DATE = new Date();
console.log(CURRENT_DATE);

const CURRENT_YEAR = CURRENT_DATE.getFullYear();
const img =
  "https://imagesvc.meredithcorp.io/v3/mm/image?url=https%3A%2F%2Fpublic-assets.meredithcorp.io%2F8ad90d6a713d7ddf16a2c590fead64ea%2F1681363353410274244D1-FFEA-452C-B5F8-FB7CAF661309.jpeg&q=60&c=sc&orient=true&poi=auto&h=512";

ReactDOM.render(
  <div>
    <h1>Hello World {fname + " " + lname}</h1>
    <p>All indroductory lessons are in this sandbox</p>

    <h1 className="heading" contentEditable="true">
      List Practice
    </h1>
    <ul>
      <li>
        Elemento 1 {fname} {lname}
      </li>
      <li>Elemento 2 {fname}</li>
      <li>Elemento 3</li>
    </ul>
    <p>Copyright {CURRENT_YEAR}</p>

    <h1>Image Practice </h1>
    <img
      className="img-page"
      alt="this test"
      src="https://images.immediate.co.uk/production/volatile/sites/30/2013/05/Puttanesca-fd5810c.jpg?quality=90&webp=true&resize=300,272"
    />
    <br />
    <img alt="this test" className="img-page" src={img} />
  </div>,
  document.getElementById("root")
);
In react-router-dom v6 useHistory() is replaced by useNavigate()

import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
navigate('/home');


"""
 <Link to="/wills/quick-booking">
                    <span className="box-title">
                      Book Quick Appointment
                    </span>
                  </Link>
  """                
                  
You are a experienced react developer.
  
currently when user clicks on above link, moves to `/wills/quick-booking` route. 
what you need to do is to first show a bootstrap modal popup before moving to that route. 
so you have to show a modal popup before moving to above quick booking page.
you have to also create a modal pop using boostrap. 

modal contents were given below:

Heading or title
-------------------
Confirm


Content or Subcontent 
--------------------
Testators may enter minimum information to secure an appointment. 
Full details must be completed 72 hours prior to the booking date to avoid appointment cancellation. 
Registered Will Draftsmen are requested to refrain from using the quick booking option

Two Buttons
---------
Continue Button - When user clicks on this button, it moves to /wills/quick-booking to open quick booing page.
Cancel Button - Close the modal popup and not redirected to above route.


No need to apply any styling as of now. We can do it later on. You have to use boostrap modal.
Sure! I can help you with that. Here's an example of how you can create a Bootstrap modal in React and use it to show a confirmation popup before redirecting to the `/wills/quick-booking` route:

First, make sure you have the Bootstrap CSS and JS files included in your project.

Next, create a new React component called `ConfirmationModal`:

```jsx
import React from 'react';
import { Modal, Button } from 'react-bootstrap';

const ConfirmationModal = ({ show, handleClose, handleContinue }) => {
  return (
    <Modal show={show} onHide={handleClose}>
      <Modal.Header closeButton>
        <Modal.Title>Confirm</Modal.Title>
      </Modal.Header>
      <Modal.Body>
        <p>Testators may enter minimum information to secure an appointment.</p>
        <p>
          Full details must be completed 72 hours prior to the booking date to avoid appointment cancellation.
        </p>
        <p>Registered Will Draftsmen are requested to refrain from using the quick booking option.</p>
      </Modal.Body>
      <Modal.Footer>
        <Button variant="secondary" onClick={handleClose}>
          Cancel
        </Button>
        <Button variant="primary" onClick={handleContinue}>
          Continue
        </Button>
      </Modal.Footer>
    </Modal>
  );
};

export default ConfirmationModal;
```

In your main component where the link is located, you can use the `ConfirmationModal` component and handle its state:

```jsx
import React, { useState } from 'react';
import { Link, useHistory } from 'react-router-dom';
import ConfirmationModal from './ConfirmationModal';

const MainComponent = () => {
  const [showModal, setShowModal] = useState(false);
  const history = useHistory();

  const handleShowModal = () => {
    setShowModal(true);
  };

  const handleCloseModal = () => {
    setShowModal(false);
  };

  const handleContinue = () => {
    handleCloseModal();
    history.push('/wills/quick-booking');
  };

  return (
    <div>
      <Link to="/wills/quick-booking" onClick={handleShowModal}>
        <span className="box-title">Book Quick Appointment</span>
      </Link>
      <ConfirmationModal
        show={showModal}
        handleClose={handleCloseModal}
        handleContinue={handleContinue}
      />
    </div>
  );
};

export default MainComponent;
```

In the above example, the `MainComponent` renders a link with the class name `box-title`, and when clicked, it calls the `handleShowModal` function to show the modal popup. The modal is conditionally rendered based on the `showModal` state.

The `ConfirmationModal` component receives three props: `show` (to determine whether the modal should be displayed), `handleClose` (to close the modal), and `handleContinue` (to handle the continue button click and redirect to the desired route).

When the user clicks "Continue" in the modal, the `handleContinue` function is called, which first closes the modal and then uses the `useHistory` hook from React Router to navigate to the `/wills/quick-booking` route.

Remember to adjust the code and import the necessary dependencies based on your project structure and setup.

I hope this helps! Let me know if you have any further questions.
you have to suggest me a branch name in which i implement UI of confirm modal pop up. branch name should follow convention.


  <Link to="/wills/quick-booking">
                    <span className="box-title">
                      Book Quick Appointment
                    </span>
                  </Link>
                  
                  
                  you are an expert in react development.
                  i have added a link component and set the route. 
                  but when i clikc "Book Quick Appointment". it throws error message like  
                  "No route matches URL \"/wills/quick-booking\""
                  its status is 404 not found.
                  Help me to find and fix solution for the problem.
                  
                  

                  Solutions:
                  
                  1. Make sure that you have a Route component in your app that matches the /wills/quick-booking path. You can do this by adding the following code to your app:

<Route exact path="/wills/quick-booking">
  {/* Insert the component for the quick booking page here */}
</Route>

check routes file in projct directory and update the path.







                  
"""
Problem Description
Given a non-empty array of digits representing a non-negative integer, plus one to the integer and return the same list.

The digits are stored such that the most significant digit is at the head of the list, and each element in the array contain a single digit.

You may assume the integer does not contain any leading zero, except the number 0 itself.

Input format
You will be given a list of integers.

Output format
Return a list of integer +1.

Sample Input 1
1 2 3

Sample Output 1
1 2 4

Explanation 1
The array represents the integer 123.

Sample Input 2
4 3 2 1

Sample Output 2
4 3 2 2
"""

Consider you are an experienced python developer.
Help me to solve the above problem and integrate the code into below code.
Code should follow python naming conventions
Return the updated code.

```py
def plusOne(digits):
if __name__ == '__main__':
    digits = input().split()
    digits = [int(i) for i in digits]
    result = plusOne(digits)
    for i in result:
        print(i,end=' ')
```
import MyReactComponent from '../components/MyReactComponent.jsx';
---
<MyReactComponent />
---
import React from 'react';
const MyReactComponent = () => {
 const handleClick = () => {
 alert('Button clicked!');
 };
return (
 <div>
 <h2>React Component</h2>
 <button onClick={handleClick}>Click me</button>
 </div>
 );
};
export default MyReactComponent;
Code 1:
"""
# TODO: Implement this method
from typing import List


def findElement(n: int, arr: List[int], x: int) -> int:

# NOTE: Please do not modify this function
def main():
    n = int(input().strip())
    arr = list(map(int, input().strip().split(' ')))
    x = int(input().strip())

    xIndex = findElement(n, arr, x)
    print(xIndex)

if __name__=="__main__":
    main()
"""

Code 2:
"""
def find_index(n,arr,x):
    for i in range(n):
        if arr[i]==x:
            return i
    return -1
"""


Consider you are a python devekoper.
Help me to integrate the Code 2 into Code 1.
Return the updated version of code. 
"""
 <Typography

              >
                {moment(dateOfBirth).format('DD/MM/YYYY')}

              </Typography>
"""

Consider you are a jaavscript developer.

I want the dateofBirth to shown as `17 May 1998` format . currenlty it is shown as `17/05/1998`.

I want you to change format i wish to. Here i used moment package you can use the same package.

Please update rhe code and return the udpated one


"""
import React, { useState } from "react";
import "./style.scss";
import Typography from "@mui/material/Typography";
import WitnessTable from "@components/WitnessTable";
import { useForm } from "react-hook-form";
import Autocomplete from "@mui/material/Autocomplete";
import AutocompleteOption from "@mui/joy/AutocompleteOption";
import { DatePicker } from "@mui/x-date-pickers";
import { TextField } from "@mui/material";

// import custom hooks
import useNationalityList from "@utils/hooks/useNationalityList";
import useCountryList from "@utils/hooks/useCountryList";
import useCityList from "@utils/hooks/useCityList";
import useIsdCodesList from "@utils/hooks/useIsdCodesList";
import { useDispatch, useSelector } from "react-redux";

// selectors
import {
  dropDownSelector,
  fetchCityList,
  fetchCountryList,
  fetchNationalityList,
} from "@redux/slices/dropDowns";
import { willsValidatorSelector } from "@redux/slices/willsValidator";
import getGuid from "@utils/Wills/getGuid";
import axios from "axios";
import {
  submitWitnessDetails,
  willWitnessDetailsSelector,
  fetchWitnessList,
  fetchWitnessDetailsByGuid,
} from "@redux/slices/wills-witness-details";

import moment from "moment";

"""
I have the given the imports above. what you have to do is to import them in correct order and it should be easilty readable. organize the imports. please dont change any package name or change into default or named import. just reorder the imports for user readablity.



payload for posting data:

"""
{
  "address": "binto",
  "bookedForProfileGUID": "05fa50b0-a450-437f-ade3-19bb128192a5",
  "city": "Wadi Zinati",
  "countryGUID": "07217663-f131-46b7-876b-8402f7a8312d",
  "dateOfBirth": "2023-06-06T18:30:00.000Z",
  "email": "gfdd@gmail.com",
  "emiratesId": "987978",
  "foreName": "test",
  "isdCode": "+81",
  "isdCodeGUID": "8841f91d-73b4-494c-b794-d8341faf80ab",
  "nationality": "33a784eb-6e88-43d6-8bf7-f41785851f25",
  "passportNo": "7456546",
  "phoneNumber": "76575675",
  "state": "rtfytrytr",
  "surName": "user",
  "zipCode": "654654"
}
"""

Data got while calling fetching:

"""
{
    "Output": {
        "profileguid": "34b4dd38-4c9c-42ee-9391-added811e2ad",
        "surName": "user",
        "foreName": "test",
        "address": "binto",
        "city": "Wadi Zinati",
        "countryName": null,
        "dateOfBirth": "2023-06-06T00:00:00",
        "passportNo": "7456546",
        "emiratesId": "",
        "phoneNumber": "76575675",
        "email": "gfdd@gmail.com",
        "nationality": "83",
        "isdCode": 106,
        "isdCodeGUID": "8841f91d-73b4-494c-b794-d8341faf80ab",
        "zipCode": "654654",
        "countryGUID": "07217663-f131-46b7-876b-8402f7a8312d",
        "state": "rtfytrytr",
        "dob": "2023-6-6",
        "emiratesIdNo": null,
        "serviceGUID": null,
        "bookedForProfileGUID": null
    },
    "status": true,
    "errorCode": "",
    "errorMessage": "",
    "statusCode": "200",
    "statusMessage": "Success",
    "responseDate": "08/Jun/2023 16:24:06",
    "version": "V1"
}

"""

Consider you are API expert.

emiratesId field is posting but when we call get method emiratesId is returned as empty string.
Post api is working. get api is also working i think but emiratedId field is retunred empty string even i inserted the same.

I had given the payload while posting data, also the response i got while fetching below it. 

I want to know what is the reason behind this issue.

Please help me to find is this a problem in the api side.
{
    "Output": {
        "saveStatus": false,
        "editStatus": true,
        "deleteStatus": false,
        "itemGUID": null,
        "isNotFirstGuardianValue": false,
        "errorMessage": null,
        "isAlreadyExists": false,
        "status": false
    },
    "status": true,
    "errorCode": "",
    "errorMessage": "",
    "statusCode": "200",
    "statusMessage": "Success",
    "responseDate": "08/Jun/2023 12:02:32",
    "version": "V1"
}
{
  "address": "dfdfg dgdf",
  "bookedForProfileGUID": "05fa50b0-a450-437f-ade3-19bb128192a5",
  "city": "San Ignacio",
  "countryGUID": "b71f3fa5-a42b-4a0b-a6c3-8d956bb57757",
  "dateOfBirth": "2023-06-06T18:30:00.000Z",
  "email": "jgh@gmail.com",
  "emiratesId": "9897897",
  "foreName": "fgsdfsdf",
  "isdCode": "+591",
  "isdCodeGUID": "4d07418d-1d45-4500-ab49-0682eaae51b7",
  "nationality": "44d7c4c3-9690-4fe8-a733-bb9b1c1240e8",
  "passportNo": "67856876",
  "phoneNumber": "8567567567",
  "profileguid": "9294c7f8-8fb0-4e61-8f02-49db54ba7254",
  "state": "jmjhmh",
  "surName": "sdfsdfs",
  "zipCode": "6756765"
}
{
    "Output": {
        "saveStatus": true,
        "editStatus": false,
        "deleteStatus": false,
        "itemGUID": "bff9b460-cae9-4b1f-8e9b-61b6dc991abc",
        "isNotFirstGuardianValue": false,
        "errorMessage": null,
        "isAlreadyExists": false,
        "status": false
    },
    "status": true,
    "errorCode": "",
    "errorMessage": "",
    "statusCode": "200",
    "statusMessage": "Success",
    "responseDate": "07/Jun/2023 12:31:09",
    "version": "V1"
}
{
    "Output": {
        "profileguid": "4320abce-c414-4c9b-967d-20323748f427",
        "surName": "dfgdf",
        "foreName": "hdf",
        "address": "gdfgdf gdfgdf",
        "city": "Ruyigi",
        "countryName": null,
        "dateOfBirth": "2023-06-06T00:00:00",
        "passportNo": "76575645",
        "emiratesId": "",
        "phoneNumber": "69573498",
        "email": "ckvh@gmail.com",
        "nationality": "9",
        "isdCode": 18,
        "isdCodeGUID": "8c7f202f-1f30-4ab9-bb6a-026f272c3c30",
        "zipCode": "76654654",
        "countryGUID": "8d68d0b0-7292-4262-a0b1-076014fcbb9d",
        "state": "kerala",
        "dob": "2023-6-6",
        "emiratesIdNo": null,
        "serviceGUID": null,
        "bookedForProfileGUID": null
    },
    "status": true,
    "errorCode": "",
    "errorMessage": "",
    "statusCode": "200",
    "statusMessage": "Success",
    "responseDate": "07/Jun/2023 12:11:17",
    "version": "V1"
}
{
    "Output": {
        "profileguid": "4320abce-c414-4c9b-967d-20323748f427",
        "surName": "dfgdf",
        "foreName": "hdf",
        "address": "gdfgdf gdfgdf",
        "city": "Ruyigi",
        "countryName": null,
        "dateOfBirth": "2023-06-06T00:00:00",
        "passportNo": "76575645",
        "emiratesId": "",
        "phoneNumber": "69573498",
        "email": "ckvh@gmail.com",
        "nationality": "9",
        "isdCode": 18,
        "isdCodeGUID": "8c7f202f-1f30-4ab9-bb6a-026f272c3c30",
        "zipCode": "76654654",
        "countryGUID": "8d68d0b0-7292-4262-a0b1-076014fcbb9d",
        "state": "kerala",
        "dob": "2023-6-6",
        "emiratesIdNo": null,
        "serviceGUID": null,
        "bookedForProfileGUID": null
    },
    "status": true,
    "errorCode": "",
    "errorMessage": "",
    "statusCode": "200",
    "statusMessage": "Success",
    "responseDate": "07/Jun/2023 11:15:19",
    "version": "V1"
}
{
    "Output": {
        "saveStatus": true,
        "editStatus": false,
        "deleteStatus": false,
        "itemGUID": "d68afb9e-8bd8-4e66-9bfa-c7666901a8ee",
        "isNotFirstGuardianValue": false,
        "errorMessage": null,
        "isAlreadyExists": false,
        "status": false
    },
    "status": true,
    "errorCode": "",
    "errorMessage": "",
    "statusCode": "200",
    "statusMessage": "Success",
    "responseDate": "07/Jun/2023 11:04:21",
    "version": "V1"
}
{
  "address": "gdfgdf gdfgdf",
  "bookedForProfileGUID": "05fa50b0-a450-437f-ade3-19bb128192a5",
  "city": "Ruyigi",
  "countryGUID": "8d68d0b0-7292-4262-a0b1-076014fcbb9d",
  "dateOfBirth": "2023-06-06T18:30:00.000Z",
  "email": "ckvh@gmail.com",
  "emiratesId": "856345346",
  "foreName": "hdf",
  "isdCode": "+880",
  "isdCodeGUID": "8c7f202f-1f30-4ab9-bb6a-026f272c3c30",
  "nationality": "5f17dd01-c266-4da2-95c9-fedde4c60e73",
  "passportNo": "76575645",
  "phoneNumber": "69573498",
  "state": "kerala",
  "surName": "dfgdf",
  "zipCode": "76654654"
}
{
    "Output": {
        "saveStatus": true,
        "editStatus": false,
        "deleteStatus": false,
        "itemGUID": "4320abce-c414-4c9b-967d-20323748f427",
        "isNotFirstGuardianValue": false,
        "errorMessage": null,
        "isAlreadyExists": false,
        "status": false
    },
    "status": true,
    "errorCode": "",
    "errorMessage": "",
    "statusCode": "200",
    "statusMessage": "Success",
    "responseDate": "07/Jun/2023 10:49:27",
    "version": "V1"
}
"""
<Autocomplete
                    disablePortal
                    id="combo-box-demo"
                    placeholder="+971"
                    options={isdCodesList}
                    isOptionEqualToValue={(option: any, value: any) => option.label === value.label}
                    renderInput={(params) => (
                      <TextField
                        {...params}
                        {...register('isdCode', {
                          required: true,
                        })}
                      />
                    )}
                    onChange={(e, newVal: any) => {
                      console.log('newVal', newVal);
                      setPhoneNumber(newVal?.label);
                    }}
                  />

"""

Sugeest you are a react developer expert.

I want to show country name instead of country code.
you can make the changes you need.
please update the code and return.
"""
<div className="row email-phone-main-wrapper">
            <div className="col-md-6 phone-col-wrapper">
              <div className="mb-3">
                <label htmlFor="phoneNumber" className="form-label phone-number-label w-100">
                  Phone Number*
                </label>
                <div className="d-flex">
                  <Autocomplete
                    disablePortal
                    id="combo-box-demo"
                    placeholder="+971"
                    options={isdCodesList}
                    isOptionEqualToValue={(option: any, value: any) => option.label === value.label}
                    renderInput={(params) => (
                      <TextField
                        {...params}
                        {...register('isdCode', {
                          required: true,
                        })}
                      />
                    )}
                    onChange={(e, newVal: any) => {
                      console.log('newVal', newVal);
                      setPhoneNumber(newVal?.label);
                    }}
                  />
                  <input
                    type="text"
                    className="form-control-phonenumber"
                    id="phoneNumber"
                    aria-describedby="phoneNumberHelp"
                    placeholder="xxx xxxx xxxxxx"
                    {...register('phoneNumber', {
                      required: true,
                    })}
                    onChange={(e) => setPhoneNumber(e.target.value)}
                  />
                </div>
                {
                  errors?.phoneNumber?.type === 'required' && (
                    <span className="error">
                      please enter your phone number
                    </span>
                  )
                }
              </div>
            </div>
            <div className="col-md-4 email-col-wrapper">
              <div className="mb-3">
                <label htmlFor="email" className="form-label w-100">
                  Email Address
                </label>
                <input
                  type="text"
                  className="form-control"
                  id="email"
                  aria-describedby="emailHelp"
                  placeholder="eg:abc@mail.com"
                  {...register('email')}
                  onChange={(e) => setEmail(e.target.value)}
                />
              </div>
            </div>
          </div>
"""


You aree CSS expert. You have to do following design changes written inbullet points:

parent element - email-phone-main-wrapper
child elements - phone-col-wrapper, email-col-wrapper 
1. childs of email-phone-main-wrapper div element should appear in row format ie top and bottom style when screem with is equal or below 768px and height 1024 px. 
2. Both the child element should have same width when responsive. code for your reference is above.
3. YOu can media queries to achieve this result.
4. Return the updated sass code having media queries.
row {
  
  display: flex;
    flex-direction: column;
}


@media (min-width: 768px)
.phone-number-wrapper {
    flex: 0 0 auto;
    width: 100%;
}

.form .email-col-wrapper {
    margin-left: 0px;
    width: 75%;
}

P2P Crypto Exchanges that have been created so far in the industry have brought significant revenue for the owners. The trust involved is the primary reason why people often sign up for a P2P Crypto Exchange. Users picking their preferred buying and selling prices and the crypto escrow script services are two factors determining confidence in a peer-to-peer cryptocurrency exchange.

Thus, Owners won't have a liquidity issue when more users join the platform. Increasing liquidity allows exchange owners to make money via a variety of methods.

Listing fee
Commission fee for ad-based transactions
Affiliate market for currency conversion using foreign fiat
Fees for withdrawals

Due to all of these opportunities for making money, startups should invest in the development of peer-to-peer cryptocurrency exchanges. In addition to the direct earnings, setting up a P2P Exchange. 

Startups should invest in P2P Crypto Exchange software to expand their revenue streams because of all this potential to make money. In addition to the direct income generated, creating a P2P Exchange indirectly contributes to making money. Future firms may develop a hybrid P2P cryptocurrency exchange that offers both centralized and decentralized choices.
"""
<form className="form">
          <div className="row form-row">
            <div
              className="col-md-4"
            >
              <div className="mb-3">
                <label
                  htmlFor="forename"
                  className="form-label w-100 forename-label"
                >
                  Forename(s) - All First and Middle Names(as per passport)
                </label>
                <input
                  type="text"
                  className="form-control forename-input"
                  id="forename"
                  placeholder="Aron Mathew"
                  onChange={(e) => setForeName(e.target.value)}
                  {...register('foreName', {
                    required: true,
                  })}
                />
                {
                errors?.foreName?.type === 'required' && (
                  <span className="error">
                    please enter your forename
                  </span>
                )
              }
              </div>
            </div>
            <div className="col" />
            <div className="row">
              <div className="col-md-4">
                <div className="mb-3">
                  <label htmlFor="surname" className="form-label w-100">
                    Surname*
                  </label>
                  <input
                    type="text"
                    className="form-control surname-input"
                    id="surname"
                    aria-describedby="surnameHelp"
                    placeholder="Eg: Philip"
                    onChange={(e) => setSurName(e.target.value)}
                    {...register('surName', {
                      required: true,
                    })}
                  />
                  {
                  errors?.surName?.type === 'required' && (
                    <span className="error">
                      please enter your surname
                    </span>
                  )
                }
                </div>
              </div>
            </div>
            {/* date of birth and  nationality */}
            <div className="row">
              <div className="col-md-4">
                <div className="mb-3">
                  <label htmlFor="dateOfBirth" className="form-label date-of-birth-label w-100">
                    Date of Birth*
                  </label>
                  <DatePicker
                    onChange={(e: any) => {
                      handleDatePicker(e);
                    }}
                    value={dateOfBirth}
                    renderInput={(params: any) => (
                      <TextField
                        {...params}
                        inputProps={{
                          ...params.inputProps,
                          placeholder: 'Select Date of Birth',
                        }}
                        {
                            ...register('dateOfBirth', {
                              required: true,
                            })
                          }
                        className="date-picker date-picker-input"
                      />
                    )}
                    className="date-picker-field"
                  />
                  {
                    errors?.surName?.type === 'required' && (
                      <span className="error">
                        please enter your date of birth
                      </span>
                    )
                  }
                </div>
              </div>
              <div className="col-md-4">
                <div className="mb-3">
                  <label htmlFor="nationality" className="form-label nationality-label w-100">
                    Nationality*
                  </label>
                  <Autocomplete
                    disablePortal
                    id="combo-box-demo"
                    options={nationalitiesList}
                    isOptionEqualToValue={(option: any, value: any) => option.nationalityGuid === value.nationalityGuid}
                    renderInput={(params) => (
                      <TextField
                        {...params}
                        {...register('nationality', {
                          required: true,
                        })}
                      />
                    )}
                    onChange={(e, newVal: any) => {
                      console.log('newVal', newVal);
                      setNationalityGuid(newVal?.nationalityGuid);
                    }}
                  />
                </div>
              </div>
            </div>

            {/* passport number and emirates ID */}
            <div className="row">
              <div className="col-md-4">
                <div className="mb-3">
                  <label htmlFor="passportNo" className="form-label passport-number-label w-100">
                    Passport Number*
                  </label>
                  <input
                    type="text"
                    className="form-control passport-number-input"
                    id="passportNo"
                    placeholder="xx xxxx xxxx"
                    onChange={(e) => setPassportNo(e.target.value)}
                    {...register('passportNo', {
                      required: true,
                    })}
                  />
                  {
                    errors?.passportNo?.type === 'required' && (
                      <span className="error">
                        please enter your passport number
                      </span>
                    )
                  }
                </div>
              </div>

              <div className="col-md-4">
                <div className="mb-3">
                  <label htmlFor="emiratesId" className="form-label emirates-id-label w-100">
                    Emirates ID*
                  </label>
                  <input
                    type="text"
                    className="form-control emirates-id-input"
                    id="emiratesId"
                    placeholder="Eg: 123456789"
                    onChange={(e) => setEmiratesID(e.target.value)}
                    {...register('emiratesID', {
                      required: true,
                    })}
                  />
                  {
                    errors?.emiratesID?.type === 'required' && (
                      <span className="error">
                        please enter your emirates id
                      </span>
                    )
                  }
                </div>
              </div>
            </div>
            <h4 className="form-sub-head">
              Current Residential Address (Not PO Box)
              <hr />
            </h4>
"""

You are scss expert.
you have to nest form-sub-head element of form class. You have to follow sass conventions.
Return the converted styling.
"""
import styled from '@emotion/styled';
import React from 'react';
import { useDispatch } from 'react-redux';
 
const WillsTable = styled('div')(({ theme }) => ({
    backgroundColor: theme.palette.background.paper,
  }));
"""
 
Property 'palette' does not exist on type 'Theme'.


Solution:

https://stackoverflow.com/a/72594201

Styled should be import from @mui/material/styles, as you can see here. So, the code will be like:

import { styled } from "@mui/material/styles";
"""
import styled from '@emotion/styled';
import React from 'react';
import { useDispatch } from 'react-redux';

const WillsTable = styled('div')(({ theme }) => ({
    backgroundColor: theme.palette.background.paper,
  }));
"""

Property 'palette' does not exist on type 'Theme'.

Suggest a solution for the abover error. and update the current code with newer.



"""
<div className="file-list-item" key={index}>

  			<div className="file-info">
                <div
                  className="file-icon"
                >
                  <img src={FileListIcon} alt="File List Icon" />
                </div>
                <div className="file-name">
                  {file.name}
                </div>
              </div>

              <div className="close-icon" onClick={() => removeFile(file)}>
                <span>Remove</span>
              </div>
            </div>
"""

Suggest you are a experienced react developer.

`file-list-item` div element contains two child div elements `file-info` element and `close-icon` div element. These two chilf elements should have space between them. You can apply flex properties if needed. Write the styling from scratch. background color and border radius of parent element is 
#E4FDFF and 30px. Also please explain the change you make. file-icon and file-name should have margin of 10px in between. equal padding around file-list-item div element.  Return the updated version of code ans styles.



You are CSS expert.
help me to resolve this design issue.
currently width of file-list-item is changing based on length of file name. I want the width to stay consistent irrespective of file we attach. It should of same width. return the updated styles


jsx
----------
<div className="file-list">
  <div className="file-list-header">
    {uploadedFiles.map((file: any, index) => (
      <div className="file-list-item" key={index}>
        <div className="file-info">
          {file.name}
          <div className="close-icon" onClick={() => removeFile(file)}>
            Remove
          </div>
        </div>
        <div className="close-icon" onClick={() => removeFile(file)}>
          &#10006;
        </div>
      </div>
    ))}
  </div>
</div>

css
-----
.file-list {
  background: #E4FDFF;
  border-radius: 30px;
}

.file-list-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 5px;
  font-family: 'Basis Grotesque Arabic Pro';
  font-style: normal;
  font-weight: 400;
  font-size: 14px;
  line-height: 18px;
  text-transform: capitalize;
  color: #1B202D;
}

.file-info {
  display: flex;
  align-items: center;
}

.close-icon {
  cursor: pointer;
  font-family: 'Basis Grotesque Arabic Pro';
  font-style: normal;
  font-weight: 500;
  font-size: 14px;
  line-height: 18px;
  text-decoration-line: underline;
  color: #1B202D;
  margin-left: 8px;
}

.close-icon:last-child {
  margin-left: 0;
}

"""
<div className="col-sm-6">
        <div className="edit-remove-sustitute">
          <div className="avatar-container">
            <div className="initials-avatar">S</div>
          </div>
          <div className="profile-card">
            <div className="profile-card__name">Shayne Anto</div>
            <div className="profile-card__role">Substitute</div>
          </div>
          <div className="action-buttons-container">
            <div
              className="edit-button"
              onClick={editSubstitute}
            >
              Edit
            </div>
            <div
              className="remove-button"
              onClick={removeSubstitute}
            >
              Remove
            </div>
          </div>
        </div>
      </div>

      <div className="col-sm-6">
        <div className="add-substitute-control">
          <div className="add-substitute-icon-wrapper">
            <img
              src={addSubstituteIcon}
              alt="Add Substitute Icon"
              onClick={handleOpenModal}
            />
          </div>
          <div
            className="add-substitute-text-wrapper"
          >
            <div className="add-substitute-title">Add Substitute</div>
            <div className="add-substitute-subtitle">Click here to add substitute</div>
          </div>
        </div>
      </div>
"""

Suggest you are CSS expert.

1. I want to change the classname from of both the divs `col-sm-6` to `col-sm-12` when media quey size is width 768px and height is 1024px.

2. Return the updated changes.


code for your reference is given below.

```
@media (max-width: 768px) and (max-height: 1024px) {
  .substitute-manager {
    flex-direction: column;
  }

  .edit-remove-sustitute,
  .add-substitute-control {
    margin-bottom: 1rem;
  }

  .add-substitute-control {
    margin-left: 0;
  }
}
```
<Autocomplete
              id="beneficiaryType"
              placeholder="individual"
              disableClearable
              options={beneficiaryTypeListArray}
              getOptionLabel={(option: any) => option.label}
              style={{
                fontFamily: "Basis Grotesque Arabic Pro",
                fontStyle: "normal",
                fontWeight: 500,
                fontSize: "0.75rem",
                lineHeight: "18px",
                color: "#9799A6",
              }}
              renderOption={(props: any, option: { label: any }) => (
                <AutocompleteOption {...props}>
                  <ListItemContent
                    sx={{
                      fontFamily: "Basis Grotesque Arabic Pro",
                      fontStyle: "normal",
                      fontWeight: 500,
                      fontSize: "0.75rem",
                      lineHeight: "18px",
                      color: "#9799A6",
                    }}
                  >
                    hello world
                  </ListItemContent>
                </AutocompleteOption>
              )}
              {...register("beneficiaryTypeGuid", {
                required: true,
              })}
              onChange={(e: any, newVal: any) => {
                console.log(newVal);
                setBeneficiaryTypeGUID(newVal.beneficiaryTypeGUID);
              }}
            />

Consider you are a react developer.

help me to solve this problem.

- No values are populating in this Beneficiary type field
- api side is working.
- I want to populate the beneficiary types label on dropdown of beneficiary type fied.
- Make appropriate changes and return the updated version of code.
//APP

import React from "react"
import Sidebar from "./components/Sidebar"
import Editor from "./components/Editor"
import { data } from "./data"
import Split from "react-split"
import { nanoid } from "nanoid"

export default function App() {
    const [notes, setNotes] = React.useState(
        () => JSON.parse(localStorage.getItem("notes")) || []
    )
    const [currentNoteId, setCurrentNoteId] = React.useState(
        (notes[0] && notes[0].id) || ""
    )

    React.useEffect(() => {
        localStorage.setItem("notes", JSON.stringify(notes))
    }, [notes])

    function createNewNote() {
        const newNote = {
            id: nanoid(),
            body: "# Type your markdown note's title here"
        }
        setNotes(prevNotes => [newNote, ...prevNotes])
        setCurrentNoteId(newNote.id)
    }

    function updateNote(text) {
        setNotes(oldNotes => {
            const newArray = []
            for (let i = 0; i < oldNotes.length; i++) {
                const oldNote = oldNotes[i]
                if (oldNote.id === currentNoteId) {
                    // Put the most recently-modified note at the top
                    newArray.unshift({ ...oldNote, body: text })
                } else {
                    newArray.push(oldNote)
                }
            }
            return newArray
        })
    }

    function deleteNote(event, noteId) {
        event.stopPropagation()
        setNotes(oldNotes => oldNotes.filter(note => note.id !== noteId))
    }

    function findCurrentNote() {
        return notes.find(note => {
            return note.id === currentNoteId
        }) || notes[0]
    }

    return (
        <main>
            {
                notes.length > 0
                    ?
                    <Split
                        sizes={[30, 70]}
                        direction="horizontal"
                        className="split"
                    >
                        <Sidebar
                            notes={notes}
                            currentNote={findCurrentNote()}
                            setCurrentNoteId={setCurrentNoteId}
                            newNote={createNewNote}
                            deleteNote={deleteNote}
                        />
                        {
                            currentNoteId &&
                            notes.length > 0 &&
                            <Editor
                                currentNote={findCurrentNote()}
                                updateNote={updateNote}
                            />
                        }
                    </Split>
                    :
                    <div className="no-notes">
                        <h1>You have no notes</h1>
                        <button
                            className="first-note"
                            onClick={createNewNote}
                        >
                            Create one now
                </button>
                    </div>

            }
        </main>
    )
}


//SIDEBAR

import React from "react"

export default function Sidebar(props) {
    const noteElements = props.notes.map((note, index) => (
        <div key={note.id}>
            <div
                
                className={`title ${
                    note.id === props.currentNote.id ? "selected-note" : ""
                }`}
                onClick={() => props.setCurrentNoteId(note.id)}
            >
                <h4 className="text-snippet">{note.body.split("\n")[0]}</h4>
                <button 
                    className="delete-btn"
                    onClick={(event) => props.deleteNote(event, note.id)}
                >
                    <i className="gg-trash trash-icon"></i>
                </button>
            </div>
        </div>
    ))

    return (
        <section className="pane sidebar">
            <div className="sidebar--header">
                <h3>Notes</h3>
                <button className="new-note" onClick={props.newNote}>+</button>
            </div>
            {noteElements}
        </section>
    )
}
const handlePersonalInfo = (data: any, e: any) => {
    e.preventDefault();
    console.log('entered info::', data);
    let hasEmiratesId: boolean;
    if (selectedOption === 'Yes') hasEmiratesId = true;
    else hasEmiratesId = false;
    let isMirrorWill: boolean;
    if (singleWillCheck) isMirrorWill = false;
    else isMirrorWill = true;
    const allData = {
      ...data,
      maritalStatusGUID,
      dateOfBirth,
      referralQuestionGUID,
      hasEmiratesId,
      isMirrorWill,
      isdCodeGUID1: countryGUID,
      isdCodeGUID2: countryGUID,
      nationalityGuid,
      countryGUID,
    };
    console.log('allData test', allData);
    axios.post(personalInformationAPI, allData).then((res) => {
      console.log('res post', res);
    });
<Box sx={{ display: 'flex', flexDirection: 'row', pt: 2 }}> <button type="submit" className="next-btn"> Next Step </button> {/* {singleWillCheck ? ( <button type="submit" className="next-btn"> Next Step </button> ) : ( <button type="button" className="next-btn" onClick={handleMirrorWill}> Enter Spouse Information </button> )} */}
    <Box sx={{ flex: '1 1 auto' }} /> <Button color="inherit">Skip</Button> <Button color="inherit" onClick={handleBack}> Back </Button>
</Box>
{!(activeStep === 7) && (
if we set active step to 7, then we can view Upload Documents page.
/* eslint-disable array-callback-return */
/* eslint-disable @typescript-eslint/no-shadow */
/* eslint-disable react/no-array-index-key */
/* eslint-disable @typescript-eslint/no-use-before-define */
/* eslint-disable no-plusplus */
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-alert */
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable jsx-a11y/control-has-associated-label */
/* eslint-disable react/button-has-type */
/* eslint-disable max-len */
import React, { useState } from 'react';
import { useDropzone } from 'react-dropzone';

import { AiOutlineClose } from 'react-icons/ai';

import FileUploadIcon from '@assets/FileUploadIcon.svg';
import FileUploadIconDark from '@assets/FileUploadIconDark.svg';
import TickMarkIconGreen from '@assets/TickMarkIconGreen.svg';
import TickMarkIconGrey from '@assets/TickMarkIconGrey.svg';
import FileArrowIcon from '@assets/FileArrowIcon.svg';

import './style.scss';

function DocumentManager() {
  const [activeElement, setActiveElement] = useState('top');
  const [uploadedFiles, setUploadedFiles] = useState([]);

  /**
   * Sets the active element to the given element string.
   *
   * @param {string} element - The string representing the active element to set.
   */
  const handleElementClick = (element: string) => {
    setActiveElement(element);
  };

  /**
   * Returns the background color style object for a given element.
   *
   * @param {string} element - The element to get background style for.
   * @return {Object} The background color style object for the given element.
   */
  const getBackgroundStyle = (element: string) => ({
    backgroundColor: activeElement === element ? '#023979' : '#FFFFFF',
  });

  /**
   * Returns an object representing the style to be applied to the title element.
   *
   * @param {string} element - The element to apply the style to.
   * @return {Object} An object containing the color property to be applied to the title element.
   */
  const getTitleStyle = (element: string) => ({
    color: activeElement === element ? '#FFFFFF' : '#1B202D',
  });

  const getFileUploadIcon = (element: string) => (activeElement === element ? FileUploadIcon : FileUploadIconDark);

  const getTickMarkicon = (element: string) => (activeElement === element ? TickMarkIconGreen : TickMarkIconGrey);

  const handleAddFileClick = (e: any) => {
    e.preventDefault();
    if (e.target !== e.currentTarget) {
      return;
    }
    document.getElementById('file-upload-input')?.click();
  };

  /**
 * Handles the file input change event.
 *
 * @param {any} e - the event object
 * @return {void}
 */
  const handleFileInputChange = (e: any) => {
    const newFiles = Array.from(e.target.files);
    checkFileValidity(newFiles);
  };

  /**
   * Handles the file drop event by checking the validity of the accepted files.
   *
   * @param {any} acceptedFiles - the files that have been accepted for upload
   */
  const handleFileDrop = (acceptedFiles: any) => {
    checkFileValidity(acceptedFiles);
  };

  /**
   * Prevents the click event from propagating and executing other click events.
   *
   * @param {any} e - the click event to be stopped from propagating
   */
  const handleRowItemClick = (e: any) => {
    e.stopPropagation();
  };

  /**
   * Filters files by their extension and size, and adds the valid files to the uploadedFiles state.
   *
   * @param {Array} files - The array of files to be checked.
   * @return {void} Returns nothing.
   */
  const checkFileValidity = (files: any) => {
    const validExtensions = ['.pdf', '.jpeg', '.jpg', '.bmp', '.doc', '.docx'];
    const maxFileSize = 20 * 1024 * 1024;

    const validFiles = files.filter((file: any) => {
      const isValidExtension = validExtensions.some((ext) => file.name.toLowerCase().endsWith(ext));
      const isWithinMaxSize = file.size <= maxFileSize;
      return isValidExtension && isWithinMaxSize;
    });

    const invalidFiles = files.filter((file: any) => !validFiles.includes(file));
    if (invalidFiles.length > 0) {
      const invalidFileNames = invalidFiles.map((file: any) => file.name).join(', ');
      alert(`Invalid files: ${invalidFileNames}. Please use A4-size PDF, JPEG, BMP, DOC, or DOCX files that are within 20MB.`);
    } else {
      setUploadedFiles((prevFiles) => [...prevFiles, ...validFiles]);
      alert('Files uploaded successfully');
    }
  };

  /**
   * Removes a file from the uploaded files list.
   *
   * @param {any} file - The file to be removed.
   */
  const removeFile = (file: any) => {
    setUploadedFiles((prevFiles) => prevFiles.filter((f) => f !== file));
  };

  const {
    getRootProps,
    getInputProps,
  } = useDropzone({
    onDrop: handleFileDrop,
  });

  return (
    <main>
      <section>
        <header className="header">Upload Documents</header>
        <p className="description">Upload the documents in PDF or JPEG format. Click on next to save the files once all the documents have been uploaded</p>
      </section>
      <div className="row document-upload-container">

        <div className="col-lg-6 container">
          <div
            className={`top${activeElement === 'top' ? ' active' : ''}`}
            style={getBackgroundStyle('top')}
            onClick={() => handleElementClick('top')}
          >
            <div className="left-container">
              <div className="file-upload-icon">
                <img src={getFileUploadIcon('top')} alt="File Uploader Icon" />
              </div>
              <div
                className="document-title"
                style={getTitleStyle('top')}
              >
                Testator Passport

              </div>
            </div>
            <div className="tick-icon">
              <img src={getTickMarkicon('top')} alt="Tick Mark" />
            </div>
          </div>

          <div
            className={`middle${activeElement === 'middle' ? ' active' : ''}`}
            style={getBackgroundStyle('middle')}
            onClick={() => handleElementClick('middle')}
          >
            <div className="left-container">
              <div className="file-upload-icon">
                <img src={getFileUploadIcon('middle')} alt="File Uploader Icon Dark" />
              </div>
              <div
                className="document-title text-bottom-2"
                style={getTitleStyle('middle')}
              >
                Additional Document
              </div>
            </div>
            <div className="tick-icon">
              <img src={getTickMarkicon('middle')} alt="Tick Mark" />
            </div>
          </div>

          <div
            className={`bottom${activeElement === 'bottom' ? ' active' : ''}`}
            style={getBackgroundStyle('bottom')}
            onClick={() => handleElementClick('bottom')}
          >
            <div className="left-container">
              <div className="file-upload-icon">
                <img src={getFileUploadIcon('bottom')} alt="File Uploader Icon Dark" />
              </div>
              <div
                className="document-title text-bottom-2"
                style={getTitleStyle('bottom')}
              >
                Executor Passport
              </div>
            </div>
            <div className="tick-icon tick-icon-last">
              <img src={getTickMarkicon('bottom')} alt="Tick Mark" />
            </div>
            <div />
          </div>
        </div>

        <div className="col-lg-6 row-item" {...getRootProps()} onClick={handleRowItemClick}>
          <div className="file-upload-arrow">
            <img src={FileArrowIcon} alt="File Upload Arrow Icon" />
          </div>
          <div className="file-upload-text">
            Drag and drop document here to upload
          </div>
          <div className="file-attach-instructions">
            Please attach the file(s) below (use the Add button). We recommend using A4-size PDF, BMP, PNG, DOC, DOCX, JPG and JPEG files. File size cannot be more than 20 megabytes (MB). Your files will be uploaded when you submit your form.
          </div>
          <div className="file-add-button">
            <button onClick={handleAddFileClick}>Add File</button>
            <input
              type="file"
              id="file-upload-input"
              name="file-upload-input"
              accept=".pdf, .bmp, .png, .doc, .docx, .jpg, .jpeg"
              multiple
              onChange={handleFileInputChange}
              style={{ display: 'none' }}
              {...getInputProps()}
            />
          </div>
          {uploadedFiles.length > 0 && (
          <div className="file-list">
            <ul>
              {uploadedFiles.map((file: any, index) => (
                <li key={index}>
                  {file.name}
                  <AiOutlineClose
                    className="close-icon"
                    onClick={() => removeFile(file)}
                  />
                </li>
              ))}
            </ul>
          </div>
          )}
        </div>
      </div>
    </main>
  );
}

export default DocumentManager;
const handleRowItemClick = (e) => {
  e.stopPropagation();
};

// ...

<div className="col-lg-6 row-item" {...getRootProps()} onClick={handleRowItemClick}>
  {/* Remaining code */}
</div>
You are a React and frontend expert.

I want to achieve below changes to my current version of code.

Constraints:

1. Add a AiOutlineClose react icon on right side of each file which is listed.
2. On Clicking this icon, that uploaded file is removed from list and from UI as well.
3. Attached current code for reference.


```
/* eslint-disable react/no-array-index-key */
/* eslint-disable @typescript-eslint/no-use-before-define */
/* eslint-disable no-plusplus */
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-alert */
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable jsx-a11y/control-has-associated-label */
/* eslint-disable react/button-has-type */
/* eslint-disable max-len */
import React, { useState } from 'react';
import { useDropzone } from 'react-dropzone';

import FileUploadIcon from '@assets/FileUploadIcon.svg';
import FileUploadIconDark from '@assets/FileUploadIconDark.svg';
import TickMarkIconGreen from '@assets/TickMarkIconGreen.svg';
import TickMarkIconGrey from '@assets/TickMarkIconGrey.svg';
import FileArrowIcon from '@assets/FileArrowIcon.svg';

import './style.scss';

function DocumentManager() {
  const [activeElement, setActiveElement] = useState('top');
  const [uploadedFiles, setUploadedFiles] = useState([]);

  const handleElementClick = (element: string) => {
    setActiveElement(element);
    console.log(activeElement);
  };

  const getBackgroundStyle = (element: string) => ({
    backgroundColor: activeElement === element ? '#023979' : '#FFFFFF',
  });

  const getTitleStyle = (element: string) => ({
    color: activeElement === element ? '#FFFFFF' : '#1B202D',
  });

  const getFileUploadIcon = (element: string) => (activeElement === element ? FileUploadIcon : FileUploadIconDark);

  const getTickMarkicon = (element: string) => (activeElement === element ? TickMarkIconGreen : TickMarkIconGrey);

  const handleAddFileClick = () => {
    document.getElementById('file-upload-input')?.click();
  };

  const handleFileInputChange = (e: any) => {
    const newFiles = Array.from(e.target.files);
    console.log(newFiles);
    checkFileValidity(newFiles);
    setUploadedFiles((prevFiles) => [...prevFiles, ...newFiles]);
  };

  const handleFileDrop = (acceptedFiles: any) => {
    console.log(acceptedFiles);
    checkFileValidity(acceptedFiles);
    setUploadedFiles((prevFiles) => [...prevFiles, ...acceptedFiles]);
  };

  const checkFileValidity = (files: any) => {
    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      const validExtensions = ['.pdf', 'jpeg', 'jpg', '.bmp', '.doc', '.docx'];
      const maxFileSize = 20 * 1024 * 1024;

      if (!validExtensions.some((ext) => file.name.toLowerCase().endsWith(ext))) {
        alert(`Invalid File: ${file.name}. Please use A4-size PDF, JPEG, BMP, DOC or DOCX files`);
      } else if (file.size > maxFileSize) {
        alert(`File size exceeds the limit: ${file.name}. Maximum file size is 20MB.`);
      } else {
        alert('File uploaded successfully');
      }
    }
  };

  const {
    getRootProps,
    getInputProps,
    isDragActive,
    isDragAccept,
    isDragReject,
  } = useDropzone({
    onDrop: handleFileDrop,
  });

  return (
    <main>
      <section>
        <header className="header">Upload Documents</header>
        <p className="description">Upload the documents in PDF or JPEG format. Click on next to save the files once all the documents have been uploaded</p>
      </section>
      <div className="row">

        <div className="col-lg-6 container">
          <div
            className={`top${activeElement === 'top' ? ' active' : ''}`}
            style={getBackgroundStyle('top')}
            onClick={() => handleElementClick('top')}
          >
            <div className="left-container">
              <div className="file-upload-icon">
                <img src={getFileUploadIcon('top')} alt="File Uploader Icon" />
              </div>
              <div
                className="document-title"
                style={getTitleStyle('top')}
              >
                Testator Passport

              </div>
            </div>
            <div className="tick-icon">
              <img src={getTickMarkicon('top')} alt="Tick Mark" />
            </div>
          </div>

          <div
            className={`middle${activeElement === 'middle' ? ' active' : ''}`}
            style={getBackgroundStyle('middle')}
            onClick={() => handleElementClick('middle')}
          >
            <div className="left-container">
              <div className="file-upload-icon">
                <img src={getFileUploadIcon('middle')} alt="File Uploader Icon Dark" />
              </div>
              <div
                className="document-title text-bottom-2"
                style={getTitleStyle('middle')}
              >
                Additional Document
              </div>
            </div>
            <div className="tick-icon">
              <img src={getTickMarkicon('middle')} alt="Tick Mark" />
            </div>
          </div>

          <div
            className={`bottom${activeElement === 'bottom' ? ' active' : ''}`}
            style={getBackgroundStyle('bottom')}
            onClick={() => handleElementClick('bottom')}
          >
            <div className="left-container">
              <div className="file-upload-icon">
                <img src={getFileUploadIcon('bottom')} alt="File Uploader Icon Dark" />
              </div>
              <div
                className="document-title text-bottom-2"
                style={getTitleStyle('bottom')}
              >
                Executor Passport
              </div>
            </div>
            <div className="tick-icon tick-icon-last">
              <img src={getTickMarkicon('bottom')} alt="Tick Mark" />
            </div>
            <div />
          </div>
        </div>

        <div className="col-lg-6 row-item" {...getRootProps()}>
          <div className="file-upload-arrow">
            <img src={FileArrowIcon} alt="File Upload Arrow Icon" />
          </div>
          <div className="file-upload-text">
            Drag and drop document here to upload
          </div>
          <div className="file-attach-instructions">
            Please attach the file(s) below (use the Add button). We recommend using A4-size PDF, BMP, PNG, DOC, DOCX, JPG and JPEG files. File size cannot be more than 20 megabytes (MB). Your files will be uploaded when you submit your form.
          </div>
          <div className="file-add-button">
            <button onClick={handleAddFileClick}>Add File</button>
            <input
              type="file"
              id="file-upload-input"
              name="file-upload-input"
              accept=".pdf, .bmp, .png, .doc, .docx, .jpg, .jpeg"
              multiple
              onChange={handleFileInputChange}
              style={{ display: 'none' }}
              {...getInputProps()}
            />
          </div>
        </div>
        {uploadedFiles.length > 0 && (
          <div className="file-list">
            <ul>
              {uploadedFiles.map((file: any, index) => (
                <li key={index}>{file.name}</li>
              ))}
            </ul>
          </div>
        )}
      </div>
    </main>
  );
}

export default DocumentManager;

```

''' 
 <div className="col-lg-6 row-item">
          <div className="file-upload-arrow">
            <img src={FileArrowIcon} alt="File Upload Arrow Icon" />
          </div>
          <div className="file-upload-text">
            Drag and drop document here to upload
          </div>
          <div className="file-attach-instructions">
            Please attach the file(s) below (use the Add button). We recommend using A4-size PDF, BMP, PNG, DOC, DOCX, JPG and JPEG files. File size cannot be more than 20 megabytes (MB). Your files will be uploaded when you submit your form.
          </div>
          <div className="file-add-button">
            <button onClick={addFileHandler}>Add File</button>
          </div>
        </div>
   '''
 
 Your are a senior react developer.
 
 I want you to implement a functionality to upload files on button click event and drag and drop.
 
 Contrainst:
 
1. function should be implemented on `addFileHandler` event given above.
2. File can also be uploaded by drag and drop into row-item div element.
3. instructions for file upload is given `file-attach-instructions` div element.
4. You can use packages like `react-uploader` to implement this.
5. Finally return the updated version of code. Current code is above for reference.


 
 
 
<div className="col-lg-6 row-item">
   <div className="file-upload-arrow">
     <img src={FileArrowIcon} alt="File Upload Arrow Icon" />
   </div>
   <div className="file-upload-text">
     Drag and drop document here to upload
   </div>
   <div className="file-attach-instructions">
     Please attach the file(s) below (use the Add button). We recommend using A4-size PDF, BMP, PNG, DOC, DOCX, JPG and JPEG files. File size cannot be more than 20 megabytes (MB). Your files will be uploaded when you submit your form.
   </div>
   <div className="file-add-button">
     <button>Add File</button>
   </div>
 </div>
 
 
 Consider you are a CSS expert. Above is the code you have to update and make neccessary styling based on below constraints
 
 Constraints:
 
 1. Center the child elements of row-item div element horizonatally & vertically.
 2. Each child element is aligned center.
 3. Update backgournd of Add File button to #023979.
 4. Set border radious of button to 5px and font color to #FFFFFF.
 5. Fibnally return the updated version of code with change in styles.
"""
<div className="top">
            <div className="left-container">
              <div className="file-upload-icon">
                <img src={FileUploadIcon} alt="File Uploader Icon" />
              </div>
              <div className="document-title">Testator Passport</div>
            </div>
            <div className="tick-icon">
              <img src={TickMarkIconGreen} alt="Tick Mark" />
            </div>
          </div>

          <div className="middle">
            <div className="left-container">
              <div className="file-upload-icon">
                <img src={FileUploadIconDark} alt="File Uploader Icon Dark" />
              </div>
              <div className="document-title text-black">Additional Document</div>
            </div>
            <div className="tick-icon">
              <img src={TickMarkIconGrey} alt="Tick Mark" />
            </div>
          </div>

          <div className="bottom">
            <div className="left-container">
              <div className="file-upload-icon">
                <img src={FileUploadIconDark} alt="File Uploader Icon Dark" />
              </div>
              <div className="document-title text-black">Executor Passport</div>
            </div>
            <div className="tick-icon tick-icon-last">
              <img src={TickMarkIconGrey} alt="Tick Mark" />
            </div>
            <div />
         </div>
"""


You are an experienced React Developer.

I want to implement a UI change.

On clicking top, middle or bottom div elements, 
  1. its backgound should be changed to #023979. 
  2. Its document-title element color should be changed to #FFFFFF.
For example. middle div element is clicked, it is active and the backgound changes to #023979.
While background of Inactive elements changes to default color #f4f4f4.
Initially when component loads, top element background is #023979, and bottom 2 element background is #f4f4f4.
you can use react hooks and state if needed. 
Help me to achieve this change by modiyfinh current version of code

I will give styles for reference below.

.container {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.top, .middle, .bottom {
    display: flex;
    justify-content: space-between;
    background-color: #f4f4f4;
    border-radius: 5px 0px 0px 5px;
}

.top {
    display: flex;
    align-items: center;
    background-color: #023979;
}

.container div {
    padding: 5px;
    text-align: center;
    cursor: pointer;
}

.document-title {
    font-family: 'Basis Grotesque Arabic Pro';
    font-style: normal;
    font-weight: 700;
    font-size: 0.875rem;
    line-height: 14px;
    color: #FFFFFF;
}

.left-container {
    display: flex;
    align-items: center;
    margin-right: 12px;
}

.file-upload-icon,
.document-title {
    margin-right: 12px;
}

.tick-icon {
    margin-left: auto;
    margin-right: 12px;
}

.document-title {
    flex-grow: 1;
}

.tick-icon-last {
    margin-right: 2px !important;
}










<Modal show={showModal}>
  <Modal.Header>
    <div className="modal-header-content">
      <div className="modal-header-left">
        <div className="modal-header-title mt-4">Add Substitute</div>
        <div className="modal-header-subtitle">
          List your Substitute Beneficiaries below and click on Add Substitute to add them to your List
        </div>
      </div>
    </div>
    <button
      className="modal-close-button"
      onClick={handleCloseModal}
    >
      <span aria-hidden="true">&times;</span>
    </button>
  </Modal.Header>
  <Modal.Body>
    <AddSubstituteForm onSubmit={handleSubmit} />
  </Modal.Body>
  <Modal.Footer>
    <Button
      variant="primary"
      onClick={handleCloseModal}
    >
      Add Substitute
    </Button>
  </Modal.Footer>
</Modal>




You are a CSS expert.

Constraints:
1. I want to show this modal center of our screen
2. Help me to add styles for element to achieve this.
3. Modal should be at center of whole window.
<button
   className="modal-close-button"
   onClick={handleCloseModal}
 >
   <span aria-hidden="true">&times;</span>
 </button>
 
 You are a CSS expert
 
 I want you to do following changes in styling.
 
 1. Rounded shape. Apply border radius to 50pc.
 2. Background to "#f1f1f1".
 3. No outer border color.
 3. border of child element span should be 2px solid #494A53.
.initials-avatar {
    background-color: #023979;
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 5px;
    width: 38px;
    height: 38px;
}
import type { UiState } from "instantsearch.js";
import { history as historyRouter } from "instantsearch.js/es/lib/routers";

type RouteState = {
  query?: string;
  page?: string;
  brands?: string[];
  category?: string;
  rating?: string;
  price?: string;
  free_shipping?: string;
  sortBy?: string;
  hitsPerPage?: string;
};

const routeStateDefaultValues: RouteState = {
  query: "",
  page: "1",
  brands: undefined,
  category: "",
  rating: "",
  price: "",
  free_shipping: "false",
  sortBy: "instant_search",
  hitsPerPage: "20",
};

const encodedCategories = {
  Cameras: "Cameras & Camcorders",
  Cars: "Car Electronics & GPS",
  Phones: "Cell Phones",
  TV: "TV & Home Theater",
} as const;

type EncodedCategories = typeof encodedCategories;
type DecodedCategories = {
  [K in keyof EncodedCategories as EncodedCategories[K]]: K;
};

const decodedCategories = Object.keys(
  encodedCategories
).reduce<DecodedCategories>((acc, key) => {
  const newKey = encodedCategories[key as keyof EncodedCategories];
  const newValue = key;

  return {
    ...acc,
    [newKey]: newValue,
  };
}, {} as any);

// Returns a slug from the category name.
// Spaces are replaced by "+" to make
// the URL easier to read and other
// characters are encoded.
function getCategorySlug(name: string): string {
  const encodedName =
    decodedCategories[name as keyof DecodedCategories] || name;

  return encodedName.split(" ").map(encodeURIComponent).join("+");
}

// Returns a name from the category slug.
// The "+" are replaced by spaces and other
// characters are decoded.
function getCategoryName(slug: string): string {
  const decodedSlug =
    encodedCategories[slug as keyof EncodedCategories] || slug;

  return decodeURIComponent(decodedSlug.replace(/\+/g, " "));
}

const originalWindowTitle = document.title;

const router = historyRouter<RouteState>({
  windowTitle({ category, query }) {
    const queryTitle = query ? `Results for "${query}"` : "";

    return [queryTitle, category, originalWindowTitle]
      .filter(Boolean)
      .join(" | ");
  },

  createURL({ qsModule, routeState, location }): string {
    const { protocol, hostname, port = "", pathname, hash } = location;
    const portWithPrefix = port === "" ? "" : `:${port}`;
    const urlParts = location.href.match(/^(.*?)\/search/);
    const baseUrl =
      (urlParts && urlParts[0]) ||
      `${protocol}//${hostname}${portWithPrefix}${pathname}search`;

    const categoryPath = routeState.category
      ? `${getCategorySlug(routeState.category)}/`
      : "";
    const queryParameters: Partial<RouteState> = {};

    if (
      routeState.query &&
      routeState.query !== routeStateDefaultValues.query
    ) {
      queryParameters.query = encodeURIComponent(routeState.query);
    }
    if (routeState.page && routeState.page !== routeStateDefaultValues.page) {
      queryParameters.page = routeState.page;
    }
    if (
      routeState.brands &&
      routeState.brands !== routeStateDefaultValues.brands
    ) {
      queryParameters.brands = routeState.brands.map(encodeURIComponent);
    }
    if (
      routeState.rating &&
      routeState.rating !== routeStateDefaultValues.rating
    ) {
      queryParameters.rating = routeState.rating;
    }
    if (
      routeState.price &&
      routeState.price !== routeStateDefaultValues.price
    ) {
      queryParameters.price = routeState.price;
    }
    if (
      routeState.free_shipping &&
      routeState.free_shipping !== routeStateDefaultValues.free_shipping
    ) {
      queryParameters.free_shipping = routeState.free_shipping;
    }
    if (
      routeState.sortBy &&
      routeState.sortBy !== routeStateDefaultValues.sortBy
    ) {
      queryParameters.sortBy = routeState.sortBy;
    }
    if (
      routeState.hitsPerPage &&
      routeState.hitsPerPage !== routeStateDefaultValues.hitsPerPage
    ) {
      queryParameters.hitsPerPage = routeState.hitsPerPage;
    }

    const queryString = qsModule.stringify(queryParameters, {
      addQueryPrefix: true,
      arrayFormat: "repeat",
    });

    return `${baseUrl}/${categoryPath}${queryString}${hash}`;
  },

  parseURL({ qsModule, location }): RouteState {
    const pathnameMatches = location.pathname.match(/search\/(.*?)\/?$/);
    const category = getCategoryName(
      (pathnameMatches && pathnameMatches[1]) || ""
    );

    const queryParameters = qsModule.parse(location.search.slice(1));
    const {
      query = "",
      page = 1,
      brands = [],
      price,
      free_shipping,
      hitsPerPage,
      sortBy,
      rating,
    } = queryParameters;

    // `qs` does not return an array when there's a single value.
    const allBrands = (
      Array.isArray(brands) ? brands : [brands].filter(Boolean)
    ) as string[];

    return {
      category,
      query: decodeURIComponent(query as string),
      page: page as string,
      brands: allBrands.map(decodeURIComponent),
      rating: rating as string,
      price: price as string,
      free_shipping: free_shipping as string,
      sortBy: sortBy as string,
      hitsPerPage: hitsPerPage as string,
    };
  },
});

const getStateMapping = ({ indexName }: { indexName: string }) => ({
  stateToRoute(uiState: UiState): RouteState {
    const indexUiState = uiState[indexName];
    return {
      query: indexUiState.query,
      page: (indexUiState.page && String(indexUiState.page)) || undefined,
      brands: indexUiState.refinementList && indexUiState.refinementList.brand,
      category:
        indexUiState.hierarchicalMenu &&
        indexUiState.hierarchicalMenu["hierarchicalCategories.lvl0"] &&
        indexUiState.hierarchicalMenu["hierarchicalCategories.lvl0"].join("/"),
      rating:
        (indexUiState.ratingMenu &&
          indexUiState.ratingMenu.rating &&
          String(indexUiState.ratingMenu.rating)) ||
        undefined,
      price: indexUiState.range && indexUiState.range.price,
      free_shipping:
        (indexUiState.toggle && String(indexUiState.toggle.free_shipping)) ||
        undefined,
      sortBy: indexUiState.sortBy,
      hitsPerPage:
        (indexUiState.hitsPerPage && String(indexUiState.hitsPerPage)) ||
        undefined,
    };
  },

  routeToState(routeState: RouteState): UiState {
    const hierarchicalMenu: { [key: string]: string[] } = {};
    if (routeState.category) {
      hierarchicalMenu["hierarchicalCategories.lvl0"] =
        routeState.category.split("/");
    }

    const refinementList: { [key: string]: string[] } = {};
    if (routeState.brands) {
      refinementList.brand = routeState.brands;
    }

    const range: { [key: string]: string } = {};
    if (routeState.price) {
      range.price = routeState.price;
    }

    return {
      [indexName]: {
        query: routeState.query,
        page: Number(routeState.page),
        hierarchicalMenu,
        refinementList,
        ratingMenu: {
          rating: Number(routeState.rating),
        },
        range,
        toggle: {
          free_shipping: Boolean(routeState.free_shipping),
        },
        sortBy: routeState.sortBy,
        hitsPerPage: Number(routeState.hitsPerPage),
      },
    };
  },
});

const getRouting = (indexName: string) => ({
  router,
  stateMapping: getStateMapping({ indexName }),
});

export default getRouting;
//Once React project is made with TypeScript do the following:

//install main dependency of jest
npm i jest --save-dev

//Install react-testing-library packages:

npm i @testing-library/jest-dom @testing-library/react @testing-library/user-event --save-dev

//If using CSS Modules
npm i jest-css-modules-transform

// If using Jest 28 or higher
npm i jest-environment-jsdom

//You will then need: 
//1. jest.config.cjs
module.exports = {
  transform: {
    "^.+\\.(t|j)sx?$": ["@swc/jest"],
    "^.+\\.jsx?$": "babel-jest",
    "^.+\\.css$": "jest-css-modules-transform",
  },
  testEnvironment: "jest-environment-jsdom",
  setupFilesAfterEnv: ["./jest.setup.tsx"],
  preset: "ts-jest",
  testMatch: ["<rootDir>/src/**/*.test.(ts|tsx)"],
  // If SVG needs to be mocked
  moduleNameMapper: {
    "\\.svg$": "<rootDir>/svgMock.tsx",
  },
};

//2. jest.setup.tsx
import '@testing-library/jest-dom';
import '@testing-library/jest-dom/extend-expect';

declare global {
  namespace NodeJS {
    interface Global {
      fetch: jest.Mock;
    }
  }
}

//3. (OPTIONAL) for svg mock; svgMock.tsx:
module.exports = '';

//Excerpt from Bing search:
//It seems like you are trying to import an SVG file as a React component in your test file. This causes Jest to throw an error because it cannot parse the SVG file as JavaScript. You need to mock the SVG file so that Jest can ignore it during testing. You can do this by using the moduleNameMapper option in your Jest configuration and mapping the SVG files to a mock file that returns an empty string or a dummy component

//Therefore, ideally package.json should look like:
{
  "name": "vite-react-starter",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "test": "jest --watch"
  },
  "dependencies": {
    "@swc/jest": "^0.2.26",
    "firebase": "^9.17.2",
    "jest-css-modules-transform": "^4.4.2",
    "jest-environment-jsdom": "^29.5.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^14.0.0",
    "@types/jest": "^29.5.1",
    "@types/react": "^18.0.26",
    "@types/react-dom": "^18.0.10",
    "@vitejs/plugin-react": "^3.0.1",
    "jest": "^29.5.0",
    "ts-jest": "^29.1.0",
    "typescript": "^4.9.5",
    "vite": "^4.0.4"
  }
}
import { useState } from "react";
import Image from "next/image";
import logo from "";

import Hamburger from "./Hamburger";
import NavItem from "./NavItem";

export default function NavBar() {
  const [toggle, setToggle] = useState(false);

  function toggleHamburgerMenu() {
    setToggle((prevToggle) => !prevToggle);
  }

  const navItems = ["", "", "", ""];

  return (
    <header className="header">
      <nav className="nav">
        //<Image className="logo" alt="personal logo" src={logo} />
        //<h4 className="logo-title"></h4>
        <ul className="links">
          {navItems.map((item, index) => (
            <NavItem
              key={index}
              onClick={() => setToggle(false)}
              href={item}
              className="link"
            >
              {item}
            </NavItem>
          ))}
        </ul>
        <Hamburger toggleHamburgerMenu={toggleHamburgerMenu} toggle={toggle} />
      </nav>

      {toggle && (
        <ul className="mobile-links">
          {navItems.map((item, index) => (
            <NavItem
              key={index}
              onClick={() => setToggle(false)}
              href={item}
              className="mobile-link"
            >
              {item}
            </NavItem>
          ))}
        </ul>
      )}
    </header>
  );
}

//Hamburger

function Hamburger({ toggleHamburgerMenu, toggle }) {
  return (
    <button
      id="hamburger-button"
      aria-label="Mobile Menu Button"
      onClick={toggleHamburgerMenu}
      className="hamburger-menu"
    >
      <span className={`${toggle && "open"} hamburger-top`}></span>
      <span className={`${toggle && "open"} hamburger-middle`}></span>
      <span className={`${toggle && "open"} hamburger-bottom`}></span>
    </button>
  );
}

export default Hamburger;

//NavItem component

function NavItem({ onClick, href, className, children }) {
  return (
    <li>
      <a onClick={onClick} href={`#${href}`} className={className} aria-label="menu links">
        {children}
      </a>
    </li>
  );
}
export default NavItem;

const handleChange2 = (e: any) => {
    const name = e.target.value;
    setCabinsSelect((prevState: any) => {
      return {
        ...prevState,
        [name]: {
          ...prevState[name] = { ...prevState[name], preSelect: e.target.checked }
        }
      }
    })
  };
As written in font awesome documentation, you can easily use it like this:
First, install the package by:

npm install @fortawesome/fontawesome-svg-core
npm install @fortawesome/free-solid-svg-icons
npm install @fortawesome/react-fontawesome

Then you can use it like this:

Then you can use it like this:

  // Light:
  <FontAwesomeIcon icon={["fal", "coffee"]} />
  // Regular:
  <FontAwesomeIcon icon={["far", "coffee"]} />
  // Solid
  <FontAwesomeIcon icon={["fas", "coffee"]} />
  // ...or, omit as FontAwesome defaults to solid, so no need to prefix:
  <FontAwesomeIcon icon="coffee" />
  // Brand:
  <FontAwesomeIcon icon={["fab", "github"]} />
You can also use it like this:

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faCoffee } from '@fortawesome/free-solid-svg-icons'

const element = <FontAwesomeIcon icon={faCoffee} />
Sizing:

  <FontAwesomeIcon icon="coffee" size="xs" />
  <FontAwesomeIcon icon="coffee" size="lg" />
  <FontAwesomeIcon icon="coffee" size="6x" />
import moment from 'moment';

const expiryDate = '03-21-2023';
const currentDate = moment();

// Parse the expiry date using Moment.js
const parsedExpiryDate = moment(expiryDate, 'MM-DD-YYYY');

// Compare the expiry date to the current date to check if the token is expired
if (parsedExpiryDate.isBefore(currentDate)) {
  console.log('Token has expired!');
} else {
  console.log('Token is still valid');
}
import React from 'react'
import './App.css';
import { data } from './beliefdata'

export default function Belief() {

  const cardData = data.map(item => {
    return (
      <a key={item.id} className="beliefCard" href={item.cardUrl} target="_blank">
        <img src={item.imgUrl} alt='beliefCard' />
        <h1>{item.title}</h1>
        <p>{item.date}</p>
      </a>
    )
  })

  return (
    <div className='container1'>
      <div className='insightsTitle'>
        <h1>Belief in action</h1>
      </div>

      <div className="beliefCardsContainer">
        {cardData}
      </div>
    </div>
  )
}
"emmet.includeLanguages": {
  "javascript": "javascriptreact"
 }

or 

"emmet.includeLanguages": {
  "javascript": "javascriptreact",
  "typescript": "typescriptreact"
}
const [state, setState] = useState(-1);
map((data, index) => (
  <Grid 
    onClick={() => setState(index)}
    style={{
      background: state === index ? 'lightblue' : 'white'
    }}
  >
))
import React from "react";
import styled, { useTheme } from "styled-components/native";

const sizeVariant = {
  small: 1,
  medium: 2,
  large: 3,
};

const positionVariant = {
  top: "marginTop",
  left: "marginLeft",
  right: "marginRight",
  bottom: "marginBottom",
};

const getVariant = (position, size, theme) => {
  const sizeIndex = sizeVariant[size];
  const property = positionVariant[position];
  const value = theme.space[sizeIndex];

  return `${property}:${value}`;
};

const SpacerView = styled.View`
  ${({ variant }) => variant};
`;

export const Spacer = ({ position, size, children }) => {
  const theme = useTheme();
  const variant = getVariant(position, size, theme);
  return <SpacerView variant={variant}>{children}</SpacerView>;
};

Spacer.defaultProps = {
  position: "top",
  size: "small",
};

//USE LIKE THIS:
<Spacer position="left" size="large">
....
</Spacer>
const textAreaResized = () => {
  const handler = (e) => {
    const target = e.currentTarget;
    target.style.height = "auto";
    target.style.height = `${target.scrollHeight}px`;
  };

  return <textarea onChange={handler} />;
};
*, *::before, *::after{
	box-sizing: border-box;
}

*{
	margin: 0,
	padding: 0,
}

html{
	color-scheme: dark light;
}

body{
	min-height: 100vh;
}

img, picture, video, svg{
	display: block;
	max-width: 100%;
}

input, textarea, select, button {
	font: inherit;
}
const OpaqueWrapper = ({ children }) => (        
    React.Children.map(children, child => (
       <Wrapper>
           {React.cloneElement(child, {style: {...child.props.style, opacity: 0.5}})}
       </Wrapper>
    )))
);
const OpaqueWrapper = ({ children }) => (
    // check that children is defined 
    // if you do not want your wrapper to be rendered empty
    children && (
        <Wrapper>
            {React.Children.map(children, child => (
                React.cloneElement(child, {style: {...child.props.style, opacity: 0.5}})
            ))}
        </Wrapper>
    )
);
import { useState, useEffect, useRef } from "react";
export default function App() {
  const [day, setDay] = useState("Monday");
  const prevDay = usePrevious(day);
  const getNextDay = () => {
    if (day === "Monday") {
      setDay("Tuesday")
    } else if (day === "Tuesday") {
      setDay("Wednesday")
    } else if (day === "Wednesday") {
      setDay("Thursday")
    } else if (day === "Thursday") {
      setDay("Friday")
    } else if (day === "Friday") {
      setDay("Monday")
    }
  }
  return (
    <div style={{padding: "40px"}}>
      <h1>
        Today is: {day}<br />
        {
          prevDay && (
            <span>Previous work day was: {prevDay}</span>
          )
        }
      </h1>
      <button onClick={getNextDay}>
        Get next day
      </button>
    </div>
  );
}
function usePrevious(val) {
  const ref = useRef()

  useEffect(() => {
    ref.current = val
  }, [val])
  return ref.current
}
// Context
import React, {useState} from "react"
const ThemeContext = React.createContext()

function ThemeContextProvider(props) {
    const [theme, setTheme] = useState("dark")
    
    function toggleTheme() {
        setTheme(prevTheme => prevTheme === "light" ? "dark" : "light")
    }
    
    return (
        <ThemeContext.Provider value={{theme, toggleTheme}}>
            {props.children}
        </ThemeContext.Provider>
    )
}

export {ThemeContextProvider, ThemeContext}


// index.js
import React from "react"
import ReactDOM from "react-dom"

import App from "./App"
import {ThemeContextProvider} from "./themeContext"

ReactDOM.render(
    <ThemeContextProvider>
        <App />
    </ThemeContextProvider>, 
    document.getElementById("root")
)


// App.js
import React from "react"

import Header from "./Header"
import Button from "./Button"

function App() {
    return (
        <div>
            <Header />
            <Button />
        </div>
    )
}

export default App


// Button.js
import React, {useContext} from "react"
import {ThemeContext} from "./themeContext"

function Button(props) {
    const {theme, toggleTheme} = useContext(ThemeContext)
    return (
        <button 
            onClick={toggleTheme} 
            className={`${theme}-theme`}
        >
            Switch Theme
        </button>
    )    
}

export default Button

// Header.js
import React, {useContext} from "react"
import {ThemeContext} from "./themeContext"

function Header(props) {
    const {theme} = useContext(ThemeContext)
    return (
        <header className={`${theme}-theme`}>
            <h2>{theme === "light" ? "Light" : "Dark"} Theme</h2>
        </header>
    )    
}

export default Header


import React from "react"
import PropTypes from "prop-types"
import ThemeContext from "./themeContext"

function Button(props) {
    return (
        <button className={`${props.theme}-theme`}>Switch Theme</button>
    )    
}

Button.propTypes = {
    theme: PropTypes.oneOf(["light", "dark"])
}

Button.defaultProps = {
    theme: "light"
}
const LOCAL_STORAGE_KEY = "task-list"

function TodoList() {
  const [todoList, setTodoList] = useState(() => {
    return JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)) || []
  });
    
  useEffect(() => {
    localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(todoList));
  }, [todoList]);

  ...
<div class="page__wrapper">
	<header></header>
  	<main></main>
  	<footer></footer>
</div>

// css style
.page__wrapper {
	width: 100%;
	max-width: 1064px;
	margin: 0 auto;
	padding: 24px 20px;
}
// set ne style in the global style sheet
.swiper-button-prev,
.swiper-button-next {
  width: 20px;
  height: 20px;
  aspect-ratio: 1 / 1;
  padding: 25px;
  //background-color: rgba($black, 0.5);
  border: none;
  border-radius: 50px;
  top: unset !important;
  bottom: -80px;
  outline: none;
  cursor: pointer;
}

.swiper-button-next {
  right: unset !important;
  margin-left: calc(60px + $half-gap);
  background-image: url("../public/arrows-16px-1-tail-right.svg");
  background-repeat: no-repeat;
  background-position: center;

  &::after {
    display: none;
  }

  &.white {
    background-color: rgba($white, 0.5);
  }

  &.black {
    background-color: rgba($black, 0.5);
  }
}

.swiper-button-prev {
  left: 0 !important;
  background-image: url("../public/arrows-16px-1-tail-right.svg");
  background-repeat: no-repeat;
  background-position: center;
  transform: rotate(180deg);

  &::after {
    display: none;
  }

  &.white {
    background-color: rgba($white, 0.5);
  }

  &.black {
    background-color: rgba($black, 0.5);
  }
}
const styles = {
  color: 'purple',
  fontSize: 40,
  border: "2px solid purple",
};

class Colorful extends React.Component {
  render() {
    // change code below this line
    return (
      <div style={styles}>Style Me!</div>
    );
    // change code above this line
  }
};
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      visibility: false
    };
    // change code below this line
    this.toggleVisibility = this.toggleVisibility.bind(this);
    // change code above this line
  }
  // change code below this line
  toggleVisibility() {
    this.setState(state => {
      if (state.visibility === true) {
         return { visibility: false };
       } else {
         return { visibility: true };
      }
    });
  }
  // change code above this line
  render() {
    if (this.state.visibility) {
      return (
        <div>
          <button onClick={this.toggleVisibility}>Click Me</button>
          <h1>Now you see me!</h1>
        </div>
      );
    } else {
      return (
        <div>
          <button onClick={this.toggleVisibility}>Click Me</button>
        </div>
      );
    }
  }
};
class MyApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: ''
    }
  this.handleChange = this.handleChange.bind(this);
  }
  handleChange(event) {
    this.setState({
      inputValue: event.target.value
    });
  }
  render() {
    return (
       <div>
         <GetInput
           input={this.state.inputValue}
           handleChange={this.handleChange}/>
         <RenderInput
           input={this.state.inputValue}/>
       </div>
    );
  }
};

class GetInput extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div>
        <h3>Get Input:</h3>
        <input
          value={this.props.input}
          onChange={this.props.handleChange}/>
      </div>
    );
  }
};

class RenderInput extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div>
        <h3>Input Render:</h3>
        <p>{this.props.input}</p>
      </div>
    );
  }
};
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message: ""
    };
    this.handleEnter = this.handleEnter.bind(this);
    this.handleKeyPress = this.handleKeyPress.bind(this);
  }
  // change code below this line
  componentDidMount() {
    document.addEventListener("keydown", this.handleKeyPress);
  }
  componentWillUnmount() {
    document.removeEventListener("keydown", this.handleKeyPress);
  }
  // change code above this line
  handleEnter() {
    this.setState((state) => ({
      message: state.message + 'You pressed the enter key! '
    }));
  }
  handleKeyPress(event) {
    if (event.keyCode === 13) {
      this.handleEnter();
    }
  }
  render() {
    return (
      <div>
        <h1>{this.state.message}</h1>
      </div>
    );
  }
}
<form action="/action_page.php">
  <label for="pswrd">Password:</label>
  <input
    type="password"
    id="pswrd"
    name="pswrd"
    pattern="[a-z0-9]{1,15}"
    title="Password should be digits (0 to 9) or alphabets (a to z)."
  />

  <button type="submit">Submit</button>
</form>
import * as React from "react";
import * as ReactDOM from 'react-dom';
import Dragula from 'react-dragula';
export class App extends React.Component {
  render () {
    return <div className='container' ref={this.dragulaDecorator}>
      <div>Swap me around</div>
      <div>Swap her around</div>
      <div>Swap him around</div>
      <div>Swap them around</div>
      <div>Swap us around</div>
      <div>Swap things around</div>
      <div>Swap everything around</div>
    </div>;
  },
  dragulaDecorator = (componentBackingInstance) => {
    if (componentBackingInstance) {
      let options = { };
      Dragula([componentBackingInstance], options);
    }
  };
});
ReactDOM.render(<App />, document.getElementById('examples'));
Grab up to 30% off on our blockchain fork development Services limited time Offer ends in November 25.

For the development of many business sectors, blockchain forks are essential. However, depending on the position, the process requires the use of technology. This is why we're going to look at some of the ways that cryptocurrencies can be developed, including forking existing blockchains to create new ones.

Hivelance, a leading blockchain fork development company, creates a customizable Blockchain Fork Development on various blockchain networks such as Ethereum, Tron, and Binance Smart Chain (BSC), allowing innovators to launch their businesses faster.

visit our site for know more-

https://www.hivelance.com/blockchain-forking
Black Friday sale : Grab up to 30% off on our NFT Token development Services limited time Offer ends in November 25.

Hivelance is a reputable NFT Token development business that works with clients from all over the world and across many industry sectors. We have developed secure, efficient, and revenue-generating NFT development solutions. Hivelance is a leading NFT token development company that offering a  top-notch innovative NFT token development solutions for various businesses across multiple industries. Being the best token development company we create and launch the different types of tokens according to the client’s requirement. We make engaging non-fungible token with transparency, high-end security, and faster delivery.

visit our website for more info-

https://www.hivelance.com/nft-token-development
Grab up to 30% off on our ERC20 Token development Services limited time Offer ends in November 25.

The ERC20 Token contract is the smart contract code logic that executes the fungible token activity. When a contract is put into practise on Ethereum, it can be exchanged for any tokens with a similar value. The ERC20 token standard is used for crypto staking, voting, and the exchange of digital cash as a result. Anyone can generate ERC20 tokens and import them into Ethereum virtual machines.

Hivelance provides ERC20 token development service.  We offer an alot of options as part of our ERC20 Token development package, such as code generation, logo design, an audit of the ERC token contract, deployment to the EVM, ongoing development, security audits at regular intervals, and more. We have supported various ICO projects and helped them scale up their fundraising efforts.

https://www.hivelance.com/erc20-token-development
const User = () => {
	<>
		<p> My name is Paul </p>
		<p> I am a boy </p>	
	</>
};
import { useState, useEffect } from "react";
import ReactLoading from "react-loading";
import Formsy from "formsy-react";
import { API } from "aws-amplify";
import OCVForm from "./OCVForm";

const axios = require("axios");

export const FormWrapper = ({
  viewData,
  classes,
  formID,
  link,
  headerText,
  submissionText,
  anchorID,
}) => {
  const [activePage, setActivePage] = useState(0);
  const [state, setState] = useState({});
  const [formData, setFormData] = useState(null);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [isSubmitted, setIsSubmitted] = useState(false);

  const disableButton = () => {
    //setCanSubmit(false);
    setState({ ...state, canSubmit: false });
  };
  const enableButton = () => {
    //setCanSubmit(true);
    setState({ ...state, canSubmit: true });
  };

  const submit = (model) => {
    setIsSubmitting(true);
    API.post("ocvapps", "/form/submission", {
      body: {
        appID: formData.appID,
        data: {
          formID: formID,
          formData: model,
        },
      },
      headers: {
        "x-api-key": "AJgsD4mQAY95dQiaJecac3WBvEFlqnvn3vAxI93f",
        "Content-Type": "application/json",
      },
    })
      .then((response) => {
        if (response?.response?.statusCode === 200) {
          setIsSubmitting(false);
          setIsSubmitted(true);
        } else {
          setIsSubmitting(false);
          setIsSubmitted(false);
          alert(
            "There has been a problem with your form submission. Contact the Web Administrator for help."
          );
        }
      })
      .catch((error) => {
        setIsSubmitting(false);
        setIsSubmitted(false);
        alert(error);
      });
  };

  // retrieve formData
  useEffect(() => {
    async function getFormData() {
      try {
        const response = await axios.get(link);
        setFormData(response?.data?.data);
      } catch (error) {
        console.error(error);
      }
    }

    getFormData();
  }, [link]);

  if (formData === null) {
    return (
      <div className="OCVFormDiv">
        <ReactLoading
          className="loading-centered"
          type={"spinningBubbles"}
          color={"#105c9c"}
          height={"10%"}
          width={"10%"}
        />
      </div>
    );
  } else {
    return (
      <Formsy
        onValidSubmit={submit}
        onValid={enableButton}
        onInvalid={disableButton}
      >
        <OCVForm
          isSubmitted={isSubmitted}
          isSubmitting={isSubmitting}
          disableButton={disableButton}
          enableButton={enableButton}
          formData={formData}
          formID={formID}
          headerText={headerText}
          submissionText={submissionText}
          anchorID={anchorID}
          classes={classes}
          viewData={viewData}
          state={state}
          setState={setState}
          activePage={activePage}
          setActivePage={setActivePage}
        />
      </Formsy>
    );
  }
};
import { useState, useEffect } from "react";
import ReactLoading from "react-loading";
import Formsy from "formsy-react";
import { API } from "aws-amplify";
import OCVForm from "./OCVForm";
import axios from "axios";

export const FormWrapper = ({
  viewData,
  classes,
  formID,
  link,
  headerText,
  submissionText,
  anchorID,
}) => {
  const [activePage, setActivePage] = useState(0);
  const [state, setState] = useState({});
  const [formData, setFormData] = useState(null);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [isSubmitted, setIsSubmitted] = useState(false);

  const disableButton = () => {
    // setCanSubmit(false);
    setState({ ...state, canSubmit: false });
  };
  const enableButton = () => {
    // setCanSubmit(true);
    setState({ ...state, canSubmit: true });
  };

  const submit = (model) => {
    setIsSubmitting(true);
    API.post("ocvapps", "/form/submission", {
      body: {
        appID: formData.appID,
        data: {
          formID,
          formData: model,
        },
      },
      headers: {
        "x-api-key": "AJgsD4mQAY95dQiaJecac3WBvEFlqnvn3vAxI93f",
        "Content-Type": "application/json",
      },
    })
      .then((response) => {
        if (response?.response?.statusCode === 200) {
          setIsSubmitting(false);
          setIsSubmitted(true);
        } else {
          setIsSubmitting(false);
          setIsSubmitted(false);
          alert(
            "There has been a problem with your form submission. Contact the Web Administrator for help."
          );
        }
      })
      .catch((error) => {
        setIsSubmitting(false);
        setIsSubmitted(false);
        alert(error);
      });
  };

  // retrieve formData
  useEffect(() => {
    async function getFormData() {
      try {
        const response = await axios.get(link);
        setFormData(response?.data?.data);
      } catch (error) {
        console.error(error);
      }
    }

    getFormData();
  }, [link]);

  if (formData === null) {
    return (
      <div className="OCVFormDiv">
        <ReactLoading
          className="loading-centered"
          type="spinningBubbles"
          color="#105c9c"
          height="10%"
          width="10%"
        />
      </div>
    );
  }
  return (
    <Formsy
      onValidSubmit={submit}
      onValid={enableButton}
      onInvalid={disableButton}
    >
      <OCVForm
        isSubmitted={isSubmitted}
        isSubmitting={isSubmitting}
        disableButton={disableButton}
        enableButton={enableButton}
        formData={formData}
        formID={formID}
        headerText={headerText}
        submissionText={submissionText}
        anchorID={anchorID}
        classes={classes}
        viewData={viewData}
        state={state}
        setState={setState}
        activePage={activePage}
        setActivePage={setActivePage}
      />
    </Formsy>
  );
};
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { useState, useEffect } from "react";
import ReactLoading from "react-loading";
import Formsy from "formsy-react";
import { Amplify, API } from "aws-amplify";
import OCVForm from "./OCVForm";

export default function FormWrapper({
  viewData,
  formID,
  //link,
  headerText,
  submissionText,
  anchorID,
}) {
  const [activePage, setActivePage] = useState(0);
  const [state, setState] = useState({});
  const [formData, setFormData] = useState(null);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [isSubmitted, setIsSubmitted] = useState(false);

  const disableButton = () => {
    setState({ ...state, canSubmit: false });
  };
  const enableButton = () => {
    setState({ ...state, canSubmit: true });
  };

  Amplify.configure({
    API: {
      endpoints: [
        {
          name: "ocvapps",
          endpoint:
            "https://oc1rhn99vi.execute-api.us-east-1.amazonaws.com/beta",
          region: "us-east-1",
        },
      ],
    },
  });

  const submit = (model) => {
    setIsSubmitting(true);
    API.post("ocvapps", "/form/submission", {
      body: {
        appID: formData.appID,
        data: {
          formID,
          formData: model,
        },
      },
      headers: {
        "x-api-key": "AJgsD4mQAY95dQiaJecac3WBvEFlqnvn3vAxI93f",
        "Content-Type": "application/json",
      },
    })
      .then((response) => {
        if (response?.response?.statusCode === 200) {
          setIsSubmitting(false);
          setIsSubmitted(true);
        } else {
          setIsSubmitting(false);
          setIsSubmitted(false);
          alert(
            "There has been a problem with your form submission. Contact the Web Administrator for help."
          );
        }
      })
      .catch((error) => {
        setIsSubmitting(false);
        setIsSubmitted(false);
        alert(error);
      });
  };

  // retrieve formData
  useEffect(() => {
    const form = {
      version: 3,
      images: 1,
      formManager: 0,
      title: "Multi Page Test",
      sendServer: 1,
      active: 1,
      autoLocation: 1,
      saveToGallery: 1,
      saveUserInfo: ["userName", "userEmail", "userPhone"],
      fromAddress: "noreply@myocv.com",
      subject: "Damage Report App submission",
      message: "A Damage Report has been submitted through the app.",
      emails: [
        {
          email: "changeme@example.com",
          name: "changeme",
        },
      ],
      inactiveMessage:
        "This form is currently inactive please check back later.",
      sections: [
        [
          {
            title: "Report Type",
            fields: [
              {
                fieldID: "reportType",
                type: 4,
                optional: 0,
                subtype: 0,
                multi: 0,
                title: "Type",
                length: 0,
                elements: [
                  "Severe Weather",
                  "Storm Damage",
                  "Power Outage",
                  "Other",
                ],
              },
              {
                fieldID: "reportType",
                type: 9,
                optional: 0,
                subtype: 0,
                multi: 0,
                title: "Location",
              },
            ],
          },
          {
            title: "Personal Details",
            fields: [
              {
                fieldID: "userName",
                type: 0,
                optional: 1,
                subtype: 0,
                multi: 0,
                title: "Name (optional)",
                length: 0,
              },
              {
                fieldID: "userEmail",
                type: 0,
                optional: 1,
                subtype: 1,
                multi: 0,
                title: "Email Address (optional)",
                length: 0,
              },
              {
                fieldID: "userPhone",
                type: 0,
                optional: 1,
                subtype: 3,
                multi: 0,
                title: "Phone Number (optional)",
                length: 0,
              },
            ],
          },
        ],
        [
          {
            title: "Report Details",
            fields: [
              {
                fieldID: "address",
                type: 0,
                optional: 0,
                subtype: 0,
                multi: 0,
                title: "Address",
                length: 0,
              },
              {
                fieldID: "city",
                type: 0,
                optional: 0,
                subtype: 0,
                multi: 0,
                title: "City",
                length: 0,
              },
              {
                fieldID: "state",
                type: 0,
                optional: 0,
                subtype: 0,
                multi: 0,
                title: "State",
                length: 0,
              },
              {
                fieldID: "zipCode",
                type: 0,
                optional: 0,
                subtype: 7,
                multi: 0,
                title: "ZIP Code",
                length: 0,
              },
              {
                fieldID: "dateTimeOfIncident",
                type: 7,
                optional: 0,
                subtype: 0,
                multi: 0,
                title: "Date/Time of Incident",
                length: 0,
              },
              {
                length: 0,
                fieldID: "additionalInfo",
                type: 1,
                optional: 1,
                subtype: 0,
                multi: 0,
                title: "Additional Information (optional)",
              },
            ],
          },
        ],
      ],
      alert911: 0,
      alertText: "",
      leaderText: "",
      footerText: "",
      appID: "a12722222",
    };

    async function getFormData() {
      try {
        //const response = await axios.get(link);
        setFormData(form);
      } catch (error) {
        console.error(error);
      }
    }

    getFormData();
  }, []);

  if (formData === null) {
    return (
      <div className="OCVFormDiv">
        <ReactLoading
          className="loading-centered"
          type="spinningBubbles"
          color="#105c9c"
          height="10%"
          width="10%"
        />
      </div>
    );
  }
  return (
    <Formsy
      onValidSubmit={submit}
      onValid={enableButton}
      onInvalid={disableButton}
    >
      <OCVForm
        isSubmitted={isSubmitted}
        isSubmitting={isSubmitting}
        disableButton={disableButton}
        enableButton={enableButton}
        formData={formData}
        formID={formID}
        headerText={headerText}
        submissionText={submissionText}
        anchorID={anchorID}
        viewData={viewData}
        state={state}
        setState={setState}
        activePage={activePage}
        setActivePage={setActivePage}
      />
    </Formsy>
  );
}
import {createContext, useContext} from 'react';

export type AuthContext = {
  isAuth: boolean
  setIsAuth: (b: boolean) => void
}

export const AuthContext = createContext<AuthContext>({
  isAuth: false,
  setIsAuth: () => undefined
})

export const useAuthContext = () => useContext(AuthContext)

// usage
const {isAuth, setIsAuth} = useAuthContext()

function App() {
  const [isAuth, setIsAuth] = useState(false)

  return (
    <div className="App">
      <AuthContext.Provider value={{isAuth, setIsAuth}}>
        <Header/>
      </AuthContext.Provider>
    </div>
  );
}
=> Simply add the following code inside your render function, like this::

class ShowCurrentYear extends React.Component {
  render() {
    return <div>{new Date().getFullYear()}</div>;
  }
}
...................
=> You could also create the get current year function outside of your render function, like this:
showCurrentYear() {
    return new Date().getFullYear();
}
...................
=> And then insert the output inside your render function wherever you want to show the current year in your app, like this:
<div>{this.showCurrentYear()}</div>
import { useState, useEffect } from "react";

const SECOND = 1_000;
const MINUTE = SECOND * 60;
const HOUR = MINUTE * 60;
const DAY = HOUR * 24;

export default function useTimer(deadline, interval = SECOND) {
  const [timespan, setTimespan] = useState(new Date(deadline) - Date.now());

  useEffect(() => {
    const intervalId = setInterval(() => {
      setTimespan((_timespan) => _timespan - interval);
    }, interval);

    return () => {
      clearInterval(intervalId);
    };
  }, [interval]);

  /* If the initial deadline value changes */
  useEffect(() => {
    setTimespan(new Date(deadline) - Date.now());
  }, [deadline]);
  
  function checkTime(i: string | number) {
    if (i < 10) i = "0" + i
    return i;
  }

// if want 0 before number return {
  //days: checkTime( Math.floor(timespan / DAY)),
// }

  return {
    days: Math.floor(timespan / DAY),
    hours: Math.floor((timespan / HOUR) % 24),
    minutes: Math.floor((timespan / MINUTE) % 60),
    seconds: Math.floor((timespan / SECOND) % 60)
  };
}

// usage
const { days, hours, minutes, seconds } = useTimer("2022-12-31T23:59:59");

(new Date(+timeStampinSeconds * 1000).toISOString()).slice(0, 19))
export const getStaticProps = async (context) => {
  const res = await fetch(
    `https://jsonplaceholder.typicode.com/posts/${context.params.id}`
  );
  const article = await res.json();

  return {
    props: {
      article,
    },
  };
};

export const getStaticPaths = async () => {
  const res = await fetch(`https://jsonplaceholder.typicode.com/posts`);
  const articles = await res.json();

  const ids = articles.map((article) => article.id);
  const paths = ids.map((id) => ({
    params: { id: id.toString() },
  }));

  return {
    paths,
    fallback: false,
  };
};
export const getServerSideProps = async (context) => {
  const res = await fetch(
    `https://jsonplaceholder.typicode.com/posts/${context.params.id}`
  );
  const article = await res.json();

  return {
    props: {
      article,
    },
  };
};
  let currentYear = (new Date()).getFullYear();
  // year
  const options = [];
  for (let i = 1950; i <= currentYear; i++) {
    options.push(i);
  }

jsx //

<select className='border p-2 border-l-pink-700 mr-2' defaultValue={currentYear} onChange={handleYear} name="year" id="year">
            {
              options.map(option => {
                return <option key={option} value={option}>{option}</option>
              })
            }
          </select>
<script>
    var dob = new Date("12/11/2012");
    //calculate month difference from current date in time
    var month_diff = Date.now() - dob.getTime();
    
    //convert the calculated difference in date format
    var age_dt = new Date(month_diff); 
    
    //extract year from date    
    var year = age_dt.getUTCFullYear();
    
    //now calculate the age of the user
    var age = Math.abs(year - 1970);
    
    //display the calculated age
    document.write("Age of the date entered: " + age + " years");
</script>
const counterReducer = (count, action) => {
  switch (action.type) {
    case 'INCREASE':
      return count + 1;
    case 'DECREASE':
      return count - 1;
    default:
      return count;
  }
};
import spinner from "./assets/spinner.gif";

function Spinner() {
  return (
    <div className="w-100 mt-20">
      <img
        width={180}
        className="text-center mx-auto"
        src={spinner}
        alt="Loading..."
      />
    </div>
  );
}
export default Spinner;
import { useState } from 'react';

function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update together</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}
import { useState } from 'react';

function MyButton() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  );
}

export default function MyApp() {
  return (
    <div>
      <h1>Counters that update separately</h1>
      <MyButton />
      <MyButton />
    </div>
  );
}
const addNewGoalHandler = (newGoal) => {
    // if the update of the states doesnt depend from the previous one
    setTask(task.concat(newGoal));
  	//also works setTodos([...todos, newTodo]);
    // setTask((prevtask) => {
    //   // if your state depends from the previous one
    //   return prevtask.concat(newGoal);
    // });
  };
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { Home, About, NotFound } from "./pages";
import Navbar from "./components/layout/Navbar";
import Footer from "./components/layout/Footer";

function App() {
return (
<BrowserRouter>
    <div className="flex flex-col justify-between h-screen">
        <Navbar />
        <main className="container mx-auto px-3 pb-12">
            <Routes>
                <Route path="/" element={<Home />} />
                <Route path="/about" element={<About />} />
                <Route path="/about" element={<NotFound />} />
                <Route path="/*" element={<NotFound />} />
            </Routes>
        </main>
        <Footer />
    </div>
</BrowserRouter>
);
}

export default App;
function Todos() {
  const [filter, setFilter] = React.useState('')


  const { data } = useQuery(
    ['todos', filter],
    () => fetchTodos(filter),
    {
      // ⬇️ disabled as long as the filter is empty
      enabled: !!filter
    }
  )


  return (
      <div>
        // 🚀 applying the filter will enable and execute the query
        <FiltersForm onApply={setFilter} />
        {data && <TodosTable data={data}} />
      </div>
  )
}
import styled from "styled-components";

// Styled component named StyledButton
const StyledButton = styled.button`
  background-color: black;
  font-size: 32px;
  color: white;
`;

function Component() {
  // Use it like any other component.
  return <StyledButton> Login </StyledButton>;
}
<div className="mx-auto container flex items-center" id="nav">
                <div className="w-full pt-2 p-4">
                    <div className="mx-auto md:p-6 md:w-1/2">
                        <div className="flex flex-wrap justify-between">
                            <h1 className="text-2xl text-orange-500 hover:text-orange-500 transition duration-500 p-4">
                                <i className="fas fa-sign-in-alt fa-fw fa-lg"></i>
                                Sign-in
                            </h1>
                            <a
                                href="#home"
                                className="mt-8 text-orange-400 hover:text-orange-600 transition duration-500"
                            >
                                <svg
                                    className=" w-6 h-6 inline-block align-bottom"
                                    fill="none"
                                    stroke-linecap="round"
                                    stroke-linejoin="round"
                                    stroke-width="2"
                                    stroke="currentColor"
                                    viewBox="0 0 24 24"
                                >
                                    <path d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path>
                                </svg>
                                Back to Home
                                <i className="fas fa-chevron-circle-left fa-fw"></i>
                            </a>
                        </div>

                        <div className="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
                            <form method="POST" action="#login">
                                <div className="mb-8">
                                    <label
                                        for="username"
                                        className="block text-gray-700 text-sm font-bold mb-2"
                                    >
                                        <span className="text-red-500">
                                            &nbsp;*
                                        </span>
                                        username
                                    </label>
                                    <div className="mt-1 relative rounded-md shadow-sm">
                                        <div className="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
                                            <svg
                                                className="h-5 w-5 text-gray-400"
                                                fill="none"
                                                stroke-linecap="round"
                                                stroke-linejoin="round"
                                                stroke-width="2"
                                                stroke="currentColor"
                                                viewBox="0 0 24 24"
                                            >
                                                <path d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path>
                                            </svg>
                                        </div>
                                        <input
                                            id="username"
                                            className="block pr-10 shadow appearance-none border-2 border-orange-100 rounded w-full py-2 px-4 text-gray-700 mb-3 leading-tight focus:outline-none focus:bg-white focus:border-orange-500 transition duration-500 ease-in-out"
                                            placeholder="you@example.com"
                                        />
                                    </div>
                                    <strong className="text-red-500 text-xs italic">
                                        username is require
                                    </strong>
                                </div>

                                <div className="mb-8">
                                    <label
                                        for="password"
                                        className="block text-gray-700 text-sm font-bold mb-2"
                                    >
                                        <span className="text-red-500">
                                            &nbsp;*
                                        </span>
                                        Password
                                    </label>
                                    <div className="mt-1 relative rounded-md shadow-sm">
                                        <div className="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
                                            <svg
                                                className="h-5 w-5 text-gray-400"
                                                fill="none"
                                                stroke-linecap="round"
                                                stroke-linejoin="round"
                                                stroke-width="2"
                                                stroke="currentColor"
                                                viewBox="0 0 24 24"
                                            >
                                                <path d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"></path>
                                            </svg>
                                        </div>
                                        <input
                                            name="password"
                                            id="password"
                                            type="text"
                                            className="block pr-10 shadow appearance-none border-2 border-orange-100 rounded w-full py-2 px-4 text-gray-700 mb-3 leading-tight focus:outline-none focus:bg-white focus:border-orange-500 transition duration-500 ease-in-out"
                                        />
                                    </div>
                                </div>

                                <div className="mb-6">
                                    <div className="flex items-center justify-between">
                                        <div>
                                            <label
                                                className="block text-gray-500 font-bold"
                                                for="remember"
                                            >
                                                <input
                                                    className="ml-2 leading-tight"
                                                    type="checkbox"
                                                    id="remember"
                                                    name="remember"
                                                />
                                                <span className="text-sm">
                                                    remember me
                                                </span>
                                            </label>
                                        </div>
                                        <div>
                                            <a
                                                className="font-bold text-sm text-orange-500 hover:text-orange-800"
                                                href="#password-request"
                                            >
                                                forgot password
                                            </a>
                                        </div>
                                    </div>
                                </div>

                                <div className="mb-4 text-center">
                                    <button
                                        className="transition duration-500 bg-orange-500 hover:bg-orange-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
                                        type="submit"
                                    >
                                        Login
                                    </button>
                                </div>
                                <hr />
                                <div className="mt-8">
                                    <p className="text-sm">
                                        no account
                                        <a
                                            className="font-bold text-sm text-orange-500 hover:text-orange-800"
                                            href="#register"
                                        >
                                            sign up
                                        </a>
                                    </p>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
import React, { useEffect, useState, useMemo, useContext } from 'react';
import styled from 'styled-components/macro';
import * as yup from 'yup';
import { yupResolver } from '@hookform/resolvers/yup';
import { useForm, Controller, SubmitHandler } from 'react-hook-form';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';

import FormInput from 'components/FormInput';
import CustomCheckbox from 'components/CustomCheckbox';
import { getUser } from 'redux/reducers/user';
import CustomModalContext from 'contexts/CustomModalContext';
import { useActions } from 'hooks/useActions';
import LearningPackageBody from 'pages/Signup/SelectLearningPackages/LearningPackageBody';
import instance from 'api/axiosInstance';
import { getFormattedSuggestYear } from 'utils/url';
import { formatDateForRegistration } from 'utils/Date';

export interface IStudentAccountForm {
  firstName: string;
  lastName: string;
  userName: string;
  password: string;
  dateOfBirth?: Date;
  email: string;
  isStudentFourYear?: boolean;
  grateStudent?: string;
}

type Props = {
  isModal?: boolean;
};

const grateStudentArr = [
  {
    value: '3',
    title: 'Year 3',
  },
  {
    value: '4',
    title: 'Year 4',
  },
  {
    value: '5',
    title: 'Year 5',
  },
  {
    value: '6',
    title: 'Year 6',
  },
];

const schema = yup.object({
  firstName: yup.string().required('First Name is a required field'),
  lastName: yup.string().required('Last Name is a required field'),
  userName: yup.string().required('User Name is a required field'),
  password: yup.string().required('Password is a required field'),
  dateOfBirth: yup.string().nullable().required('Date of Birth is a required field'),
  email: yup.string().email(),
  isStudentFourYear: yup.boolean(),
  grateStudent: yup.string(),
});

const CreateStudentModal: React.FC<Props> = ({ isModal }) => {
  const { setStudentAccount } = useActions();
  const customModalContext = useContext(CustomModalContext);
  const { hideModal, setActiveView } = customModalContext;
  const history = useHistory();
  const dispatch = useDispatch();
  const currentUser = useSelector(getUser);
  const studentWhenAppClosed = JSON.parse(localStorage.getItem('studentAccount') || '{}');
  const memoizedIsCurUserIdEqualsStudentId = useMemo(
    () => currentUser.userId === studentWhenAppClosed?.parentId,
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [currentUser, studentWhenAppClosed],
  );

  const [studentYear, setStudentYear] = useState('');

  const {
    register,
    formState: { errors },
    control,
    handleSubmit,
    watch,
    setValue,
  } = useForm<IStudentAccountForm>({
    defaultValues: {
      firstName: Boolean(studentWhenAppClosed?.firstName) ? studentWhenAppClosed.firstName : '',
      lastName: Boolean(studentWhenAppClosed?.lastName) ? studentWhenAppClosed.lastName : '',
      userName: Boolean(studentWhenAppClosed?.userName) ? studentWhenAppClosed.userName : '',
      password: Boolean(studentWhenAppClosed?.password) ? studentWhenAppClosed.password : '',
      email: Boolean(studentWhenAppClosed?.email) ? studentWhenAppClosed.email : '',
      isStudentFourYear: studentWhenAppClosed?.isStudentFourYear ? studentWhenAppClosed.isStudentFourYear : true,
      grateStudent: Boolean(studentWhenAppClosed?.grateStudent) ? studentWhenAppClosed.grateStudent : '',
    },
    resolver: yupResolver(schema),
  });

  const newDate = watch('dateOfBirth');
  const isStudentFourYear = watch('isStudentFourYear');
  const grateStudentValue = watch('grateStudent');
  const onSubmit: SubmitHandler<IStudentAccountForm> = async (data) => {
    dispatch(
      setStudentAccount({
        firstName: data.firstName,
        lastName: data.lastName,
        userName: data.userName,
        password: data.password,
        dateOfBirth: data.dateOfBirth!,
        email: data.email,
        isStudentFourYear: data.isStudentFourYear,
        grateStudent: data.grateStudent,
      }),
    );
    !isModal && history.push('/select-learning-packages');
    localStorage.setItem(
      'studentAccount',
      JSON.stringify({ ...data, dateOfBirth: data.dateOfBirth!, parentId: currentUser.userId }),
    );
  };

  const createStudentAccount: SubmitHandler<IStudentAccountForm> = async (data) => {
    setActiveView({
      component: LearningPackageBody,
      props: {
        student: data,
        isModal,
      },
    });
  };

  const getDate = async () => {
    try {
      const selectedDate = newDate;
      const formattedDateValue = formatDateForRegistration(selectedDate);
      const payload = {
        date: formattedDateValue,
      };

      if (formattedDateValue === 'Invalid Date') {
        return;
      }

      const response = await instance.post(getFormattedSuggestYear, payload);

      if (response !== null) {
        setStudentYear(response.data.year);
        if (!isStudentFourYear) {
          setValue('isStudentFourYear', false);
        } else if (String(response.data.year) === grateStudentValue) {
          setValue('isStudentFourYear', true);
        } else {
          setValue('grateStudent', String(response.data.year));
        }
      }
      return response;
    } catch (e) {
      console.log(e);
    }
  };

  useEffect(() => {
    getDate();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [grateStudentValue, newDate, isStudentFourYear]);

  useMemo(() => {
    if (!memoizedIsCurUserIdEqualsStudentId) {
      localStorage.removeItem('studentAccount');
    }
  }, [memoizedIsCurUserIdEqualsStudentId]);

  return (
    <StyledContainer isModal={isModal}>
      {!isModal ? <h3 className="create-student-account__title">Create Student Account</h3> : null}
      <form
        className="create-student-account__form"
        onSubmit={isModal ? handleSubmit(createStudentAccount) : handleSubmit(onSubmit)}
      >
        <div className="create-student-account__form-fields-wrapper">
          <StyledFormInput
            label="First Name"
            name="firstName"
            error={errors.firstName}
            register={register}
            placeholder="Enter a first name"
            inputType="text"
          />
          <StyledFormInput
            label="Last Name"
            name="lastName"
            error={errors.lastName}
            register={register}
            placeholder="Enter a last name"
            inputType="text"
          />
          <StyledFormInput
            label="User Name"
            name="userName"
            error={errors.userName}
            register={register}
            placeholder="Enter a user name"
            inputType="text"
          />
          <StyledFormInput
            label="Password"
            name="password"
            error={errors.password}
            register={register}
            placeholder="Enter a password"
            inputType="password"
          />
          <Controller
            name="dateOfBirth"
            control={control}
            defaultValue={
              Boolean(studentWhenAppClosed?.dateOfBirth)
                ? (new Date(studentWhenAppClosed?.dateOfBirth) as unknown as Date)
                : (new Date() as unknown as Date)
            }
            render={({ field: { onChange, value } }) => (
              <div className="create-student-account__date-wrapper">
                <label htmlFor="date" className="create-student-account__label">
                  Date of Birth
                </label>
                <StyledDatePicker
                  id="date"
                  onChange={onChange}
                  selected={value}
                  value={value as unknown as string}
                  placeholderText="Enter a date of birthday"
                  onKeyDown={(e) => {
                    e.preventDefault();
                  }}
                  dateFormat="MM/dd/yyyy"
                  dateFormatCalendar="MM/dd/yyyy"
                />
                <p className="create-student-account__error">{errors?.dateOfBirth?.message}</p>
              </div>
            )}
          />
          <StyledFormInput
            label="Email Address (optional):"
            name="email"
            error={errors.email}
            register={register}
            placeholder="Enter a email"
            inputType="text"
          />
          <div className="create-student-account__checkbox-form-wrapper">
            <p className="create-student-account__checkbox-title">Is this student in year {studentYear}?</p>
            <Controller
              render={({ field: { onChange, value } }) => (
                <StyledCustomCheckbox
                  title="Yes"
                  name="Yes"
                  register={register}
                  onChange={() => onChange(true)}
                  checked={value}
                />
              )}
              name="isStudentFourYear"
              control={control}
            />
            <Controller
              render={({ field: { onChange, value } }) => (
                <StyledCustomCheckbox
                  title="No"
                  name="No"
                  register={register}
                  onChange={() => onChange(false)}
                  checked={!value}
                />
              )}
              name="isStudentFourYear"
              control={control}
            />
          </div>
          <div className="create-student-account__checkbox-form-wrapper">
            <p className="create-student-account__checkbox-title">What grate is the student? </p>
            {grateStudentArr.map((item, index) => (
              <Controller
                key={index}
                render={({ field: { onChange, value } }) => (
                  <StyledCustomCheckbox
                    title={item.title}
                    register={register}
                    name={item.title}
                    onChange={() => onChange(item.value)}
                    disabled={isStudentFourYear}
                    checked={value === item.value}
                  />
                )}
                name="grateStudent"
                control={control}
              />
            ))}
          </div>
        </div>
        {!isModal ? (
          <button className="create-student-account__form-button-next" type="submit">
            Next
          </button>
        ) : (
          <div className="create-student-account__buttons-wrapper">
            <button className="create-student-account__close-button" type="button" onClick={hideModal}>
              Close
            </button>
            <button className="create-student-account__form-button-next" type="submit">
              Add Student
            </button>
          </div>
        )}
      </form>
    </StyledContainer>
  );
};

const StyledContainer = styled.div<Props>`
  width: ${(props) => (props.isModal ? '901px' : '1016px')};
  margin: 0 auto;
  background: white;
  border-radius: ${(props) => (props.isModal ? 0 : '25px')};
  padding: ${(props) => (props.isModal ? 0 : '42px 68px 58px')};
  border-top: ${(props) => (props.isModal ? '1px solid #ececec' : 'none')};
  padding-top: ${(props) => (props.isModal ? '32px' : 'none')};
  font-family: ${({ theme }) => theme.font.fontFamily.popins};
  .create-student-account {
    &__title {
      font-size: 30px;
      line-height: 39px;
      letter-spacing: 0.43px;
      color: #20114d;
      margin: 0;
      padding-bottom: 25px;
      font-weight: 600;
      border-bottom: 1px solid #ececec;
      margin-bottom: 18px;
    }

    &__form {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: start;
    }

    &__form-fields-wrapper {
      width: 100%;
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      grid-template-rows: repeat(3, max-content);
      column-gap: 28px;
      row-gap: 10px;
      margin-bottom: 51px;
    }

    &__checkbox-form-wrapper {
      display: grid;
      grid-template-columns: min-content repeat(2, 0.1fr);
      column-gap: 45px;
      grid-column: 1 / 3;

      :last-of-type {
        grid-template-columns: min-content repeat(4, 0.1fr);
      }
    }

    &__checkbox-title {
      font-family: ${({ theme }) => theme.font.fontFamily.popins};
      font-weight: 600;
      font-size: 16px;
      line-height: 18px;
      letter-spacing: 0.2px;
      width: 221px;
      color: #20114d;
    }

    &__form-button-next {
      padding: 11px 30px;
      width: fit-content;
      color: white;
      background: #32e790;
      text-align: center;
      font-weight: 600;
      font-size: 14px;
      line-height: 18px;
      letter-spacing: 0.2px;
      border-radius: 27px;
      border: 2px solid #32e790;
      align-self: end;
      cursor: pointer;
      font-family: ${({ theme }) => theme.font.fontFamily.popins};

      :last-of-type {
        padding: 9px 34px;
      }
    }

    &__date-wrapper {
      display: flex;
      flex-direction: column;
      justify-content: start;
    }

    &__label {
      margin: 0 0 10px 0;
      margin-bottom: 10px;
      font-size: 14px;
      color: #20114d;
      font-weight: 400;
    }

    &__error {
      font-size: 9px;
      color: red;
      margin-top: 5px;
      text-transform: capitalize;
    }

    &__buttons-wrapper {
      display: flex;
      flex-direction: row;
      align-items: space-between;
      justify-content: space-between;
      width: 100%;
    }

    &__close-button {
      padding: 9px 34px;
      width: 157px;
      color: rgba(245, 80, 83, 1);
      background: white;
      text-align: center;
      font-weight: 600;
      font-size: 14px;
      line-height: 18px;
      letter-spacing: 0.2px;
      border-radius: 27px;
      border: 2px solid rgba(245, 80, 83, 1);
      align-self: end;
      cursor: pointer;
    }
  }
`;

const StyledCustomCheckbox = styled(CustomCheckbox)`
  width: 90px;

  label {
    font-family: ${({ theme }) => theme.font.fontFamily.popins};
    font-weight: ${({ theme }) => theme.font.fontWeight.medium};
    font-size: 16px;
    line-height: 18px;
    letter-spacing: 0.2px;
    color: #20114d;
  }

  .custom-checkbox + label {
    position: relative;
  }

  .custom-checkbox + label::before {
    width: 23px;
    height: 23px;
    border-radius: 50%;
    width: 1.5em;
    height: 1.5em;
  }

  .custom-checkbox:checked + label::before {
    background-color: #41e85b;
    background-image: none;
  }

  .custom-checkbox:checked + label::after {
    content: '';
    width: 14px;
    height: 14px;
    position: absolute;
    border-radius: 50%;
    left: 5px;
    background-color: #41e85b;
    border: 2px solid white;
  }
`;

const StyledDatePicker = styled(DatePicker)`
  border: 1px solid #dad1c9;
  border-radius: 13px;
  padding: 11px 15px 11px 15px;
  outline: none;
  width: 100%;
  font-weight: 600;
  font-size: 16px;
  line-height: 18px;
  letter-spacing: 0.2px;
  font-family: ${({ theme }) => theme.font.fontFamily.popins};

  ::placeholder {
    color: rgba(32, 17, 77, 0.5);
    font-family: ${({ theme }) => theme.font.fontFamily.popins};
  }
`;

const StyledFormInput = styled(FormInput)`
  font-weight: 600;
  font-size: 16px;
  line-height: 18px;
  letter-spacing: 0.2px;
  color: rgb(166, 160, 184);
  font-family: ${({ theme }) => theme.font.fontFamily.popins};

  ::after {
    color: #20114d;
  }
`;

export default CreateStudentModal;
import React, {useState} from 'react'

function HookCounterThree() {
  
  const[name, setName]= usestate({ firstName:'', lastName:'' })
  return (
    <form>
 //can overwrite previously entered input
      <input type="text" value={name.firstName} onChange={e =>setName({firstName:e.target.value})/>
      <input type="text"value={name.lastName} onChange={e =>setName({lastName:e.target.value})/>
//fixed using the spread operator
         <input type="text" value={...name.firstName} onChange={e =>setName({firstName:e.target.value})/>
      <input type="text"value={...name.lastName} onChange={e =>setName({lastName:e.target.value})/>
      <h2> Your first name is {name.firstName}</h2>
      <h2> Your last name is {name.lastName}</h2>
    </form>
  )
}
export default HookCounterThree
import React, {useState} from 'react'

function HookCounterTwo () {
  const initialCount = 0
  const [count, setCount] = useState(initialCount)
  return (
    <div>
    Count: {count}
	<button onClick={() => setCount(initialCount)}>Reset</button>
//This is not the best method because it is based upon whatever the initial Count is it doesn't access the previous state
    <button onClick={() => setCount(count + 1)}>Increment</button>
	<button onClick={() => setCount(count - 1)}>Decrement</button>
//Best Method below
    <button onClick={() => setCount(prevCount => prevCount + 1)}>Increment</button>
	<button onClick={() => setCount(prevCount => prevCount - 1)}>Decrement</button>
    </div>
  )
}
export default HookCounterTwo
import React, {useState} from 'react'

function HookCounter() {
  const [count, setCount]= useState(0)
  
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Count {count}</button>
    </div>
  )
}
export default HookCounter
import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  function updateCount() {
    setCount(count + 1);
  }

  return <button onClick={updateCount}>Count is: {count}</button>;
}
import React, { Component } from 'react';
import { Platform, StyleSheet, Text, View, WebView } from 'react-native';

export default class App extends Component {
  render() {
    var htmlContent = 'test';

    return (
      <WebView
        style={styles.container}
        javaScriptEnabled={true}
        domStorageEnabled={true}
        source={{ html: htmlContent }}
      />
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#e5e5e5',
  },
});
import { useParams } from 'react-router-dom'

<h1>Sample {params.id}</h1>

//Route
<Route path='/sample/:id/' element={<Post />} />
export const toggle=()=>{
    return dispatch=>{
        dispatch({
        type:'toggle'
    })
    }
}
npm i --save @fortawesome/fontawesome-svg-core
npm install --save @fortawesome/free-solid-svg-icons
npm install --save @fortawesome/react-fontawesome
//import 
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faDash,faBan,faTrash ,faCoffee} from '@fortawesome/free-solid-svg-icons'

 <FontAwesomeIcon icon={faBan}  />
//Import the useState hook
import {useState} from 'react';

function App(){

//Define the state
  const [name, setName] = useState('Stephanie')
  const [color, setColor] = useState('Blue')
  
//Update the state
  const handleChange =()=>{
    setName('Bryan')
    setColor('red')
  }

  return(
    <section className = 'app'>
    <p>Hi I'm {name} and my favourite color is {color}</p>
    <button onClick ={handleChange}>Click me </button>
    </section>
  )
}

export default App
// A Modal with input in it, that receives focus when it is mounted and displayed on screen

// child component
import {useEffect} from "react"

export const Modal =({forwardedRef}) =>{
  useEffect(()=> {
    // adding the focus() to the ref when component is mounting
    forwardedRef.current?.focus()
  },[forwardedRef])

  return(
    <div>
      <label htmlFor="email">Add your email:</label>
      <input type="email" name="email" id="email" ref={forwardedRef}/>
    </div>
  )
}

// parent component
import {useRef, useState} from "react"
import {Modal} from "./Modal"

export default function App() {
  const [isModalOpened, setIsModalOpened] = useState(false)
  const inputRef = useRef()

  function handleModal(){
    setIsModalOpened(!isModalOpened)
  }
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button type="button" onClick={handleModal}>
  		{isModalOpened === true ? "Close modal" : "Open modal"}
	</button>

      {isModalOpened && <Modal forwardedRef={inputRef}/>}
    </div>
  );
}

// Parent component will receive as props the values or functions set for the ref on the child component
// child component
import {forwardRef} from "react"

export const Button = forwardRef(({...props}, ref) => {
return <button ref={ref} id="buttonId-js" {...props}>Button</button>
})

// parent component
import {useRef} from "react"
import { Button } from "./Button";

export default function App() {
const buttonRef = useRef()
return (
<div className="App">
    <h1>Hello CodeSandbox</h1>
    <h2>Start editing to see some magic happen!</h2>
    <Button ref={buttonRef} onClick={()=> console.log(buttonRef.current.id)}
        />
</div>
);
}

// buttonRef.current gives access nodes and DOM, allowing to change the component
// useRef should be used in uncontrolled components - those ones that are not handled by React states or handle functions
<Route path=":id/makeYear?" element={<User/>} />
  //
const [searchParams, setSearchParams] = useSearchParams();
const makeYear = searchParams.get("makeYear");
 <Route path="users">
        <Route path=":userId" element={<ProfilePage />} />
        <Route path="me" element={...} />
      </Route>
npm create vite@latest 
cd <project name>
npm install
npm run dev
// components/Navigation.js

import { useEffect, useState } from "react";

export default function Navigation() {
  
  const [clientWindowHeight, setClientWindowHeight] = useState("");

  const [backgroundTransparacy, setBackgroundTransparacy] = useState(0);
  const [padding, setPadding] = useState(30);
  const [boxShadow, setBoxShadow] = useState(0);

  useEffect(() => {
    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  });

  const handleScroll = () => {
    setClientWindowHeight(window.scrollY);
  };

  useEffect(() => {
    let backgroundTransparacyVar = clientWindowHeight / 600;

    if (backgroundTransparacyVar < 1) {
      let paddingVar = 30 - backgroundTransparacyVar * 20;
      let boxShadowVar = backgroundTransparacyVar * 0.1;
      setBackgroundTransparacy(backgroundTransparacyVar);
      setPadding(paddingVar);
      setBoxShadow(boxShadowVar);
    }
  }, [clientWindowHeight]);

  return (
    <nav
      class="navbar navbar-expand-lg navbar-light fixed-top"
      style={{
        background: `rgba(255, 255, 255, ${backgroundTransparacy})`,
        padding: `${padding}px 0px`,
        boxShadow: `rgb(0 0 0 / ${boxShadow}) 0px 0px 20px 6px`,
      }}
    >
      <div className="container">
        <a class="navbar-brand" href="#">
          Techomoro
        </a>
        <button
          class="navbar-toggler"
          type="button"
          data-toggle="collapse"
          data-target="#navbarText"
          aria-controls="navbarText"
          aria-expanded="false"
          aria-label="Toggle navigation"
        >
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarText">
          <ul class="navbar-nav mr-auto">
            <li class="nav-item active">
              <a class="nav-link" href="#">
                Home
              </a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">
                About
              </a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">
                Contact
              </a>
            </li>
          </ul>
        </div>
      </div>
    </nav>
  );
}
// React with webpack and babel configuration, to support Sass and SVG files
// npm init to initialize the project, then install packages 
// set project structure similar to CRA 
// index.jsx and App.jsx following same of CRA

// package.json
{
  "name": "something project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "npm run start & npx webpack serve",
    "build": "cross-env NODE_ENV=production webpack",
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@babel/cli": "^7.18.10",
    "@babel/core": "^7.18.10",
    "@babel/preset-env": "^7.18.10",
    "@babel/preset-react": "^7.18.6",
    "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
    "babel-loader": "^8.2.5",
    "cross-env": "^7.0.3",
    "css-loader": "^6.7.1",
    "dotenv": "^16.0.1",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^5.5.0",
    "react-refresh": "^0.14.0",
    "sass": "^1.54.1",
    "sass-loader": "^13.0.2",
    "style-loader": "^3.3.1",
    "svg-url-loader": "^7.1.1",
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.9.3"
  }
}


//webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
const isDevelopment = process.env.NODE_ENV !== "production";

module.exports = {
  mode: isDevelopment ? "development" : "production",
  devtool: isDevelopment ? "eval-source-map" : "source-map",
  entry: path.resolve(__dirname, "src", "index.jsx"),
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
  resolve: {
    extensions: [".js", ".jsx"],
  },
  module: {
    rules: [
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            plugins: [
              isDevelopment && require.resolve("react-refresh/babel"),
            ].filter(Boolean),
          },
        },
      },
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: ["style-loader", "css-loader"],
      },
      {
        test: /\.scss$/,
        exclude: /node_modules/,
        use: ["style-loader", "css-loader", "sass-loader"],
      },
      {
        test: /\.svg$/,
        use: [
          {
            loader: "svg-url-loader",
            options: {
              limit: 10000,
            },
          },
        ],
      },
      {
        test: /\.(png|jpe?g|gif)$/i,
        use: [
          {
            loader: "file-loader",
            options: {
              name: "images/[hash]-[name].[ext]",
            },
          },
        ],
      },
    ],
  },
  plugins: [
    isDevelopment && new ReactRefreshWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "public", "index.html"),
    }),
  ].filter(Boolean),
  devServer: {
    // contentBase: path.join(__dirname, "public") // renamed to 'static'
    static: path.join(__dirname, "public"),
    hot: true,
  },
};

// babel.config.js
module.exports = {
  presets: [
    "@babel/preset-env",
    ["@babel/preset-react", { runtime: "automatic" }],
  ],
};

export enum KycModeKind {
  VIEW = 'VIEW',
  EDIT = 'EDIT',
}

export type KycMode = KycModeKind.VIEW | KycModeKind.EDIT;
var condition = true;

var props = {
  value: 'foo',
  ...(condition && { disabled: true })
};

var component = <div {...props} />;
<Form.Field control={Radio} label="Male" checked={gender === 'Male'} value="Male" onClick={() => setGender('Male')} />
<Form.Field control={Radio} label="Female" checked={gender === 'Female'} value="Female" onClick={() => setGender('Female')} />
// custom.d.ts
declare module "*.svg" {
  import React = require('react');
  export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
  const src: string;
  export default src;
}

// tsconfig
"include": [
    "src",
    "custom.d.ts"
  ]
import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client";

const httpLink = createHttpLink({
  uri: <insert uri here>,
});

//Without authentication
const createApolloClient = () => {
  return new ApolloClient({
    link: httpLink,
    cache: new InMemoryCache(),
  });
}


/* With authentication using setContext. <authentication_token> can also be a function or method returning an authentication token */
import {setContext} from "@apollo/client/link/context";

const createApolloClient = (<authentication_token>) => {
  const authLink = setContext(async (_, { headers }) => {
    try {
      const accessToken = <authentication_token>;
      return {
        headers: {
          ...headers,
          authorization: accessToken ? `Bearer ${accessToken}` : "",
        },
      };
    } catch (e) {
      console.log(e);
      return {
        headers,
      };
    }
  });

  return new ApolloClient({
    link: authLink.concat(httpLink),
    cache: new InMemoryCache(),
  });
};
  

export default createApolloClient;
import { useEffect, useState } from 'react';

interface ConfirmState {
  isOpen: boolean;
  proceed: any;
  cancel: any;
}

interface UseConfirmReturnType extends ConfirmState {
  isConfirm: () => Promise<boolean>;
}

export const useConfirm = (): UseConfirmReturnType => {
  const [confirm, setConfirm] = useState<ConfirmState>({} as ConfirmState);
  const [needsCleanup, setNeedsCleanup] = useState(false);

  const isConfirm = () => {
    setNeedsCleanup(true);
    const promise = new Promise((resolve, reject) => {
      setConfirm({
        isOpen: true,
        proceed: resolve,
        cancel: reject,
      });
    });

    return promise.then(
      () => {
        setConfirm({ ...confirm, isOpen: false });
        return true;
      },
      () => {
        setConfirm({ ...confirm, isOpen: false });
        return false;
      }
    );
  };

  useEffect(() => {
    return () => {
      if (confirm.cancel && needsCleanup) {
        confirm.cancel();
      }
    };
  }, [confirm, needsCleanup]);

  return {
    ...confirm,
    isConfirm,
  };
};
import React from "react";
import {createRoot} from "react-dom/client";

// do not modify this function
function Navbar() {
    return (
        <>
            <h3>Supermarket</h3>
            <p>Start shopping</p>
        </>
    );
}

const root = document.querySelector("#react-root");
createRoot(root).render(Navbar());
// TODO:
npm install -g gitignore
npx gitignore <language/framework/library>
  
/* npx gitignore node
npx gitignore react
npx gitignore reactNative */
//Nested If Construct or Statements

static void Main(string[] args)

        {

            int Salary, Service;

            Console.Write("Enter Yrs Of Service:-");
            Service = Convert.ToInt32(Console.ReadLine());

 

            Console.Write("Enter Salary:-");
            Salary = Convert.ToInt32(Console.ReadLine());

 

            if (Service < 5)
            {
                if (Salary < 500)
                {
                    Console.WriteLine("Provided Bonus:-> 100");
                }
                else
                {
                    Console.WriteLine("Provided Bonus:-> 200");
                }
            }
            else
            {
                Console.WriteLine("Provided Bonus:-> 700");
            }
            Console.ReadLine();
        }
//=========================================
//Switch .. Case Construct or Statements

static void Main(string[] args)
        {
            int Day;
            Console.WriteLine("Enter Your Choice:-");
            Day = Convert.ToInt32(Console.ReadLine());

            switch (Day)
            {
                case 1:
                    Console.WriteLine("Sunday");
                    break;
                case 2:
                    Console.WriteLine("Monday");
                    break;
                case 3:
                    Console.WriteLine("Tuesday");
                    break;
                case 4:
                    Console.WriteLine("Wednesday");
                    break;
                case 5:
                    Console.WriteLine("Thursday");
                    break;
                case 6:
                    Console.WriteLine("Friday");
                    break;
                case 7:
                    Console.WriteLine("Saturday");
                    break;
                default:
                    Console.WriteLine("Enter a Number between 1 to 7");
                    break;
            }
            Console.ReadLine();
        }

//==================================
//The while loop


static void Main(string[] args)
        {
            int num = 1;
            //Console.Write("Enter Number:-");
            //num = Convert.ToInt32(Console.ReadLine());

            while (num <= 11)
            {
                   if ((num % 2) == 0)
                   {
                         Console.WriteLine(+num);
                   }
              
              num = num + 1;
            }
            Console.ReadLine();

        }

//==================================
//The "Do-While" Loop

module.exports = {
  globals: {
    module: true,
  },
  env: {
    browser: true,
    es6: true,
    jest: true,
  },
  extends: [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
  ],
  plugins: ["react", "@typescript-eslint"],
  settings: {
    react: {
      pragma: "React",
      version: "detect",
    },
  },
  rules: {
    "@typescript-eslint/explicit-function-return-type": 0,
    "@typescript-eslint/explicit-module-boundary-types": 0,
    "react/react-in-jsx-scope": 0,
  },
  'import/order': [
    2,
    {
      'newlines-between': 'always',
      groups: [
        'builtin',
        'external',
        'internal',
        'parent',
        'sibling',
        'index',
        'unknown',
        'object',
        'type',
      ],
      alphabetize: {
        order: 'asc',
        caseInsensitive: true,
      },
      pathGroups: [
        {
          pattern: 'react*',
          group: 'external',
          position: 'before',
        },
      ],
    },
  ],
};

// Add lint script to package.json
// "lint": "eslint './src/**/*.{ts,tsx}'"
$npm install --save-dev eslint @babel/eslint-parser eslint-plugin-react eslint-plugin-react-native ...

// AUTOMATIC CONFIG FILE
$npm init @eslint/config

//GLOBAL INSTALLATION AND USE
$npm i -g eslint
$eslint --init

// PACKAGE.JSON
{ //...,
  
  "devDependencies": {
    "@babel/eslint-parser": "^7.18.9",
    "@trivago/prettier-plugin-sort-imports": "^3.3.0",
    "@typescript-eslint/eslint-plugin": "^5.32.0",
    "@typescript-eslint/parser": "^5.32.0",
    "eslint": "^8.21.0",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-import": "^2.26.0",
    "eslint-plugin-jsx-a11y": "^6.6.1",
    "eslint-plugin-react": "^7.30.1",
    "eslint-plugin-react-hooks": "^4.6.0"
  },
   //...
}

// TSCONFIG.JSON
{
  "compilerOptions": {
    "target": "es6",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "noImplicitAny": false,
    "strictNullChecks": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src/**/*"
  ]
}


// .ESLINTRC
{
  "globals": {
    "module": true
  },
  "env": {
    "browser": true,
    "es2021": true
  },
  "extends": [
    "airbnb",
    "airbnb/hooks",
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": "latest",
    "sourceType": "module"
  },
  "plugins": [
    "react",
    "@typescript-eslint"
  ],
  "rules": {
    "@typescript-eslint/explicit-function-return-type": 0,
    "@typescript-eslint/explicit-module-boundary-types": 0,
    "react/react-in-jsx-scope": 0,
    "quotes": [
      "error",
      "double"
    ],
    "import/extensions": 0,
    "import/no-unresolved": 0,
    "linebreak-style": [
      "error",
      "windows"
    ],
    "operator-linebreak": "off",
    "react/jsx-filename-extension": 0,
    "no-shadow": "off",
    "jsx-a11y/label-has-associated-control": 0,
    "react/jsx-no-bind": 0,
    "no-unused-expressions": [
      "warn",
      {
        "allowShortCircuit": true,
        "allowTernary": true
      }
    ]
  }
}

// .PRETTIERRC
{
  "trailingComma": "all",
  "importOrder": [
    "^(next/(.*)$)|^(next$)",
    "<THIRD_PARTY_MODULES>",
    "next-seo.config",
    "^components/(.*)$",
    "^utils/(.*)$",
    "^assets/(.*)$",
    "^@fontsource/(.*)$",
    "^[./]"
  ],
  "importOrderSeparation": true,
  "importOrderSortSpecifiers": true
}
<Image source={{uri: 'https://reactnative.dev/docs/assets/p_cat2.png', }}
          style={{ width: 250, height: 200 }}
/>
//------------------------------------------------
// texbox

<TextInput
        style={styles.input}
        onChangeText={onChangeNumber}
        value={number}
        placeholder="useless placeholder"
        keyboardType="numeric"
		//defaultValue="Name me!"
      />
          
        
//------------------------------------------------        
//funtion 
const Cat = (props) => { return (
    <View>
      <Text>Hello, I am {props.name}!</Text>
    </View>
  );}
       


 // call funtion <Cat />

    <Cat name="Maru" />

//-----------------------------------------------   
// list view
      
const styles = StyleSheet.create({
  container: {
   flex: 1,
   paddingTop: 80
  },
  item: {
    padding: 10,
    fontSize: 18,
    height: 44,
  },
});

const FlatListBasics = () => {
  return (
    <View style={styles.container}>
      <FlatList
        data={[
          {key: 'Devin'},
          {key: 'Dan'},
          {key: 'Dominic'},
          {key: 'Jackson'},
          {key: 'James'},
          {key: 'Joel'},
          {key: 'John'},
          {key: 'Jillian'},
          {key: 'Jimmy'},
          {key: 'Julie'},
        ]}
        renderItem={({item}) => <Text style={styles.item}>{item.key}</Text>}
      />
    </View>
  );
}

export default FlatListBasics;   

// show the list off item 
//renderitem will list down the name
      
//--------------------------------
// for button 

export default class ButtonBasics extends Component { _onPressButton() 
{ 
alert('You tapped the button!')
}

  render() {
    return (
      <View style={styles.container}>
        <View style={styles.buttonContainer}>
          
         	 	<Button onPress={this._onPressButton} title="Press Me"/>
        </View>
        <View style={styles.buttonContainer}>
          		
          		<Button onPress={this._onPressButton} title="Press Me" color="#841584" />
        </View>
        <View style={styles.alternativeLayoutButtonContainer}>
          
          		<Button onPress={this._onPressButton} title="This looks great!" />
          		<Button onPress={this._onPressButton} title="OK!" color="#841584" />
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
   flex: 1,
   justifyContent: 'center',
  },
  buttonContainer: {
    margin: 4
  },
  alternativeLayoutButtonContainer: {
    margin: 40,
    flexDirection: 'row',
    justifyContent: 'space-between'
  }
});     
    
const container = React.createElement('div', {}, [title, paragraph]);
const container = React.createElement('div', {className='container'}, [title, paragraph]);
const container = React.createElement('div', {className='container', children: 'Hello Stranger'});

// with JSX
const container = <div className='container'>Hello Stranger</div>
// with return with a single child
{events.map((item) => {
  return <p>{item.title}</p>;
  }
)}

// with return with a multiple children
{events.map((item) => {
  return (
  <>
    <p>{item.title}</p>
   <p>{item.description}</p>
  </>
  );
 }
)}

// with return and conditional
{events.map((item, index) => {
  if (index % 2 === 0) {
    return (
      <p>{index}{item.title}</p>
  	);
  }
})}

//no return declaration and single child
{events.map((item, index) => (
  <p>{item.title}</p>
  )
)}

//no return declaration and multiple chidlren
{events.map((item, index) => (
  <>
  	<p>{item.title}</p>
  	<p>{item.description}</p>
  </>
 )
)}

//Ps.: conditionals are only allowed with return declaration
// Consider a array that you need to map to display it
// You want to group the array content into pairs
// Each pair will have: open div tag + pair of items + close div tag
// To reach that, use index during the mapping, like below
// Ps.: The list I have to reproduce this has 15 items

var openDiv = "<div>";
var closeDiv = "</div>";
var animation = "--- collapsible content ---";

list.map((item, index) => {
  // call all odd indexes and last item of the list, opening the div before each one
  if (index % 2 === 0 || index === mealList.length - 1) {
    console.log(openDiv);
    console.log(index, item.foodItem);
  }
  // call all even numbers, closing the div after each one
  if (index % 2) {
    console.log(index, item.foodItem);
    console.log(closeDiv);
    console.log(animation);
    console.log(" ");
  }
  // call the last item of the list to close the div
  if (index === mealList.length - 1) {
    console.log(closeDiv);
    console.log(animation);
  }
});

/* 
Output:
<div>
0 Oven Mitt - 13 Inch
1 Lamb - Bones
</div>
--- collapsible content ---
 
<div>
2 Mcguinness - Blue Curacao
3 Pumpkin - Seed
</div>
--- collapsible content ---

<div>
4 Onions - Red Pearl
5 Wine - Rioja Campo Viejo
</div>
--- collapsible content ---

<div>
6 Pepper - Green, Chili
7 Coffee Caramel Biscotti
</div>
--- collapsible content ---

<div>
8 Water - Perrier
9 Bread - Multigrain
</div>
--- collapsible content ---

<div>
10 Veal - Tenderloin, Untrimmed
11 Butcher Twine 4r
</div>
--- collapsible content ---

<div>
12 Extract Vanilla Pure
13 Strawberries - California
</div>
--- collapsible content ---

<div>
14 Nut - Walnut, Chopped
</div>
--- collapsible content ---
*/
const [inputValue, setInputValue] = useState('');
const [list, setList]= useState([]);

handleAddIntemOnList(){
  // create a new item as object to be added to the list array
  const newItem = {
    name: inputValue,
    addedAt: new Date().toLocaleTimeString("pt-br", {
      hour: '2-digit',
      minute: '2-digit'
    })
  }
  // save into the list state
  setList(prevState => [...prevState, newItem])
}
setState(prevState => [...prevState, newState])
const createdAt = new Date().toLocaleTimeString("pt-br", {
  hour: '2-digit',
  minute: '2-digit',
  second: '2-digit',
})
const [inputs, setInputs] = useState({
    title: '',
    address: '',
    methodName: '',
    signatures: '',
    calldatas: ''
  }) 


const inputHandler = (event:React.ChangeEvent<HTMLInputElement>) => {
    setInputs({...inputs, [event.target.name]: event.target.value})
  };


<Input placeholder='Title' name='title' onChange={inputHandler}/>
<Input placeholder='Target contract address' name='address' onChange={inputHandler}/>
<Input placeholder='Method name' name='methodName' onChange={inputHandler}/>
 const initialState = {
    name: "",
    email: "",
    mobile: "",
    subject: "",
    message: "",
  };
  const [formData, setFormData] = useState(initialState);

  const newsletterHandler = (e) => {
    e.preventDefault();
    console.log(formData);
    window.location.href =
      "mailto:info@gmail.com?" +
      "&body=" +
      "Name : " +
      formData.name +
      "%0D" +
      "Email : " +
      formData.email +
      "%0D" +
      "Mobile : " +
      formData.mobile +
      "%0D" +
      "Subject : " +
      formData.subject +
      "%0D" +
      "Message : " +
      formData.message;

    setTimeout(() => {
      setFormData(initialState);
    }, 3000);
  };
If you want to get rid of unnecessary files created by create-react-app you can:
1. Install this: npm i -g cleanup-react-app
2. Run inside your REACT project: cleanup-react-app
 <Control
type="text"
size="sm"
style={{ width: '146px' }}
placeholder="Enter new library name"
onInput={(e) => setLibraryName((e.target as HTMLInputElement).value)}
onBlur={() => dispatch(posesSlice.actions.setLibrary({ name: libraryName }))}
/>
this.setState automatically calls render, so it would create infinite loop.


Question:

What values can you store in state?
Answer

A React component’s state is a plain JavaScript object, so it can store any valid value that is storable within a JavaScript object. This includes booleans, strings, numbers, and even other objects which you can nest within the state.
/* 
1. A constructor is a function that creates an instance of a class 
 which is typically called an “object”.

 2. In JavaScript, a constructor gets
 called when you declare an object using the new keyword.

 3. The purpose of a constructor is to create an object and 
 set values if there are any object properties present.
*/
function Person(first, last, age, eye) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
}

// Create a Person object
const myFather = new Person("John", "Doe", 50);
console.log(myFather)
/*
Inheritance is when we create a parent class with properties and methods
that we can extend to child classes.
We use the extends keyword to create a subclass.
The super keyword calls the constructor() of a parent class.
*/

/*
Remember Functions are function-object combo, In the object bit of 
function we put all the methods in a default property(which every
object has) called prototype and it is itself an object. 

In ES6 class keyword puts them in prototype object for us automatically
and the function bit of function-object combo, we rename it 
"constructor".
Every object has hidden property called __proto__ which makes link to 
prototype in the objects chain. That's how we access shared functions.

Methods should never be comma-separated, if inside of a class body. This is to emphasize the fact that classes and object literals are different.
*/



Answer
An HTML-like JSX element is an element with a lower case tag name. In JSX, lower case tag names will be treated as HTML tags, while upper case tag names will be treated as a component instance.

For instance, lower case <button> is treated as an HTML element, while upper case <Button> would be treated as a component instance of the Button class.

As a consequence of this, React components must always start with a capital letter, or will otherwise be treated as an HTML element.
// Card.js
const ContainerCard = styled.div`
  width: 50px;
  height: 50px;
`;

const Card = ({ className }) => {
  return <ContainerCard className={className} />;
};

// Use any valid prop, Card.StyledComponent, Card.Style etc.
Card.className = ContainerCard;
export default Card;

// App.js
const Container = styled.div`
  height: 100vh;
  width: 100vw;
`;

// Styling custom components, through className prop.
const VioletredRedCard = styled(Card)`
  background-color: palevioletred;
`;


// Target the component generated by styled-components
const CardWrapper = styled.div`
  ${Card.className} {
    width: 100px;
    height: 100px;
    background-color: paleturquoise;
  }
`;


const App = () => {
  return (
    <Container>
      <CardWrapper>
        <Card />
      </CardWrapper>
      <VioletredRedCard />
    </Container>
  );
};
/*
you have to define an event handler before you can pass one anywhere. 

How do you define an event handler in React?

You define an event handler as a method on the component class, just like the render method.
*/

class Example extends React.Component {
  handleEvent() {
    alert(`I am an event handler.
      If you see this message,
      then I have been called.`);
  }

  render() {
    return (
      <h1 onClick={this.handleEvent}>
        Hello world
      </h1>
    );
  }
}


const root = ReactDOM.createRoot(document.getElementById("app"));
root.render(<Data />);
// create services folder and api file
import axios from "axios";

export const api = axios.create({
  baseURL: " http://localhost:3333",
});

// on the page where the useEffect is located
import { api } from "./services/api";

 useEffect(() => {
    async function getData() {
      const response = await api.get("/episodes");
      setData(response.data);
    }
    getData();
  }, []);
import React from "react";

interface Props {
  style?: string;
  type: "button" | "submit" | "reset";
  title?: string;
  icon?: React.ReactNode;
  onClick: () => void;
}

// Button component could accept text, icons and/or styles as props
// style and onClick props are mandatory
export const Button = ({ style, type, title, icon, onClick }: Props) => {
  return (
    <button className={style} type={type} onClick={onClick}>
      <span>{icon}</span>
      {title}
    </button>
  );
};
import React, { useState } from "react";
import { Button } from "./Button";

// data is an array of objects const data = [{id:1, url: "https://..."}, ...]
import { data } from "../data/carouselData";

export const Carrousel = () => {
  const [index, setIndex] = useState(0);

  // when buttons are clicked, the state (index) would increased or decreased
  // to avoid the code crash when index reachs its min and max values, conditios are set on click 	events 
  function handlePreviousBtn() {
    index > 0 ? setIndex(index - 1) : setIndex(data.length - 1);
  }

  function handleNextBtn() {
    index < data.length - 1 ? setIndex(index + 1) : setIndex(0);
  }

  return (
    // carousel has width 100% and specif height
    <div className="carousel">
      {/* Button is a custom component */}
      <Button
        style="carousel--btn left-4"
        type="button"
        title="left"
        onClick={() => handlePreviousBtn()}
      />
      <Button
        style="carousel--btn right-4"
        type="button"
        title="right"
        onClick={() => handleNextBtn()}
      />
		{/* carousel--item and carousel--item-img has widht and heigth 100% */}
      <div className="carousel--item">
        {/* also carousel--item-img has object-contain style prop */}
        <img
          className="carousel--item-img"
          src={data[index].url}
          alt="Random Image"
        />
      </div>
    </div>
  );
};
  state = {
    disabled: false,
  };

  handleButtonClicked = () => {
    //going back logic
    this.setState({
      disabled: true,
    });
    setTimeout(() => {
        this.setState(() => ({
          disabled: false,
        }));
      }, 5000);
  };

  render() {
    const { disabled } = this.state;
    return (
      <button   
        onClick={this.handleButtonClicked}
        disabled={disabled}
      >
        Button to be disabled
      </button>
    );
  }
// helpers
import { getDataWithNonDuplicatedEntries } from "./getSetDataList";
import { filterData } from "./filterData";
import { reduceData } from "./reduceData";

type DataListType = {
  idade: string;
  quantidade: string;
};

export const groupData = (
  data: any[],
  filterProperty: string,
  reduceProperty: string,
  property: any
) => {
  // declare and empty array to save the results
  let dataList: any = [];

  // set a new list with no duplicated entries
  const list: number[] = getDataWithNonDuplicatedEntries(data, property);
  console.log(list);

  // then, for each item of the list...
  list.forEach((item) => {
    // filter elements
    const filteredData = filterData(data, filterProperty, item);
    console.log(filteredData);

    // get the total by age on the filtered data
    const age = reduceData(filteredData, reduceProperty);

    // finally, pass the results into an object
    const obj = {
      idade: item,
      quantidade: age,
    };
    dataList.push(obj);
  });

  return dataList;
};
import React from 'react';
import Card from './components/Card'
import './index.css'; 

class App extends React.Component{
    state = {
      image_id:51
    }
    
    changeAvatar=()=>{
     this.setState({
        image_id:65
      })
    }
    
    render(){
     return(
            <div className="container">
            <div className="row">
                <Card name="James Smith" job="Pilot" image_id={this.state.image_id}/>
                <Card name="Jessica Jones" job="Nurse" image_id={28}/>
                <Card name="Tom Hanks" job="Lawyer" image_id={68}/>
            </div>
            <div className="row">
                <div className="col-md-3">
                <a onClick={this.changeAvatar} className="changeAvatar" href="#"> Change Avatar </a>
                </div>
            </div>
            </div>
        );
    }
}

export default App;
import React from'react';

class App extends React.Component {
  render() {
    return(
        <div className="container">
          <div className="row">
            <div className="col-md-4">
              <div className="card">
                <img className="card-img-top"src="https://i.pravatar.cc/150?img=52"alt="Card image cap"/>
                  <div className="card-body">
                    <h5 className="card-title">Card title</h5>
                    <p className="card-text">Some quick example text to build on the card title and make up the</p>
                    <a href="#" className="btn btn-primary"> Go somewhere </a>
                  </div>
              </div>
            </div>
          </div>
        </div>
      );
    }
}

export default App;
<Router>
	<NavLink 
	to='users' 
	className={({ isActive }) => isActive ? "navlink--active" : "navlink"} 
	style={({ isActive }) => ({color: isActive ? "#ffffff" : undefined})}>
	Users
	</NavLink>	
</Router>
import styled from 'styled-components';
// backdrop
export const Wrapper = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  background-color: #000000e1;
`

// для отключения скрола когда открыто окно
  useEffect(() => {
    document.body.style.overflow = isModalOpen ? "hidden" : "unset"
  }, [isProposalEditorOpen]);

// @ts-ignore
const Backdrop = ({children, onClick}) => {
  return (
    <Wrapper
      onClick={() => onClick()}
    >
      {children}
    </Wrapper>
  );
};

export default Backdrop;

// modal
const Modal = () => {
  return (
    <Wrapper
      onClick={(e) => e.stopPropagation()}
    >
    </Wrapper>
  );
};

export default Modal;

import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
navigate('/home');
interface FullName {
    firstName: string;
    lastName: string;
}
function FunctionalComponent(props:FullName){
    // props.firstName
    // props.lastName
}


//Or:

// Using the same FullName interface from the last example
function FunctionalComponent({firstName, lastName}:FullName){
    // firstName
   // lastName
}
function makeActive(a) {
    const items = document.querySelectorAll('.tab-active');
    if (items.length) items[0].className = null;
    a.className = 'tab-active';
  }

<a href="" className="tab-active" onClick={(e) => {makeActive(e.target)}}>Moulds</a>
<a href="" className='tab' onClick={(e) => {makeActive(e.target)}}>Fractionalization</a>
const [scroll, setScroll] = useState(false)

  useEffect(() => {
    window.addEventListener("scroll", () => {
      setScroll(window.scrollY > 200)
    })
    return function cleanup() {
      setScroll(true)
    }
  }, [])
  const [data, setData] = useState([]);

  //Fetch data from a local json file.
  const getData = () => {
    fetch("data.json", {
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json",
      },
    })
      .then(function (response) {
        console.log(response);
        return response.json();
      })
      .then(function (myJson) {
        console.log(myJson);
        setData(myJson);
      });
  };

  useEffect(() => {
    getData();
  }, []);
const Component = ({ receiveAmount, sendAmount }) => {
  const prevAmount = useRef({ receiveAmount, sendAmount }).current;
  useEffect(() => {
    if (prevAmount.receiveAmount !== receiveAmount) {
     // process here
    }
    if (prevAmount.sendAmount !== sendAmount) {
     // process here
    }
    return () => { 
      prevAmount.receiveAmount = receiveAmount;
      prevAmount.sendAmount = sendAmount;
    };
  }, [receiveAmount, sendAmount]);
};
import { useEffect } from 'react';

export const useClickOutside = (ref, setIsModalOpen) => {
  useEffect(() => {
    function handleClickOutside(event) {
      if (ref.current && !ref.current.contains(event.target)) {
        setIsModalOpen(false)
      }
    }
    document.addEventListener("mousedown", handleClickOutside);
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, [ref]);
};
/* Redux is a state management library
1 Create Initial State
2 Define Action Types
3 Define Action Creators
4 Create Reducers
5 Change the initial State
6 Pass the parameters to the Creator function and the reducers */

Code
// Initial State

const initialState = {
  todos: [
    {
      text: "eat food",
    },
    {
      text: "Exercise",
    },
  ],
};

// Action Types
// create a simple action type

const ADD_TODO = "ADD_TODO";

// ACtion creators

function addTodo(text) {
  return {
    type: ADD_TODO,
    payload: text,
  };
}

//create reducers
function todoReducer(state = [], action) {
  switch (action.type) {
    case ADD_TODO:
      return [...state.todos, { text: action.payload }];
    default:
      return state;
  }
}

console.log("Initial State : ", initialState);

// Lets make changes to initial states
const action = addTodo("Make it work");
const newState = todoReducer(initialState, action);

console.log(newState);
import React from "react";
import { Col, Card, Row, Statistic } from "antd";

class Workplace extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [],
      DataisLoaded: false,
    };
  }

  componentDidMount() {
    fetch("http://localhost:3005/results")
      .then((res) => res.json())
      .then((json) => {
        this.setState({
          items: json,
          DataisLoaded: true,
        });
      });
  }

  render() {
    const { DataisLoaded, items } = this.state;
    if (!DataisLoaded) return <div>Give me time</div>;

    return (
      <div className="import-container">
        <Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }}>
          
        </Row>
      </div>
    );
  }
}

export default Workplace;
import { Row, Col, Card, Statistic } from "antd";

const CardRow = ({ info }) => {
  return (
    <>
      {info.map((n) => (
        <Col key={n.key} className="gutter-row" span={8}>
          <Card
            className="campaign-card-row"
            hoverable={true}
            style={{ marginBottom: "10px" }}
          >
            <div className="campaign-card-title">
              <span>{n.name}</span>
            </div>
            <Statistic value={n.salary} prefix={"$"} />
          </Card>
        </Col>
      ))}
    </>
  );
};

export default CardRow;
import { useEffect, useState } from "react";
import { Row, Col, Card, Skeleton, Statistic } from "antd";
import CardRow from "../../components/CardRow";
import {
  SettingOutlined,
  EditOutlined,
  EllipsisOutlined,
} from "@ant-design/icons";

const { Meta } = Card;

const Workplace = () => {
  const [info, setInfo] = useState(null);

  const [isLoading, setLoading] = useState(true);

  useEffect(() => {
    setTimeout(() => {
      fetch("http://localhost:3005/results")
        .then((res) => {
          return res.json();
        })
        .then((data) => {
          setInfo(data);
          setLoading(false);
        });
    }, 1000);
  }, []);
  return (
    <div className="import-container">
      <Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }}>
        {isLoading && (
          <Col span={8} className="gutter-row">
            <Card
              className="campaign-card-row"
              hoverable={true}
              style={{ marginBottom: "10px" }}
            >
              <Skeleton loading={isLoading} active>
                <div className="campaign-card-title">
                  <span>{"Silly"}</span>
                </div>
                <Statistic value={30000} prefix={"$"} />
              </Skeleton>
            </Card>
          </Col>
        )}
        {info && <CardRow info={info} />}
        {/* conditional templating:: only if data is true, will the cardrow output */}
      </Row>
    </div>
  );
};

export default Workplace;
feat/WP-3264/Event-dates
to react js template
yarn create vite player-react --template react

to ts template 
yarn create vite player-react --template react-ts
/^(?!00)(?!\.)[0-9]*\.?[0-9]*$/ только цифры и точка, не может начинаться с 00 или .

export const useNumericInput = () => {
  const [value, setValue] = useState<string>('')

  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const rgx = /^[0-9]*\.?[0-9]*$/
    const inputValue = e.target.value
    if (!inputValue.match(rgx) || inputValue.charAt(0) === '.' || inputValue.charAt(1) === '0') {
      return setValue(prevState => prevState)
    }
    return setValue(inputValue)
  };

  return { onChange, value }
};

/// ИЛИ чистый js

export const numericInputValidator = (e: React.ChangeEvent<HTMLInputElement>, inputId: string) => {
  const userInput = e.target.value
  // @ts-ignore
  const input: HTMLInputElement = document.getElementById(inputId)

  if (userInput.charAt(1) === '0') {
    input.value = '0'
  }
  if (userInput.charAt(0) === '.') {
    input.value = ''
  }
  input.value = input.value.replace(/[^0-9\.]/g,'');
  input.addEventListener("blur", () => {
    input.value = stringTrim(userInput, 10);
  });
  input.addEventListener("focus", () => {
    input.value = userInput
  })
};

import React, {
	useState,
	useEffect
} from 'react';
import ReactDOM from 'react-dom';
import {
	Line
} from '@ant-design/plots';

const DemoLine = () => {
	const data = [{
			year: '1991',
			value: 3,
		},
		{
			year: '1992',
			value: 4,
		},
		{
			year: '1993',
			value: 3.5,
		},
		{
			year: '1994',
			value: 5,
		},
		{
			year: '1995',
			value: 4.9,
		},
		{
			year: '1996',
			value: 6,
		},
		{
			year: '1997',
			value: 7,
		},
		{
			year: '1998',
			value: 9,
		},
		{
			year: '1999',
			value: 13,
		},
	];
	const config = {
		data,
		xField: 'year',
		yField: 'value',
		label: {},
		point: {
			size: 1,
			shape: '',
			style: {
				fill: 'white',
				stroke: '#5B8FF9',
				lineWidth: 2,
			},
		},
		lineStyle: {
			lineWidth: 0,
		},
		tooltip: {
			showMarkers: false,
		},
		state: {
			active: {
				style: {
					shadowBlur: 4,
					stroke: '#000',
					fill: 'red',
				},
			},
		},
		interactions: [{
			type: 'marker-active',
		}, ],
	};
	return <Line {
		...config
	}
	/>;
};

ReactDOM.render( < DemoLine / > , document.getElementById('container'));
pragma solidity ^0.5.11;

contract A {
    address addressB;
    function setAddressB(address _addressB) external {
        addressB = _addressB;
    }
    function callHelloWorld() external view returns(string memory) {
        B b = B(addressB);
        return b.helloWorld();
    }
}

contract B {
    function helloWorld() external pure returns(string memory) {
        return 'HelloWorld';
    }
}



contract MyContract {
    uint a;
    function foo() external {
        if(a == 10) {
            revert('error');
        }
        require(a != 10, 'err');
        assert(a != 10);
    }
    function willThrow() external {
        require(true == false, 'the reasons');
    }
}
import React, { useState } from "react";
import NewTask from "../Presentational/NewTask";
import TasksList from "../Presentational/TasksList";

export default function AppFunction() {
  const [newTask, setNewTask] = useState({});
  const handleChange = ({ target }) => {
    const { name, value } = target;
    setNewTask((prev) => ({ ...prev, id: Date.now(), [name]: value }));
  };

  const [allTasks, setAllTasks] = useState([]);
  const handleSubmit = (event) => {
    event.preventDefault();
    if (!newTask.title) return;
    setAllTasks((prev) => [newTask, ...prev]);
    setNewTask({});
  };
  const handleDelete = (taskIdToRemove) => {
    setAllTasks((prev) => prev.filter(
      (task) => task.id !== taskIdToRemove
    ));
  };

  return (
    <main>
      <h1>Tasks</h1>
      <NewTask
        newTask={newTask}
        handleChange={handleChange}
        handleSubmit={handleSubmit}
      />
      <TasksList allTasks={allTasks} handleDelete={handleDelete} />
    </main>
  );
}
import React, { Component } from "react";
import NewTask from "../Presentational/NewTask";
import TasksList from "../Presentational/TasksList";

export default class AppClass extends Component {
  constructor(props) {
    super(props);
    this.state = {
      newTask: {},
      allTasks: []
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleDelete = this.handleDelete.bind(this);
  }

  handleChange({ target }){
    const { name, value } = target;
    this.setState((prevState) => ({
      ...prevState,
      newTask: {
        ...prevState.newTask,
        [name]: value,
        id: Date.now()
      }
    }));
  }

  handleSubmit(event){
    event.preventDefault();
    if (!this.state.newTask.title) return;
    this.setState((prevState) => ({
      allTasks: [prevState.newTask, ...prevState.allTasks],
      newTask: {}
    }));
  }

  handleDelete(taskIdToRemove){
    this.setState((prevState) => ({
      ...prevState,
      allTasks: prevState.allTasks.filter((task) => task.id !== taskIdToRemove)
    }));
  }

  render() {
    return (
      <main>
        <h1>Tasks</h1>
        <NewTask
          newTask={this.state.newTask}
          handleChange={this.handleChange}
          handleSubmit={this.handleSubmit}
        />
        <TasksList
          allTasks={this.state.allTasks}
          handleDelete={this.handleDelete}
        />
      </main>
    );
  }
}
import React, { useState } from "react";

export default function EditProfile() {
  const [profile, setProfile] = useState({});

  const handleChange = ({ target }) => {
    const { name, value } = target;
    setProfile((prevProfile) => ({
      ...prevProfile,
      [name]: value
    }));
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    alert(JSON.stringify(profile, '', 2));
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        value={profile.firstName || ''}
        onChange={handleChange}
        name="firstName"
        type="text"
        placeholder="First Name"
      />
      <input
        value={profile.lastName || ''}
        onChange={handleChange}
        type="text"
        name="lastName"
        placeholder="Last Name"
      />
      <input
        value={profile.bday || ''}
        onChange={handleChange}
        type="date"
        name="bday"
      />
      <input
        value={profile.password || ''}
        onChange={handleChange}
        type="password"
        name="password"
        placeholder="Password"
      />
      <button type="submit">Submit</button>
    </form>
    
  );
}
import { useState, useEffect, useRef } from 'react';
import '../Styles/Hero.css';

function Hero() {
    // USE REF SETTINGS
    const activeItem = useRef([]);
    const toggleTarget = useRef(false);
    const targetObject = useRef({
        id: "",
        active: false,
    });
    const boxCustomRef = useRef(null);

    // BOXES AMOUNT 
    const boxesAmout = 160;
    const updatedItemArray = []

    // Create new Array based on boxesAmount
    const itemArr = new Array(boxesAmout).fill(0);

    // FOR LOOP => iterate over each item
    // => push item w/ index as id in updatedItemArray
    for (let i = 0; i < itemArr.length; i++) {
        updatedItemArray.push({
            id: itemArr[i] = i
        })
    };


    const toggleBoxHandler = (event) => {
        // id of clicked element
        let targetId = parseInt(event.target.id);

        // new Arr based on previous elements
        let prevArr = [...activeItem.current];

        // current Object to push in array
        targetObject.current = {
            id: targetId,
            active: toggleTarget.current,
        };

        // if Arr is empty => push first element
        if ((activeItem.current.length === 0) && (targetObject.current.active === false)) {
            targetObject.current = {
                id: targetId,
                active: true
            }
            activeItem.current = [...prevArr, targetObject.current];
            console.log("first item");
            console.log(activeItem.current);
            // add active class
            event.target.className = "hero__grid__box--overlay--default hero__grid__box--overlay--isActive"
        }
        //
        // IF ARR IS NOT EMPTY => logic goes here
        //
        // FIRST => check if target id is already included in previous Arr
        // -> if not: push new targetObject / toggle active state
        // -> if yes: remove item from Arr / edit new targetObject & toggle active state / push updated item back in Arr
        //
        else if (activeItem.current.length > 0) {
            console.log("arr includes at least one item");

            // loop over prevArr
            for (let i = 0; i < prevArr.length; i++) {

                // if prevArr doesn't include targetId
                if (prevArr[i].id !== targetId) {
                    console.log("it's not a match!");

                    //
                    // activeState default is false
                    // => set State to true
                    // => hydrate current Arr with current targetObject
                    // => toggle active class
                    //
                    targetObject.current = {
                        id: targetId,
                        active: true
                    }

                    activeItem.current = [...prevArr, targetObject.current];

                    // add active class
                    event.target.className = "hero__grid__box--overlay--default hero__grid__box--overlay--isActive";
                }
                // if prevArr includes targetId
                // Remove & replace item from prevArr => update its active State / push updated item back in Arr
                if (prevArr[i].id === targetId) {
                    console.log("arr already include this item");
                    // console.log(prevArr[i].id);
                    let updatedArr;
                    let updatedItem = {
                        id: "",
                        active: "",
                    };

                    // FILTER & CREATE new Array w/ item to update
                    const filteredItem = prevArr.filter((item) => item.id === targetId);

                    // FILTER & CREATE new Array without item to update
                    const filteredArr = prevArr.filter(item => item.id !== targetId);
                    console.log(filteredArr);

                    // Updates filtered item
                    updatedItem = {
                        id: filteredItem[0].id,
                        active: !filteredItem[0].active
                    }

                    // UPDATE prevArr w/ correct active value
                    prevArr = [...filteredArr, updatedItem];

                    // IF state is true => add class active
                    if (updatedItem.active === true) {
                        event.target.className = "hero__grid__box--overlay--default hero__grid__box--overlay--isActive"
                    }
                    // IF state is false => remove class active
                    if (updatedItem.active === false) {
                        event.target.className = "hero__grid__box--overlay--default hero__grid__box--overlay--notActive"
                    }

                    // HYDRATE current array w/ updated previous values
                    activeItem.current = [...prevArr];
                    return;
                }
            }
        }
    }


    return (
        <div className="section__container hero__container">
            <div className='hero__grid__container'>
                <div className='hero__grid__container__background'></div>
                {
                    updatedItemArray.map((item) => {
                        return (
                            <div key={item.id} id={item.id} ref={boxCustomRef} className='hero__grid__box'>
                                <div id={item.id} className='hero__grid__box--overlay--default hero__grid__box--overlay--notActive' onClick={toggleBoxHandler}></div>
                            </div>
                        )
                    })
                }
            </div>
        </div>
    );
}

export default Hero;
const [animateHeader, setAnimateHeader] = useState(false)

useEffect(() => {
  const listener = () =>
  window.scrollY > 140 ? setAnimateHeader(true) : setAnimateHeader(false)
  window.addEventListener('scroll', listener)
  return () => {
    window.removeEventListener('scroll', listener)
  }
}, [])

// Example usage with TailwindCSS:
<div className={`bg-header/75 transition duration-500 ease-in-out ${animateHeader && 'bg-header/[0.95]'}`}>...</div>
<MenuItem
  component={Link}
  // the 'to' prop (and any other props not recognized by MenuItem itself)
  // will be passed down to the Link component
  to="/profile"
>
  Profile
</MenuItem>
event.currentTarget 

that always gives back the element that has the event listner on it
const handleScrollBotto = () => {
    // @ts-ignore
  // за основу берется положение определенного элемента страницы
    const pos = document.getElementById(elementId).getBoundingClientRect()
    if (document.body.offsetHeight - (pos.height + pos.y) > 100) {
      setIsFetchingMore(true)
    }
  };
function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  return (
    <div>
      <h1>Hello!</h1>

      {unreadMessages.length > 0 &&
        <h2>
          You have {unreadMessages.length} unread messages.
        </h2>
      }
    </div>
  );
}

const messages = ['React', 'Re: React', 'Re:Re: React'];
ReactDOM.render(
  <Mailbox unreadMessages={messages} />,
  document.getElementById('root')
);
class Widget extends React.Component {
  render() {
    let ui;
    return <div>{ui}</div>;
  }
}
const MyComponent = ()=>{
  return <h1>Hello World</h1>
}
export default MyComponent;
<Welcome>Hello world!</Welcome>



function Welcome(props) {
  return <p>{props.children}</p>;
}
In normal JS
events are calling from child -> parent -> parent -> ... -> body

In react, if there are any manual event wired then those will be called first then the events added via react in child => parent manner
1) using [],  Only once when component is intially rendered
useEffect(() => {
  console.log('inside use effect')
}, [])

2) nothing, run at initial render and at every single re-render
useEffect(() => {
  console.log('inside use effect')
})

2)[selectedItem], everytime whenever the state of selectedItem changes
useEffect(() => {
  console.log('inside use effect')
}, [selectedItem])

3) [selectedItem > 2], everytime the condition matches
useEffect(() => {
  console.log('inside use effect')
}, [selectedItem > 2])
border: ${(props: { error: boolean }) => (props.error ? '1px solid #F20D19' : '1px solid transparent')};

export const Img = styled.img<{ alt: string, src: string}>`
  margin-right: 15px;
`;
const useSortableData = (items, config = null) => {
  const [sortConfig, setSortConfig] = React.useState(config);
  
  const sortedItems = React.useMemo(() => {
    let sortableItems = [...items];
    if (sortConfig !== null) {
      sortableItems.sort((a, b) => {
        if (a[sortConfig.key] < b[sortConfig.key]) {
          return sortConfig.direction === 'ascending' ? -1 : 1;
        }
        if (a[sortConfig.key] > b[sortConfig.key]) {
          return sortConfig.direction === 'ascending' ? 1 : -1;
        }
        return 0;
      });
    }
    return sortableItems;
  }, [items, sortConfig]);

  const requestSort = key => {
    let direction = 'ascending';
    if (sortConfig && sortConfig.key === key && sortConfig.direction === 'ascending') {
      direction = 'descending';
    }
    setSortConfig({ key, direction });
  }

  return { items: sortedItems, requestSort };
}
onClick={() => window.open(url, "_blank")}
### react ###
.DS_*
*.log
logs
**/*.backup.*
**/*.back.*

node_modules
bower_components

*.sublime*

psd
thumb
sketch
const analyticsItemsHelper = (offer) => {
    if (offer.name.includes('Web Coins')) {
      offer.bonusItems.forEach((el) => {
        Titan.SendEvent({
          name: 'sys.game_transaction',
          parameters: {
            trans_type: 'reward_web_portal',
            trans_desc: 'redeem_promo_code',
            tournament_id: '',
            item_id: el.itemId,
            item_name: el.itemName,
            context: offer.id,
            quantity: +el.itemQuantity,
            transaction_id: +transactionIdAnalytics,
            stage_id: '',
            gacha_pack: '',
            gacha_pack_name: '',
            battle_id: '',
            season_id: '',
            item_balance: +currentUser.webCoin,
            tickets: '',
            skin: '',
            is_sgss: '',
            is_female_ss: '',
            item_ev: '',
            reference_id: 'special_offers',
            discount_info: JSON.stringify({
              promo_id: promotionId,
              promo_code: input,
            }),
            alliance_id: currentUser?.factionId || '',
            alliance_name: currentUser?.factionName || '',
            league_level: currentUser?.leagueId || '',
            player_level: currentUser?.playerId || '',
            player_name: currentUser?.nickname || '',
          },
        });
      });
      rubyIsActive &&
        Titan.SendEvent({
          name: 'sys.game_transaction',
          parameters: {
            trans_type: 'reward_web_portal',
            trans_desc: 'redeem_promo_code',
            tournament_id: '',
            item_id: 'web_currency_ruby',
            item_name: 'Ruby',
            context: offer.id,
            quantity: currencyQuantity('Ruby', offer),
            transaction_id: +transactionIdAnalytics,
            stage_id: '',
            gacha_pack: '',
            gacha_pack_name: '',
            battle_id: '',
            season_id: '',
            item_balance: +currentUser.ruby,
            tickets: '',
            skin: '',
            is_sgss: '',
            is_female_ss: '',
            item_ev: '',
            reference_id: 'special_offers',
            discount_info: JSON.stringify({
              promo_id: promotionId,
              promo_code: input,
            }),
            alliance_id: currentUser?.factionId || '',
            alliance_name: currentUser?.factionName || '',
            league_level: currentUser?.leagueId || '',
            player_level: currentUser?.playerId || '',
            player_name: currentUser?.nickname || '',
          },
        });
    } else if (offer.name.includes('Rubies')) {
      offer.bonusItems.forEach((el) => {
        Titan.SendEvent({
          name: 'sys.game_transaction',
          parameters: {
            trans_type: 'reward_web_portal',
            trans_desc: 'redeem_promo_code',
            tournament_id: '',
            item_id: el.itemId,
            item_name: el.itemName,
            context: offer.id,
            quantity: +el.itemQuantity,
            transaction_id: +transactionIdAnalytics,
            stage_id: '',
            gacha_pack: '',
            gacha_pack_name: '',
            battle_id: '',
            season_id: '',
            item_balance: +currentUser.ruby + el.itemQuantity,
            tickets: '',
            skin: '',
            is_sgss: '',
            is_female_ss: '',
            item_ev: '',
            reference_id: 'special_offers',
            discount_info: JSON.stringify({
              promo_id: promotionId,
              promo_code: input,
            }),
            alliance_id: currentUser?.factionId || '',
            alliance_name: currentUser?.factionName || '',
            league_level: currentUser?.leagueId || '',
            player_level: currentUser?.playerId || '',
            player_name: currentUser?.nickname || '',
          },
        });
      });
      Titan.SendEvent({
        name: 'sys.game_transaction',
        parameters: {
          trans_type: 'reward_web_portal',
          trans_desc: 'redeem_promo_code',
          tournament_id: '',
          item_id: 'web_currency_web_coin',
          item_name: 'Web Coin',
          context: offer.id,
          quantity: currencyQuantity('Web Coin', offer),
          transaction_id: +transactionIdAnalytics,
          stage_id: '',
          gacha_pack: '',
          gacha_pack_name: '',
          battle_id: '',
          season_id: '',
          item_balance: +currentUser.webCoin,
          tickets: '',
          skin: '',
          is_sgss: '',
          is_female_ss: '',
          item_ev: '',
          reference_id: 'special_offers',
          discount_info: JSON.stringify({
            promo_id: promotionId,
            promo_code: input,
          }),
          alliance_id: currentUser?.factionId || '',
          alliance_name: currentUser?.factionName || '',
          league_level: currentUser?.leagueId || '',
          player_level: currentUser?.playerId || '',
          player_name: currentUser?.nickname || '',
        },
      });
    } else {
      offer.bonusItems.forEach((el) => {
        console.log(activeCurrencies, 'activeCurrencies');
        console.log(currentUser, 'currentUser');
        console.log(offer, 'offer');
        console.log(el.itemName, 'itemNameitemNameItemNameitemNameitemName')
        Titan.SendEvent({
          name: 'sys.game_transaction',
          parameters: {
            trans_type: 'reward_web_portal',
            trans_desc: 'redeem_promo_code',
            tournament_id: '',
            item_id: el.itemId,
            item_name: el.itemName,
            context: offer.id,
            quantity: +el.itemQuantity,
            transaction_id: +transactionIdAnalytics,
            stage_id: '',
            gacha_pack: '',
            gacha_pack_name: '',
            battle_id: '',
            season_id: '',
            item_balance: '',
            tickets: '',
            skin: '',
            is_sgss: '',
            is_female_ss: '',
            item_ev: '',
            reference_id: 'special_offers',
            discount_info: JSON.stringify({
              promo_id: promotionId,
              promo_code: input,
            }),
            alliance_id: currentUser?.factionId || '',
            alliance_name: currentUser?.factionName || '',
            league_level: currentUser?.leagueId || '',
            player_level: currentUser?.playerId || '',
            player_name: currentUser?.nickname || '',
          },
        });
      });
      Titan.SendEvent({
        name: 'sys.game_transaction',
        parameters: {
          trans_type: 'reward_web_portal',
          trans_desc: 'redeem_promo_code',
          tournament_id: '',
          item_id: 'web_currency_web_coin',
          item_name: 'Web Coin',
          context: offer.id,
          quantity: currencyQuantity('Web Coin', offer),
          transaction_id: +transactionIdAnalytics,
          stage_id: '',
          gacha_pack: '',
          gacha_pack_name: '',
          battle_id: '',
          season_id: '',
          item_balance: +currentUser.webCoin,
          tickets: '',
          skin: '',
          is_sgss: '',
          is_female_ss: '',
          item_ev: '',
          reference_id: 'special_offers',
          discount_info: JSON.stringify({
            promo_id: promotionId,
            promo_code: input,
          }),
          alliance_id: currentUser?.factionId || '',
          alliance_name: currentUser?.factionName || '',
          league_level: currentUser?.leagueId || '',
          player_level: currentUser?.playerId || '',
          player_name: currentUser?.nickname || '',
        },
      });
      rubyIsActive &&
        Titan.SendEvent({
          name: 'sys.game_transaction',
          parameters: {
            trans_type: 'reward_web_portal',
            trans_desc: 'redeem_promo_code',
            tournament_id: '',
            item_id: 'web_currency_ruby',
            item_name: 'Ruby',
            context: offer.id,
            quantity: currencyQuantity('Ruby', offer),
            transaction_id: +transactionIdAnalytics,
            stage_id: '',
            gacha_pack: '',
            gacha_pack_name: '',
            battle_id: '',
            season_id: '',
            item_balance: +currentUser.ruby,
            tickets: '',
            skin: '',
            is_sgss: '',
            is_female_ss: '',
            item_ev: '',
            reference_id: 'special_offers',
            discount_info: JSON.stringify({
              promo_id: promotionId,
              promo_code: input,
            }),
            alliance_id: currentUser?.factionId || '',
            alliance_name: currentUser?.factionName || '',
            league_level: currentUser?.leagueId || '',
            player_level: currentUser?.playerId || '',
            player_name: currentUser?.nickname || '',
          },
        });
    }
  };
const [ user, setUser ] = useState(JSON.parse(localStorage.getItem('profile'))); //convert to object
 
const logout = () =>{
        dispatch({type: 'LOGOUT'});
        history.push("/");
        setUser(null);
    }
 
    useEffect(()=>{
        const token = user?.token;
 
        //JWT check if token expired
        if(token){
            const decodedToken = decode(token)
            if(decodedToken.exp*1000 < newDate().getTime()) logout();
        }
        setUser(JSON.parse(localStorage.getItem('profile')))
    },[location])
const array = [1, 2, 3, 4]

//remove the first element of the array
array.shift()

//add an element to the beginning of the array
array.unshift()

//remove the last element in an array
array.pop()

//add an element to the end of the array
array.push()
navigator.geolocation.getCurrentPosition(showPosition);
let dog = document.querySelector("p .dog");
dog.classList.add("cat");
dog.classList.remove("<strong>dog</strong>");


//attribute
let weatherIconElement = document.querySelector("#weather-icon");
  weatherIconElement.setAttribute(
    "src",
    `http://www.openweathermap.org/img/wn/${response.data.weather[0].icon}@2x.png`
  );
  weatherIconElement.setAttribute("alt", response.data.weather[0].description);
//Date

let now = new Date(); //will give you the full date
now.getMilliseconds();
now.getSeconds();
now.getMinutes();
now.getHours();
now.getDate(); // number date of month
now.getDay(); //day of the week 0=sunday
now.getMonth();//january = 0
now.getFullYear();

//example of getting the current date to show up as h2
let now = new Date();
let h2 = document.querySelector("h2");
let daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thurs", "Fri", "Sat"]
let date = now.getDate();
let day = daysOfWeek [now.getDay()];
let year = now.getFullYear();
let hours = now.getHours();
let minutes = now.getMinutes();
let monthsOfYear = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]
let month = monthsOfYear[now.getMonth()];

h2.innerHTML = `${day} ${month} ${date}, ${hours}:${minutes}, ${year}`;
function isCold(temperature) {
    return temperature <= 10;}

 if (isCold(10)) {
   alert("It is cold today");}
   else {
     alert("It is warm today");
   } 
//example two
function isWindy(speed, unit) {
  return speed  > 5 && unit === "metric";
};
//edit an array (this will change the array called "numbers" from [1,2,6,7] to [1, 2,8,7])

numbers[2] = 8

//remove from an array (from the beginning)

numbers.shift();
let number = 20;
  Math.round(number);
  Math.floor(number);
  Math.ceil(number);
  Math.min(number);
  Math.max(number);
  Math.random(number);
//if else statement with length condition//
let firstName = prompt(`What is your first name?`);
firstName = firstName.trim();
if (firstName.length < 1) {
  alert(`Too bad for you`);
} else {
  alert(`Welcome, ` + firstName);
}

(city === undefined)
(city !=== undefined)
(age > 3) (age >= 4)
(country === "brazil" || country === "portugal")
country = country.replace("brasil", "brazil");

//replaces string with another string 
// making all uppercase
city.toUpperCase();

//removing spaces and making all lowercase
city = city.trim().toLowerCase();

//capitalizing the first letter
cityCapitalized = city.charAt(0).toUpperCase() + city.slice(1);
import React, { useState } from "react";
import axios from "axios";
let elements = ['one', 'two', 'three'];

return (
  <ul>
    {elements.map(function(value, index) {
      return <li key={index}>{value}</li>
    })}
  </ul>
);
let elements = ['one', 'two', 'three'];

return (
  <ul>
    {elements.map((value, index) => {
      return <li key={index}>{value}</li>
    })}
  </ul>
);
Clipboard events= onCopy onCut onPaste

Keyboard Events = onKeyDown onKeyPress onKeyUp

Mouse Events = onClick onContextMenu onDoubleClick onDrag onDragEnd onDragEnter onDragExit
onDragLeave onDragOver onDragStart onDrop onMouseDown onMouseEnter onMouseLeave
onMouseMove onMouseOut onMouseOver onMouseUp

Pointer Events  = onPointerDown onPointerMove onPointerUp onPointerCancel onGotPointerCapture
onLostPointerCapture onPointerEnter onPointerLeave onPointerOver onPointerOut

Selection Events = onSelect

UI Events = onScroll

Media Events = onAbort onCanPlay onCanPlayThrough onDurationChange onEmptied onEncrypted
onEnded onError onLoadedData onLoadedMetadata onLoadStart onPause onPlay
onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend
onTimeUpdate onVolumeChange onWaiting

image events = onLoad onError

trransition event = onTransitionEnd

toggle = onToggle

import React, { useEffect, useState } from 'react';
import Moveable from 'react-moveable';

const Movable = ({ moveRef, setStyle}) => {

    const [ renderMovable, setRenderMovable ] = useState(false);

    useEffect(() => {
        setRenderMovable(true);
    }, []);

    const handleDrag = e => {
        setStyle(e.transform);
    };

    const onResize= e => {
        console.log("onResize", e.target);
        e.delta[0] && (e.target.style.width = `${e.width}px`);
        e.delta[1] && (e.target.style.height = `${e.height}px`);
    }

    const onRotate = e => {
        setStyle(e.transform);
    }

    if (!renderMovable) return null;

    return (
        <Moveable 
            target={moveRef.current}
            draggable={true}
            resizable={true}
            rotatable={true}
            onRotate={onRotate}
            clipArea={true}
            throttleDrag={0}
            onDrag={handleDrag}
            onResize={onResize}
            bounds={false}
        />
    );
};

export default Movable;
$ npm install @mui/material @emotion/react @emotion/styled @mui/styled-engine-sc styled-components @mui/lab @mui/icons-material
 const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => {
    setRowsPerPage(+event.target.value);
    setPage(0);
  };
const SearchBar = (props) => {
  const initialState = [];
  const [options, setoptions] = useState(initialState);

  const nameList = () => {
    props.data.map((i) => setoptions((options) => [...options, i.name.common]));
  };
const handleChange = (e, name) => {
      setState({ [name]: e.target.value });
    };
import thunk, { ThunkDispatch } from 'redux-thunk'

export type IRootThunkDispatch = ThunkDispatch<IRootState, null, IRootAction>

const store = createStore<IRootState,IRootAction,{},{}>(
    rootReducer,
    composeEnhancers(
        applyMiddleware(logger),
        applyMiddleware(routerMiddleware(history)),
        applyMiddleware(thunk),
    )
);

export default store;
// store.ts
import {
  RouterState,
  connectRouter,
  routerMiddleware,
  CallHistoryMethodAction
} from 'connected-react-router';
import { createBrowserHistory } from 'history';

export const history = createBrowserHistory();

export interface IRootState{
    board: IBoardState,
    score: IScoreState
    router: RouterState
}

const rootReducer = combineReducers<IRootState>({
    board: boardReducers,
    score: scoreReducers,
    router: connectRouter(history)
});

type  IRootAction = ... | CallHistoryMethodAction;
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

let store = createStore<IRootState,IRootAction,{},{}>(
                rootReducer,
                composeEnhancers(
                    applyMiddleware(logger),
                    applyMiddleware(routerMiddleware(history))
                )
            );

export default store;


//-----------------------------------------
// App.tsx
import { ConnectedRouter } from 'connected-react-router';
import { history } from './store';
import { Link } from 'react-router-dom';
/*Other imports are omitted for simplicity reason*/

class App extends React.Component {
  public render() {
    return (
      <Provider store={store}>
        <ConnectedRouter history={history}>
          <div>
            <nav className="nav-bar">
              <Link to="/" className="link">Home</Link>
              <Link to="/board" className="link">Open Board</Link>
              <Link to="/scores" className="link">Score Board</Link>
              <Link to="/about" className="link">About us</Link>
            </nav>
            <div>
                <Switch>
                  <Route path="/" exact={true} component={Home} />
                  <Route path="/scores"  component={Scores} />
                  <Route path="/board" component={Board} />
                  <Route path="/about" component={About} />
                  <Route component={NoMatch} />
                </Switch>
            </div>
          </div>
        </ConnectedRouter>
      </Provider>
    );
  }
}

export default App
import {createStore, combineReducers, compose, applyMiddleware} from "redux";

declare global {
    /* tslint:disable:interface-name */
    interface Window {
        __REDUX_DEVTOOLS_EXTENSION_COMPOSE__: any
    }
}
....

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

export default createStore<IRootState,IRootAction,{},{}>(
    rootReducer,
    composeEnhancers(
      applyMiddleware(logger)
    )
);
import React, { useEffect } from 'react'
import { Button, Form } from 'react-bootstrap'
import { useForm } from 'react-hook-form'

type FormState = {
  name: string
  color: string
  gender: string
}

export default function FormDemo() {
  const { register, handleSubmit, watch } = useForm<FormState>({
    defaultValues: {
      name: '',
      color: '#c0ffee',
      gender: '',
    },
  })

  useEffect(() => {
    let sub = watch(data => {
      console.log('update form data:', data)
    })
    return () => sub.unsubscribe()
  }, [watch])

  function submit(data: FormState) {
    console.log('submit form data:', data)
  }

  return (
    <div className="container">
      <h1>Form Demo</h1>
      <Form onSubmit={handleSubmit(submit)}>
        <Form.Group>
          <Form.Label>Name</Form.Label>
          <Form.Control type="text" {...register('name')} />
        </Form.Group>
        <Form.Group>
          <Form.Label>Color</Form.Label>
          <Form.Control
            type="color"
            {...register('color')}
            className="d-inline"
          />
          <Form.Text className="text-muted">
            Custom the background color
          </Form.Text>
        </Form.Group>
        <Form.Group>
          <Form.Label>Gender</Form.Label>
          <Form.Control as="select" custom {...register('gender')}>
            <option value="">Prefer not to say</option>
            <option>M</option>
            <option>F</option>
            <option>T</option>
            <option>Others</option>
          </Form.Control>
        </Form.Group>
        <Button variant="primary" type="submit">
          Submit
        </Button>
      </Form>
    </div>
  )
}
const [feed, setFeed] = useState([]);
useEffect(() => {
    async function fetchData() {
      const response = await fetch(
        "https://www.sciencedaily.com/rss/earth_climate/environmental_issues.xml"
      )
        .then((response) => response.text())
        .then((responseData) => rssParser.parse(responseData))
        .then((rss) => {
          // console.log(rss.items);
          setFeed(rss.items);
        });
    }
    fetchData();
  }, []);
import React from 'react';
import { connect } from 'react-redux';
import { RootState, Item } from '../redux/state';
import { addItem, deleteItem, RootDispatch } from '../redux/action';

type Props = {
    author: string,
    items: Item[],
    handleAddItem: (newItemText: string) => void,
    handleDeleteItem: (targetId: number) => void
}
    
class TodoList extends React.Components<Props, {}> {
  constructor(props: Props) {
    super(props);
    // ...
  }
  
  // using redux dispatcher
  addItem(text: string) {
    this.props.handleAddItem(text);
  }
  
  render() {
    return (
      <>
      	<button onClick={() => this.addItem('123')}>Add item</button>
      	// using redux state
      	{this.props.items.map(item => return <p>item.name</p>)}
      </>
    )
  }
}

const mapStateToProps = (state: RootState) => {
    return {
        author: state.author,
        items: state.items
    }
}

const mapDispatchToProps = (dispatch: RootDispatch) => {
    return {
        handleAddItem: (newItemText: string) => {
            dispatch(addItem(newItemText));
        },
        handleDeleteItem: (targetId: number) => {
            dispatch(deleteItem(targetId));
        }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(TodoList);
import { createStore }from 'redux';
import { RootAction } from './action';

import { RootState } from './state';
import { rootReducer } from './reducer';

declare global {
    /* tslint:disable:interface-name */
    interface Window {
       __REDUX_DEVTOOLS_EXTENSION__: any
    }
}

const store = createStore<RootState, RootAction, {}, {}>(
    rootReducer, 
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);

export default store;
import { useState } from 'react';
import { useSelector } from 'react-redux';
import { RootState } from '../redux/store';

export default function TodoList() {
  // state from redux store
  const items = useSelector((state: RootState) => state.items);
  
  // normal state
  const [nextId, setNextId] = useState<number>(0);
  
  // proceed to use state as usual
  return (
    <>
    	{items.map(item => {
         	return (
         		<TodoItem
         			text={item.name}
    			/>
         	)
        })}
    </>
  )
}
import React from 'react';

import { connect } from 'react-redux';
import { RootState } from '../redux/store';

type State = { 
  //...
}

class TodoList extends React.Components<RootState, State> {
  // rootstate is integrated into props of class component
  constructor(props: RootState) {
    super(props);
    this.state = { 
      // ... 
    }
  }
  
  render() {
    return (
      <>
      	<this.props.items>
      </>
    )
  }
}

const mapStateToProps = (state: RootState) => {
  return {
    items: state.items;
  }
}

export default connect(mapStateToProps)(TodoList);
import {createStore, Action} from "redux";


export interface IRootState{
    squares : Array<string|null>
    oIsNext: boolean
}

const initialState = {
    squares: [],
    oIsNext: true
}

const rootReducer = (state:IRootState = initialState) => {
    return {
        squares: [null,null,null,null,'O','X',null,null,null],
        oIsNext: true
    }
}

const store = createStore<IRootState,Action<any>,{},{}>(rootReducer);
export default store;

import { Provider} from 'react-redux';
import store from './store';
import Board from './Board';


class App extends React.Component {
  public render() {
    return (
      <Provider store={store}>
        <div className="game">
          <div className="game-board">
            <Board />
          </div>
          <div className="game-info">
            <div>{/* status */}</div>
            <ol>{/* TODO */}</ol>
          </div>
        </div>
      </Provider>
    );
  }
}
yarn add redux react-redux @types/react-redux
import '@testing-library/jest-dom'
import React from 'react';
import {render, screen} from '@testing-library/react'
yarn add @testing-library/react @testing-library/jest-dom
yarn add bootstrap@4
//----------------------

import 'bootstrap/dist/css/bootstrap.min.css'; // Add this line
import './App.css';
<section style={{backgroundColor: color}}></section>
import { AsyncStorage } from 'react-native';
    
const HAS_LAUNCHED = 'hasLaunched';

function setAppLaunched() {
  AsyncStorage.setItem(HAS_LAUNCHED, 'true');
}

export default async function checkIfFirstLaunch() {
  try {
    const hasLaunched = await AsyncStorage.getItem(HAS_LAUNCHED);
    if (hasLaunched === null) {
      setAppLaunched();
      return true;
    }
    return false;
  } catch (error) {
    return false;
  }
}
//import and use elswhere like this

import React, { useEffect, useState } from 'react';
import { Text } from 'react-native';
import checkIfFirstLaunch from './utils/checkIfFirstLaunch';

const App = () => {
    const [isFirstLaunch, setIsFirstLaunch] = useState(null)

    useEffect(() => {
        checkIfFirstLaunch().then((isFirstLaunch) => {
            setIsFirstLaunch(isFirstLaunch)
        });
    }, [])

    if (isFirstLaunch === null) return null

    return isFirstLaunch ?
      <Text>This is the first launch</Text> :
      <Text>Has launched before</Text>
    ;
}

export default App
// Arrow function
filter((element) => { ... } )
filter((element, index) => { ... } )
filter((element, index, array) => { ... } )

// Callback function
filter(callbackFn)
filter(callbackFn, thisArg)

// Inline callback function
filter(function callbackFn(element) { ... })
filter(function callbackFn(element, index) { ... })
filter(function callbackFn(element, index, array){ ... })
filter(function callbackFn(element, index, array) { ... }, thisArg)
  handleFilter = key => {
    const selected = parseInt(key);
    if (selected === 3) {
      return this.setState({
        eventsData
      });
    }

    const statusMap = {
      1: "complete",
      2: "inProgress"
    };

    const selectedStatus = statusMap[selected];

    const filteredEvents = eventsData.filter(
      ({ status }) => status === selectedStatus
    );
    this.setState({
      eventsData: filteredEvents
    });
  };
  handleSearch = searchText => {
    const filteredEvents = eventsData.filter(({ title }) => {
      title = title.toLowerCase();
      return title.includes(searchText);
    });

    this.setState({
      eventsData: filteredEvents
    });
  };
npx create-react-app my-app --template typescript
cd my-app/
yarn start
const [isCopySuccess, setIsCopySuccess] = useState<boolean>(false)
const copyTextRef = useRef(null)

   const copyToClipBoard = async () => {
  {  try {
       await navigator.clipboard.writeText(copyTextRef.current.innerHTML)
      setIsCopySuccess(true)
       setTimeout(function() {
         setIsCopySuccess(false)
       }, 2500)
     } catch (err) {
       setIsCopySuccess(false)
     }
  }
react-native start --reset-cache
import { useCallback, useRef } from 'react';
export default function useDebounce(callback, delay = 400) {
  const debounce = useRef(null);
  return useCallback(
    (...args) => {
      const context = this;
      clearTimeout(debounce.current);
      debounce.current = setTimeout(() => {
        callback.apply(context, args);
      }, delay);
    },
    [callback, delay],
  );
}

/* 
Usage:

const handleWindowResize = useDebounce(SetWindow)

useEffect(() => {
window.addEventListener('resize', handleResize)
*/
function addList(list) {
  setLists([...lists, list]);
}
function removeList(id) {
  const tempLists = lists.slice();
  const index = tempLists.findIndex(list=> list.id === id);
  tempLists.splice(index, 1);
  setLists(tempLists);
}
    const logout = useCallback(() =>{
        dispatch({type: 'LOGOUT'});
        setUser(null);
        window.location.reload();               //the old version is history.push('/'), this cause a error when user log in, refresh the page, log out, then SIGN IN button doesn't work, I have no idea why it happens 
    },[dispatch]) 
    
const [ user, setUser ] = useState(JSON.parse(localStorage.getItem('profile'))); //convert to object

const logout = () =>{
        dispatch({type: 'LOGOUT'});
        history.push("/");
        setUser(null);
    }

    useEffect(()=>{
        const token = user?.token;

        //JWT check if token expired
        if(token){
            const decodedToken = decode(token)
            if(decodedToken.exp*1000 < newDate().getTime()) logout();
        }
        setUser(JSON.parse(localStorage.getItem('profile')))
    },[location])
const { whatsAppTopics, selectedTopics, setSelectedTopics } = useContext(
    WhatsAppConfigContext
  );

  function handleChangeCheckBox(e) {
    const clickedTopic = e.target;
    if (clickedTopic.checked) {
      setSelectedTopics([...selectedTopics, clickedTopic.value]);
    }
    if (!clickedTopic.checked) {
      const updatedSelectedTopics = selectedTopics.filter(
        (selectedTopic) => selectedTopic !== clickedTopic.value
      );

      setSelectedTopics(updatedSelectedTopics);
    }
  }
{
  "name": "frontend",
    // add proxy, so instead of looking at front end server, our api requests look at backend server
    // call it prox, then add the loopback address and the backend server port
  "proxy": "http://127.0.0.1:8080",
  "version": "0.1.0",
<OrangeLink to={{
                  pathname: `/dapps/p2p/my-trades/create-trade/${item?.idAdvert}`,
                  state: { prevPath: '/my-chats',
                  participant: item?.participant?.name}}
                }>
                Create trade
              </OrangeLink>
const Nav = styled.div`
    div > a.active > div {
        color: ${props => props.color}
     }
`
function Header() {
    const {DefaultColor} = useContext(GlobalContext)
    return <Nav color={DefaultColor?.success} />
}
import React, { useState } from "react";
import "./App.css";

const App = () => {
  const [counterA, setCounterA] = useState(0);
  const [counterB, setCounterB] = useState(0);

  return (
    <div>
      <button
        onClick={() => {
          setCounterA(counterA + 1);
        }}
      >
        Increment A
      </button>
      <button
        onClick={() => {
          setCounterB(counterB + 1);
        }}
      >
        Increment B
      </button>
      <div>counterA: {counterA}</div>
      <div>counterB: {counterB}</div>
    </div>
  );
};

export default App;
//Using Inline Styles
import React from 'react';

function App() {
  return (
    <div
      style={{
        backgroundColor: 'blue',
        width: '100px',
        height: '100px'
      }}
    />
  );
}

export default App;

//Conditional Changing the Background Color in React
import React from 'react';

function App() {
  const isBackgroundRed = true;

  return (
    <div
      style={{
        backgroundColor: isBackgroundRed ? 'red' : 'blue',
      }}
    />
  );
}

export default App;

//OR

//App.js
import React from 'react';
import './App.css';

function App() {
  const isBackgroundRed = true;
  
  return (
    <div className={isBackgroundRed ? 'background-red' : 'background-blue'} />
  );
}

export default App;
//App.css
.background-red {
  background-color: red;
}

.background-blue {
  background-color: blue;
}
//logs a table of users who use Yuan currency, displays all info
const onlyYuanUsers = users.filter( user => user.currency === "Yuan Renminbi")
console.table(onlyYuanUsers)

//just display iddx, id, and currency
console.table(onlyYuanUsers, ['id', 'currency'])
//Provider Component
import React, { Component } from 'react';

// Create new context
const MyContext = React.createContext();

// Create the Provider that will pass down state and methods to the rest of the application.
class MyProvider extends Component {
  state = {
    name: 'Dominic',
    age: 28,
  };
  render() {
    return (
      <MyContext.Provider value={{
        state: this.state,
        addYear: () => this.setState({
          age: this.state.age + 1
        })
      }}>
        {this.props.children}
      </MyContext.Provider>
    )
  }
}

// Create the consumer that will consume the data provided by the Provider.
class Company extends Component {
  render() {
    return(
      <div className="company">
        <MyContext.Consumer>
          {(context) => (
            //Fragment added here since you can only return one child
            <>
              <p>Welcome to {context.state.name}</p>
              <p>We are {context.state.age} years old!</p>
              <button onClick={context.addYear}>Add Year</button>
            </>
          )}
        </MyContext.Consumer>
      </div>
    )
  }
}

// We'll nest our Consumer inside another component just to show that we don't need to pass props to each component.
const Companies = () => (
  <div>
    <Company />
  </div>
)

class App extends Component {
  render() {
    return (
      // Ensure the provider wraps all the components you want to share data between.
      <MyProvider>
        <div className="App">
          <Companies />
        </div>
      </MyProvider>
    );
  }
}

export default App;
import React, { useState } from 'react'

const MyComponent = () => {
  const [toggle, setToggle] = useState(false)

  return(
    <>
      <button onClick={() => setToggle(!toggle)}>Toggle Dropdown Markup</button>
      {toggle && (
        <ul>
          <li>Show me</li>
          <li>Only when</li>
          <li>Toggle === true</li>
        </ul>
      )}
    </>
  )
}
//app.js
import React, { useState } from 'react';
import './App.css';

function App() {
  const [firstDieResult, setFirstDieResult] = useState(1);
  const [secondDieResult, setSecondDieResult] = useState(6);
  //OR
  //const [diceResult, setDiceResult] = useState({
  	//firstDieResult: 1,
  	//secondDieResult: 6,
	//});

  const firstDieImage = require(`./assets/${firstDieResult}.png`);
  const secondDieImage = require(`./assets/${secondDieResult}.png`);

  function rollDice() {
    setFirstDieResult(Math.floor(Math.random() * 6) + 1);
    setSecondDieResult(Math.floor(Math.random() * 6) + 1);
  }

  return (
    <div className="App">
      <header className="App-header">
        <div style={{ display: 'flex', margin: 20 }}>
          <img src={firstDieImage} className="die" alt="Die one" />
          <img src={secondDieImage} className="die" alt="Die two" />
        </div>
        <span>{firstDieResult + secondDieResult}</span>
        <button className="button" onClick={rollDice}>Roll</button>
      </header>
    </div>
  );
}

export default App;

//css

.App {
  text-align: center;
}

.App-header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(16px + 2vmin);
  color: white;
}

.die {
  width: 50px;
  height: 50px;
  margin: 10px;
}

.button {
  margin-top: 20px;
  outline: none;
  animation: button-gradient 25s ease infinite;
  background-image: -webkit-linear-gradient(65deg,#21d4fd,#b721ff 50%,#017eff);
  background-image: linear-gradient(25deg,#21d4fd,#b721ff 50%,#017eff);
  background-size: 500%;
  border: none;
  border-radius: 3px;
  box-shadow: 0 3px 0 0 #5664a7;
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  height: 40px;
  width: 150px;
}

.button:hover {
  box-shadow: 0 2px 0 0 #5664a7;
}

.button:active {
  box-shadow: inset 0 2px 4px rgba(0,0,0,0.25), 0 1px 2px rgba(0,0,0,0.05);
}
// get images => https://upmostly.com/wp-content/uploads/react-dice-assets.zip
import React, { useEffect, useState } from 'react';

function App() {
  const [age, setAge] = useState(0);
  
  updateAge(value) {
    setDisplayUsaStudents(
            (prevDisplayUsaStudents) => !prevDisplayUsaStudents
          );
    setAge({prevAge: value});
  };

  useEffect(() => {
    if (age !== 0 && age >= 21) {
      // Make API call to /beer
    } else {
      // Throw error 404, beer not found
    }
//the square parentheses with the age state variable inside is called the dependency array. //it tells the useEffect function to listen for any changes to the state of age.
//when age changes, useEffect executes
  }, [age]);

  return (
    <div>
      <p>Drinking Age Checker</p>
      <input
        type="number"
        value={age} 
        onChange={e => setAge(e.target.value)}
      />
    </div>
  );
}

export default App;
import React, { Component } from 'react';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      age: 0,
    };
  }
  
  // this.checkAge is passed as the callback to setState
  updateAge = (value) => {
    this.setState({ age: value}, this.checkAge);
  };

  checkAge = () => {
    const { age } = this.state;
    if (age !== 0 && age >= 21) {
      // Make API call to /beer
    } else {
      // Throw error 404, beer not found
    }
  };

  render() {
    const { age } = this.state;
    return (
      <div>
        <p>Drinking Age Checker</p>
        <input
          type="number"
          value={age}
          onChange={e => this.updateAge(e.target.value)}
        />
      </div>
    );
  }

}

export default App;
//app.js
import React, { useState } from 'react';
import './App.css';
import Switch from "./Switch";

function App() {
  const [value, setValue] = useState(false);
  return (
    <div className="app">
      <Switch
        isOn={value}
        onColor="#EF476F"
        handleToggle={() => setValue(!value)}
      />
    </div>
  );
}

export default App;

//Switch.js
import React from 'react';

const Switch = ({ isOn, handleToggle, onColor }) => {
  return (
    <>
      <input
        checked={isOn}
        onChange={handleToggle}
        className="react-switch-checkbox"
        id={`react-switch-new`}
        type="checkbox"
      />
      <label
        style={{ background: isOn && onColor }}
        className="react-switch-label"
        htmlFor={`react-switch-new`}
      >
        <span className={`react-switch-button`} />
      </label>
    </>
  );
};

export default Switch;

//css
.react-switch-checkbox {
  height: 0;
  width: 0;
  visibility: hidden;
}

.react-switch-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
  width: 100px;
  height: 50px;
  background: grey;
  border-radius: 100px;
  position: relative;
  transition: background-color .2s;
}

.react-switch-label .react-switch-button {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 45px;
  height: 45px;
  border-radius: 45px;
  transition: 0.2s;
  background: #fff;
  box-shadow: 0 0 2px 0 rgba(10, 10, 10, 0.29);
}

.react-switch-checkbox:checked + .react-switch-label .react-switch-button {
  left: calc(100% - 2px);
  transform: translateX(-100%);
}

.react-switch-label:active .react-switch-button {
  width: 60px;
}
import React from 'react';

const people = [
  {
    name: 'James',
    age: 31,
  },
  {
    name: 'John',
    age: 45,
  },
  {
    name: 'Paul',
    age: 65,
  },
  {
    name: 'Ringo',
    age: 49,
  },
  {
    name: 'George',
    age: 34,
  }
];

function App() {
  return (
    <div>
      {people.filter(person => person.age < 60).map(filteredPerson => (
        <li>
          {filteredPerson.name}
        </li>
      ))}
    </div>
  );
}

export default App;
import React from 'react';

const names = ['James', 'John', 'Paul', 'Ringo', 'George'];

function App() {
  return (
    <div>
      {names.filter(name => name.includes('J')).map(filteredName => (
        <li>
          {filteredName}
        </li>
      ))}
    </div>
  );
}

export default App;
// This is what I've been using, pretty straight forward
// It passes the JSON to the children as props
// Of course, you fetch what you will
 
import React, { Component, Fragment } from 'react';
 
export class FetchJsonController extends Component
{
	constructor(props) {
		super(props);
		this.state = {
			data: null,
		};
	}
 
	componentDidMount() {
		fetch(this.props.src)
			.then(response => response.json())
			.then(data => {
				console.log(data);
				this.setState({ data })
			});
	}
 
	render() {
		const _data = this.state.data;
		const children = React.Children.map(this.props.children, child => {
			return React.cloneElement(child, {
				jsonData: _data
			});
		});
		return (
			<div>{ children }</div>
		)
	}
}
 
// This is how it's used
// SomeCompnent will receive the JSON data
<FetchJsonController src="somefile.json">
  <SomeComponent />
</FetchJsonController>
const { scrollTop, offsetHeight } = document.documentElement;
const { innerHeight } = window;
const bottomOfWindow = Math.round(scrollTop) + innerHeight === offsetHeight;

if (bottomOfWindow) {
  console.log('Bottom of window');
}
//What are pure functions?
//Pure functions take an input value (a parameter or argument) and produce an output value. //Like with hashing, the same input it will always return the same output 

const myPureFunction = number => return number * 4

//Pure functions must:
//1. Contain no side effects
//2. When given the same input, return the same output.
// A pure component avoids any use of state.
map
filter
reduce
import React, { Component } from "react";

class IconList extends Component {
  static defaultProps = {
    options: [
      "angry",
      "anchor",
      "archive",
      "at",
      "archway",
      "baby",
      "bell",
      "bolt",
      "bone",
      "car",
      "city",
      "cloud",
      "couch"
    ]
  };
  constructor(props) {
    super(props);
    this.state = { icons: ["bone", "cloud"] };
    this.addIcon = this.addIcon.bind(this);
  }
  //DON'T DO THIS!!!!
  // addIcon() {
  //   let idx = Math.floor(Math.random() * this.props.options.length);
  //   let newIcon = this.props.options[idx];
  //   let icons = this.state.icons;
  //   icons.push(newIcon);
  //   this.setState({ icons: icons });
  // }

  addIcon() {
    // get random index
    let idx = Math.floor(Math.random() * this.props.options.length);
 	// get new element
    let newIcon = this.props.options[idx];
    // update the state of the icons array (spread icons into new array, add new icon to it)
    this.setState({ icons: [...this.state.icons, newIcon] });
  }
  render() {
    // render newly mapped icons array
    const icons = this.state.icons.map(i => <i className={`fas fa-${i}`} />);
    return (
      <div>
        <h1>Icons: {icons}</h1>
        <button onClick={this.addIcon}>Add New Icon</button>
      </div>
    );
  }
}

export default IconList;
idを付けたelementが出てくる前に、<script src="app.js"></script>が先に来ているから。

<div id="test"></div>
のあとに
<script src="app.js"></script>
を持ってこないとJavaScriptは何を言わているか分からない。
一番良いのは</body>の直前。
import React from 'react';
import Carousel from 'react-material-ui-carousel'
import { Paper, Button } from '@material-ui/core'

function Example(props)
{
    var items = [
        {
            name: "Random Name #1",
            description: "Probably the most random thing you have ever seen!"
        },
        {
            name: "Random Name #2",
            description: "Hello World!"
        }
    ]

    return (
        <Carousel>
            {
                items.map( (item, i) => <Item key={i} item={item} /> )
            }
        </Carousel>
    )
}

function Item(props)
{
    return (
        <Paper>
            <h2>{props.item.name}</h2>
            <p>{props.item.description}</p>

            <Button className="CheckButton">
                Check it out!
            </Button>
        </Paper>
    )
}
function App() {
  const [checked, setChecked] = useState(false);
  const toggleChecked = () => setChecked(value => !value);
  return (
    <input
      type="checkbox"
      checked={checked}
      onChange={toggleChecked}
    />
  );
}
<Input type="number"
    onInput={(e)=>{ 
        e.target.value = Math.max(0, parseInt(e.target.value) ).toString().slice(0,2)
    }}
/>
import React from 'react'

import styled, { keyframes } from 'styled-components'

const rotate = keyframes`
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
`

const StyledSVG = styled.svg<{ size: string; stroke?: string }>`
  animation: 2s ${rotate} linear infinite;
  height: ${({ size }) => size};
  width: ${({ size }) => size};
  path {
    stroke: ${({ stroke, theme }) => stroke ?? theme.primary1};
  }
`

export default function Loader({
  size = '16px',
  stroke,
  ...rest
}: {
  size?: string
  stroke?: string
  [k: string]: any
}) {
  return (
    <StyledSVG viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" size={size} stroke={stroke} {...rest}>
      <path
        d="M12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 9.27455 20.9097 6.80375 19.1414 5"
        strokeWidth="2.5"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </StyledSVG>
  )
}
  let sortedArray= !loading && assets.slice().sort((a, b) => a.name.localeCompare(b.name))
{(() => {
  if (minMaxError) return <InputInfoError>{errorMessage}</InputInfoError>
  else return <InputInfo>{sellAssetName}</InputInfo>
})()}
const onlyIntegers = () => {
    const myInput = document.querySelectorAll("input[type=number]");

    function keyAllowed(key) {
      const keys = [8, 9, 13, 16, 17, 18, 19, 20, 27, 46, 48, 49, 50,
        51, 52, 53, 54, 55, 56, 57, 91, 92, 93
      ];
      if (key && keys.indexOf(key) === -1)
        return false;
      else
        return true;
    }

    myInput.forEach(function(element) {
      element.addEventListener('keypress', function(e) {
        const key = !isNaN(e.charCode) ? e.charCode : e.keyCode;
        if (!keyAllowed(key))
          e.preventDefault();
      }, false);

      // Disable pasting of non-numbers
      element.addEventListener('paste', function(e) {
        const pasteData = e.clipboardData.getData('text/plain');
        if (pasteData.match(/[^0-9]/))
          e.preventDefault();
      }, false);
    })
  };

  useEffect(() => {
    onlyIntegers()
  }, []);

 <Input type='number'/>
const referencePickupTime = moment(booking.reference_pickup_time).format('H:mm')
	console.log('test', referencePickupTime)
{
    "about.contactEmail":"E-mail",
    "about.contactForm":"Formulaire",
    "about.contactPhone":"Téléphone",
    "about.contactTitle":"Contacter notre service {brand} par :",
    "about.copyEmail":"Copier l'adresse e-mail",
    "about.copyPhone":"Copier le numéro de téléphone",
    "about.formFill":"Aller sur le site internet",
    "about.labelTab1":"Zone du service",
    "about.labelTab2":"Contact",
    "about.noInfos":"Les informations de cette page seront bientôt disponibles.",
    "about.operating":"Découvrir le fonctionnement du service",
    "about.text":"Sur la carte vous pouvez voir la zone d'action de notre service.",
    "about.title":"Vous utilisez le service de {brand}",
    "about.zone":"Voir les zones desservies",
    "brand":"Marque",
    "booking.confirm":"{dayCount, plural, one {La} other {Les}} {dayCount, plural, one {réservation} other {réservations}} {dayCount, plural, one {suivante} other {suivantes}} {dayCount, plural, one {est} other {sont}} {dayCount, plural, one {confirmée} other {confirmées}} :",
    "booking.error":"{dayCount, plural, one {La} other {Les}} {dayCount, plural, one {réservation} other {réservations}} {dayCount, plural, one {suivante} other {suivantes}} {dayCount, plural, one {a} other {ont}} {dayCount, plural, one {échoué} other {échoué}} :",
    "breadcrumb.bookingValidation":"Confirmation",
    "breadcrumb.home":"Accueil",
    "breadcrumb.reservation":"Trajets à venir",
    "breadcrumb.myResa":"Ma réservation",
    "breadcrumb.callcenter":"Espace centre d'appel",
    "breadcrumb.search":"Propositions",
    "button.confirm_next":"Valider et continuer",
    "cancel":"Annuler",
    "credit.buyWithDiscount":"Acheter {creditAmount} crédits et payer {price} {currency}",
    "credit.wallet":"Portefeuille",
    "credit.balance":"Solde actuel : {balance} {balance, plural, one {crédit} other {crédits}}",
    "credit.notEnough":"Vous n'avez pas assez de crédits. Vous pouvez en acheter depuis le menu en haut à droite !",
    "credit.balanceAfter":"Solde après paiement : {balance}",
    "date.the":"le {date}",
    "date.title":"Dates",
    "edition.title":"Modifiez votre réservation",
    "editionConfirm.title":"Confirmez votre modification de réservation",
    "favorite.error":"Vous n'avez pas de favoris",
    "favorite.favorite1":"Favori 1",
    "favorite.favorite2":"Favori 2",
    "favorite.home":"Domicile",
    "favorite.home_to_workplace":"Domicile > Gare",
    "favorite.trip_1_to_2":"Favori 1 > Favori 2",
    "favorite.trip_2_to_1":"Favori 2 > Favori 1",
    "favorite.workplace":"Gare",
    "favorite.workplace_to_home":"Gare > Domicile",
    "footer.cvg":"CGU",
    "footer.gdpr":"Vie privée",
    "footer.privatePolicy":"Mentions légales",
    "forgetPassword.title":"Formulaire de réinitialisation de mot de passe",
    "forgetPassword.newPassword":"Nouveau mot de passe",
    "forgetPassword.newPasswordConfirmed":"Mot de passe modifié avec succès",
    "forgetPassword.resetPassword":"Réinitialiser votre mot de passe",
    "forgetPassword.enterEmail":"Veuillez entrer votre adresse email, et nous vous enverrrons un lien de réinitialisation de mot de passe",
    "forgetPassword.send":"Envoyer",
    "form.error.date_past":"La date doit être supérieure à aujourd'hui",
    "form.error.endstart":"La date de fin doit être après celle de début",
    "form.error.datetime_past":"L'heure doit être ultérieure à l'heure actuelle",
    "form.error.not_blank":"Cette valeur ne doit pas être vide",
    "form.error.select_date":"Veuillez sélectionner une date",
    "form.error.select_time":"Veuillez sélectionner une heure",
    "form.error.too_many_dates":"Le nombre de jour est limité à {count}",
    "help.swap":"Inverser les lieux de départ et d'arrivée",
    "help.address":"Adresse, arrêt de bus ...",
    "help.fav1To2":"favori 1 vers favori 2",
    "help.fav2To1":"favori 2 vers favori 1",
    "help.history":"Liste des lieux de départ et d'arrivée des derniers trajets",
    "help.passengersAdd":"Actuellement {number} {type}, Ajouter un passager",
    "help.passengersSubstract":"Actuellement {number} {type}, Enlever un passager",
    "help.recurrenceOffer":"Fréquence de répétition",
    "help.calendar":"{number, plural, one {La date choisie est} other {Les dates choisies sont}}",
    "help.recurrenceStartDate":"La période récurrente commence à {startDate}",
    "help.calendarMonth":"Le mois en cours est {month1}, aller à {month2}",
    "help.recurrenceEndDate":"La période récurrente finit à {endDate}",
    "help.rideShort":"Départ de {pickupNode} à {pickupTime}. Arrivée à {dropoffNode} à {dropoffTime}.",
    "impersonate.title":"Espace de la centrale d'appel",
    "impersonate.floattingHint":"Rechercher par nom, prénom, téléphone, email",
    "impersonate.helpText":"Utilisez la barre de recherche pour rechercher un utilisateur. Une fois validé, vous agirez en sa personne",
    "impersonate.new":"Créer un nouvel utilisateur",
    "impersonate.session_closed":"Session terminée",
    "impersonate.start":"Démarrer la session",
    "impersonate.title2":"Agir en tant que",
    "impersonate.me":"Votre identité principale",
    "impersonate.users_available":"Utilisateurs disponibles",
    "impersonate.survey_title":"Aidez-nous à améliorer votre expérience du site de réservation",
    "impersonate.survey_body":"C’est très rapide, cela vous prendra 5 min pour répondre à notre questionnaire. Vos réponses nous permettront d’améliorer notre service pour mieux répondre à vos besoins.",
    "impersonate.survey_link":"Répondre au questionnaire",
    "link.register":"S'inscrire",
    "locale.timepicker_hint":"saisissez l'heure de la réservation",
    "menu.about":"Aide et contact",
    "menu.account":"Informations du compte",
    "menu.booking":"Réserver un trajet",
    "menu.choose_territory":"Choisir mon territoire",
    "menu.current_territory":"Votre territoire : \u200B {territory}",
    "menu.edit_favorite":"Editer vos favoris",
    "menu.favorite":"Vos favoris",
    "menu.impersonate":"Agir en tant que",
    "menu.journey":"Vos trajets",
    "menu.logout":"Déconnexion",
    "menu.switch_territory":"Changer mon territoire",
    "menu.territory_current":"Votre territoire desservi",
    "menu.territory_info":"Votre choix de territoire affectera la zone dans laquelle vous pourrez chercher des trajets dans l’application. Vous pourrez changer de territoire à tout moment, dans le menu de l'application.",
    "menu.territory_other":"Autres territoires",
    "misc.back_to_search":"Retour à la recherche",
    "misc.book":"Réserver",
    "misc.book_price":"Réserver {price} {currency}",
    "misc.cancel":"Annuler",
    "misc.choose_list":"Choisir dans la liste",
    "misc.confirm":"Confirmer",
    "misc.confirm_cancellation":"Confirmer l'annulation",
    "misc.confirm_delete_reservation":"Voulez vous vraiment annuler cette réservation ?",
    "misc.delete":"Annuler",
    "misc.edit":"Modifier",
    "misc.editTime":"Modifier les horaires",
    "misc.editPassengers":"Modifier le nombre de passagers",
    "misc.loading":"Chargement",
    "misc.later":"Plus tard",
    "misc.redirect":"Y aller",
    "misc.new":"Nouveau",
    "misc.no":"Non",
    "misc.not_blank":"Veuillez remplir ce champ",
    "misc.save":"Enregistrer",
    "misc.see_my_ride":"Voir mon trajet",
    "misc.see_my_rides":"Voir mes trajets",
    "misc.sooner":"Plus tôt",
    "misc.unexpected_error":"Une erreur est survenue",
    "misc.validate":"Valider",
    "misc.why_delete_reservation":"Optionnel: Pourquoi souhaitez-vous annuler votre réservation ?",
    "misc.yes":"Oui",
    "notFound.title":"Cette page n'est pas disponible",
    "notFound.not_exist":"Le lien saisi est incorrect ou n'existe plus.",
    "notFound.not_exist2":"Nous vous invitons à revenir à l'accueil.",
    "notFound.back_home":"Accéder à l'accueil",
    "optin.accept":"Oui, je donne mon consentement",
    "optin.confirmation":"Confirmez-nous que vous souhaitez recevoir de notre part des informations et des propositions commerciales ?",
    "optin.decline":"Non, je ne donne pas mon consentement",
    "optin.info":"Pour plus d’information sur le traitement de vos données,",
    "optin.link":"cliquez sur ce lien",
    "optin.rule":"Le 25 mai 2018, le règlement général sur la protection des données (GDPR) est entré en vigueur. Nous nous engageons à ne pas vendre, louer ou céder vos données personnelles.",
    "passengers.title":"Passagers",
    "payment.title":"Paiement des trajets sélectionnés",
    "payment.confirmed":"Paiement confirmé",
    "payment.credits":"Crédits",
    "payment.credit_card":"Carte de crédit",
    "payment.cardNumber":"Numéro de carte",
    "payment.cvc":"CVC",
    "payment.enter_credit_card":"Entrez votre n° de carte de crédit",
    "payment.expiration_date":"Date d'expiration",
    "payment.free":"Votre réservation est à présent gratuite !",
    "payment.onboard":"À bord",
    "payment.payment":"Paiement",
    "payment.promoCode":"Promo code",
    "payment.ride":"Payer votre réservation {price} {currency}",
    "payment.general":"Payer {price} {currency}",
    "payment.type":"Mode de paiement :",
    "payment.total": "Total : {price} {currency}",
    "payment.saved_cards": "Cartes enregistrées",
    "payment.saveCard": "Enregistrez votre carte",
    "payment.saveCard2": "Enregistrer votre carte vous permettra de payer en un clic lors de votre prochaine résevation",
    "payment.summary":"Récapitulatif",
    "payment.new_card": "Nouvelle carte",
    "payment.withCredits":"Payer {price} crédits",
    "payment.withOnBoard":"Payer à bord",
    "profile.title":"Modifier les informations personnelles",
    "profile.edit_password":"Modifiez le mot de passe",
    "profile.old_password":"Ancien mot de passe",
    "profile.repeat_new_password":"Répetez le nouveau mot de passe",
    "profile.updated":"Profil mis à jour",
    "reservationList.title":"votre liste de réservation",
    "reservation.title":"Votre reservation",
    "reservation.deleted":"Réservation annulée",
    "reservation.edited":"Réservation modifiée",
    "reservationEdition.sidebar.desc":"Modifier ici l'horaire de votre réservation",
    "reservationEdition.sidebar.title":"Modifier votre réservation",
    "reservations.date":"Date",
    "reservations.dropoff":"Point d'arrivée",
    "reservations.passengers":"Passager(s)",
    "reservations.pickup":"Point de départ",
    "reservations.time":"Heure départ",
    "reservation.rate.button":"Me noter",
    "reservation.rate.subtitle":"Comment s'est passé votre trajet ?",
    "reservation.rate.driver":"Notez votre conducteur",
    "reservation.rate.ride":"Notez votre course",
    "reservation.rate.error":"Veuillez choisir une note",
    "reservation.ride":"Course",
    "reservation.rate.comment":"Commentaires",
    "ride.alternatives":"Voir les alternatives",
    "ride.arrive_on":"Votre bus arrive le {time}",
    "ride.arrive_at":"Votre bus arrive à {time}",
    "ride.arrive_in":"Votre bus arrive dans {time}",
    "ride.bus_model":"Modèle",
    "ride.bus_plate":"Plaque",
    "ride.delete":"Annuler",
    "ride.driver_name":"Conducteur",
    "ride.driver_phone":"N° de téléphone",
    "ride.incoming":"Votre bus arrive",
    "ride.maximum_detours_allowed":"L'heure d'arrivée inclut les détours maximums possibles.",
    "ride.minute":"{count} {count, plural, =0 {minute} one {minute} other {minutes}}",
    "ride.price":"Prix: {price} {currency}",
    "ride.reference":"Il vous attendra jusqu'à {time}",
    "ride.see_more":"Voir plus",
    "ride.welcome":"Bienvenue à bord !",
    "ride.no_trips":"Il n'y a pas de voyage sélectionné",
    "ride.select_trips":"Aller à la page d'accueil pour en sélectionner un!",
    "search.title":"Formulaire de recherche de trajets",
    "search.arrival_time":"Arrivée à",
    "search.confirm.title":"Trajets sélectionnés",
    "search.confirm.single_trip":"Trajet sélectionné",
    "search.confirm.notrip":"Aucun trajet sélectionné",
    "search.confirmation.no_date_selected":"Veuillez sélectionner au moins une date",
    "search.confirmationText.edition":"Changement d'horaire pour la réservation du :",
    "search.confirmationText.many":"Vous avez réservé {count} {count, plural, one {jour} other {jours}} entre :",
    "search.confirmationText.one":"Vous avez réservé 1 jour :",
    "search.date":"Le {date}",
    "search.recurring":"À partir du {start_date} jusqu'au {end_date} pour : {offer}",
    "search.departure_time":"Départ à",
    "search.departureNow":"Dès que possible",
    "search.dropoff":"À",
    "search.dropoff.placeholder":"Arrivée",
    "search.error.nbPassengers":"Vous devez renseigner au moins un passager",
    "search.grid.title":"Vos trajets préselectionnés",
    "search.lastBookings":"Trajets récents",
    "search.motive":"Motif",
    "search.multi_date":"Du {startDate} au {endDate}",
    "search.nb_bikechairs":"Passagers en vélo",
    "search.nb_wheelchairs":"Passagers en fauteuil roulant",
    "search.nb_standards":"Passagers",
    "search.no_result":"Aucun résultat pour le {date}",
    "search.no_result2":"Il n'y a actuellement aucun trajet possible possible pour votre recherche",
    "search.once":"Une seule fois",
    "search.passengersNumber":"Nombre de passagers",
    "search.pickup":"DE",
    "search.pickup.placeholder":"Départ",
    "search.recurrence.start_date":"Sélectionner une date de début",
    "search.recurrence.doNotRepeat":"Ne pas répéter",
    "search.recurrence.end_date":"Sélectionner une date de fin",
    "search.recurrence.title":"Répétition",
    "search.recurrence.from":"Du",
    "search.recurrence.until":"Jusqu'au",
    "search.schedule":"Date(s)",
    "search.sidebar.title":"Votre recherche",
    "search.submit":"Rechercher",
    "search.time":"Heure",
    "search.the":"Sélectionner une ou plusieurs date(s)",
    "search.monoDate":"Sélectionner une date",
    "searchResult.title":"Sélection des résultats de recherche",
    "searchResultConfirm.title":"Confirmer les trajets sélectionnées",
    "section.history":"Mes derniers trajets",
    "section.time":"Date et heure",
    "section.options":"Options de trajet",
    "signin.title":"Formulaire de connexion",
    "signin.connexion":"Se connecter",
    "signin.disabled":"Bonjour, le site de réservations est indisponible pour ce service, utiliser l'application mobile pour réserver s'il-vous-plaît, bonne journée !",
    "signin.forgetPassword":"J'ai oublié mon mot de passe",
    "signin.password":"Mot de passe",
    "signin.email":"Adresse email",
    "signup.title":"Formulaire d'inscription",
    "signup.accept_terms":"En vous inscrivant, vous acceptez les {cgu}",
    "signup.firstname":"Prénom ou pseudo",
    "signup.lastname":"Nom (Privé)",
    "signup.mail":"Mail",
    "signup.passportNumber":"Carte d'Identité/Passeport",
    "signup.password_doesnt_match":"Les mots de passe ne correspondent pas",
    "signup.password_repeat":"Répétez votre mot de passe",
    "signup.phoneNumber":"Numéro de téléphone",
    "signup.terms":"CGU",
    "signup.verification.number":"Numéro de vérification",
    "signup.verification.re_send":"renvoyer un SMS",
    "signup.verification.verify":"Vérifier",
    "signupVerification.title":"Vérifiez Votre Identité",
    "sitemap.title":"Plan du Site",
    "tabs.recurring":"Trajets récurrents",
    "tabs.empty_recurring":"Pas de trajet récurrent",
    "tabs.cancelled":"Trajets annulés",
    "tabs.empty_cancelled":"Aucun trajet annulé",
    "tabs.empty_past":"Aucun trajet passé",
    "tabs.empty_upcoming":"Aucun trajet à venir",
    "tabs.past":"Trajets passés",
    "tabs.upcoming":"Trajets à venir",
    "terms.additional_checkbox":"J'accepte aussi que TAD collecte et utilise les données personnelles que je viens de renseigner dans ce formulaire dans le but de m'envoyer des propositions commerciales, en lien avec la politique de protection des données de TAD",
    "terms.body":"J’accepte les conditions générales du service",
    "terms.bodyAge":"J’accepte les conditions générales du service et je confirme avoir plus de {age} ans",
    "terms.button_terms_of_use":"Voir les conditions d’utilisation",
    "terms.button_gdpr_traitement":"Voir les conditions RGPD",
    "terms.commercial":"J'accepte également que {brand} collecte et utilise mes données personnelles pour envoyer des offres commerciales et des suggestions, conformément à la politique de protection des données de {brand}",
    "terms.confirm":"En cliquant sur \"CONFIRMER\", j'accepte les conditions d'utilisation du service.",
    "terms.dataConfirm":"J'accepte également que {brand} collecte et utilise mes données personnelles pour envoyer des offres commerciales et des suggestions, conformément à la politique de protection des données de {brand}",
    "terms.unsubscribe":"Vous n'êtes plus inscrits aux e-mails à visée commerciale !",
    "terms.title":"Conditions d’utilisation et politique de données",
    "territories":"Territoire"
}
import React, { useState, useEffect } from 'react'
import { connect } from 'react-redux'
import { TextField, List, ListItem, CircularProgress, InputAdornment, createMuiTheme, makeStyles } from '@material-ui/core'
import NodeSuggestions from 'components/Autocomplete/NodeSuggestions'
import AddressSuggestions from 'components/Autocomplete/AddressSuggestions'
import UserSuggestions from 'components/Autocomplete/UserSuggestions'
import GeocodedSuggestion from 'components/Autocomplete/GeocodedSuggestion'
import {map} from 'lodash'
import { ARROW_UP, ARROW_DOWN,
	enter, onInputChange, RESET_AUTOCOMPLETE, contextToData } from 'containers/Autocomplete/actions'
import PickUp from 'components/Icons/PickUp/PickUp.jsx'
import {useIntl} from 'react-intl'


const suggestionProviders = {
	'geocodes': GeocodedSuggestion,
	'nodes': NodeSuggestions,
	'addresses': AddressSuggestions,
	'users': UserSuggestions
}

const useStyles = makeStyles((theme) => ({
	root: {
		'& .MuiTextField-root': {
			margin: '20px',
		}
	}
}))

function Autocomplete(props){
	const classes = useStyles()

	/********  props from parent
    * text : the text in the field, controlled by parent with:
		* onChange
    * context : the view where is the autocomplete => which data it displays ?
    * onSelect : when clicking on suggestion
    */
	const { onChange, onInputChange, context, onSelect, loading, highlightedIndex } = props
	const { text, helperText, label} = _.get(props, 'inputProps', {})
	/******* props generated from inside
		*/
	const { arrowUp, arrowDown, enter, resetAutocomplete } = props

	/******** internal state that is not needed above the component
    */
	const [isFocused, setFocus] = useState(false)
	// conditional opening of autocomplete
	const open = isFocused && text &&	text.length >= 3

	// highlighted index (for keyboard navigation) is managed via redux to answer the case of
	// switching from node to address suggestion

	const handleKey = (e) => {
		e.stopPropagation()
		switch (e.keyCode) {
		// second thought : a "selected" element with arrows is also displayed and entered in form
		// context to know which datatypes are displayed and to guess the highlightedIndex element
		case 38:// arrowUp key
			arrowUp(context)
			enter(context, onSelect)
			break
		case 40:// arrowDown key
			arrowDown(context)
			enter(context, onSelect)

			break
		case 13:// enter key
			enter(context, onSelect)
			setFocus(false)
			resetAutocomplete()
			break
		}
	}

	// below is cleaning the "highlightedIndex" in an edge case
	useEffect(()=>{
		if(isFocused && text &&	text.length < 3){
			resetAutocomplete()
		}
	},[text])

	const intl = useIntl()

	return(
		<div className="fullWidth" style={{position:'relative'}}
			//ACCESSIBILITY
			role="combobox"
			aria-expanded={open}
		>
			<label htmlFor={label} style={{color:'#6c6c6c'}}>{label}</label>
			<TextField
				autoComplete="off" // not from the browser
				id={label}
				fullWidth
				value={text}
				onChange={e =>{
					// update search.formData and textfield
					onChange(e)
					// update autoComplete only when user types a letter
					onInputChange(e.target.value, context)
					setFocus(true)
				}}
				onFocus={()=>{
					// loads suggestions also when clicking
					if (text && text.length >= 3){
						onInputChange(text, context)
					}
					setFocus(true)
				}}
				onBlur={()=>{
					setFocus(false)
					resetAutocomplete()
				}}
				onKeyDown={handleKey}
				// label={label}
				// hiddenLabel
				helperText={helperText}
				error={Boolean(helperText)}
				title={label}
				InputProps={{
					disableUnderline: true
				}}
				InputLabelProps={{ shrink: true }}

				// ACCESSIBILITY
				inputProps={{
					autoComplete:'off',
					'aria-autocomplete':open ? 'list' : 'none',
					'aria-controls':open ? 'autocomplete_results' : '',
					'aria-activedescendant': open ? 'suggestion-'+highlightedIndex : '',
					role:'textbox'
				}}
				placeholder={intl.formatMessage({ id: 'help.address' })}
				style={{height: '2.5rem', marginTop:'0.5rem', backgroundColor:'#f1f0f0', borderRadius:'0 5px 5px 0'}}
			/>

			{ open &&
			<List
				tabIndex={-1}
				disablePadding
				className="suggestionsContainer"
				// ACCESSIBILITY
				id="autocomplete_results"
				role="listbox"
			>
        	{ loading ? <div className="row centered fullWidth padded"><CircularProgress size={20} /></div>
					:
						 map(contextToData[context],(dataType,i)=>{
        		const SuggestionProvider = suggestionProviders[dataType]
        		return(
        			<SuggestionProvider
        				key={i}
        				onSelect={onSelect}
        			/>
        		)
        	})}
			</List>
			}
		</div>
	)
}
const mapStateToProps = state => ({
	loading: state.autocomplete.loading,
	highlightedIndex: state.autocomplete.highlightedIndex
})

const mapDispatchToProps = dispatch => ({
	arrowUp : (context) => dispatch({ type : ARROW_UP, context }),
	arrowDown : (context) => dispatch({ type : ARROW_DOWN, context }),
	enter : (context, onSelect) => dispatch(enter(context, onSelect)),
	onInputChange : (newText, context) => dispatch(onInputChange(newText, context)),
	resetAutocomplete: () => dispatch({type: RESET_AUTOCOMPLETE})
})
export default connect(mapStateToProps, mapDispatchToProps)(Autocomplete)
import React from 'react'
import { MenuItem, IconButton, Button as MuiButton, Switch, RadioGroup, Radio, FormControlLabel,
	Typography, Paper, TextField, Collapse, Card, makeStyles, InputLabel, InputAdornment } from '@material-ui/core'
import Swap from 'components/Icons/Swap'
import FavoriteLoader from './FavoriteLoader.jsx'
import PassengersCount from './PassengersCount.jsx'
import Autocomplete from 'containers/Autocomplete/Autocomplete.js'
import CustomDayPickerInput from 'containers/CustomDayPickerInput/CustomDayPickerInput.jsx'
import styles from './form.cssmodule.scss'
import api from 'api'
import moment from 'moment'
import DropOff from 'components/Icons/DropOff/DropOff.jsx'
import PickUp from 'components/Icons/PickUp/PickUp.jsx'
import { FormattedMessage } from 'react-intl'
import LastBookings from './LastBookings'
import FormSectionHeader from './FormSectionHeader'
import { get } from 'lodash'
import {extrasToGenericSeats} from 'lib/genericSeatsFunctions'
import {KeyboardTimePicker as TimePicker} from '@material-ui/pickers'
import Clock from 'components/Icons/Clock/Clock.jsx'
import ExpandMore from '../Icons/ExpandMore.js'


const useStyles = makeStyles((theme) => ({
	input: {
		background: '#cee6f3',
		color: '#0869af',
		// fontSize:'18px'
		borderRadius:'10px',
		padding: '0.5rem',
	}
}))


export default function SearchForm(props){
	const classes = useStyles()

	const { formData, errors, onAddressSelected, onFieldChange, loadFavorite, intl,
		territory, increasePassengers, decreasePassengers, onSubmit, swapActive, swapAddresses,
		actualizeDeparture, onDayClick, customFieldInfos, requesting } = props
	const { departure, destination, time, timeRestrictionType,
		passengers, asap, recurrence, selectedDays, customFields} = formData

	const recurringOffers = _.get(props, 'territory.booking.recurring_bookings.offers') || []

	const extras = _.get(territory,'extras',{}) // special seats
	const extrasTypes = extrasToGenericSeats(extras)

	const nbPassengers = _.reduce(extrasTypes, (red, type) => red + _.get(passengers, type, 0), passengers.standard)

	return (
		<div className={styles.form}>
			<Paper>
				<form
					className={'row'}
					style={{justifyContent:'space-around'}}
				>
					<div className="column padded" style={{ flex: '0 0 45%' }}>
						<div className='column' style={{justifyContent:'flex-start'}}>
							<div className={`row-only ${styles.autoCompletes}`}>
								<div className="column" style={{ width: '100%' }}>
									<div className="row-only" style={{margin:'0.5rem 0',alignItems: 'flex-end'}}>
										<PickUp width={24} height={24} style={{marginTop:'0.5rem', padding:'0.5rem', backgroundColor:'#f1f0f0', borderRadius:'5px 0 0 5px'}}/>
										<Autocomplete
											context="search"
											inputProps={{
												label:intl.formatMessage({id: 'search.pickup.placeholder'}),
												helperText:errors.departure,
												text:departure.display,
											}}
											onChange={ e => {
												onFieldChange('departure', {
													display: e.target.value
												})
											}}
											onSelect={p =>
												onAddressSelected(p.suggestion, p.nodeId, 'departure', p.latitude, p.longitude, p.address)
											}
										/>
									</div>
									<div className="row-only" style={{margin:'0.5rem 0',alignItems: 'flex-end'}}>
										<DropOff width={24} height={24}  style={{marginTop:'0.5rem', padding:'0.5rem', backgroundColor:'#f1f0f0', borderRadius:'5px 0 0 5px'}}/>
										<Autocomplete
											context="search"
											inputProps={{
												label:intl.formatMessage({id: 'search.dropoff.placeholder'}),
												helperText:errors.destination,
												text:destination.display
											}}
											onChange={ e => {
												onFieldChange('destination', {
													display: e.target.value
												})
											}}
											onSelect={p =>
												onAddressSelected(p.suggestion, p.nodeId, 'destination', p.latitude, p.longitude, p.address)
											}
										/>
									</div>
								</div>
								<div className={`column ${styles.swapIcon}`}>
									{swapActive &&
								<IconButton
									title={intl.formatMessage({ id: 'help.swap' })}
									onClick={swapAddresses}
								>
									<Swap
										color="primary"
										style={{width:'1.5rem', height:'1.5rem'}}
									/>
								</IconButton>
									}
								</div>

							</div>
							<FavoriteLoader
								intl={intl}
								loadFavorite={loadFavorite}
							/>

							<LastBookings />
						</div>
					</div>

					<div className="column aligned padded"
						style={{ flex: '0 0 45%'}}>
						<div // big vertical container so that the BOOK button is on bottom
							className="column aligned fullWidth"
							style={{flexGrow:1, justifyContent:'space-around'}}>

							<Card elevation={4} style={{width:'100%', padding:'1rem'}}>
								<div className="column aligned fullWidth" /* HOUR + DATE + RECURRENCE */>
									<FormSectionHeader title={intl.formatMessage({ id:'section.time'})}/>
									<RadioGroup aria-label={intl.formatMessage({id:'search.time'})}
									// MAYBE REFACTOR INTELLIGENCE ?
										row
										className="fullWidth"
										style={{paddingLeft:'1rem'}} 
										value={asap ? 'asap' : timeRestrictionType}
										onChange={(e)=>{
											if (e.target.value === 'asap'){
												actualizeDeparture()
											}
											else {
												onFieldChange('asap', false)
												onFieldChange('timeRestrictionType', e.target.value)
											}
										}}>
										<FormControlLabel value="asap"
											control={<Radio color="primary" id="asap"/>}
											label={intl.formatMessage({ id: 'search.departureNow' })}
										/>
										<FormControlLabel value="departure"
											control={<Radio color="primary" id="departure"/>}
											label={intl.formatMessage({id: 'search.departure_time'})}
										/>
										<FormControlLabel value="arrival"
											control={<Radio color="primary" id="arrival"/>}
											label={intl.formatMessage({id: 'search.arrival_time'})}
										/>
									</RadioGroup>
									<Collapse in={!asap} style={{width:'100%'}} /* HOUR + DATE + RECURRENCE */>
										<div // HOUR
											className={styles.selectTime}>
											<TimePicker
												value={window.Cypress ? 1582949766 : time}
												onChange={newTime=>{
													if (newTime && newTime.isValid()){
														onFieldChange('time',newTime.format())
													}
												}}
												autoOk
												ampm={false}
												disabled={asap}
												inputVariant="outlined"
												maskChar=" "
												// below is because the modal is not keyboard accessible
												KeyboardButtonProps={{tabIndex:-1}}
												keyboardIcon={<Clock color="grey"/>}
												invalidDateMessage={<Typography color="error">"Invalid date"</Typography>}
												invalidLabel="false"
												helperText={errors && errors.time}
												error={Boolean(errors.time)}
												label={intl.formatMessage({id:'search.time'})}
												id="time"
												className={styles.timePicker}
												required
											/>

											{ /**  recurrence enabled but "do not repeat" => classic calendar here */
												recurringOffers && recurringOffers.length > 0 && recurrence.id === 0 &&
											<CustomDayPickerInput
												disabled={asap}
												tabIndex={0}
												selectedDays={(!asap ? selectedDays : [time]) || []}
												onDayClick={(day, r) => onDayClick(moment(day).format(), r)}
												errorText={errors.selectedDays}
												maxBookingDay={_.get(territory, 'booking.max_booking_day')}
												name="date"
												maxBookableDates={
													_.get(territory, 'booking.multi_date.max_bookable_dates')
												}
												label={intl.formatMessage({
													id: _.get(territory, 'booking.multi_date.enabled')
														&& _.get(territory, 'booking.multi_date.max_bookable_dates',0) > 1
														? 'search.the'
														: 'search.monoDate'
												})}
											/>
											}
										

											{	/*recurring two fields (start & end) */
												recurringOffers && recurringOffers.length > 0 && recurrence.id !== 0 &&
												<div className="column">
													<CustomDayPickerInput
														name="startDate"
														disabled={asap}
														// tabIndex={asap ? -1 : 12}
														selectedDays={[recurrence.start_datetime]}
														onDayClick={(day, requestRide) => onFieldChange('recurrence', {
															...recurrence,
															start_datetime: moment(day).format()
														})}
														errorText={errors.selectedDays}
														label={intl.formatMessage({
															id: 'search.recurrence.start_date'
														})}
													/>
													<CustomDayPickerInput
														name="endDate"
														disabled={asap}
														selectedDays={[recurrence.end_datetime]}
														onDayClick={(day, requestRide) => onFieldChange('recurrence', {
															...recurrence,
															end_datetime: moment(day).format()
														})}
														// tabIndex={asap ? -1 : 12}
														errorText={errors.selectedDays}
														label={intl.formatMessage({
															id: 'search.recurrence.end_date'
														})}
													/>
												</div>
											}
										</div>
										
										{ // either calendar OR recurence-offer-choice here
											!recurringOffers || recurringOffers.length === 0
												// CALENDAR
												?
												<CustomDayPickerInput
													disabled={asap}
													tabIndex={0}
													selectedDays={(!asap ? selectedDays : [time]) || []}
													onDayClick={(day, r) => onDayClick(moment(day).format(), r)}
													errorText={errors.selectedDays}
													maxBookingDay={_.get(territory, 'booking.max_booking_day')}
													name="date"
													maxBookableDates={
														_.get(territory, 'booking.multi_date.max_bookable_dates')
													}
													label={intl.formatMessage({
														id: _.get(territory, 'booking.multi_date.enabled')
														&& _.get(territory, 'booking.multi_date.max_bookable_dates',0) > 1
															? 'search.the'
															: 'search.monoDate'
													})}
												/>
												:
												<div style={{display: 'flex', alignItems:'center'}}>
													<label 
														htmlFor={'recurrence-offer-select'} 
														variant='body' style={{fontSize:'18px', marginRight:'0.5rem'}}
													>
														{intl.formatMessage({id:'help.recurrenceOffer'})}
													</label>
													<TextField  // RECURRENCE OFFER
														required
														id="recurrence-offer-select"
														select
														name="recurrenceOffer"
														className={`column ${styles.selectTargetMode}`}
														value={recurrence.id}
														style={asap ? { color: '#ccc' } : null}
														disabled={asap}
														onChange={(e) => {
															onFieldChange('recurrence', {
																...recurrence,
																id: e.target.value
															})
														}}
														// style={{minWidth:'18rem'}}
														InputProps={{ 
															className: classes.input,
															disableUnderline: true,
														}}
														SelectProps={{ 
															IconComponent: () => <ExpandMore style={{position:'absolute', right: 10}}/>
														}}
													>
														<MenuItem value={0}>
															{intl.formatMessage({
																id: 'search.recurrence.doNotRepeat',
															})}
														</MenuItem>
														{/* map on [{id: "work_days", display_name:"Work days"}]}
												 	OR territory.recurringOffers. */}
														{recurringOffers.map((offer, index) =>
															(<MenuItem key={index} value={offer.id}>
																{offer.name}
															</MenuItem>)
														)}
													</TextField>
												</div>
										}
									</Collapse>
								</div>
							</Card>

							<Card elevation={4} style={{width:'100%', padding:'1rem', margin:'1rem'}}>
								<div className="column aligned fullWidth" /* OPTIONS : PASSENGERS + CUSTOM FIELDS */>
									<FormSectionHeader title={intl.formatMessage({ id:'section.options'})}/>
									<div className='fullWidth'>
										<PassengersCount
											type="standard"
											decrease={() => decreasePassengers('standard')}
											increase={() => increasePassengers('standard')}
											value={passengers.standard}
										/>
										{ extrasTypes.map( type =>{
											return(
												<PassengersCount
													extras={extras}
													key={type + '_counter'}
													type={type}
													decrease={() => decreasePassengers(type)}
													increase={() => increasePassengers(type)}
													value={passengers[type]}
												/>
											)}
										)}
									</div>
								</div>
								{ nbPassengers == 0 ?
									<Typography 
										color="error"
										variant="caption"
									>
										{intl.formatMessage({ id: 'search.error.nbPassengers'})}
									</Typography>
									: null 
                    		}
								{ /* customFields is a dict. This works similarly to "recurrence" */
									customFields &&
								<div className="column spaced" style={{flexWrap:'wrap'}}>
									{_.map(_.keys(customFieldInfos).sort(), (cf_key, name)=>{
										const cf = customFieldInfos[cf_key]
										return(
											<div
												className="ron-only column"
												style={{padding:'1rem 0 0 0'}}
												key={'cf-'+name}
											>
												<TextField
													id={cf.display_name}
													required={Boolean(cf.is_required)}
													label={cf.display_name}
													style={{width: '90%'}}
													select={cf.type === 'select'}
													value={_.get(formData, 'customFields.'+cf_key) || ''}
													onChange={e => onFieldChange(
														'customFields',{
															...customFields,
															[cf_key]:e.target.value
														}
													)}
													error={Boolean(get(errors,'customFields.'+cf_key))}
													helperText={get(errors,'customFields.'+cf_key)}
													variant="outlined"
													SelectProps={{ 
														IconComponent: () => <ExpandMore style={{position:'absolute', right: 10}}/>
													}}
												>
													{_.map(_.get(cf, 'options', []), (m, index) =>
														(<MenuItem key={index} value={m.key}>
															{m.display}
														</MenuItem>)
													)}
												</TextField>
											</div>
										)})
									}
								</div>
								}
							</Card>
						</div>
					</div>

				</form>
			</Paper>
			<div className="row"
				style={{ paddingTop:'1rem', flexDirection: 'row-reverse' }}>
				<MuiButton
					variant="contained"
					color="primary"
					disabled={requesting}
					onClick={()=>onSubmit()}
				>
					<Typography variant="body1">
						{intl.formatMessage({ id: 'search.submit' })}
					</Typography>
				</MuiButton>
			</div>
		</div>
	)
}

.form {
  box-sizing: border-box;
  margin-top: 80px;
  margin-bottom: auto;
  width: 100%;
  @media (min-width: 800px) {
      width: 100%;
  }
  @media (min-width: 1200px) {
      width: 90%;
  }
}

.autoCompletes {
    width: 100%;
    justify-content: center;
    align-items: center;
}

.asap {
  flex: 0 0 5em;
  width: 80%;
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  align-items: center;
}

.searchNode {
    width: 70%;
}

.listContainer {
  text-align:center;
}

.listItem {
  text-align:center;
}

.favoriteLoadersWrapper {
    width: 100%;
    display: flex;
    // justify-content: flex-start;
    margin: 1.5rem 0 3rem 0;
    text-align: center;
    @media (max-width: 614px) {
        width: 100%;
    }
}

.selectTargetMode {
  flex: 0 1 10rem;
  max-width: 70%;
  @media (max-width: 800px) {
    //see below, flex becomes vertical
      flex: 0 1 auto;
  }
}

.selectTime {
  width: 100%;
  // justify-content: space-between;
  align-items: center;
  display: flex;
  flex-direction: row;
  padding: 1rem 0 0 0;
  //flex: 1 1 3rem;
  @media (max-width: 800px) {
      flex-direction: column;
      flex: 0 0 8rem;
      align-items: flex-start;
  }
}

.timePicker {
  width:'9rem'
}

.swapIcon {
  margin-left: 1rem;
  margin-top: 2rem;
}

.passengersCounterWrapper {
    flex: 1 0 auto;
    display: flex;
    flex-direction: row;
    justify-content: flex-end;
    padding:0.5rem;
}

.passengersCounterLabel {
    display: flex;
    flex-direction: column;
    justify-content: center;
    margin-right: 10px;
    font-weight: 600;
}

.counter {
    display: -webkit-flex;
    display: flex;
    -webkit-flex-direction: row;
    flex-direction: row;

    background: #f2f2f2;
    max-width: 110px;
}

.counterDecrement,
.counterIncrement,
.counterValue {
    padding: 10px 15px;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

.counterIncrement {
    &:hover { cursor: pointer; }
}

.counterDecrement {
    &:hover { cursor: pointer; }
}

.submitForm {
  padding: 0.5rem;
}

div[class^="input-cssmodule-day"]:focus {

  box-shadow: inset 0px 0px 0px 1px rgba(0,0,0,1);

}

div[class^="input-cssmodule-wrapper"]:hover, div[class^="input-cssmodule-wrapper"]:focus {
  box-shadow: inset 0px 0px 0px 1px rgba(0,0,0,1);
}

.passengersLabel {
  color: black !important;
}


function App() {
const { register, handleSubmit } = useForm();
const onSubmit = data => console.log(data);

  
return (
<>
<form onSubmit={handleSubmit(onSubmit)}>
                <label htmlFor="name">Naam</label>
                <input {...register("firstName")} />
                <select {...register("gender")}>
                    <option value="female">female</option>
                    <option value="male">male</option>
                    <option value="other">other</option>
                </select>
</form
</>
);
}

export default App;
	// const menuOptions = [
	// 	{
	// 		labelId: 'menu.account',
	// 		icon: (<Icon>account_circle</Icon>),
	// 		component: (<AccountInfo info={props} />)
	// 	},
	// 	{
	// 		labelId: 'menu.favorite',
	// 		icon: (<Icon>favorite</Icon>),
	// 		component: (<Favourites info={props} />)
	// 	},
	// 	{
	// 		labelId: 'password',
	// 		icon: (<Icon>enhanced_encryption</Icon>),
	// 		component: (<Password info={props} />)
	// 	}
	// ]

	// // when credit enabled
	// if (isCreditEnabled){
	// 	menuOptions.push({
	// 		name: 'credit wallet',
	// 		labelId: 'credit.wallet',
	// 		icon: (<Purse/>),
	// 		component: (<CreditManager />)
	// 	})
	// }

	// const [index, setIndex] = useState(showFavorites ? 1 : showWallet ? 3 : 0)
	// const [open, setOpen] = useState('')

			{/* <div className="row">
				<Paper className="paperContainer" style={{paddingRight:'1rem', height:'fit-content', width:'fit-content'}}>
					<Tabs
						orientation="vertical"
						value={index}
						onChange={(e, i) => setIndex(i)}
						indicatorColor="primary"
						textColor="primary"
						style={{width:'20rem'}}
					>
						{menuOptions.map((option, i)=>
							<Tab
								key={i}
								index={i}
								label={<FormattedMessage id={option.labelId} />}
								icon={option.icon}
								name={option.name}
							/>CreditManager
						)}
					</Tabs>
				</Paper>

				{menuOptions[index].component}
			</div> */}
react-routerの使いかたを学ぶ。
参考にしたサイトはhttps://dezanari.com/react-react-router/

1. まず、react-create-appで土台を作成。

2. react-router-domをインストール(react-create-appだといらない?!)
```
yarn add react-router-dom
```
3. 
(例えば)App.jsで、
import { BrowserRouter, Route, Link, Switch } from 'react-router-dom'; 
と、インポートしておいて、

Linkで飛ぶ先はコンポーネントとして作成し、このファイルにインポートする。
import PageA from '../PageA/PageA';
import PageB from '../PageB/PageB';

そして、切り替えを以下のように設定。

```
<BrowserRouter>         /* 全体をBrowserRouterで囲む。*/

    <div className="wrapper"> 

      <div className="nav">             
        <h1>Do you like A or B???</h1>
        <Link to="/pageA">PageA</Link><br/>  /*Linkでアンカーと同じものを作れる。*/
        <Link to="/pageB">PageB</Link>
      </div>
    
      <div className="main">
        <Switch>                    /* Switchで囲んだ中には、、、*/
          <Route path="/pageA" component={PageA}/>  /* RouteでLinkで飛ぶ先を設定。*/
          <Route path="/pageB" component={PageB}/>  
        </Switch>    
      </div>
    
    </div>

    </BrowserRouter>
```
function Slider ({ callback, disabled = false, readOnly = false }) {
return (
<input
  type="range"
  disabled={disabled}
  readOnly={readOnly}
  onChange={({ target: { value } }) => callback(value)}
/>
);
}
export default class Controller {
    static instance = Controller.instance || new Controller()

    helloWorld() {
        console.log("Hello World... \(^_^)/ !!")
    }
}
{
  "emmet.includeLanguages": {
    "javascript": "javascriptreact"
 }
}
  bug/ch27169/booking-site-forbid-searchs-with-0-passengers
  bug/ch27169/booking-site-forbid-searchs-with-0-passengers-2
  bug/ch27458/cs-bug-show-displayed-name-for-equipments
  chore/ch30121/booking-site-api-management
  dev
  feature/ch28070/booking-site-allow-user-to-change-his-phone
  feature/ch29858/booking-site-creation-of-footer
* feature/ch30356/booking-site-account-page-new-design
  feature/ch30703/booking-site-new-menu-design
import React, {useState, useEffect} from 'react'
import {connect} from 'react-redux'
import { FormattedMessage } from 'react-intl'
import {getCreditMatrix, getCreditBalance, purchaseCredit} from './actions'
import StripeContainer from 'containers/Stripe/StripeContainer'
import {Paper, Slider, CircularProgress, Typography, Divider, Button} from '@material-ui/core'
import Credit from '../../components/Icons/Credit'

function CreditManager(props) {
	const { matrix, balance, isRequesting, isRequestingPurchase, paymentOptions, showSuccess } = props
	const { getCreditMatrix, getCreditBalance, purchaseCredit} = props

	const [creditAmount, setCreditAmount] = useState(null)

	useEffect(() => {
		getCreditMatrix()
		getCreditBalance()
	}, [])

	useEffect(() => {
		if (matrix.length > 0)
			setCreditAmount(matrix[0][0])
	}, [matrix])

	if (matrix.length === 0 || balance === null)
		return null

	const min = matrix[0][0]
	const max = matrix[matrix.length - 1][0]


	const sliderMarks = matrix.map(pair => ({
		value: pair[0]
	}))

	const realAmount = _.get(_.find(matrix, pair => pair[0] === creditAmount), 1)
	return (
		<div style={{width:'100%'}}>
			<Paper className="row" classes={{root: 'paperContainer'}}>
				<Credit style={{fontSize:'36', padding: '1rem'}}/>

				<div className="row" style={{justifyContent:'space-between'}}>
					<Typography aria-label="credit balance" style={{padding: '1rem'}}>
						<FormattedMessage id="credit.balance" values={{balance}} />
					</Typography>
					<Button
						variant="outlined"
						color="primary"
						style={{margin: '1rem'}}
					>
						Acheter des crédits
					</Button>
				</div>
			</Paper>

			<Paper classes={{root: 'paperContainer'}}>
				<div className="column" style={{alignItems: 'center'}}>
					<Typography style={{padding: '1rem'}}>
						<FormattedMessage
							id="credit.buyWithDiscount"
							values={{
								creditAmount,
								price: realAmount,
								currency: _.get(paymentOptions, 'currency')
							}} />
					</Typography>
					<div className="row" style={{width: '100%', alignItems: 'center', justifyContent: 'space-between', padding: '1rem'}}>
						<Typography style={{padding: '1rem'}}>{min}</Typography>
						<Slider
							defaultValue={min}
							step={null}
							marks={sliderMarks}
							onChange={(e, v) => setCreditAmount(v)}
							min={min}
							max={max}
							valueLabelDisplay="auto"
						/>
						<Typography style={{padding: '1rem'}}>{max}</Typography>
					</div>
				</div>
			</Paper>

			{ /* this condition is a little hack for refreshing the form after success (more UX friendly) */
				!showSuccess &&
				<div className="paperContainer">
					<StripeContainer
						validate={data => purchaseCredit(creditAmount, realAmount, {
							method: 'STRIPE',
							data
						})}
						totalPrice={realAmount}
						isRequesting={isRequesting}
						buttonLabel="purchase credit with creditcard"
					/>
				</div>
			}

		</div>
	)
}
const mapStateToProps = (state) => {
	const credit = state.credit
	const territory = _.get(state, 'territory.locals', []).find(t => t.territory_key === state.territory.current)
	return {
		matrix: credit.matrix,
		balance: credit.balance,
		isRequesting: credit.isRequestingMatrix || credit.isRequestingBalance || credit.isRequestingPurchase,
		isRequestingPurchase: credit.isRequestingPurchase,
		paymentOptions: _.get(territory, 'payment', {})
	}
}

const mapDispatchToProps = dispatch => ({
	getCreditMatrix: () => dispatch(getCreditMatrix()),
	getCreditBalance: () => dispatch(getCreditBalance()),
	purchaseCredit: (creditAmount, realAmount, payment) => dispatch(purchaseCredit(creditAmount, realAmount, payment)),
})
export default connect(mapStateToProps, mapDispatchToProps)(CreditManager)
import React, {useState, useEffect} from 'react'
import {connect} from 'react-redux'
import { FormattedMessage } from 'react-intl'
import {getCreditMatrix, getCreditBalance, purchaseCredit} from './actions'
import StripeContainer from 'containers/Stripe/StripeContainer'
import {Paper, Slider, CircularProgress, Typography, Divider, Button} from '@material-ui/core'
import Credit from '../../components/Icons/Credit'

function CreditManager(props) {
	const { matrix, balance, isRequesting, isRequestingPurchase, paymentOptions, showSuccess } = props
	const { getCreditMatrix, getCreditBalance, purchaseCredit} = props

	const [creditAmount, setCreditAmount] = useState(null)

	useEffect(() => {
		getCreditMatrix()
		getCreditBalance()
	}, [])

	useEffect(() => {
		if (matrix.length > 0)
			setCreditAmount(matrix[0][0])
	}, [matrix])

	if (matrix.length === 0 || balance === null)
		return null

	const min = matrix[0][0]
	const max = matrix[matrix.length - 1][0]


	const sliderMarks = matrix.map(pair => ({
		value: pair[0]
	}))

	const realAmount = _.get(_.find(matrix, pair => pair[0] === creditAmount), 1)
	return (
		<div style={{width:'100%'}}>
			<Paper className="row" classes={{root: 'paperContainer'}}>
				<Credit style={{fontSize:'36', padding: '1rem'}}/>

				<div className="row" style={{justifyContent:'space-between'}}>
					<Typography aria-label="credit balance" style={{padding: '1rem'}}>
						<FormattedMessage id="credit.balance" values={{balance}} />
					</Typography>
					<Button
						variant="outlined"
						color="primary"
						style={{margin: '1rem'}}
					>
						Acheter des crédits
					</Button>
				</div>
			</Paper>

			<Paper classes={{root: 'paperContainer'}}>
				<div className="column" style={{alignItems: 'center'}}>
					<Typography style={{padding: '1rem'}}>
						<FormattedMessage
							id="credit.buyWithDiscount"
							values={{
								creditAmount,
								price: realAmount,
								currency: _.get(paymentOptions, 'currency')
							}} />
					</Typography>
					<div className="row" style={{width: '100%', alignItems: 'center', justifyContent: 'space-between', padding: '1rem'}}>
						<Typography style={{padding: '1rem'}}>{min}</Typography>
						<Slider
							defaultValue={min}
							step={null}
							marks={sliderMarks}
							onChange={(e, v) => setCreditAmount(v)}
							min={min}
							max={max}
							valueLabelDisplay="auto"
						/>
						<Typography style={{padding: '1rem'}}>{max}</Typography>
					</div>
				</div>
			</Paper>

			{ /* this condition is a little hack for refreshing the form after success (more UX friendly) */
				!showSuccess &&
				<div className="paperContainer">
					<StripeContainer
						validate={data => purchaseCredit(creditAmount, realAmount, {
							method: 'STRIPE',
							data
						})}
						totalPrice={realAmount}
						isRequesting={isRequesting}
						buttonLabel="purchase credit with creditcard"
					/>
				</div>
			}

		</div>
	)
}
const mapStateToProps = (state) => {
	const credit = state.credit
	const territory = _.get(state, 'territory.locals', []).find(t => t.territory_key === state.territory.current)
	return {
		matrix: credit.matrix,
		balance: credit.balance,
		isRequesting: credit.isRequestingMatrix || credit.isRequestingBalance || credit.isRequestingPurchase,
		isRequestingPurchase: credit.isRequestingPurchase,
		paymentOptions: _.get(territory, 'payment', {})
	}
}

const mapDispatchToProps = dispatch => ({
	getCreditMatrix: () => dispatch(getCreditMatrix()),
	getCreditBalance: () => dispatch(getCreditBalance()),
	purchaseCredit: (creditAmount, realAmount, payment) => dispatch(purchaseCredit(creditAmount, realAmount, payment)),
})
export default connect(mapStateToProps, mapDispatchToProps)(CreditManager)
import React from 'react';
import {
  Button,
  DrawerLayoutAndroid,
  Text,
  TextInput,
  TouchableOpacity,
  View,
  StyleSheet
} from 'react-native';

import {NavigationContainer} from '@react-navigation/native'
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import {createStackNavigator} from '@react-navigation/stack'
import axios from 'axios'
import {createDrawerNavigator} from '@react-navigation/drawer'
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'
import LoginTextbox from './components/Textbox'
import Signup from './components/Signup'
import FlatList3 from './components/FlatList'
import FlatList_Api from './components/FlatList_Api'
import Class_comp from './components/Class_comp';
import Func_comp from './components/Func_comp'
import { useState } from 'react';
import { color } from 'react-native-reanimated';
import FormValidation from './components/FormValidation';

// const drawer = createDrawerNavigator()
const stack = createStackNavigator()
// const tab = createBottomTabNavigator()

 
function App(){  
    return(
       <NavigationContainer>
         <stack.Navigator>
           <stack.Screen name="Login" component={Appdata}/>
           <stack.Screen name="Home" component={home}/>
           <stack.Screen name="Signup" component={Signup}/>
           <stack.Screen name="FlatList3" component={FlatList3}/>
           <stack.Screen name="FlatList_Api" component={FlatList_Api}/>
           <stack.Screen name="FormValidate" component={FormValidation}/>
         </stack.Navigator>
       </NavigationContainer>
    )
}

const Appdata = (props, route) =>
{
 const [state, stateupt] = useState({cardnum:'', pass:''})
 const LoginPress2 = () => {

    var cardno = state.cardnum
    var password = state.pass
    if(cardno.length == 0 || password.length == 0)
    {
      alert("Required Fields Missing!")
    }else 
    {

    //   Login with axios

    //   var Data =
    //   {
    //     'cardno': cardno,
    //     'password': password
    //   }
    //   console.warn(JSON.stringify(Data))
    //  let URL1 = 'https://scrapcollector12.000webhostapp.com/cardLogin.php'
    //  axios.post(URL1, JSON.stringify(Data))
    // .then(function (response) {
    //  alert(response)
    // })
    // .catch(function (error) {
    //   console.warn(error);
    // });

    //   Login With PHP API

    //   let URL = 'https://scrapcollector12.000webhostapp.com/cardLogin.php'
    //   var headers = {
    //       'Accept' : 'application/json',
    //       'Content-Type': 'application.json' 
    //   }
    //   var Data =
    //   {
    //     cardno: cardno,
    //     password: password
    //   }
    //   fetch(URL, {
    //     method: 'POST',
    //     headers: headers,
    //     body: JSON.stringify(Data)
    //   })
    //   .then((response)=> response.json())
    //   .then((response) => 
    //   {
    //     alert(response[0].Message)
    //     if (response[0].Message =='success') {
          
    //        props.navigation.navigate('Home')
    //     }else{
             
    //     }
    // })
    //   .catch(error =>
    //     {
    //       alert("Error" + error)
    //     }
    //   )

    //   REST API

      let URL = 'http://www.smartpaygs.com:87/Api/Users/Authentication'
      var headers = {
          'Accept': 'application/json',
          'Content-Type': 'application.json' 
      }
      let Data =
      {
        'Username': cardno,
        'Password': password
      }
      fetch(URL, {
        method: 'POST',
        headers: headers,
        body: JSON.stringify(Data)
      })
      .then((response)=> response.json())
      .then((response) => 
      {
        alert(response.EmbossLine)
        // if (response[0].Message =='success') {
          
        //    props.navigation.navigate('Home')
        // }else{
             
        // }
    })
      .catch(error =>
        {
          alert("Error" + error)
        }
      )


    // var Data =
    //   {
    //     cardno: cardno,
    //     password: password
    //   }
    //   // let data = { Users: { cardno: cardno, Password: password } }
    //   //   console.log(JSON.stringify(data))
    //   axios.post('http://www.smartpaygs.com:87/Api/Users/Authentication',Data)
    //   .then(function (response) {
    //     console.warn(response);
    //   })
    //   .catch(function (error) {
    //     console.warn(error);
    //   });
    }
  }

  return(
      <View>
        <LoginTextbox 
          placeholder='Enter card Number'
          keyboardType='numeric'
          placeholderTextColor='darkgrey'
          width='60%'
          value={state.cardnum}
          onChangeText={(e) => stateupt({...state, cardnum:e})}
        />
         <LoginTextbox 
          placeholder='Enter Your Password'
          secureTextEntry={true}
          placeholderTextColor='darkgrey'
          width='60%'
          value={state.pass}
          onChangeText={(e) => stateupt({...state,pass:e})}
        />
        <Text>{state.cardnum}</Text>
        <Text>{state.pass}</Text>
       {/* <Button title="Login" onPress={()=> {LoginPress2()} /*(props.navigation.navigate('Home')}/> */}
       <TouchableOpacity style={styles.btn} activeOpacity={0.8} onPress={()=>{LoginPress2()}}>
           <Text style={styles.btnText}>Login</Text>
       </TouchableOpacity> 
       <Text onPress={() => {props.navigation.push('Signup',state.cardnum)}} style={{marginTop:30, marginLeft: 30}}>Sign Up</Text>
       {/* const regular_icon_btn = <FontAwesome5.Button name={'comments'} />; */}
      </View>
  )
}
const home = (props) => {
  const data = "some data!!!"

  return (
    <View>
       <Text style={{fontSize:30}}>Functional Component!!!</Text>
       <TextInput placeholder={"Enter Your Name"} onChangeText={(e)=>{console.warn(e)} }/>
       <Button title="Logout" onPress={() => props.navigation.navigate('Login')}/>
       <Func_comp Data={data} />

       <TouchableOpacity style={styles.btn} activeOpacity={0.8} onPress={()=>{props.navigation.navigate('FlatList3')}}>
           <Text style={styles.btnText}>Flat List</Text>
       </TouchableOpacity> 
      
       <TouchableOpacity style={styles.btnAPi} activeOpacity={0.8} onPress={()=>{
         props.navigation.navigate('FlatList_Api')}}>
           <Text style={styles.btnText}>Flat List with Api</Text>
       </TouchableOpacity>

       <TouchableOpacity 
       style={styles.btnFormValid} activeOpacity={0.8}
        onPress={()=>{
         props.navigation.navigate('FormValidate')}}
         >
           <Text style={styles.btnText}>Form Validation</Text>
       </TouchableOpacity>
    </View>
  )
}

function Detailscr()
{
    return(
      <View>
        <Text style={{fontSize:50}}>Details screen</Text>
      </View>
    )
}
class Class_comp1 extends React.Component
{
    render()
    {
        return(
            <View>
                <Text style={{fontSize:60,}}>From Class_comp</Text>
                <Button width='40' title="Btn from class" onPress={()=> alert("from class comp")}/>
            </View>
        )
    }
}

const styles = StyleSheet.create
({
  btnFormValid:
  {
    marginTop: 10,
    backgroundColor: "purple",
    height: 50,
    width: 130,
    justifyContent:'center',
    alignItems:'center',
    alignSelf:'center'
  },
    btnAPi:
    {
      marginTop: 10,
      backgroundColor: "red",
      height: 50,
      width: 70,
      justifyContent:'center',
      alignItems:'center',
      alignSelf:'center'
    },
    btn:{
        marginTop: 10,
        backgroundColor: "maroon",
        height: 50,
        width: 70,
        justifyContent:'center',
        alignItems:'center',
        alignSelf:'center'
    },
    btnText:{
        color: 'white',
        fontSize: 15
    }
})
export default App;
//componentDidMount
useEffect(() => {
    console.log("Behavior before the component is added to the DOM");
  }, []);

//componentDidUpdate
useEffect(() => {
    console.log("Behavior when the component receives new state or props.");
  });

//Or

useEffect(() => {
    console.log("Behavior when the value of 'stateName' changes.");
  }, [stateName]);

//Or
import React, { useEffect, useRef } from "react"
const mounted = useRef()
useEffect(() => {
  if (!mounted.current) {
    // do componentDidMount logic
    mounted.current = true
  } else {
    // do componentDidUpdate logic
  }
})

//componentWillUnmount
useEffect(() => {
    return () => {
            console.log("Behavior right before the component is removed from the DOM.");
        }
  }, []);

//Putting it all together
  useEffect(() => {
    const intervalId = setInterval(() => {
      document.title = `Time is: ${new Date()}`;
    }, 1000);
 
    return () => {
      document.title = "Time stopped.";
      clearInterval(intervalId);
    }
  }, []);
.then((response) => 
      {
        alert(response[0].Message)
        if (response[0].Message =='success') {
          
           props.navigation.navigate('Home')
        }else{
             
        }
      })
function ContactManager(props) {
  const [contacts, setContacts] = useState(props.data);

  return (
    <div>
      <AddPersonForm />
      <PeopleList data={contacts} />
    </div>
  );
} 
function PeopleList(props) {
  const arr = props.data;
  const listItems = arr.map((val, index) =>
    <li key={index}>{val}</li>
  );
  return <ul>{listItems}</ul>;
}
function AddPersonForm() {
  const [ person, setPerson ] = useState("");

  function handleChange(e) {
    setPerson(e.target.value);
  }

  function handleSubmit(e) {
    e.preventDefault();
  }
  return (
    <form onSubmit={handleSubmit}>
    <input type="text" 
    placeholder="Add new contact" 
    onChange={handleChange} 
    value={person} />
    <button type="submit">Add</button>
    </form>
    );
}
function AddForm() {
  const [sum, setSum] = useState(0);
  const [num, setNum] = useState(0);

  function handleChange(e) {
    setNum(e.target.value);
  }

  function handleSubmit(e) {
    setSum(sum + Number(num));
    e.preventDefault();
  }

  return <form onSubmit={handleSubmit}>
  <input type="number" value={num} onChange={handleChange} />
  <input type="submit" value="Add" />
  <p> Sum is {sum} </p>
  </form>;
}
 function handleChange(e) {
    setState(e.target.value);
  }
function Converter() {
  const [km, setKm] = useState(0);

  function handleChange(e) {
    setKm(e.target.value);
  }
  function convert(km) {
    return (km/1.609).toFixed(2);
  }

  return <div>
  <input type="text" value={km}
     onChange={handleChange} />
  <p> {km} km is {convert(km)} miles </p>
  </div>;
}
function Counter() {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    alert("Number of clicks: " + counter);
  });

  function increment() {
    setCounter(counter+1);
  }
  return <div>
  <p>{counter}</p>
  <button onClick={increment}>Increment</button>
  </div>;
}
function Counter() {
  const [counter, setCounter] = useState(0);

  function increment() {
    setCounter(counter+1);
  }

  return <div>
  <p>{counter}</p>
  <button onClick={increment}>
    Increment
  </button>
  </div>;
}
import React from 'react';
import {
  Button,
  DrawerLayoutAndroid,
  Text,
  TextInput,
  View,
} from 'react-native';

import {NavigationContainer} from '@react-navigation/native'
import {createStackNavigator} from '@react-navigation/stack'
import axios from 'axios'
import {createDrawerNavigator} from '@react-navigation/drawer'
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'
import LoginTextbox from './components/Textbox'
import Class_comp from './components/Class_comp';
import Func_comp from './components/Func_comp'
import { useState } from 'react';
// import FlatList from './components/FlatList'

// const drawer = createDrawerNavigator()
const stack = createStackNavigator()
// const tab = createBottomTabNavigator()

 
function App(){  
    return(
       <NavigationContainer>
         <stack.Navigator>
           <stack.Screen name="Login" component={Appdata}/>
           <stack.Screen name="Home" component={home}/>
         </stack.Navigator>
       </NavigationContainer>
    )
}

const Appdata = (props) =>
{
 const [state, stateupt] = useState({cardnum:'', pass:''})
 const LoginPress2 = () => {
    // URL1 = 'https://scrapcollector12.000webhostapp.com/cardLogin.php'
    // Post = async (URL1, Data) => {
     
    //   return await axios.post(URL1, Data
    //     .then(function (response) {
    //       console.warn(response);
    //     }
    //     .catch(function (error) {
    //       console.warn(error);
    //     }))
    //     );       
    //   }
    var cardno = state.cardnum
    var password = state.pass
    if(cardno.length == 0 || password.length == 0)
    {
      alert("Required Fields Missing!")
    }else 
    {
      let URL = 'https://scrapcollector12.000webhostapp.com/cardLogin.php'
      var headers = {
          'Accept' : 'application/json',
          'Content-Type': 'application.json' 
      }
      var Data =
      {
        cardno: cardno,
        password: password
      }
      fetch(URL, {
        method: 'POST',
        headers: headers,
        body: JSON.stringify(Dat)
      })
      .then((response)=> response.json())
      .then((response) => 
      {
        alert(response[0].Message)
      })
      .catch(error =>
        {
          alert("Error" + error)
        }
      )
      // axios.post('https://scrapcollector12.000webhostapp.com/cardLogin.php', {
          
      // })
      // .then(function (response) {
      //   console.warn(response);
      // })
      // .catch(function (error) {
      //   console.warn(error);
      // });
    }
  }
  console.warn(state)
  return(
      <View >
        <LoginTextbox 
          placeholder='Enter card Number'
          keyboardType='numeric'
          placeholderTextColor='darkgrey'
          width='60%'
          value={state.cardnum}
          onChangeText={(e) => stateupt({...state, cardnum:e})}
        />
         <LoginTextbox 
          placeholder='Enter Your Password'
          secureTextEntry={true}
          placeholderTextColor='darkgrey'
          width='60%'
          value={state.pass}
          onChangeText={(e) => stateupt({...state,pass:e})}
        />
        <Text>{state.cardnum}</Text>
        <Text>{state.pass}</Text>
       <Button style={{}} title="Login" onPress={()=> {LoginPress2} /*(props.navigation.navigate('Home')*/}/> 
      </View>
  )
}
const home = (props) => {
  const data = "some data!!!"

  return (
    <View>
       <Text style={{fontSize:30}}>Functional Component!!!</Text>
       <TextInput placeholder={"Enter Your Name"} onChangeText={(e)=>{console.warn(e)} }/>
       <Button title="Go to next Screen" onPress={() => props.navigation.navigate('Detail')}/>
       <Func_comp Data={data} />
    </View>
  )
}

function Detailscr()
{
    return(
      <View>
        <Text style={{fontSize:50}}>Details screen</Text>
      </View>
    )
}
class Class_comp1 extends React.Component
{
    render()
    {
        return(
            <View>
                <Text style={{fontSize:60,}}>From Class_comp</Text>
                <Button title="Btn from class" onPress={()=> alert("from class comp")}/>
            </View>
        )
    }
}

export default App;
import React from 'react';
import {
  Button,
  DrawerLayoutAndroid,
  Text,
  placeholder,
  TextInput,
  View,
  StyleSheet
} from 'react-native';
import { NavigationContainer } from '@react-navigation/native'
import { createStackNavigator } from '@react-navigation/stack'
import { Value } from 'react-native-reanimated';
import { WHITE } from '../styles/colors/colors';

const LoginTextbox = (props) => {
  return (
    <View style={styles.flex}>
      <TextInput
        placeholder = {props.placeholder}
            keyboardType = {props.keyboardType}
            secureTextEntry = {props.secureTextEntry}
            placeholderTextColor={props.placeholderTextColor}
            width={props.width}
            value = {props.value}
            style={styles.container}
            onChangeText = {props.onChangeText}
      />
    </View>
  )
}

const styles = StyleSheet.create({
  flex:{flexDirection:'row', borderWidth:1, width: '100%'},
   container:{width: 200}
})

export default LoginTextbox;
import React from 'react';
import {
  Button,
  DrawerLayoutAndroid,
  Text,
  TextInput,
  View,
} from 'react-native';

import {NavigationContainer} from '@react-navigation/native'
import {createStackNavigator} from '@react-navigation/stack'
import axios from 'axios'
import {createDrawerNavigator} from '@react-navigation/drawer'
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'
import LoginTextbox from './components/Textbox'
import Class_comp from './components/Class_comp';
import Func_comp from './components/Func_comp'
import { useState } from 'react';
// import FlatList from './components/FlatList'

// const drawer = createDrawerNavigator()
const stack = createStackNavigator()
// const tab = createBottomTabNavigator()

 
function App(){  
    return(
       <NavigationContainer>
         <stack.Navigator>
           <stack.Screen name="Login" component={Appdata}/>
           <stack.Screen name="Home" component={home}/>
         </stack.Navigator>
       </NavigationContainer>
    )
}

const Appdata = (props) =>
{
  Data = [stateupt.cardnum, stateupt.pass]
  URL1 = 'https://scrapcollector12.000webhostapp.com/cardLogin.php'
  const LoginPress2 = () => {
    Post = async (URL1, Data) => {
      return await axios.post(URL1, Data
        .then(function (response) {
          console.warn(response);
        }
        .catch(function (error) {
          console.warn(error);
        }))
        );       
      }
  }
  const [state, stateupt] = useState({cardnum:'', pass:''})
  console.warn(state)
  return(
      <View >
        <LoginTextbox 
          placeholder='Enter card Number'
          keyboardType='numeric'
          placeholderTextColor='darkgrey'
          width='60%'
          value={state.cardnum}
          onChangeText={(e) => stateupt({cardnum:e})}
        />
         <LoginTextbox 
          placeholder='Enter Your Password'
          secureTextEntry={true}
          placeholderTextColor='darkgrey'
          width='60%'
          value={state.pass}
          onChangeText={(e) => stateupt({pass:e})}
        />
       <Button style={{}} title="Login" onPress={()=> props.navigation.navigate('Home')}/> 
      </View>
  )
}
const home = (props) => {
  const data = "some data!!!"

  return (
    <View>
       <Text style={{fontSize:30}}>Functional Component!!!</Text>
       <TextInput placeholder={"Enter Your Name"} onChangeText={(e)=>{console.warn(e)} }/>
       <Button title="Go to next Screen" onPress={() => props.navigation.navigate('Detail')}/>
       <Func_comp Data={data} />
    </View>
  )
}

function Detailscr()
{
    return(
      <View>
        <Text style={{fontSize:50}}>Details screen</Text>
      </View>
    )
}
class Class_comp1 extends React.Component
{
    render()
    {
        return(
            <View>
                <Text style={{fontSize:60,}}>From Class_comp</Text>
                <Button title="Btn from class" onPress={()=> alert("from class comp")}/>
            </View>
        )
    }
}

export default App;
useEffect(() => {
  requestPets();
}, []);

async function requestPets() {
  const res = await fetch(API_URL);
  const json = await res.json();
  setPets(json.pets)
}
    <Navbar bg="dark" variant="dark">
      <Navbar.Brand href="#home">Navbar</Navbar.Brand>
      <Nav className="mr-auto">
        <Nav.Link href="#home">Home</Nav.Link>
        <Nav.Link href="#features">Features</Nav.Link>
        <Nav.Link href="#pricing">Pricing</Nav.Link>
      </Nav>
      <Form inline>
        <FormControl type="text" placeholder="Search" className="mr-sm-2" />
        <Button variant="outline-info">Search</Button>
      </Form>
    </Navbar>
  const target = useRef<HTMLDivElement>(null);

  const listenScrollEvent = (event) => {
    const toLeft = event.deltaY < 0 && target.current.scrollLeft > 0;
    const toRight =
      event.deltaY > 0 &&
      target.current.scrollLeft <
        target.current.scrollWidth - target.current.clientWidth;

    if (toLeft || toRight) {
      event.preventDefault();
      event.stopPropagation();

      target.current.scrollLeft += event.deltaY;
    }
  };

  return (
    <div ref={target} onWheel={listenScrollEvent}>
/* eslint new-cap:0 */
export default function renderToJson(element) {
    let res = {};
    if (!element || !element.type) {
        return element;
    }
    const Component = element.type;
    res.name = element.type;
    res.attributes = { ...element.props };
    let children = element.props ? element.props.children : null;
    delete res.attributes.children;
    if (typeof Component !== "string") {
        res.name = Component.name;
        const context = element.context || {};
        if (Component.prototype && typeof Component.prototype.render === "function") { // ReactComponent
            children = new Component(element.props, context).render();
        } else { // function component
            children = Component(element.props, context);
        }
    }
    if (Array.isArray(children)) {
        res.children = children.map(child => renderToJson(child));
        return res;
    }
    res.children = children ? [renderToJson(children)] : [];
    return res;
}
// Данные документов
const documents = [
    { id: 'F0100111', name: 'ПОДАТКОВА ДЕКЛАРАЦІЯ ПРО МАЙНОВИЙ СТАН І ДОХОДИ' },
    { id: 'F0100703', name: 'ПОДАТКОВА ДЕКЛАРАЦІЯ з податку на прибуток підприємств' },
    { id: 'F0102003', name: 'ЗАЯВА про застосування спрощеної системи оподаткування' },
    { id: 'F0102103', name: 'РОЗРАХУНОК доходу за попередній календарний рік, що передує року переходу на спрощену систему оподаткування' },
    { id: 'F0103306', name: 'ПОДАТКОВА ДЕКЛАРАЦІЯ ПЛАТНИКА ЄДИНОГО ПОДАТКУ ФІЗИЧНОЇ ОСОБИ - ПІДПРИЄМЦЯ' },
    { id: 'F0111611', name: "РОЗРАХУНОК суми податку, на яку зменшуються податкові зобов'язання з податку на доходи фізичних осіб,у зв'язку з використанням права на податкову знижку" },
    { id: 'F0121211', name: "РОЗРАХУНОК податкових зобов'язань з податку на доходи фізичних осіб та військового збору" },
    { id: 'F0121411', name: "РОЗРАХУНОК податкових зобов'язань з податку на доходи фізичних осіб та військового збору з доходів отриманих самозайнятою особою" },
    { id: 'F0121611', name: "РОЗРАХУНОК суми податку, на яку зменшуються податкові зобов'язання з податку на доходи фізичних осіб, у зв'язку з використанням права на податкову знижку" },
];
 
// Создаёт выделение текста
const MarkUp = (props) => (<span dangerouslySetInnerHTML={{__html:props.HTML}}></span>)
 
// Рендерит список документов
const DocsList = () => {
    const [searchDocName, setSearchDocName] = React.useState('');
    
    // получает пользовательский ввод
    const handleChange = event => {
        setSearchDocName(event.target.value);
    };
 
    // отменяет перезагрузку страницы при подтверждении формы
    const handleSubmit = event => {
        event.preventDefault()
    };
 
    // выполняет поиск и подсвечивает совпадающие символы
    const searchResults = !searchDocName
        ? documents
        : documents.filter(doc =>
            doc.name.trim().toLowerCase().includes(searchDocName.trim().toLowerCase())
        )
        .map(doc => {
            // находит подстроку в поисковом запросе и выделяет её
            let markedDocName = doc.name.replace(
                new RegExp(searchDocName, 'gi'),
                match => `<mark style='background: #2769AA; color: white;'>${match}</mark>`
            );
                return {
                    ...doc,
                    id: doc.id,
                    name: markedDocName,
                }
            });
 
    return (
          <RadioGroup name='value' value={active ? active : ''} onChange={handleSelection}>
              {searchResults.map(doc => (
              <FormControlLabel className={classes.item}
                                  style={{margin: 0}}
                                  label={
                                      <Box className={classes.label}>
                                          <Box className={classes.documentId}>
                                              <span>{doc.id}</span>
                                          </Box>
                                          // подсветка результата поиска
                                          <span className={classes.documentName}>
                                              <MarkUp HTML={doc.name}/>
                                          </span>
                                      </Box>
                                  }
                                  key={doc.id}
                                  value={doc.id}
                                  control={<Radio style={{marginTop: -2}} color='primary'/>}/>
              ))}
          </RadioGroup>
        </Paper>
    );
};
 
 
export default DocsList;
// setter
localStorage.setItem('myData', data);
 
// getter
localStorage.getItem('myData');
 
// remove
localStorage.removeItem('myData');
 
// remove all
localStorage.clear();
import React, { Component, useRef } from "react";

import PropTypes from "prop-types";

export default class App extends Component {
  constructor(props) {
    super(props);

    this.myref = React.createRef();
    this.myrefSecondInstance = React.createRef();
    this.childref = React.createRef();

    this.state = {
      defaultOrNew: "default",
      firstNameDefault: "Arhan",
      lastNameDefault: "Kamra",
      firstName: this.myref.value,
    };
  }

  static propTypes = {
    prop: PropTypes,
  };

  componentDidMount() {
    this.myref.current.focus();
    this.childref.current.me();
  }

  handleClick = () => {
    this.myref.current.focus();
  };

  handleClickSecondInstance = () => {
    this.myrefSecondInstance.current.focus();
  };

  handleClickBlur = () => {
    this.myref.current.blur();
  };

  handleClickBlurSecondInstance = () => {
    this.myrefSecondInstance.current.blur();
  };

  changeName = () => {
    this.setState(() => {
      return {
        defaultOrNew: "new",
        firstNameDefault: this.myref.current.value,
        lastNameDefault: this.myrefSecondInstance.current.value,
        firstName: this.myref.current.value,
        lastName: this.myrefSecondInstance.current.value,
      };
    });
  };

  render() {
    return (
      <div className="app">
        <input
          type="text"
          onChange={this.changeName}
          defaultValue={this.state.firstNameDefault}
          ref={this.myref}
        />
        <input
          type="text"
          onChange={this.changeName}
          defaultValue={this.state.lastNameDefault}
          ref={this.myrefSecondInstance}
        />
        <button onClick={this.handleClick}>Focus input</button>
        <button onClick={this.handleClickBlur}>Remove focus</button>
        <button onClick={this.handleClickSecondInstance}>Focus inputSecondInstance</button>
        <button onClick={this.handleClickBlurSecondInstance}>RemoveSecondInstance focus</button>
        <p>
          Hi my <strong>{this.state.defaultOrNew}</strong> name is {this.state.firstNameDefault}{" "}
          {this.state.middleNameDefault} {this.state.lastNameDefault}
        </p>
        <Child ref={this.childref} />
      </div>
    );
  }
}

class Child extends Component {
  me = () => {
    console.log("sophisticated coder");
    window.alert("xyz abc");
  };

  render() {
    return <div>{4 + 4}</div>;
  }
}
key={`${button.text}-${button.bootstrapWidth}-${i}`}
npm i typescript @types/node @types/react --save-dev
// SHA

function sha256(plain: any) {
  // returns promise ArrayBuffer
  const encoder = new TextEncoder();
  const data = encoder.encode(plain);
  return window.crypto.subtle.digest('SHA-256', data);
}

function base64urlencode(a: any) {
  // Convert the ArrayBuffer to string using Uint8 array.
  // btoa takes chars from 0-255 and base64 encodes.
  // Then convert the base64 encoded to base64url encoded.
  // (replace + with -, replace / with _, trim trailing =)
  // @ts-ignore
  return btoa(String.fromCharCode.apply(null, new Uint8Array(a)))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
}

export async function pkceChallengeFromVerifier(v: any) {
  const hashed = await sha256(v);
  return base64urlencode(hashed);
}
import React,{ Component } from 'react'
  
class Form extends Component{ 
  constructor(props){ 
    super(props) 
    this.state = { email:'',name:'', age:null, address:'',phoneNo:''} 
    this.handleChange = this.handleChange.bind(this) 
    this.handleSubmit = this.handleSubmit.bind(this) 
  } 
  
  // Form submitting logic, prevent default page refresh  
  handleSubmit(event){ 
    const { email, name, age, address, phoneNo } = this.state 
    event.preventDefault() 
    alert(` 
      ____Your Details____\n 
      Email : ${email} 
      Name : ${name} 
      Age : ${age} 
      Address : ${address} 
      Phone No : ${phoneNo} 
    `) 
  } 
  
  // Method causes to store all the values of the  
  // input field in react state single method handle  
  // input changes of all the input field using ES6  
  // javascript feature computed property names 
  handleChange(event){ 
    this.setState({ 
      // Computed property names 
      // keys of the objects are computed dynamically 
      [event.target.name] : event.target.value 
    }) 
  } 
  
  // Return a controlled form i.e. values of the  
  // input field not stored in DOM values are exist  
  // in react component itself as state 
  render(){ 
    return( 
      <form onSubmit={this.handleSubmit}> 
        <div> 
          <label htmlFor='email'>Email</label> 
          <input  
            name='email'
            placeholder='Email' 
            value = {this.state.email} 
            onChange={this.handleChange} 
          /> 
        </div> 
        <div> 
          <label htmlFor='name'>Name</label> 
          <input 
            name='name' 
            placeholder='Name'
            value={this.state.name} 
            onChange={this.handleChange} 
          /> 
        </div> 
        <div> 
          <label htmlFor='age'>Age</label> 
          <input 
            name='age' 
            placeholder='Age'
            value={this.state.age} 
            onChange={this.handleChange} 
          /> 
        </div> 
        <div> 
          <label htmlFor='address'>Address</label> 
          <input 
            name='address' 
            placeholder='Address'
            value={this.state.address} 
            onChange={this.handleChange} 
          /> 
        </div> 
        <div> 
          <label htmlFor='phoneNo'>Phone Number</label> 
          <input 
            name='phoneNo' 
            placeholder='Phone No'
            value={this.state.phoneNo} 
            onChange={this.handleChange} 
          /> 
        </div> 
        <div> 
          <button>Create Account</button> 
        </div> 
      </form> 
    ) 
  } 
} 
  
export default Form
import React from 'react';
import ReactDOM from 'react-dom';

class MyForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = { username: '' };
  }
  myChangeHandler = (event) => {
    this.setState({username: event.target.value});
  }
  render() {
    return (
      <form>
      <h1>Hello {this.state.username}</h1>
      <p>Enter your name:</p>
      <input
        type='text'
        onChange={this.myChangeHandler}
      />
      </form>
    );
  }
}

ReactDOM.render(<MyForm />, document.getElementById('root'));
Just a general website reference
https://www.valentinog.com/blog/socket-react/
// sending to sender-client only
socket.emit('message', "this is a test");

// sending to all clients, include sender
io.emit('message', "this is a test");

// sending to all clients except sender
socket.broadcast.emit('message', "this is a test");

// sending to all clients in 'game' room(channel) except sender
socket.broadcast.to('game').emit('message', 'nice game');

// sending to all clients in 'game' room(channel), include sender
io.in('game').emit('message', 'cool game');

// sending to sender client, only if they are in 'game' room(channel)
socket.to('game').emit('message', 'enjoy the game');

// sending to all clients in namespace 'myNamespace', include sender
io.of('myNamespace').emit('message', 'gg');

// sending to individual socketid
socket.broadcast.to(socketid).emit('message', 'for your eyes only');

// list socketid
for (var socketid in io.sockets.sockets) {}
 OR
Object.keys(io.sockets.sockets).forEach((socketid) => {});
export const addParensToFormatAreaCode = (phone?: string) => {
  const phoneParts = phone?.split("-");
  if (phoneParts !== undefined && phoneParts[0] !== "") {
    const phoneJoin: string = `(${phoneParts[0]}) ${phoneParts[1]}-${phoneParts[2]}`;
    return phoneJoin;
  }
  return strings.DEFAULT;
};
const StyledMotionComponent = styled(motion.div)`

  /* ----- styles go here ----- */

`
`Pomoci zpětné uvozovky vytvoříte speciální řetězec, který lze psát na více 
 řádků a dají se do něj vkládat výrazy ${ 1+2 }, proměnné ${ x+y }, pole ${ seznam[0] },
 objekty ${ uzivatelske.jmeno } a dokonce ihned volané funkce ${ function() { return x+y; }() } 
 nebo metody ${ "sidon".toUpperCase() }.`
      {arr.map(({ what ever you want to get from map }) => (
        <div>
			code goes here to display through html elements
        </div>
      ))}
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider, connect } from 'react-redux'
import { createStore, combineReducers, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'

import rootReducer from './redux/reducers'
import App from './components/App'

const store = createStore(
  rootReducer,
  applyMiddleware(thunk)
);

ReactDOM.render(
  <Provider store={store}>
    <App/>
  </Provider>,
  document.getElementById('root')
);


// Only change code below this line
// Redux:
const ADD = 'ADD';

const addMessage = (message) => {
  return {
    type: ADD,
    message: message
  }
};

const messageReducer = (state = [], action) => {
  switch (action.type) {
    case ADD:
      return [
        ...state,
        action.message
      ];
    default:
      return state;
  }
};

const store = Redux.createStore(messageReducer);

// React:
const Provider = ReactRedux.Provider;
const connect = ReactRedux.connect;

// Change code below this line
class Presentational extends React.Component {
  constructor(props) {
    super(props);
    
    // Remove property 'messages' from Presentational's local state
    this.state = {
      input: ''
    }
    this.handleChange = this.handleChange.bind(this);
    this.submitMessage = this.submitMessage.bind(this);
  }
  handleChange(event) {
    this.setState({
      input: event.target.value
    });
  }
  submitMessage() {
  
    // Call 'submitNewMessage', which has been mapped to Presentational's props, with a new message;
    // meanwhile, remove the 'messages' property from the object returned by this.setState().
    this.props.submitNewMessage(this.state.input);
    this.setState({
      input: ''
    });
  }
  render() {
    return (
      <div>
        <h2>Type in a new Message:</h2>
        <input
          value={this.state.input}
          onChange={this.handleChange}/><br/>
        <button onClick={this.submitMessage}>Submit</button>
        <ul>
           {/* The messages state is mapped to Presentational's props; therefore, when rendering,
               you should access the messages state through props, instead of Presentational's
               local state. */}
          {this.props.messages.map( (message, idx) => {
              return (
                 <li key={idx}>{message}</li>
              )
            })
          }
        </ul>
      </div>
    );
  }
};
// Change code above this line

const mapStateToProps = (state) => {
  return {messages: state}
};

const mapDispatchToProps = (dispatch) => {
  return {
    submitNewMessage: (message) => {
      dispatch(addMessage(message))
    }
  }
};

const Container = connect(mapStateToProps, mapDispatchToProps)(Presentational);

class AppWrapper extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <Container/>
      </Provider>
    );
  }
};
// Redux:
const ADD = 'ADD';

const addMessage = (message) => {
  return {
    type: ADD,
    message: message
  }
};

const messageReducer = (state = [], action) => {
  switch (action.type) {
    case ADD:
      return [
        ...state,
        action.message
      ];
    default:
      return state;
  }
};

const store = Redux.createStore(messageReducer);

// React:
class Presentational extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: '',
      messages: []
    }
    this.handleChange = this.handleChange.bind(this);
    this.submitMessage = this.submitMessage.bind(this);
  }
  handleChange(event) {
    this.setState({
      input: event.target.value
    });
  }
  submitMessage() {
    const currentMessage = this.state.input;
    this.setState({
      input: '',
      messages: this.state.messages.concat(currentMessage)
    });
  }
  render() {
    return (
      <div>
        <h2>Type in a new Message:</h2>
        <input
          value={this.state.input}
          onChange={this.handleChange}/><br/>
        <button onClick={this.submitMessage}>Submit</button>
        <ul>
          {this.state.messages.map( (message, idx) => {
              return (
                 <li key={idx}>{message}</li>
              )
            })
          }
        </ul>
      </div>
    );
  }
};

// React-Redux:
const mapStateToProps = (state) => {
  return { messages: state }
};

const mapDispatchToProps = (dispatch) => {
  return {
    submitNewMessage: (newMessage) => {
       dispatch(addMessage(newMessage))
    }
  }
};

const Provider = ReactRedux.Provider;
const connect = ReactRedux.connect;

// define the Container component here:
const Container = connect(mapStateToProps,mapDispatchToProps)(Presentational)

class AppWrapper extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    // complete the return statement:
    return (
      <Provider store={store}>
        <Container />
      </Provider>
      );
  }
};
const addMessage = (message) => {
  return {
    type: 'ADD',
    message: message
  }
};

// change code below this line
const mapDispatchToProps = (dispatch) => {
    return {
        submitNewMessage: (message)=>{
            dispatch(addMessage(message))
        }
    }
}
const state = [];

// change code below this line
const mapStateToProps = (state)=>{
  return {
    messages: state
  }
}
// Redux Code:
  const ADD = 'ADD';

  const addMessage = (message) => {
    return {
      type: ADD,
      message
    }
  };

  const messageReducer = (state = [], action) => {
    switch (action.type) {
      case ADD:
        return [
          ...state,
          action.message
        ];
      default:
        return state;
    }
  };



  const store = Redux.createStore(messageReducer);
  
  
 /****REACT COMPONENTS*****/
  
 // React Code:

  class DisplayMessages extends React.Component {
  
 /*CONSTRUCTOR*/
  
    constructor(props) {
      super(props);
      this.state = {
        input: '',
        messages: []
      }
      this.handleChange = this.handleChange.bind(this);
      this.submitMessage = this.submitMessage.bind(this);
    }
    
 /*METHODES*/
  
    handleChange(event) {
      this.setState({
        input: event.target.value
      });
    }
    
    
    submitMessage() {
      const currentMessage = this.state.input;
      this.setState({
        input: '',
        messages: this.state.messages.concat(currentMessage)
      });
    }
    
    
    render() {
      return (
        <div>
          <h2>Type in a new Message:</h2>
          <input
            value={this.state.input}
            onChange={this.handleChange}/><br/>
          <button onClick={this.submitMessage}>Submit</button>
          <ul>
            {this.state.messages.map( (message, idx) => {
                return (
                   <li key={idx}>{message}</li>
                )
              })
            }
          </ul>
        </div>
      );
    }
  };
  
  
 /*PROVIDER*/
  
  const Provider = ReactRedux.Provider;

/*MAIN COMPONENTS*/
  class AppWrapper extends React.Component {
    // Below is the code required to pass the test
    render() {
      return (
        <Provider store={store}>
          <DisplayMessages />
        </Provider>
      );
    }
    // Above is the code required to pass the test
  };
// define ADD, addMessage(), messageReducer(), and store here:
const ADD = "ADD";
const addMessage = message => {
  return {
    type: ADD,
    message
  };
};

// Use ES6 default paramter to give the 'previousState' parameter an initial value.
const messageReducer = (previousState = [], action) => {
  // Use switch statement to lay out the reducer logic in response to different action type
  switch (action.type) {
    case ADD:
      // Use ES6 spread operator to return a new array where the new message is added to previousState
      return [...previousState, action.message];
      break;

    default:
      // A default case to fall back on in case if the update to Redux store is not for this specific state.
      return previousState;
  }
};

const store = Redux.createStore(messageReducer);
class DisplayMessages extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: '',
      messages: []
    }
  }
  // add handleChange() and submitMessage() methods here
  handleChange(event){
    this.setState({
      input: event.target.value,
      messages: this.state.messages
    })
  }

  submitMessage(){
    this.setState({
      input: '',
      messages: [...this.state.messages, this.state.input]
    })
  }

  render() {
    return (
      <div>
        <h2>Type in a new Message:</h2>
        { /* render an input, button, and ul here */ }
        <input onChange={this.handleChange.bind(this)} value={this.state.input}/>
        <button onClick={this.submitMessage.bind(this)}>Submit</button>
        <ul>
          {this.state.messages.map((x, i)=>{
            return <li key={i}>{x}</li>
          })}
        </ul>
        { /* change code above this line */ }
      </div>
    );
  }
};
import * as Yup from 'yup';

validationSchema: Yup.object({
  password: Yup.string().required('Password is required'),
  passwordConfirmation: Yup.string()
     .oneOf([Yup.ref('password'), null], 'Passwords must match')
});
// Make a request for a user with a given ID
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

// Optionally the request above could also be done as
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
// utils/useDeviceDetect.js
import React from "react";

export default function useDeviceDetect() {
  const [isMobile, setMobile] = React.useState(false);

  React.useEffect(() => {
    const userAgent =
      typeof window.navigator === "undefined" ? "" : navigator.userAgent;
    const mobile = Boolean(
      userAgent.match(
        /Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i
      )
    );
    setMobile(mobile);
  }, []);

  return { isMobile };
}
const useRemoteTable = ({ promiseFn, searchOption, defaultOrder, columnSchema = [] }) => {
  const [page, setPage] = useState(1);
  const [limit, setLimit] = useState(10);
  const [order, setOrder] = useState(defaultOrder);
  const [reloadTimeStamp, setTimeStamp] = useState(Date.now());

  const onChange = (onChangeNest) => (pagination, filter, sorter, ...args) => {
    if (pagination.current !== page) {
      setPage(pagination.current);
    }
    if (pagination.pageSize !== limit) {
      setPage(1);
      setLimit(pagination.pageSize);
    }
    if (!isEmpty(sorter) && sorter.column) {
      const newOrder = map(columnSchema, (item, index) =>
        index === sorter.column?.columnIndex ? sorter.order : false
      );
      setOrder(newOrder);
    } else {
      setOrder(undefined);
    }
    onChangeNest(pagination, filter, sorter, ...args);
  };

  const reload = useCallback(() => {
    setTimeStamp(Date.now());
  }, []);

  useEffect(() => {
    setPage(1);
  }, [searchOption]);

  const watchWalue = useMemo(
    () => ({
      limit,
      page,
      order,
      searchOption,
      reload: reloadTimeStamp
    }),
    [limit, order, page, reloadTimeStamp, searchOption]
  );

  const { data, error, isPending } = useAsync({
    promiseFn,
    searchOption,
    watch: watchWalue,
    pagination: {
      order: getOrderFromTableToAPI(order),
      orderField: columnSchema[findIndex(order, (i) => i)],
      skip: (page - 1) * limit,
      limit
    }
  });
  return {
    loading: isPending,
    reload,
    page,
    limit,
    error,
    data,
    order,
    onChange
  };
};
import React from "react";

export default class ClassDemo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: "Agata"
    };
    this.handleNameChange = this.handleNameChange.bind(this);
  }

  handleNameChange(e) {
    this.setState({
      name: e.target.value
    });
  }

  render() {
    return (
      <section>
        <form autoComplete="off">
          <section>
            <label htmlFor="name">Name</label>
            <input
              type="text"
              name="name"
              id="name"
              value={this.state.name}
              onChange={this.handleNameChange}
            />
          </section>
        </form>
        <p>Hello {this.state.name}</p>
      </section>
    );
  }
}
    db.collection('iot').doc('test')
      .get()
      .then(snapshot => {
         setData(snapshot.data())
      })
      .catch(error => {
        console.error(error)
      })
this.setState({ name: 'Matt' }, () => console.log(this.state.name))
import { createMuiTheme } from '@material-ui/core/styles';

// A custom theme for this app
const theme = createMuiTheme({});

export default theme;
<Grid container><Grid item></Grid></Grid>
const useStyles = makeStyles((theme) => ({}));
render() {
  const elements = ['one', 'two', 'three'];

  const items = []

  for (const [index, value] of elements.entries()) {
    items.push(<li key={index}>{value}</li>)
  }

  return (
    <div>
      {items}
    </div>
  )
}

////////// or:

render: function() {
  const elements = ['one', 'two', 'three'];
  return (
    <ul>
      {elements.map((value, index) => {
        return <li key={index}>{value}</li>
      })}
    </ul>
  )
}
import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);


  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
this.state = {
	zombies:[
    {
    	name: 'Zombie'
    },{
    	name: 'Zombie'
    } {
    	name: 'Zombie'
    } {
    	name: 'Zombie'
    } {
    	name: 'Zombie'
    }
    ]
}

render() {
	return (
    	<div>
        {
        	this.state.zombies.map(zombie => <h1>{zombie.name}</h1>)
        }
        
        </div>
    )
}
star

Sat Mar 16 2024 23:38:29 GMT+0000 (Coordinated Universal Time) https://github.com/shadcn-ui/taxonomy/blob/main/app/(auth)/login/page.tsx

#react #react.js #javascript #jsx #tailwind #css
star

Thu Mar 14 2024 04:19:15 GMT+0000 (Coordinated Universal Time) https://admin.nivobet724.com/users

#react.js
star

Thu Feb 15 2024 23:49:23 GMT+0000 (Coordinated Universal Time) https://vitejs.dev/guide/

#react.js
star

Wed Jan 24 2024 22:51:04 GMT+0000 (Coordinated Universal Time) https://react.dev/reference/react/useContext

#react.js #javascript
star

Sun Jan 21 2024 21:31:29 GMT+0000 (Coordinated Universal Time) https://chat.openai.com/?__cf_chl_tk

#react.js #javascript #nodejs
star

Wed Jan 03 2024 18:25:16 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Dec 28 2023 22:58:13 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Dec 28 2023 05:00:26 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Dec 20 2023 09:53:20 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Dec 19 2023 04:45:44 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sun Dec 17 2023 12:05:06 GMT+0000 (Coordinated Universal Time) https://chat.openai.com/c/9c689a90-e565-43b2-b16e-e4e64203e782

#react.js #javascript #css
star

Fri Dec 15 2023 09:02:33 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Dec 14 2023 15:40:43 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Dec 14 2023 12:37:58 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Dec 14 2023 07:34:11 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Dec 14 2023 07:33:05 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Dec 12 2023 08:37:55 GMT+0000 (Coordinated Universal Time)

#react.js
star

Fri Dec 08 2023 17:03:44 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Dec 05 2023 20:38:19 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Dec 05 2023 17:10:22 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Dec 05 2023 17:10:22 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Dec 04 2023 17:07:47 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Dec 04 2023 17:06:43 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Nov 30 2023 19:50:30 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Nov 29 2023 12:06:23 GMT+0000 (Coordinated Universal Time) https://www.dappfort.com/blog/create-an-order-book-exchange-using-binance-clone-script/

#objectivec #react.js #c# #c++
star

Thu Nov 23 2023 23:12:42 GMT+0000 (Coordinated Universal Time)

#typescript #react.js
star

Thu Nov 16 2023 07:15:10 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Nov 13 2023 12:45:27 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Nov 13 2023 11:51:13 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Nov 13 2023 09:36:14 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sun Nov 12 2023 14:31:01 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sun Nov 05 2023 07:36:07 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Oct 31 2023 09:27:32 GMT+0000 (Coordinated Universal Time) https://www.w3schools.com/react/react_usestate.asp

#react.js #usestate #object #update
star

Mon Oct 23 2023 19:43:02 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Oct 23 2023 19:41:54 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Oct 17 2023 19:10:39 GMT+0000 (Coordinated Universal Time)

#react.js #javascript
star

Tue Oct 17 2023 06:27:23 GMT+0000 (Coordinated Universal Time) https://www.chartjs.org/docs/latest/charts/line.html

#react.js #javascript
star

Tue Oct 17 2023 06:26:51 GMT+0000 (Coordinated Universal Time) https://www.chartjs.org/docs/latest/charts/line.html

#react.js #javascript
star

Mon Oct 16 2023 09:29:28 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Thu Oct 12 2023 15:29:47 GMT+0000 (Coordinated Universal Time) https://play.tailwindcss.com/cSpMlF5BQj

#css #react.js #frontend #styling #tailwindcss
star

Thu Oct 12 2023 15:29:39 GMT+0000 (Coordinated Universal Time) https://play.tailwindcss.com/cSpMlF5BQj

#css #react.js #frontend #styling #tailwindcss
star

Thu Oct 12 2023 15:19:31 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Oct 11 2023 06:40:11 GMT+0000 (Coordinated Universal Time) https://play.tailwindcss.com/x7vMjleR9z

#css #react.js #frontend #styling #tailwindcss
star

Mon Oct 09 2023 22:50:10 GMT+0000 (Coordinated Universal Time) https://bling2.com/

#json #mysql #react.js #nodejs
star

Sun Oct 08 2023 15:39:33 GMT+0000 (Coordinated Universal Time)

#css #react.js #frontend #styling
star

Thu Oct 05 2023 07:23:29 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Fri Sep 29 2023 07:19:58 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Sun Sep 17 2023 22:37:38 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sat Sep 09 2023 04:31:01 GMT+0000 (Coordinated Universal Time) gist: https://gist.github.com/Sadik-Hossain/154501199e62d8827dc9322adbbfd883

#tailwindcss #react.js #frontend #typescript #range-input #range-slider #dual-range-slider #radix-ui #price-range #price-range-slider
star

Fri Sep 08 2023 16:59:55 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/16037165/displaying-a-number-in-indian-format-using-javascript

#react.js #javascript #ubuntu #apache #linux #var/www/htm
star

Wed Sep 06 2023 16:03:38 GMT+0000 (Coordinated Universal Time) https://chat.openai.com/share/8f1f514b-9bc2-4019-ad1e-a6a5f203a87b

#css #tailwindcss #react.js #frontend #style
star

Wed Sep 06 2023 05:41:11 GMT+0000 (Coordinated Universal Time)

#css #tailwindcss #react.js #frontend #style
star

Tue Sep 05 2023 15:02:43 GMT+0000 (Coordinated Universal Time) https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/deploying_different_types_of_servers/setting-apache-http-server_deploying-different-types-of-servers

#react.js #javascript #ubuntu #apache #linux #var/www/htm
star

Fri Sep 01 2023 18:31:11 GMT+0000 (Coordinated Universal Time)

#react.js
star

Fri Sep 01 2023 18:30:00 GMT+0000 (Coordinated Universal Time)

#react.js
star

Fri Sep 01 2023 13:14:20 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Aug 30 2023 23:57:12 GMT+0000 (Coordinated Universal Time)

#react #usecontext #react.js
star

Thu Aug 24 2023 11:21:32 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Tue Aug 22 2023 15:30:51 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Aug 22 2023 14:39:19 GMT+0000 (Coordinated Universal Time) https://www.npmjs.com/package/jspdf

#react.js #javascript #ubuntu #apache #linux #var/www/htm
star

Tue Aug 22 2023 10:21:50 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Tue Aug 22 2023 04:55:11 GMT+0000 (Coordinated Universal Time)

#react.js #javascript #ubuntu #apache #linux #var/www/htm
star

Thu Aug 17 2023 22:20:37 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Aug 17 2023 22:20:25 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sat Aug 12 2023 08:41:19 GMT+0000 (Coordinated Universal Time) https://www.codingem.com/javascript-how-to-calculate-age-from-birthdate/

#react.js #javascript
star

Wed Aug 09 2023 21:49:01 GMT+0000 (Coordinated Universal Time) https://youtu.be/li7FzDHYZpc?t=84

#react.js
star

Wed Aug 09 2023 01:42:34 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Aug 08 2023 17:21:34 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Aug 08 2023 01:32:52 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Aug 03 2023 14:48:09 GMT+0000 (Coordinated Universal Time) https://chat.openai.com/share/b5a5f8e2-a1f2-465b-950e-1ffa302628f6

#react.js #css #javascript
star

Tue Aug 01 2023 08:44:00 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Mon Jul 31 2023 21:24:41 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Jul 27 2023 16:14:50 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Jul 27 2023 16:14:02 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Jul 27 2023 07:24:12 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Fri Jul 21 2023 13:45:05 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Fri Jul 21 2023 13:43:19 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Thu Jul 20 2023 10:44:40 GMT+0000 (Coordinated Universal Time) https://react.dev/learn/your-first-component

#react.js
star

Thu Jul 20 2023 10:05:14 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Jul 19 2023 13:23:38 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Jul 18 2023 13:14:58 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Tue Jul 18 2023 11:35:10 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Tue Jul 18 2023 11:05:08 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Jul 11 2023 12:58:59 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Mon Jul 10 2023 08:42:35 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Fri Jul 07 2023 17:22:15 GMT+0000 (Coordinated Universal Time)

#react.js
star

Fri Jun 30 2023 13:15:37 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Fri Jun 30 2023 06:55:47 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Thu Jun 29 2023 21:10:34 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Jun 29 2023 11:49:25 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Thu Jun 29 2023 09:01:29 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Thu Jun 29 2023 07:20:06 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Jun 28 2023 23:46:03 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Jun 28 2023 17:59:45 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Jun 28 2023 08:30:00 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Jun 28 2023 06:41:09 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Jun 28 2023 05:46:47 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Jun 28 2023 05:12:32 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Tue Jun 27 2023 23:11:09 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Jun 27 2023 22:39:14 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Jun 27 2023 22:26:18 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Jun 27 2023 22:11:54 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Jun 27 2023 21:29:27 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sun Jun 25 2023 10:56:49 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Jun 22 2023 18:33:24 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Thu Jun 22 2023 13:02:09 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Jun 22 2023 12:32:07 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Jun 21 2023 14:01:29 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Jun 21 2023 12:54:01 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Jun 21 2023 12:45:16 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Jun 21 2023 12:27:49 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Jun 21 2023 11:51:26 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Jun 21 2023 07:00:02 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Jun 21 2023 01:57:37 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Jun 21 2023 00:23:59 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Jun 20 2023 05:17:36 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Mon Jun 19 2023 17:40:20 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Jun 19 2023 15:36:04 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Jun 19 2023 15:25:47 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Jun 19 2023 15:22:42 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Jun 19 2023 13:48:40 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Jun 19 2023 13:23:18 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Jun 19 2023 11:43:32 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Jun 19 2023 10:22:13 GMT+0000 (Coordinated Universal Time) https://maticz.com/ai-crypto-trading-bot

#react.js
star

Sun Jun 18 2023 17:09:40 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sun Jun 18 2023 01:09:42 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sun Jun 18 2023 00:50:07 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sun Jun 18 2023 00:34:35 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sun Jun 18 2023 00:24:23 GMT+0000 (Coordinated Universal Time)

#react.js
star

Fri Jun 16 2023 07:10:41 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Fri Jun 16 2023 05:41:48 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Fri Jun 16 2023 05:18:20 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Jun 14 2023 06:41:44 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Jun 14 2023 01:46:31 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Sat Jun 10 2023 22:43:11 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sat Jun 10 2023 22:40:53 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sat Jun 10 2023 17:05:12 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Thu Jun 08 2023 13:37:38 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Thu Jun 08 2023 12:08:17 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Thu Jun 08 2023 11:40:20 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Thu Jun 08 2023 06:37:12 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Thu Jun 08 2023 06:35:37 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Jun 07 2023 07:02:49 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Jun 07 2023 06:45:38 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Jun 07 2023 05:46:37 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Jun 07 2023 05:35:16 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Jun 07 2023 05:26:12 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed Jun 07 2023 05:23:57 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Tue Jun 06 2023 13:24:12 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Mon Jun 05 2023 09:33:33 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Mon Jun 05 2023 09:19:17 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Mon Jun 05 2023 09:04:22 GMT+0000 (Coordinated Universal Time) https://maticz.com/p2p-cryptocurrency-exchange-development

#react.js
star

Mon Jun 05 2023 07:47:04 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Fri Jun 02 2023 05:21:25 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Fri Jun 02 2023 05:17:36 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Thu Jun 01 2023 08:49:27 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Thu Jun 01 2023 07:40:05 GMT+0000 (Coordinated Universal Time) https://maticz.com/metamask-wallet-clone

#react.js
star

Thu Jun 01 2023 05:18:53 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed May 31 2023 10:08:15 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Wed May 31 2023 05:18:33 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Sun May 28 2023 22:41:10 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed May 24 2023 12:14:27 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Tue May 23 2023 10:01:35 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Tue May 23 2023 09:50:48 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Tue May 23 2023 09:06:33 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Mon May 22 2023 13:01:18 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Mon May 22 2023 10:31:30 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Mon May 22 2023 09:33:42 GMT+0000 (Coordinated Universal Time)

#react.js #css #javascript
star

Thu May 18 2023 04:57:44 GMT+0000 (Coordinated Universal Time)

#react.js #css #prompts
star

Mon May 15 2023 09:19:53 GMT+0000 (Coordinated Universal Time)

#javascript #html #css #typescript #react.js
star

Tue May 02 2023 19:10:41 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Apr 26 2023 08:05:52 GMT+0000 (Coordinated Universal Time)

#css #sass #react.js
star

Sat Apr 01 2023 18:43:31 GMT+0000 (Coordinated Universal Time) https://codesandbox.io/s/wonderful-cookies-ykwkdp?file

#react.js
star

Wed Mar 22 2023 08:55:44 GMT+0000 (Coordinated Universal Time)

#react.js
star

Fri Mar 17 2023 16:14:11 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/72117276/how-to-properly-use-fontawesome-on-react-js

#react #react.js #fontawosome
star

Wed Mar 08 2023 11:10:51 GMT+0000 (Coordinated Universal Time)

#react.js #javascript
star

Wed Mar 01 2023 11:20:15 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Wed Feb 22 2023 18:17:51 GMT+0000 (Coordinated Universal Time) https://blog.logrocket.com/type-html-faster-react-emmet-vs-code/

#emmet #vscode #react #react.js
star

Sat Feb 11 2023 07:49:40 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/74179582/react-change-color-of-a-specific-div-inside-a-map-function

#react.js
star

Mon Jan 16 2023 18:34:33 GMT+0000 (Coordinated Universal Time)

#react.js #react-native #styled-components
star

Mon Jan 09 2023 12:30:39 GMT+0000 (Coordinated Universal Time) https://tamiadev.github.io/tamia/

#react.js
star

Sun Jan 08 2023 20:31:43 GMT+0000 (Coordinated Universal Time) https://codesandbox.io/s/textarea-resize-27kwsd?file=/src/App.js:84-94

#javascript #react.js #input #resized
star

Fri Dec 30 2022 15:41:30 GMT+0000 (Coordinated Universal Time) https://www.youtube.com/shorts/2lyDv0wOQuQ

#javascript #react.js
star

Fri Dec 30 2022 10:44:39 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/49496906/react-mapping-children-of-a-parent-component

#react.js
star

Fri Dec 30 2022 10:44:02 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/49496906/react-mapping-children-of-a-parent-component

#react.js
star

Wed Dec 28 2022 09:32:11 GMT+0000 (Coordinated Universal Time) https://www.coursera.org/learn/advanced-react/supplement/DcqzI/solution-create-your-own-custom-hook-useprevious

#react.js #useref #ref #hooks #customhook
star

Sat Dec 24 2022 11:43:43 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sat Dec 24 2022 11:11:21 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Dec 20 2022 18:09:01 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/72222728/why-is-localstorage-getting-cleared-whenever-i-refresh-the-page

#javascript #react.js
star

Sat Dec 17 2022 00:11:42 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Thu Dec 15 2022 13:13:22 GMT+0000 (Coordinated Universal Time) https://dev.to/timo_ernst/how-to-customize-prev-next-buttons-in-react-swiper-js-4lki

#javascript #react.js
star

Wed Dec 14 2022 08:17:14 GMT+0000 (Coordinated Universal Time) https://forum.freecodecamp.org/t/freecodecamp-challenge-guide-add-inline-styles-in-react/301378

#react.js
star

Tue Dec 13 2022 12:44:11 GMT+0000 (Coordinated Universal Time) https://forum.freecodecamp.org/t/freecodecamp-challenge-guide-use-state-to-toggle-an-element/301421

#react.js
star

Mon Dec 12 2022 11:04:48 GMT+0000 (Coordinated Universal Time) https://www.coursera.org/learn/advanced-react/quiz/vhZwu/self-review-create-a-registration-form

#react.js #registration #form
star

Mon Dec 12 2022 10:34:23 GMT+0000 (Coordinated Universal Time) https://forum.freecodecamp.org/t/freecodecamp-challenge-guide-pass-a-callback-as-props/301400

#react.js
star

Mon Dec 12 2022 10:33:43 GMT+0000 (Coordinated Universal Time) https://forum.freecodecamp.org/t/freecodecamp-challenge-guide-add-event-listeners/301377

#react.js
star

Sun Dec 11 2022 14:47:50 GMT+0000 (Coordinated Universal Time) https://beta.reactjs.org/learn/rendering-lists

#react.js
star

Tue Dec 06 2022 15:12:12 GMT+0000 (Coordinated Universal Time) https://nextjs.org/docs/guides/building-forms#form-validation-using-regular-expressions

#javascript #react.js
star

Sat Dec 03 2022 10:37:21 GMT+0000 (Coordinated Universal Time) https://www.hivelance.com/erc721-token-development

#react.js #nodejs #mongoshell #jquery
star

Tue Nov 29 2022 23:19:01 GMT+0000 (Coordinated Universal Time) https://readymadecode.com/create-drag-and-drop-in-react/

#react.js
star

Tue Nov 22 2022 11:39:18 GMT+0000 (Coordinated Universal Time) https://www.hivelance.com/blockchain-forking

#b2b #c++ #css #react.js #javascript #mongoshell #mysql #crypto #nft #blockchainfork development
star

Tue Nov 22 2022 11:38:10 GMT+0000 (Coordinated Universal Time) https://www.hivelance.com/nft-token-development

#b2b #c++ #css #react.js #javascript #mongoshell #mysql #crypto #nft #nfttoken
star

Tue Nov 22 2022 11:36:30 GMT+0000 (Coordinated Universal Time) https://www.hivelance.com/erc20-token-development

#erc20 #b2b #c++ #css #react.js #javascript #mongoshell #mysql #crypto
star

Fri Nov 04 2022 17:43:23 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Nov 02 2022 15:03:12 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Nov 02 2022 15:01:43 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Nov 02 2022 14:21:13 GMT+0000 (Coordinated Universal Time)

#react.js
star

Fri Oct 28 2022 09:11:27 GMT+0000 (Coordinated Universal Time)

#react.js #typescript
star

Fri Oct 21 2022 14:15:40 GMT+0000 (Coordinated Universal Time)

#react.js #typescript
star

Wed Oct 19 2022 10:27:20 GMT+0000 (Coordinated Universal Time) https://maticz.com/token-development

#nodejs #angular #javascript #php #python #vue.js #react.js
star

Mon Oct 17 2022 08:50:06 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Oct 17 2022 08:18:36 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Oct 11 2022 01:27:20 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Tue Oct 11 2022 01:26:12 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Wed Sep 28 2022 06:00:28 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Sep 27 2022 05:41:59 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Sep 20 2022 19:17:19 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Sep 20 2022 19:16:50 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Sep 20 2022 08:37:08 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Fri Sep 16 2022 05:17:28 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Sep 15 2022 14:12:53 GMT+0000 (Coordinated Universal Time) https://tanstack.com/query/v4/docs/guides/disabling-queries#lazy-queries

#tsx #react.js #usequery
star

Tue Sep 13 2022 22:28:02 GMT+0000 (Coordinated Universal Time) https://www.smashingmagazine.com/2020/07/styled-components-react/

#react.js
star

Tue Sep 13 2022 18:41:32 GMT+0000 (Coordinated Universal Time) cientificosdelsoftware.com

#javascript #react.js
star

Wed Sep 07 2022 07:44:16 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Sep 06 2022 19:40:33 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Sep 06 2022 17:42:12 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Sep 06 2022 17:22:56 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Sep 06 2022 17:19:03 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Sep 06 2022 08:04:57 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Aug 30 2022 02:21:13 GMT+0000 (Coordinated Universal Time)

#react.js
star

Fri Aug 26 2022 18:56:04 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Fri Aug 26 2022 16:37:27 GMT+0000 (Coordinated Universal Time) https://www.google.com/search?q

#react.js
star

Thu Aug 25 2022 20:02:39 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Aug 24 2022 04:59:02 GMT+0000 (Coordinated Universal Time) https://search.brave.com/search?q

#nodejs #react.js
star

Tue Aug 23 2022 02:22:36 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Aug 15 2022 10:15:01 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Mon Aug 15 2022 09:06:42 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Fri Aug 12 2022 00:04:54 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Aug 11 2022 23:49:16 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Aug 08 2022 04:52:17 GMT+0000 (Coordinated Universal Time)

#react.js #npm #create-react-app
star

Mon Aug 08 2022 04:21:51 GMT+0000 (Coordinated Universal Time)

#react.js #vite.js #npm
star

Thu Aug 04 2022 15:32:15 GMT+0000 (Coordinated Universal Time) https://www.techomoro.com/change-navbar-style-with-the-scroll-in-a-next-js-website/

#javascript #react.js #next.js
star

Thu Aug 04 2022 08:50:46 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Wed Aug 03 2022 11:45:56 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Wed Jul 27 2022 11:42:41 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/31163693/how-do-i-conditionally-add-attributes-to-react-components?rq

#react.js #javascript
star

Sun Jul 24 2022 17:53:28 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/58094441/correct-way-of-using-usestate-hook-on-radio-buttons

#javascript #react.js
star

Fri Jul 22 2022 10:05:54 GMT+0000 (Coordinated Universal Time)

#react.js #typescript
star

Wed Jul 20 2022 23:49:25 GMT+0000 (Coordinated Universal Time) https://www.youtube.com/watch?v=VsUzmlZfYNg

#javascript #react.js
star

Tue Jul 19 2022 17:58:03 GMT+0000 (Coordinated Universal Time) https://www.codementor.io/@amappuji/how-to-use-google-maps-iframe-in-your-react-app-1aoi4rr1nj

#react.js
star

Tue Jul 19 2022 13:46:17 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Tue Jul 19 2022 11:20:54 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Thu Jul 14 2022 05:25:19 GMT+0000 (Coordinated Universal Time)

#react.js #javascript
star

Tue Jul 12 2022 21:25:00 GMT+0000 (Coordinated Universal Time)

#javascript #react.js #typescript
star

Tue Jul 12 2022 07:20:11 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sun Jul 10 2022 09:22:45 GMT+0000 (Coordinated Universal Time)

#javascript #react.js #typescript
star

Sun Jul 10 2022 08:19:18 GMT+0000 (Coordinated Universal Time) https://eslint.org/docs/latest/user-guide/getting-started

#javascript #nodejs #react.js
star

Wed Jul 06 2022 00:29:49 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Jul 05 2022 12:17:49 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Tue Jul 05 2022 09:43:23 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Tue Jul 05 2022 07:59:46 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Sat Jul 02 2022 06:18:12 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Sat Jul 02 2022 06:11:53 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Sat Jul 02 2022 06:08:42 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Fri Jul 01 2022 08:06:37 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Jun 30 2022 06:45:47 GMT+0000 (Coordinated Universal Time)

#javascriptreact #react.js
star

Wed Jun 29 2022 23:10:55 GMT+0000 (Coordinated Universal Time) https://www.google.com/search?q

#javascript #react.js
star

Tue Jun 28 2022 13:12:35 GMT+0000 (Coordinated Universal Time) undefined

#react.js
star

Tue Jun 21 2022 10:51:54 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Jun 20 2022 12:02:21 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sat Jun 18 2022 11:41:05 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sat Jun 18 2022 11:23:42 GMT+0000 (Coordinated Universal Time)

#react.js
star

Fri Jun 17 2022 10:59:42 GMT+0000 (Coordinated Universal Time) https://discuss.codecademy.com/t/what-is-an-html-like-jsx-element/392722?_gl

#react.js
star

Fri Jun 17 2022 08:32:51 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/61984855/styled-components-nested-rules-dont-work

#react.js
star

Fri Jun 17 2022 05:55:23 GMT+0000 (Coordinated Universal Time)

#react.js
star

Fri Jun 17 2022 03:23:09 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Jun 14 2022 16:23:11 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Tue Jun 14 2022 12:21:09 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Tue Jun 14 2022 12:18:49 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Tue Jun 14 2022 10:16:41 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/61954636/prevent-a-button-being-clicked-consecutively-in-react

#react.js
star

Sun Jun 12 2022 09:22:28 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Jun 08 2022 09:12:34 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Tue Jun 07 2022 18:35:50 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Tue Jun 07 2022 14:43:22 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Tue Jun 07 2022 12:46:13 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Mon May 30 2022 11:16:53 GMT+0000 (Coordinated Universal Time)

#react.js #html
star

Mon May 30 2022 10:10:30 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/62861269/attempted-import-error-usehistory-is-not-exported-from-react-router-dom

#javascript #react.js
star

Thu May 19 2022 22:31:50 GMT+0000 (Coordinated Universal Time) https://www.pluralsight.com/guides/defining-props-in-react-function-component-with-typescript

#react.js
star

Thu May 19 2022 08:41:32 GMT+0000 (Coordinated Universal Time)

#react.js #html
star

Sun May 08 2022 14:13:38 GMT+0000 (Coordinated Universal Time) https://github.com/MartinConde/asuree/blob/main/src/components/layout.js

#react.js
star

Sat May 07 2022 15:41:30 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Apr 28 2022 20:56:22 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/53446020/how-to-compare-oldvalues-and-newvalues-on-react-hooks-useeffect

#javascript #react.js #useeffect
star

Wed Apr 27 2022 06:49:33 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Apr 20 2022 11:01:29 GMT+0000 (Coordinated Universal Time) https://www.youtube.com/watch?v

#react.js
star

Tue Apr 19 2022 12:10:02 GMT+0000 (Coordinated Universal Time) https://www.codegrepper.com/profile/ketan

#react.js
star

Fri Apr 08 2022 15:23:35 GMT+0000 (Coordinated Universal Time)

#antd #react.js
star

Fri Apr 08 2022 15:23:09 GMT+0000 (Coordinated Universal Time)

#antd #react.js
star

Fri Apr 08 2022 15:22:28 GMT+0000 (Coordinated Universal Time)

#antd #react.js
star

Tue Mar 29 2022 11:40:26 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Mar 17 2022 19:35:35 GMT+0000 (Coordinated Universal Time) vitejs.dev

#react.js
star

Sat Mar 12 2022 10:17:59 GMT+0000 (Coordinated Universal Time)

#react.js #typescript
star

Fri Mar 04 2022 06:21:16 GMT+0000 (Coordinated Universal Time) https://charts.ant.design/en/examples/line/basic#line-point-style

#react.js
star

Wed Mar 02 2022 09:47:41 GMT+0000 (Coordinated Universal Time)

#react.js #solidity #contract
star

Fri Feb 18 2022 05:48:52 GMT+0000 (Coordinated Universal Time) https://www.codecademy.com/courses/react-101/lessons/the-state-hook/exercises/lesson-review

#react.js
star

Fri Feb 18 2022 05:46:14 GMT+0000 (Coordinated Universal Time) https://www.codecademy.com/courses/react-101/lessons/the-state-hook/exercises/lesson-review

#react.js
star

Fri Feb 18 2022 03:08:37 GMT+0000 (Coordinated Universal Time) https://www.codecademy.com/courses/react-101/lessons/the-state-hook/exercises/objects-in-state

#react.js
star

Sat Feb 12 2022 19:17:12 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Sat Feb 05 2022 10:49:57 GMT+0000 (Coordinated Universal Time)

##javascript ##js #next.js #react.js
star

Thu Feb 03 2022 18:54:43 GMT+0000 (Coordinated Universal Time) https://kentcdodds.com/blog/application-state-management-with-react

#react.js #kentcdodds
star

Wed Feb 02 2022 14:42:13 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/32106513/material-ui-menu-using-routes

#react.js
star

Fri Jan 28 2022 10:48:12 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Mon Jan 24 2022 21:39:34 GMT+0000 (Coordinated Universal Time) https://reactjs.org/docs/conditional-rendering.html

#javascript #react.js
star

Mon Jan 24 2022 21:03:48 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Tue Jan 18 2022 16:16:26 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Jan 17 2022 10:25:21 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Jan 10 2022 18:35:56 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sat Jan 08 2022 14:35:34 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Dec 27 2021 13:36:17 GMT+0000 (Coordinated Universal Time)

#react.js
star

Fri Dec 24 2021 18:05:03 GMT+0000 (Coordinated Universal Time) https://www.smashingmagazine.com/2020/03/sortable-tables-react/

#react.js #sorting
star

Mon Dec 13 2021 13:39:01 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Dec 07 2021 12:48:47 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Dec 07 2021 06:40:16 GMT+0000 (Coordinated Universal Time)

#react.js
star

Fri Nov 19 2021 12:42:00 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Nov 11 2021 16:42:30 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Wed Nov 10 2021 15:43:16 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Wed Nov 10 2021 15:42:55 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Wed Nov 10 2021 15:40:38 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Wed Nov 10 2021 15:39:38 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Wed Nov 10 2021 15:37:13 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Wed Nov 10 2021 15:36:38 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Wed Nov 10 2021 15:32:40 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Wed Nov 10 2021 15:31:31 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Wed Nov 10 2021 15:28:48 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Thu Oct 28 2021 10:54:14 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Oct 28 2021 09:48:40 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Oct 28 2021 09:48:09 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Oct 27 2021 12:50:19 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Oct 26 2021 11:21:41 GMT+0000 (Coordinated Universal Time) https://github.com/daybrush/moveable

#react.js
star

Thu Oct 21 2021 18:52:10 GMT+0000 (Coordinated Universal Time)

#javascript #react.js #material
star

Wed Oct 20 2021 00:41:05 GMT+0000 (Coordinated Universal Time)

#ja #react.js
star

Tue Oct 19 2021 23:27:28 GMT+0000 (Coordinated Universal Time)

#ja #react.js
star

Tue Oct 19 2021 23:22:55 GMT+0000 (Coordinated Universal Time)

#ja #react.js
star

Thu Oct 07 2021 02:40:23 GMT+0000 (Coordinated Universal Time) https://cms.tecky.io/mod/page/view.php?id

#typescript #react.js
star

Wed Oct 06 2021 02:51:33 GMT+0000 (Coordinated Universal Time)

#typescript #react.js
star

Wed Oct 06 2021 02:15:09 GMT+0000 (Coordinated Universal Time)

#typescript #react.js
star

Wed Oct 06 2021 01:57:34 GMT+0000 (Coordinated Universal Time)

#typescript #react.js
star

Tue Oct 05 2021 05:46:33 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Oct 05 2021 03:18:33 GMT+0000 (Coordinated Universal Time)

#typescript #react.js
star

Mon Oct 04 2021 04:30:49 GMT+0000 (Coordinated Universal Time) https://cms.tecky.io/mod/page/view.php?id

#typescript #react.js
star

Mon Oct 04 2021 04:12:15 GMT+0000 (Coordinated Universal Time)

#typescript #react.js
star

Mon Oct 04 2021 04:07:33 GMT+0000 (Coordinated Universal Time)

#typescript #react.js
star

Mon Oct 04 2021 03:15:55 GMT+0000 (Coordinated Universal Time) https://cms.tecky.io/mod/page/view.php?id

#typescript #react.js
star

Mon Oct 04 2021 03:15:29 GMT+0000 (Coordinated Universal Time) https://cms.tecky.io/mod/page/view.php?id

#typescript #react.js
star

Mon Oct 04 2021 03:01:18 GMT+0000 (Coordinated Universal Time) https://cms.tecky.io/mod/page/view.php?id

#react.js
star

Wed Sep 29 2021 09:11:46 GMT+0000 (Coordinated Universal Time) https://cms.tecky.io/mod/page/view.php?id

#react.js #typescript
star

Wed Sep 29 2021 09:05:09 GMT+0000 (Coordinated Universal Time) https://cms.tecky.io/mod/page/view.php?id

#react.js
star

Wed Sep 29 2021 04:51:41 GMT+0000 (Coordinated Universal Time)

#react.js #typescript
star

Tue Sep 28 2021 08:54:15 GMT+0000 (Coordinated Universal Time)

#jsx #react.js #inlinestyling
star

Tue Sep 28 2021 08:29:02 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Sep 28 2021 06:54:32 GMT+0000 (Coordinated Universal Time) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

#react.js #javascript
star

Tue Sep 28 2021 06:51:14 GMT+0000 (Coordinated Universal Time)

#react.js #javascript
star

Tue Sep 28 2021 06:47:59 GMT+0000 (Coordinated Universal Time) https://codesandbox.io/s/z3ln7y0p04?file=/src/EventsSection/EventsSection.js:1256-1503

#react.js #javascript
star

Tue Sep 28 2021 02:28:32 GMT+0000 (Coordinated Universal Time) https://cms.tecky.io/mod/page/view.php?id

#react.js
star

Tue Sep 14 2021 08:37:31 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Sep 08 2021 15:40:31 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Aug 09 2021 18:29:41 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Mon Aug 09 2021 02:29:47 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Jul 29 2021 07:53:06 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Jul 20 2021 06:31:09 GMT+0000 (Coordinated Universal Time) https://www.youtube.com/watch?v=LKlO8vLvUao&list=PL6QREj8te1P7VSwhrMf3D3Xt4V6_SRkhu&index=3

#react.js #redux
star

Sun Jul 18 2021 18:56:11 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Mon Jul 12 2021 12:01:56 GMT+0000 (Coordinated Universal Time)

#react.js
star

Fri Jul 02 2021 20:00:39 GMT+0000 (Coordinated Universal Time)

#css #styledcomponents #react.js #reactnative
star

Wed Jun 30 2021 08:17:32 GMT+0000 (Coordinated Universal Time)

#react.js #usestate #setstate #counter
star

Tue Jun 29 2021 11:33:36 GMT+0000 (Coordinated Universal Time)

#react.js #css
star

Tue Jun 29 2021 10:26:39 GMT+0000 (Coordinated Universal Time) https://dev.to/hymanaharon/why-i-will-no-longer-be-using-console-log-to-check-react-state-updates-29el

#console #debugging #react.js
star

Tue Jun 29 2021 10:18:46 GMT+0000 (Coordinated Universal Time) https://upmostly.com/tag/react-hooks

#react.js
star

Tue Jun 29 2021 10:17:43 GMT+0000 (Coordinated Universal Time)

#react.js #javascript #react
star

Tue Jun 29 2021 10:10:50 GMT+0000 (Coordinated Universal Time) https://dommagnifi.co/2020-12-03-toggle-state-with-react-hooks/

#react.js #javascript #react #usestate #setstate
star

Tue Jun 29 2021 10:09:25 GMT+0000 (Coordinated Universal Time)

#react.js #javascript #react #usestate #setstate
star

Tue Jun 29 2021 10:03:32 GMT+0000 (Coordinated Universal Time)

#react.js #javascript #react #usestate
star

Tue Jun 29 2021 09:50:41 GMT+0000 (Coordinated Universal Time)

#react.js #javascript #react
star

Tue Jun 29 2021 09:45:03 GMT+0000 (Coordinated Universal Time) https://upmostly.com/tutorials/build-a-react-switch-toggle-component

#react.js #javascript #react
star

Tue Jun 29 2021 09:34:54 GMT+0000 (Coordinated Universal Time) https://upmostly.com/tutorials/react-filter-filtering-arrays-in-react-with-examples

#array #react.js #javascript #react #filter #map
star

Tue Jun 29 2021 09:30:58 GMT+0000 (Coordinated Universal Time)

#array #react.js #javascript #react #filter #map
star

Tue Jun 29 2021 09:28:03 GMT+0000 (Coordinated Universal Time)

#array #destructuring #javasc #react.js
star

Thu Jun 24 2021 16:18:30 GMT+0000 (Coordinated Universal Time)

#array #destructuring #javasc #react.js
star

Thu Jun 24 2021 16:12:14 GMT+0000 (Coordinated Universal Time)

#array #destructuring #javasc #react.js
star

Sat Jun 19 2021 00:10:27 GMT+0000 (Coordinated Universal Time)

#react.js #react-feather #css #clamp #html
star

Thu Jun 17 2021 15:57:27 GMT+0000 (Coordinated Universal Time) https://github.com/Learus/react-material-ui-carousel

#js #react.js
star

Thu Jun 10 2021 17:21:39 GMT+0000 (Coordinated Universal Time) https://javascript.plainenglish.io/5-advanced-react-patterns-a6b7624267a6

#react.js
star

Wed Jun 09 2021 15:32:53 GMT+0000 (Coordinated Universal Time) https://javascript.plainenglish.io/tired-of-boring-static-dashboards-lets-build-a-fully-customizable-dashboard-in-react-88cb5369cfe1

#react.js #draggable
star

Wed Jun 09 2021 14:49:41 GMT+0000 (Coordinated Universal Time) https://javascript.plainenglish.io/tired-of-boring-static-dashboards-lets-build-a-fully-customizable-dashboard-in-react-88cb5369cfe1

#react #react.js #draggable
star

Wed Jun 09 2021 14:45:35 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/40359800/how-to-toggle-boolean-state-of-react-component

#react.js #javascript #checkboxtoggle
star

Tue Jun 08 2021 09:41:37 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon May 31 2021 15:03:03 GMT+0000 (Coordinated Universal Time)

#react.js
star

Fri May 28 2021 09:30:57 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu May 27 2021 15:32:22 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu May 27 2021 15:31:56 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu May 27 2021 15:30:56 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu May 27 2021 15:28:47 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu May 27 2021 11:00:52 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon May 24 2021 14:26:04 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sun May 16 2021 08:59:25 GMT+0000 (Coordinated Universal Time) 参考にしたサイトはhttps://dezanari.com/react-react-router/

#react.js #javascript
star

Tue May 11 2021 14:41:03 GMT+0000 (Coordinated Universal Time) https://nadimmahmud25.medium.com/all-the-fundamental-react-js-core-concepts-that-you-should-know-as-a-react-developer-b89608f09e34

#react.js
star

Mon May 10 2021 17:53:11 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon May 10 2021 07:18:30 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/44023879/react-native-best-way-to-create-singleton-pattern/45476473#45476473

#javascript #react.js
star

Tue May 04 2021 19:41:58 GMT+0000 (Coordinated Universal Time) https://medium.com/@eshwaren/enable-emmet-support-for-jsx-in-visual-studio-code-react-f1f5dfe8809c

#react.js
star

Mon May 03 2021 09:43:58 GMT+0000 (Coordinated Universal Time)

#react.js #allowuserchangehisphone
star

Mon May 03 2021 09:38:34 GMT+0000 (Coordinated Universal Time)

#react.js #allowuserchangehisphone
star

Mon May 03 2021 09:36:59 GMT+0000 (Coordinated Universal Time)

#react.js #allowuserchangehisphone
star

Tue Apr 27 2021 11:43:12 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Apr 27 2021 10:38:17 GMT+0000 (Coordinated Universal Time) https://blog.carbonfive.com/replacing-component-lifecycle-methods-with-react-hooks/

#javascriptreact #react.js
star

Sun Apr 18 2021 20:55:04 GMT+0000 (Coordinated Universal Time)

#react.js
star

Sat Apr 17 2021 19:50:49 GMT+0000 (Coordinated Universal Time) https://www.sololearn.com/learning/1097/3381/7655/1

#react.js
star

Sat Apr 17 2021 19:48:37 GMT+0000 (Coordinated Universal Time) https://www.sololearn.com/learning/1097/3381/7655/1

#react.js
star

Sat Apr 17 2021 19:48:07 GMT+0000 (Coordinated Universal Time) https://www.sololearn.com/learning/1097/3381/7655/1

#react.js
star

Sat Apr 17 2021 19:43:44 GMT+0000 (Coordinated Universal Time) https://www.sololearn.com/learning/1097/3381/7655/1

#react.js
star

Sat Apr 17 2021 19:41:58 GMT+0000 (Coordinated Universal Time) https://www.sololearn.com/learning/1097/3381/7655/1

#react.js
star

Sat Apr 17 2021 19:40:46 GMT+0000 (Coordinated Universal Time) https://www.sololearn.com/learning/1097/3381/7655/1

#react.js
star

Sat Apr 17 2021 19:38:05 GMT+0000 (Coordinated Universal Time) https://www.sololearn.com/learning/1097/3381/7655/1

#react.js
star

Sat Apr 17 2021 19:34:31 GMT+0000 (Coordinated Universal Time) https://www.sololearn.com/learning/1097/3381/7655/1

#react.js
star

Fri Apr 16 2021 11:44:59 GMT+0000 (Coordinated Universal Time) https://www.youtube.com/watch?v=xo_ZRD_IAp0

#react.js
star

Fri Apr 16 2021 11:43:26 GMT+0000 (Coordinated Universal Time)

#react.js #react-native.ja
star

Thu Apr 15 2021 11:46:05 GMT+0000 (Coordinated Universal Time)

#react.js #react-native.ja
star

Thu Apr 15 2021 11:45:41 GMT+0000 (Coordinated Universal Time)

#react.js #react-native.ja
star

Wed Mar 17 2021 18:26:19 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Thu Mar 11 2021 16:22:23 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Mar 02 2021 16:19:31 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue Mar 02 2021 16:17:03 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Feb 22 2021 17:21:08 GMT+0000 (Coordinated Universal Time)

#react.js
star

Wed Feb 10 2021 18:47:05 GMT+0000 (Coordinated Universal Time) https://www.digitalocean.com/community/tutorials/how-to-create-wrapper-components-in-react-with-props

#react.js #wrapper-components
star

Tue Feb 09 2021 14:54:02 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Mon Feb 01 2021 15:38:57 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Sat Jan 23 2021 22:53:14 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Fri Jan 22 2021 13:05:25 GMT+0000 (Coordinated Universal Time) https://codepen.io/marcobiedermann/pen/WNGWzYR

#css #react.js
star

Wed Jan 20 2021 07:27:23 GMT+0000 (Coordinated Universal Time) http://customer-portal.fusion-tech.pro/

#javascript #react.js
star

Mon Dec 21 2020 00:32:04 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Dec 21 2020 00:24:48 GMT+0000 (Coordinated Universal Time)

#react.js #javascript
star

Mon Dec 21 2020 00:10:56 GMT+0000 (Coordinated Universal Time) https://www.digitalocean.com/community/tutorials/how-to-build-forms-in-react

#react.js
star

Wed Dec 16 2020 18:50:24 GMT+0000 (Coordinated Universal Time) https://www.valentinog.com/blog/socket-react/

#react.js
star

Wed Dec 16 2020 18:04:16 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/questions/10058226/send-response-to-all-clients-except-sender

#react.js
star

Fri Dec 11 2020 14:22:35 GMT+0000 (Coordinated Universal Time)

#react.js #javascript
star

Wed Dec 02 2020 09:38:44 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Thu Nov 26 2020 01:31:12 GMT+0000 (Coordinated Universal Time)

#javascript #typescript #angular #react.js
star

Tue Nov 24 2020 19:16:56 GMT+0000 (Coordinated Universal Time)

#javascript #typescript #react.js #next.js
star

Fri Nov 13 2020 00:26:54 GMT+0000 (Coordinated Universal Time)

#react.js
star

Fri Nov 13 2020 00:25:01 GMT+0000 (Coordinated Universal Time) https://forum.freecodecamp.org/t/freecodecamp-challenge-guide-extract-local-state-into-redux/301428

#react.js
star

Fri Nov 13 2020 00:08:59 GMT+0000 (Coordinated Universal Time) https://www.freecodecamp.org/learn/front-end-libraries/react-and-redux/connect-redux-to-the-messages-app

#react.js
star

Thu Nov 12 2020 23:54:08 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Nov 12 2020 23:49:43 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Nov 12 2020 23:41:22 GMT+0000 (Coordinated Universal Time) https://forum.freecodecamp.org/t/freecodecamp-challenge-guide-use-provider-to-connect-redux-to-react/301435

#react.js
star

Thu Nov 12 2020 23:28:31 GMT+0000 (Coordinated Universal Time) https://forum.freecodecamp.org/t/freecodecamp-challenge-guide-extract-state-logic-to-redux/301429

#react.js
star

Thu Nov 12 2020 23:19:15 GMT+0000 (Coordinated Universal Time) https://forum.freecodecamp.org/t/freecodecamp-challenge-guide-manage-state-locally-first/301431

#react.js
star

Fri Nov 06 2020 05:01:28 GMT+0000 (Coordinated Universal Time) https://til.hashrocket.com/posts/vahuw4phan-check-the-password-confirmation-with-yup

#javascript #react.js #yup
star

Mon Oct 26 2020 19:39:13 GMT+0000 (Coordinated Universal Time) https://kapeli.com/cheat_sheets/Axios.docset/Contents/Resources/Documents/index

#react.js ##axios ##react
star

Wed Oct 21 2020 17:34:45 GMT+0000 (Coordinated Universal Time) https://medium.com/code-artistry/how-to-create-a-custom-usedevicedetect-react-hook-f5a1bfe64599

#react.js #hooks
star

Tue Oct 20 2020 07:22:51 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Mon Oct 19 2020 11:03:08 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Oct 15 2020 23:22:27 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Oct 15 2020 07:52:45 GMT+0000 (Coordinated Universal Time) https://dev.to/thawkin3/3-react-mistakes-junior-developers-make-with-component-state-1bhd?utm_source

#react.js #setstate
star

Mon Oct 05 2020 13:07:35 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Oct 05 2020 01:03:27 GMT+0000 (Coordinated Universal Time)

#react.js
star

Mon Oct 05 2020 00:24:33 GMT+0000 (Coordinated Universal Time)

#react.js
star

Thu Aug 27 2020 20:08:59 GMT+0000 (Coordinated Universal Time)

#javascript #react.js
star

Wed Jul 08 2020 15:10:14 GMT+0000 (Coordinated Universal Time) https://reactjs.org/docs/hooks-overview.html

#javascript #react.js
star

Thu May 28 2020 06:27:13 GMT+0000 (Coordinated Universal Time)

#react.js
star

Tue May 19 2020 11:25:57 GMT+0000 (Coordinated Universal Time) https://useworker.js.org/

#react.js

Save snippets that work with our extensions

Available in the Chrome Web Store Get Firefox Add-on Get VS Code extension