Preview:
import React, {
  ChangeEvent,
  useEffect,
  useLayoutEffect,
  useRef,
  useState,
} from "react";
import { AttachCreatedFile, IDisplayComponentRef } from "./DisplayComponent";
import { Components, PropNames } from "./Components";
import {
  ComponentTitle,
  Container,
  GridItem,
  Label,
  TextInput,
  WideGridItem,
  WideTextInput,
  WideTextArea,
} from "./EditComponents";
import Repository from "../../common/repository/repository";
import config from "../../config.json";
import { ColorSelector } from "./ColorSelector";
import {
  AssetType,
  IAsset,
  IDirection,
  IObjectFit,
  ITemperatureType,
  IAnimatedDrmDotPosition,
  AssetNames,
} from "../../digital_assets_management/interfaces/IAsset";
import { useTranslations } from "../../i18n/useTranslations";
import { Input } from "reactstrap";
import { ThumbnailModal } from "../../common/components/ThumbnailModal";
import * as Constants from "../constants/component-constants";
import * as Global_Constants from "../../common/constants/shared-constants";
import * as Property_Constants from "../../common/constants/property-constants";
interface IComponentProps {
  component: IDisplayComponentRef | null;
  configuration: any;
  onValueChanged: (x: number, y: number, width: number, height: number) => void;
  onDeleteComponent?: (c: string) => void;
  onDuplicateComponent?: (c: IDisplayComponentRef) => void;
}
export const ComponentPropertyBar = ({
  component,
  configuration,
  onValueChanged,
  onDeleteComponent,
  onDuplicateComponent,
}: IComponentProps) => {
  const [checked, setChecked] = useState(true);
  const [isPlaying, setIsPlaying] = useState(false);
  const [align, setAlign] = useState("");
  const [extraProps, setExtraProps] = useState(
    {} as { [key: string]: any | number | boolean }
  );
  const refX = useRef<any>();
  const refY = useRef<any>();
  const refW = useRef<any>();
  const refH = useRef<any>();
  const i18n = useTranslations();
  const [createdFile, setCreatedFile] = useState({
    name: "",
    fileptr: Global_Constants.NOT_A_FP,
  } as AttachCreatedFile);
  const [styleAssets, setStyleAssets] = useState<IAsset[]>([]);
  const [arrowImage, setArrowImage] = useState<string | undefined>(undefined);
  const [imageAssets, setImageAssets] = useState<IAsset[]>([]);
  const [videoAssets, setVideoAssets] = useState<IAsset[]>([]);
  const [multiTextChecked, setMultiTextChecked] = useState(false);
  const [direction, setDirection] = useState<string>("left");
  const directionOptional = useRef([
    IDirection.LEFT,
    IDirection.RIGHT,
    IDirection.UP,
    IDirection.DOWN,
  ]);
  const [fitObject, setFitObject] = useState<string>();
  const objectsFitOptions = useRef([
    IObjectFit.CONTAIN,
    IObjectFit.COVER,
    IObjectFit.fill,
  ]);
  const [, setTempartureType] = useState();
  const tempartureTypesOptions = useRef([
    ITemperatureType.CELSIUS,

    ITemperatureType.FAHRENHEIT,
  ]);
  const [temperatureUnit, setTemperatureUnit] = useState<string>();
  const [ddrInputEvents, setDDRInputEvents] = useState<string>();
  const [animatedDrmDotOptionValue, setAnimatedDrmDotOptionValue] =
    useState("default");
  const animatedDrmDotPosition = useRef([
    IAnimatedDrmDotPosition.DEFAULT,
    IAnimatedDrmDotPosition.UPPER,
    IAnimatedDrmDotPosition.LOWER,
    IAnimatedDrmDotPosition.ZIGZAG,
  ]);
  const [showImageModal, setShowImageModal] = useState(false);
  const openImageModal = () => {
    setShowImageModal(true);
  };
  const closeImageModal = () => {
    setShowImageModal(false);
  };
  const [searchQuery, setSearchQuery] = useState("");
  const [numStations, setNumStations] = useState(2); // Default number of stations
  const [numberofArrows, setArrowIndex] = useState(0);
  const [fontOptions, setFontOptions] = useState([]);
  const [selectedFont, setSelectedFont] = useState("");
  const dataChanged = () => {
    const bounds = component!.getBounds();
    let x = parseInt(refX.current!.value);
    x = isNaN(x) ? bounds.x : x;
    let y = parseInt(refY.current!.value);
    y = isNaN(y) ? bounds.y : y;
    let width = parseInt(refW.current!.value);
    width = isNaN(width) ? bounds.width : width;
    let height = parseInt(refH.current!.value);
    height = isNaN(height) ? bounds.height : height;
    onValueChanged(x, y, width, height);
  };
  useEffect(() => {
    if (extraProps.direction) {
      setDirection(extraProps.direction.toString());
    } else {
      setDirection("left");
    }
  }, [extraProps.direction]);

  useEffect(() => {
    setExtraProps({});
    if (!component) return;
    const bounds = component.getBounds();
    setValue(refX.current!, Math.round(bounds.x));
    setValue(refY.current!, Math.round(bounds.y));
    setValue(refW.current!, Math.round(bounds.width));
    setValue(refH.current!, Math.round(bounds.height));
    const props = component.getExtraProps();
    if (props) {
      setExtraProps(props);
      setChecked(props[Property_Constants.IS_ANIMATED]);
      setAlign(props[Property_Constants.ALIGNMENT]);
      setIsPlaying(props[Property_Constants.IS_PLAYING]);
      setMultiTextChecked(props[Constants.MULTI_LINE_TEXT]);
      setFitObject(props[Constants.OBJECT_FIT]);
      setTempartureType(props[Property_Constants.TEMPERATURE_TYPE]);
      setDDRInputEvents(props[Property_Constants.DDR_EVENTS]);
      setNumStations(props[Property_Constants.NUM_STATIONS]);
      setArrowIndex(props[Property_Constants.NUMBER_OF_ARROWS]);
    }
    const attachedFile = component.getCreatedFile();
    if (attachedFile) {
      setCreatedFile(attachedFile);
    }
  }, [component]);
  useEffect(() => {
    const retreiveAssets = async () => {
      const styleAssets = (
        await Repository.getInstance().getAssets(0, 0, "", AssetType.Style)
      ).items;
      setStyleAssets(styleAssets);

      const imageAssets = (
        await Repository.getInstance().getAssets(0, 0, "", AssetType.Image)
      ).items;
      setImageAssets(imageAssets);

      const videoAssets = (
        await Repository.getInstance().getAssets(0, 0, "", AssetType.Video)
      ).items;
      setVideoAssets(videoAssets);
    };

    retreiveAssets();
  }, []);
  const setValue = (el: HTMLInputElement, value: number) => {
    el.value = value.toString();
  };
  const animateChanged = (t: HTMLInputElement) => {
    const newValue = t.checked;
    setChecked(newValue);
    const props = { ...extraProps, isAnimated: newValue };
    setExtraProps(props);
    component!.setExtraProps(props);
  };
  const multiLineChanged = (t: HTMLInputElement) => {
    const newValue = t.checked;
    setMultiTextChecked(newValue);
    const props = { ...extraProps, multiLineText: newValue };
    setExtraProps(props);
    component!.setExtraProps(props);
  };

  const changeAnimationDirection = (t: React.ChangeEvent<HTMLInputElement>) => {
    const newValue = t.target.value;
    setDirection(newValue);
    const props = { ...extraProps, direction: newValue };
    setExtraProps(props);
    component!.setExtraProps(props);
  };

  const handleTemperatureChange = (t: React.ChangeEvent<HTMLInputElement>) => {
    const newValue = t.target.value;
    const props = { ...extraProps, temperatureScales: newValue };
    setTemperatureUnit(newValue);
    setExtraProps(props);
    component!.setExtraProps(props);
  };
  const handleDotOptionChange = (t: React.ChangeEvent<HTMLInputElement>) => {
    const newValue = t.target.value;
    setAnimatedDrmDotOptionValue(newValue);
    const props = { ...extraProps, animatedDrmDotOptionValue: newValue };
    setExtraProps(props);
    component!.setExtraProps(props);
  };

  const handleFileUploadChange = (
    event: React.ChangeEvent<HTMLInputElement>
  ) => {
    const file = event.target.files?.[0];
    if (file) {
      const reader = new FileReader();
      reader.onload = (e) => {
        const uploadedFile = e.target?.result as string;
        // Set uploaded file as background image
        setArrowImage(uploadedFile);
      };
      reader.readAsDataURL(file);
    }
  };

  const changeProp = (
    propName: string,
    propValue: string | number | boolean
  ) => {
    const currentValue = extraProps[propName];
    if (currentValue !== propValue) {
      const props = { ...extraProps, [propName]: propValue };
      setExtraProps(props);
      component!.setExtraProps(props);
    }
  };

  const propChanged = (e: ChangeEvent<HTMLInputElement>) => {
    const propName = e.target.id.toString().substring(5);
    const newValue =
      typeof extraProps[propName] === "number"
        ? +e.target.value
        : typeof extraProps[propName] === "boolean"
        ? e.target.checked
        : e.target.value;

    changeProp(propName, newValue);
  };

  const propChangedForTextarea = (e: ChangeEvent<HTMLTextAreaElement>) => {
    const propName = e.target.id.toString().substring(5);
    const newValue = e.target.value;
    changeProp(propName, newValue);
  };

  const alignChanged = (e: ChangeEvent<HTMLInputElement>) => {
    const propName = e.target.id.toString().split("-")[1];
    const newValue = e.target.value;
    setAlign(newValue);
    changeProp(propName, newValue);
  };

  const changeInputDDREventState = (e: React.ChangeEvent<HTMLInputElement>) => {
    const ddrValue = e.target.value;
    const props = { ...extraProps, ddrEvents: ddrValue };
    setDDRInputEvents(ddrValue);
    setExtraProps(props);
    component!.setExtraProps(props);
  };

  const changeComponetObjectFit = (e: React.ChangeEvent<HTMLInputElement>) => {
    const targetValue = e.target.value;
    const props = { ...extraProps, objectFit: targetValue };
    setFitObject(targetValue);
    setExtraProps(props);
    component!.setExtraProps(props);
  };

  const handleStationChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    //  const newNumStations = +e.target.value;
    const newNumStations = parseInt(e.target.value);
    setNumStations(newNumStations);
    // Ensure arrow index doesn't exceed the number of stations
    setArrowIndex(Math.min(numberofArrows, newNumStations - 1));
    const props = { ...extraProps, numStations: newNumStations };
    setExtraProps(props);
    component!.setExtraProps(props);
  };

  const handleArrowChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const newArrowIndex = Number(e.target.value);
    setArrowIndex(Math.max(0, Math.min(newArrowIndex, numStations - 1)));
    const props = { ...extraProps, numberofArrows: newArrowIndex };
    setExtraProps(props);
    component!.setExtraProps(props);
  };

  const changeComponentAssetSelector = (
    e: React.ChangeEvent<HTMLInputElement>,
    assetType: string | undefined
  ) => {
    let createdFile = {
      name: "",
      fileptr: Global_Constants.NOT_A_FP,
    } as AttachCreatedFile;
    let props = extraProps;
    if (e.target.value === Global_Constants.NOT_A_FP) {
      setCreatedFile(createdFile);
      return;
    }

    if (assetType === AssetType.Style) {
      const asset = styleAssets?.find((v) => v.file_pointer === e.target.value);
      if (!asset) return;
      props = { ...props, style: asset?.infoJson ?? "{}" };
      createdFile = {
        name: asset.name,
        fileptr: asset.file_pointer,
      } as AttachCreatedFile;
    } else {
      const asset =
        assetType === AssetType.Image
          ? imageAssets?.find((v) => v.file_pointer === e.target.value)
          : videoAssets?.find((v) => v.file_pointer === e.target.value);
      if (!asset) return;
      props = {
        ...extraProps,
        src: `${config.assetsUrl}/${asset.file_pointer}`,
        source: asset.name,
      };
      createdFile = {
        name: asset.name,
        fileptr: asset.file_pointer,
      } as AttachCreatedFile;
      if (assetType === AssetType.Video) {
        const bounds = component!.getBounds();
        const newSize = JSON.parse(asset.infoJson);
        component!.setBounds({
          ...bounds,
          width: newSize["width"],
          height: newSize["height"],
        });
      }
    }

    setExtraProps(props);
    component!.setExtraProps(props);
    setCreatedFile(createdFile);
    component!.setCreatedFile(createdFile);
  };

  function updateMultilanguage(locale: string, duration: any) {
    let multiLanguage = JSON.parse(
      String(extraProps[Property_Constants.MULTI_LANGUAGE])
    );
    multiLanguage = {
      ...multiLanguage,
      [locale]: { ...multiLanguage[locale], duration: duration },
    };
    return multiLanguage;
  }

  const handleMultilingualCheckboxChange = (
    e: any,
    localecode: string,
    sampleMessage: string
  ) => {
    const sortedLocales = [...configuration.medialocales.locales].sort(
      (a, b) => a.order - b.order
    );
    const allLocales = sortedLocales.map((item: any) => item.localecode);
    let multiLanguage = JSON.parse(
      String(extraProps[Property_Constants.MULTI_LANGUAGE])
    );

    const currentLocaleIndex = allLocales.indexOf(localecode);

    for (
      let index = currentLocaleIndex + 1;
      index < allLocales.length;
      index++
    ) {
      const nextLocale = allLocales[index];
      if (!e.target.checked) {
        if (multiLanguage[nextLocale].checked) {
          const nextLocaleDuration =
            parseInt(multiLanguage[nextLocale][Property_Constants.DURATION]) +
            parseInt(multiLanguage[localecode][Property_Constants.DURATION]);
          multiLanguage = updateMultilanguage(nextLocale, nextLocaleDuration);
          break;
        }
      } else {
        if (multiLanguage[nextLocale].checked) {
          let nextLocaleDuration =
            parseInt(multiLanguage[nextLocale][Property_Constants.DURATION]) -
            parseInt(multiLanguage[localecode][Property_Constants.DURATION]);
          nextLocaleDuration = Math.max(nextLocaleDuration, 0);
          multiLanguage = updateMultilanguage(nextLocale, nextLocaleDuration);
          break;
        }
      }
    }
    multiLanguage = {
      ...multiLanguage,
      [localecode]: {
        ...multiLanguage[localecode],
        id: localecode,
        sampleText: sampleMessage,
        checked: e.target.checked,
      },
    };
    const props = {
      ...extraProps,
      [Property_Constants.MULTI_LANGUAGE]: JSON.stringify(multiLanguage),
    };
    setExtraProps(props);
    component!.setExtraProps(props);
  };

  const handleDurationsInputChange = (
    event: React.ChangeEvent<HTMLInputElement>,
    locale: string
  ) => {
    const { value } = event.target;
    const multiLanguage = updateMultilanguage(locale, value);
    const props = {
      ...extraProps,
      [Property_Constants.MULTI_LANGUAGE]: JSON.stringify(multiLanguage),
    };
    setExtraProps(props);
    component!.setExtraProps(props);
  };

  const onMultilanguageTextChanged = (e: ChangeEvent<HTMLTextAreaElement>) => {
    const propName = e.target.id.toString().split("-")[1];
    const newValue = e.target.value;
    let multiLanguage = JSON.parse(
      String(extraProps[Property_Constants.MULTI_LANGUAGE])
    );
    multiLanguage = {
      ...multiLanguage,
      [propName]: {
        id: propName,
        sampleText: newValue,
        checked: true,
        duration: multiLanguage[propName][Property_Constants.DURATION],
      },
    };
    const props = {
      ...extraProps,
      [Property_Constants.MULTI_LANGUAGE]: JSON.stringify(multiLanguage),
    };
    setExtraProps(props);
    component!.setExtraProps(props);
  };

  const toProperCase = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);

  const playPause = () => {
    const newValue = !isPlaying;
    setIsPlaying(newValue);
    changeProp(Property_Constants.IS_PLAYING, newValue);
    document
      .getElementById("icon-play")!
      .setAttribute("class", `fa fa-fw ${newValue ? "fa-pause" : "fa-play"}`);
  };

  const hiddenProps = [
    Property_Constants.SOURCE,
    Property_Constants.SRC,
    Property_Constants.IS_PLAYING,
    Constants.MULTI_LINE_TEXT,
    Constants.OBJECT_FIT,
    Property_Constants.TEMPERATURE_SCALES,
    Property_Constants.INPUT_BOX,
  ];

  const radioChanged = () => {
    //
  };

  const alignmentInput = (p: string, propId: string): JSX.Element => {
    return (
      <WideGridItem className="px-2" key={p}>
        <label>
          {i18n(Global_Constants.SCENE_LOCALES, PropNames[p]?.displayText) ??
            toProperCase(p)}
        </label>
        <div onChange={alignChanged} className="d-flex justify-content-between">
          <div>
            <input
              type="radio"
              id={propId + "-left"}
              value="left"
              checked={align === "left"}
              onChange={radioChanged}
            />
            <i className="fa fa-align-left mx-1" />
          </div>
          <div>
            <input
              type="radio"
              id={propId + "-center"}
              value="center"
              checked={align === "center"}
              onChange={radioChanged}
            />
            <i className="fa fa-align-center mx-1" />
          </div>
          <div>
            <input
              type="radio"
              id={propId + "-right"}
              value="right"
              checked={align === "right"}
              onChange={radioChanged}
            />
            <i className="fa fa-align-right mx-1" />
          </div>
        </div>
      </WideGridItem>
    );
  };

  const styleInput = (p: string, propId: string): JSX.Element => (
    <WideGridItem key="style">
      <Label htmlFor="prop-source" accessKey="s">
        {i18n(Global_Constants.GLOBAL, Global_Constants.STYLE)}
      </Label>
      <Input
        type="select"
        value={createdFile.fileptr}
        onChange={(e) => changeComponentAssetSelector(e, AssetType.Style)}
        id="comp-text-style-sel"
        name="comp-text-style-sel"
        title="Text Style selector"
        className="comp-textStyle-select"
      >
        <option value="_not_a_fp__" key="non_comp-text-style-id">
          {i18n(Global_Constants.SCENE_LOCALES, Constants.CHOOSE_STYLE)}
        </option>
        {styleAssets?.map((sa) => (
          <option
            key={`comp-text-style-id-${sa.file_pointer}`}
            value={sa.file_pointer}
          >
            {sa.name}
          </option>
        ))}
      </Input>
    </WideGridItem>
  );

  const DynamicField = (p: string) => {
    const renderFields = () => {
      const sortedLocales = [...configuration.medialocales.locales].sort(
        (a, b) => a.order - b.order
      );
      const multiLanguageText = JSON.parse(String(extraProps[p]));
      const inputBox = Boolean(extraProps.inputBox);
      const fields = sortedLocales.map((item: any) => {
        const { title, sampleText, localecode } = item;
        const languageTextObj =
          multiLanguageText && multiLanguageText[localecode]
            ? multiLanguageText[localecode]
            : {
                id: localecode,
                sampleText: sampleText,
                checked: true,
                duration: "4",
              };
        if (!multiLanguageText[localecode]) {
          multiLanguageText[localecode] = languageTextObj;
          const props = {
            ...extraProps,
            [p]: JSON.stringify(multiLanguageText),
          };
          setExtraProps(props);
          component!.setExtraProps(props);
        }
        return getInputWithCheckboxComponent(
          `${p}-${localecode}`,
          `multilanguage-${localecode}`,
          multiLanguageText[localecode].sampleText,
          onMultilanguageTextChanged,
          null,
          multiLanguageText[localecode].checked,
          title,
          inputBox,
          multiLanguageText[localecode].duration
        );
      });
      return fields;
    };
    return <>{renderFields()}</>;
  };

  const handleDropdownChange = (
    e: React.ChangeEvent<HTMLInputElement>,
    component: any,
    p: string,
    index: number
  ) => {
    const newValue = e.target.value;
    const updatedDropdown = extraProps.dropdown.map(
      (dropdownItem: any, idx: number) => {
        if (idx === index) {
          return { ...dropdownItem, selectedValue: newValue };
        }
        return dropdownItem;
      }
    );

    const props = {
      ...extraProps,
      dropdown: updatedDropdown,
    };
    setExtraProps(props);
    component!.setExtraProps(props);
  };

  const createDropdown = (p: string, component: any) => {
    const renderFields = () => {
      if (!Array.isArray(extraProps.dropdown)) {
        return null;
      }

      return extraProps.dropdown.map((dropdownItem: any, index: number) => {
        const dropdownData: any =
          Components[component.componentType].properties?.[dropdownItem.name];
        const dropdownOptions = dropdownData?.options || [];
        const selectedValue = dropdownItem.selectedValue;

        return (
          <WideGridItem key={index}>
            <Label
              htmlFor={`${component.componentType}${dropdownItem.name}Dropdown`}
            >
              {i18n(Global_Constants.SCENE_LOCALES, dropdownItem.name)}
            </Label>
            <Input
              type="select"
              onChange={(e) => handleDropdownChange(e, component, p, index)}
              className="animation-direction text-capitalize"
              value={selectedValue}
            >
              {dropdownOptions.map((value: any, idx: number) => (
                <option key={idx} value={value}>
                  {value}
                </option>
              ))}
            </Input>
          </WideGridItem>
        );
      });
    };

    return <>{renderFields()}</>;
  };

  const getInputWithCheckboxComponent = (
    pElementkey: string,
    propId: string,
    inputValue: string,
    onChangeHandler: any,
    numberProps: any,
    isChecked: boolean,
    label: string,
    inputBox: boolean,
    duration: any
  ) => {
    return (
      <WideGridItem key={pElementkey}>
        <Label htmlFor={propId} accessKey={PropNames[pElementkey]?.accessKey}>
          {label
            ? label
            : i18n(
                Global_Constants.SCENE_LOCALES,
                PropNames[pElementkey]?.displayText
              ) ?? toProperCase(pElementkey)}
          <input
            className="check-multilang"
            id={propId}
            key={`checkbox-${propId}`}
            checked={isChecked}
            onChange={(e) =>
              handleMultilingualCheckboxChange(
                e,
                propId.split("-")[1],
                inputValue
              )
            }
            type="checkbox"
          />
          {inputBox && (
            <input
              type="number"
              id={`text-${propId}`}
              key={`text-${propId}`}
              min={0}
              max={3600}
              style={{
                width: "50px",
                border: "1px solid black",
                borderRadius: "5px",
                marginLeft: "5px",
                marginBottom: "2px",
              }}
              value={duration}
              onChange={(e) =>
                handleDurationsInputChange(e, propId.split("-")[1])
              }
            />
          )}
        </Label>
        <WideTextArea
          id={propId}
          value={inputValue}
          onChange={onChangeHandler}
          {...numberProps}
        />
      </WideGridItem>
    );
  };

  const textInput = (
    p: string,
    propId: string,
    inputType: string
  ): JSX.Element => {
    let numberProps = {};
    if (
      component &&
      component.componentType === Constants.COMPONENT_TYPE_MULTILINE_TEXT
    ) {
      numberProps = { min: 1, max: 3 };
    }
    return propId === "prop-text" ? (
      <WideGridItem key={p}>
        <Label htmlFor={propId} accessKey={PropNames[p]?.accessKey}>
          {i18n(Global_Constants.SCENE_LOCALES, PropNames[p]?.displayText) ??
            toProperCase(p)}
        </Label>
        <WideTextArea
          id={propId}
          value={extraProps[p].toString()}
          onChange={propChangedForTextarea}
          {...numberProps}
        />
      </WideGridItem>
    ) : propId === "prop-ddrEvents" ? (
      <WideGridItem key={p}>
        <Label htmlFor={propId} accessKey={PropNames[p]?.accessKey}>
          {i18n(Global_Constants.SCENE_LOCALES, PropNames[p]?.displayText) ??
            toProperCase(p)}
        </Label>
        <WideTextInput
          id={propId}
          value={ddrInputEvents}
          placeholder={i18n(
            Global_Constants.SCENE_LOCALES,
            Constants.ENTER_DDR_VAR_NAMES
          )}
          onChange={changeInputDDREventState}
          {...numberProps}
        />
      </WideGridItem>
    ) : propId == "prop-numStations" ? (
      <WideGridItem key={p}>
        <Label htmlFor={propId} accessKey={PropNames[p]?.accessKey}>
          {i18n(Global_Constants.SCENE_LOCALES, PropNames[p]?.displayText) ??
            toProperCase(p)}
        </Label>
        <WideTextInput
          id={propId}
          type="number"
          className="numarrows"
          value={numStations}
          min={2}
          onChange={handleStationChange}
          {...numberProps}
        />
      </WideGridItem>
    ) : propId == "prop-numberofArrows" ? (
      <WideGridItem key={p}>
        <Label htmlFor={propId} accessKey={PropNames[p]?.accessKey}>
          {i18n(Global_Constants.SCENE_LOCALES, PropNames[p]?.displayText) ??
            toProperCase(p)}
        </Label>
        <WideTextInput
          id={propId}
          type="number"
          value={numberofArrows}
          className="numarrows"
          max={numStations - 1}
          min={0}
          onChange={handleArrowChange}
          {...numberProps}
        />
      </WideGridItem>
    ) : propId !== "prop-direction" ? (
      <WideGridItem key={p}>
        <Label htmlFor={propId} accessKey={PropNames[p]?.accessKey}>
          {i18n(Global_Constants.SCENE_LOCALES, PropNames[p]?.displayText) ??
            toProperCase(p)}
        </Label>
        <WideTextInput
          id={propId}
          value={extraProps[p].toString()}
          onChange={propChanged}
          {...numberProps}
        />
      </WideGridItem>
    ) : (
      <></>
    );
  };

  return component ? (
    <Container>
      <ComponentTitle>
        {i18n(
          Global_Constants.SCENE_LOCALES,
          Components[component.componentType].displayName
        )}
      </ComponentTitle>
      <GridItem>
        <Label htmlFor="prop-x" accessKey="x">
          x
        </Label>
        <TextInput
          id="prop-x"
          ref={refX}
          onChange={dataChanged}
          type="number"
        />
      </GridItem>
      <GridItem>
        <Label htmlFor="prop-y" accessKey="y">
          y
        </Label>
        <TextInput
          id="prop-y"
          ref={refY}
          onChange={dataChanged}
          type="number"
        />
      </GridItem>
      <GridItem>
        <Label htmlFor="prop-width" accessKey="l">
          {i18n(
            Global_Constants.SEQUENCE_LOCALES,
            PropNames["width"]?.displayText
          ) ?? "Width"}
        </Label>
        <TextInput
          id="prop-width"
          ref={refW}
          onChange={dataChanged}
          type="number"
          readOnly={component.componentType === "Video"}
        />
      </GridItem>
      <GridItem>
        <Label htmlFor="prop-height" accessKey="h">
          {i18n(
            Global_Constants.SEQUENCE_LOCALES,
            PropNames["height"]?.displayText
          ) ?? "Height"}
        </Label>
        <TextInput
          id="prop-height"
          ref={refH}
          onChange={dataChanged}
          type="number"
        />
      </GridItem>

      {component && Components[component.componentType].canAnimate ? (
        <WideGridItem className="form-check form-switch">
          <input
            className="form-check-input"
            onChange={(e) => animateChanged(e.target)}
            type="checkbox"
            id="checkAnimate"
            checked={checked}
          />
          <label
            className="form-check-label"
            htmlFor="checkAnimate"
            accessKey="a"
          >
            {i18n(Global_Constants.SCENE_LOCALES, Constants.ANIMATE)}
          </label>
        </WideGridItem>
      ) : (
        <></>
      )}

      {Components[component.componentType].assetType ===
      AssetType.AnimatedDrmDropdown ? (
        <WideGridItem>
          <Label htmlFor="animatedDrmDropdown" accessKey="d">
            Line Style
          </Label>

          <Input
            type="select"
            onChange={(e) => handleDotOptionChange(e)}
            className="animation-direction text-capitalize"
            value={animatedDrmDotOptionValue}
          >
            {animatedDrmDotPosition.current.map((value, index) => (
              <option key={index} value={value}>
                {value}
              </option>
            ))}
          </Input>
        </WideGridItem>
      ) : (
        <></>
      )}

      {Components[component.componentType].assetNames ===
      AssetNames.AT_DotsDropdown ? (
        <WideGridItem>
          <Label htmlFor="DotsDropdown" accessKey="d">
            Arrow Type{" "}
          </Label>

          <input
            type="file"
            id="fileUpload"
            onChange={handleFileUploadChange}
          />
        </WideGridItem>
      ) : (
        <></>
      )}

      {component && Components[component.componentType].canMultiLine ? (
        <WideGridItem className="form-check form-switch">
          <input
            className="form-check-input"
            onChange={(e) => multiLineChanged(e.target)}
            type="checkbox"
            id="multiLine"
            checked={multiTextChecked}
          />
          <label className="form-check-label" htmlFor="multiLine" accessKey="m">
            {i18n(Global_Constants.SCENE_LOCALES, Constants.MULTI_LINE_TEXT)}
          </label>
        </WideGridItem>
      ) : (
        <></>
      )}

      {extraProps &&
        Object.keys(extraProps)
          .filter((p) => p !== "isAnimated" && !hiddenProps.includes(p))
          .map((p) => {
            const inputType = p.toLowerCase().includes("color")
              ? "color"
              : typeof extraProps[p] === "number"
              ? "number"
              : "text";
            const propId = `prop-${p}`;
            return p.toLowerCase().includes("color") ? (
              <ColorSelector
                key={p}
                propId={propId}
                colorValue={extraProps[p].toString()}
                onColorChanged={(c) => changeProp(p, c)}
                component={component}
              />
            ) : typeof extraProps[p] === "boolean" ? (
              <WideGridItem className="form-check form-switch" key={p}>
                <input
                  className="form-check-input"
                  onChange={propChanged}
                  type="checkbox"
                  id={propId}
                />
                <label
                  className="form-check-label"
                  htmlFor={propId}
                  accessKey={PropNames[p]?.accessKey}
                >
                  {i18n(
                    Global_Constants.SCENE_LOCALES,
                    PropNames[p]?.displayText
                  ) ?? toProperCase(p)}
                </label>
              </WideGridItem>
            ) : p.toLowerCase() === "alignment" ? (
              alignmentInput(p, propId)
            ) : p.toLowerCase() === "style" ? (
              styleInput(p, propId)
            ) : p.toLowerCase() === "direction" ? (
              <WideGridItem>
                <Label htmlFor={propId} accessKey="s">
                  {i18n(
                    Global_Constants.SCENE_LOCALES,
                    PropNames[p]?.displayText
                  ) ?? toProperCase(p)}
                </Label>
                <Input
                  type="select"
                  onChange={(e) => changeAnimationDirection(e)}
                  id={propId}
                  name={propId}
                  className="animation-direction text-capitalize"
                  value={direction}
                >
                  {directionOptional.current.map((value, index) => (
                    <option key={index} value={value}>
                      {value}
                    </option>
                  ))}
                </Input>
              </WideGridItem>
            ) : p === "multilanguage" ? (
              DynamicField(p)
            ) : p === "dropdown" ? (
              createDropdown(p, component)
            ) : (
              textInput(p, propId, inputType)
            );
          })}

      {Components[component.componentType].assetType === "AT_Temprature" ? (
        <WideGridItem key="Type">
          <Label htmlFor="prop-Temperature" accessKey="t">
            Type
          </Label>
          <Input
            type="select"
            onChange={(e) => handleTemperatureChange(e)}
            id="prop-Temperature"
            name="Temprature"
            title="Type Temprature"
            className="comp-temprature-select"
            value={temperatureUnit}
          >
            {tempartureTypesOptions.current.map((item) => (
              <option key={item} value={item}>
                {item}
              </option>
            ))}
          </Input>
        </WideGridItem>
      ) : (
        Components[component.componentType].assetType &&
        Components[component.componentType].assetType !==
          AssetType.AnimatedDrmDropdown && (
          <WideGridItem key="Source">
            <Label htmlFor="prop-source" accessKey="s">
              Source
            </Label>
            {showImageModal && (
              <ThumbnailModal
                show={showImageModal}
                header="Select Resource"
                onCloseModal={closeImageModal}
                isOkVisible={false}
                isCanVisible={true}
                searchQuery={searchQuery}
                setSearchQuery={setSearchQuery}
                // eslint-disable-next-line @typescript-eslint/no-empty-function
                // onOkClick={() => {}}
                i18n={i18n}
              >
                <div
                  style={{
                    display: "flex",
                    flexWrap: "wrap",
                    overflowX: "hidden",
                    height: "100%",
                    width: "1100px",
                    minHeight: "600px",
                    minWidth: "1100px",
                    justifyContent: "center",
                  }}
                >
                  {(Components[component.componentType].assetType ===
                  AssetType.Image
                    ? imageAssets
                    : videoAssets
                  )
                    ?.filter((asset) =>
                      asset.name
                        .toLowerCase()
                        .includes(searchQuery.toLowerCase())
                    )
                    .map((asset) => (
                      <div
                        style={{
                          padding: "5px",
                          justifyContent: "center",
                          alignItems: "center",
                          flex: "0 0 250px",
                          marginRight: "20px",
                          marginBottom: "20px",
                          border: "5px solid black",
                          height: "250px",
                          position: "relative",
                          display: "flex",
                          flexDirection: "column",
                          paddingTop: "15px",
                        }}
                        key={asset.file_pointer}
                        onClick={() => {
                          const syntheticEvent = {
                            target: { value: asset.file_pointer },
                          } as React.ChangeEvent<HTMLInputElement>;
                          changeComponentAssetSelector(
                            syntheticEvent,
                            Components[component.componentType].assetType ===
                              AssetType.Image
                              ? AssetType.Image
                              : AssetType.Video
                          );
                          closeImageModal();
                        }}
                      >
                        <div
                          style={{
                            display: "flex",
                            justifyContent: "center",
                            alignItems: "center",
                            height: "100%",
                          }}
                        >
                          {Components[component.componentType].assetType ===
                          AssetType.Image ? (
                            <img
                              src={`${config.assetsUrl}/${asset.file_pointer}`}
                              alt={asset.name}
                              style={{
                                maxWidth: "150px",
                                maxHeight: "150px",
                                cursor: "pointer",
                                marginBottom: "10px",
                                alignSelf: "center",
                              }}
                            />
                          ) : (
                            <video
                              src={`${config.assetsUrl}/${asset.file_pointer}`}
                              style={{
                                maxWidth: "150px",
                                maxHeight: "150px",
                                cursor: "pointer",
                                marginBottom: "10px",
                                alignSelf: "center",
                              }}
                            />
                          )}
                        </div>
                        <p
                          style={{
                            textAlign: "center",
                            marginTop: "auto",
                            marginBottom: "0",
                            backgroundColor: "#548b8b",
                            padding: "5px",
                            color: "white",
                            fontWeight: "bold",
                            height: "50px",
                            width: "100%",
                            overflow: "auto",
                          }}
                        >
                          {asset.name}
                        </p>
                      </div>
                    ))}
                </div>
              </ThumbnailModal>
            )}
            <button className="btn btn-secondary" onClick={openImageModal}>
              {i18n(Global_Constants.SCENE_LOCALES, Constants.SELECT_RESOURCE)}
            </button>
          </WideGridItem>
        )
      )}

      {Components[component.componentType].assetType === AssetType.Image ? (
        <WideGridItem key="Object-fit">
          <Label htmlFor="prop-objectFit" accessKey="s">
            {i18n(Global_Constants.SCENE_LOCALES, Constants.OBJECT_FIT)}
          </Label>
          <Input
            type="select"
            name="prop-objectFit"
            id="prop-objectFit"
            title="ObjectFit"
            onChange={(e) => changeComponetObjectFit(e)}
            value={fitObject}
            className="text-capitalize"
          >
            {objectsFitOptions.current.map((item) => (
              <option className="text-capitalize" key={item} value={item}>
                {item}
              </option>
            ))}
          </Input>
        </WideGridItem>
      ) : (
        <></>
      )}

      {Components[component.componentType].assetType === AssetType.Video ? (
        <WideGridItem>
          <button className="btn btn-primary" onClick={playPause}>
            <i className="fa fa-play fa-fw" id="icon-play" />
          </button>
        </WideGridItem>
      ) : (
        <></>
      )}
      {onDeleteComponent && (
        <GridItem>
          <button
            className="btn btn-primary"
            onClick={() => onDeleteComponent(component.compId)}
          >
            <i className="fa fa-trash fa-fw" />
          </button>
        </GridItem>
      )}
      {onDuplicateComponent && (
        <GridItem>
          <button
            className="btn btn-success"
            onClick={() => onDuplicateComponent(component)}
          >
            <i className="fa fa-clone fa-fw" />
          </button>
        </GridItem>
      )}
    </Container>
  ) : (
    <div>
      {i18n(Global_Constants.SCENE_LOCALES, Constants.SELECT_COMPONENT)}
    </div>
  );
};
downloadDownload PNG downloadDownload JPEG downloadDownload SVG

Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!

Click to optimize width for Twitter