SME-Web/src/components/process/processStepTwo/rightSideBar/RightSideBar.tsx

491 lines
19 KiB
TypeScript

import { DroppedItemsObj } from "../DocumentContainer";
import React, { useEffect, useState } from "react";
import { dateFormats, dateTimeFormats, timeFormats } from "../../../../utlity/dateTimeFormats";
import { DroppedItem } from "../../../../utlity/types";
import { IoIosArrowDown } from "react-icons/io";
import { TagsTypes } from "../../../../utlity/types";
import LabelAttr from "./LabelAttr";
import RequiredAttr from "./RequiredAttr";
import CurrTimeStampAttr from "./currTimeStampAttr";
import CommonAttrDropDown from "./CommonAttrDropDown";
import MaskTypePassAttr from "./MaskTypePassAttr";
import TemporalDateAttr from "./TemporalDateAttr";
import SelectTagAttr from "./SelectTagAttr";
import MaxMinLenAttr from "./MaxMinLenAttr";
import RecipientsAttrCon from "./RecipientsAttrCon";
import MovableFieldContainer from "./MovableField";
import DirectionalControls from "./DirectionalControls";
// interface DirectionalControlsProps {
// onMove: (direction: 'up' | 'down' | 'left' | 'right') => void;
// disabled?: boolean;
// stepSize?: number;
// className?: string;
// }
export interface DroppedItemProps {
selectedTag: DroppedItem
setDroppedItems: React.Dispatch<React.SetStateAction<DroppedItemsObj>>
selTagKey: string,
selTagIndx: number,
DirectionalControlsProps: {
onMove: (direction: 'up' | 'down' | 'left' | 'right', stepSize?: number) => void;
disabled?: boolean;
stepSize?: number;
className?: string;
}
}
export enum TEXT {
PARAGRAPH = "paragraph",
SINGLE_LINE = "single_line",
PASSWORD = "password",
}
export enum TEMPORAL {
DATE = "date",
TIME = "time",
DATE_TIME = "date_time",
}
export enum NUMBER {
INTEGER = "integer",
DECIMAL = "decimal",
CURRENCY = "currency"
}
export enum SELECT {
SINGLE_SELECT = "single select",
MULTI_SELECT = "multi select"
}
export enum MASKTYPE {
ALL = "all",
LAST_FOUR = "last_four",
CREDIT_CARD = "credit_Card",
NATIONAL_INSURANCE = "national_insurance",
SOCIAL_SECURITY = "social_security",
SOCIAL_INSURANCE = "social_insurance"
}
export enum MASKCHARACTER {
ASTERISK = "ASTERISK",
DOT = "DOT",
X = "CROSS",
}
export const enumMap = {
text: TEXT,
temporal: TEMPORAL,
number: NUMBER,
image: String,
select: SELECT
}
export enum DROPDOWNTOGGLE {
TYPE,
MASK_TYPE,
MASK_CHARACTER,
DDMMYY_FORMAT
}
const defaultStyles = {
font: "",
italic: false,
bold: false,
underline: false,
color: "#000000",
textSize: 0
};
const RightSideBar: React.FC<DroppedItemProps> = ({ selectedTag, setDroppedItems, selTagKey, selTagIndx, DirectionalControlsProps }) => {
const selectedType = selectedTag.type in enumMap && enumMap[selectedTag.type as keyof typeof enumMap];
console.log("selectedTag", selectedTag, selectedType)
const [styles, setStyles] = useState(defaultStyles);
const [dropDownToggle, setDropDownToggle] = useState<DROPDOWNTOGGLE | null>(null);
const [decimalPlace, setDecimalPlace] = useState<number>(2)
const [styleOpen, setStyleOpen] = useState(false);
const handlePropertyChange = (changeTo: string, changeWith: string | boolean | number, is24Hrs = null) => {
console.log("changeTo", changeTo, "changeWith", changeWith)
if (changeTo === '' || changeWith === '') return
if (changeWith === "paragraph") {
return
}
if (changeTo === "subType" && (changeWith === TEMPORAL.DATE || changeWith === TEMPORAL.DATE_TIME || changeWith === TEMPORAL.TIME)) {
// let change: string = changeWith;
// if (change === "DATE TIME") {
// change = "DATE_TIME"
// }
setDroppedItems((prev) => {
console.log("Temporal30", prev);
return {
...prev,
[selTagKey]: Array.isArray(prev[selTagKey]) // Ensure it's an array
? prev[selTagKey].map((item, i) =>
i === selTagIndx ? { ...item, [changeTo]: changeWith || "", format: "", update: true } : item
)
: [], // Fallback in case it's undefined or not an array
};
});
} else if (changeTo === "subType" && typeof changeWith === "string" && changeWith.toLowerCase() === "password") {
console.log("Second check")
console.log("Line 161")
setDroppedItems((prev) => (
{
...prev,
[selTagKey]: Array.isArray(prev[selTagKey])
? prev[selTagKey].map((item, i) =>
i === selTagIndx ? { ...item, [changeTo]: changeWith, maskType: "All", maskCharacter: "ASTERISK", update: true } : item
)
: [],
}
));
}
else if (changeTo === "subType" && (changeWith === NUMBER.CURRENCY || changeWith === NUMBER.INTEGER || changeWith === NUMBER.DECIMAL)) {
console.log("Third check")
let decPlace = changeWith !== NUMBER.DECIMAL ? 0 : decimalPlace;
const isCurrency = changeWith === NUMBER.CURRENCY;
// const currencyType = null
setDroppedItems((prev) => (
{
...prev,
[selTagKey]: Array.isArray(prev[selTagKey]) // Ensure it's an array
? prev[selTagKey].map((item, i) =>
i === selTagIndx ? { ...item, [changeTo]: changeWith, decimalPlace: decPlace, isCurrency, update: true } : item
)
: [],
}// Provide a fallback in case it's undefined or not an array
));
} else if (changeTo === "format" && selectedTag.subType === TEMPORAL.DATE_TIME) {
console.log("Fourth Check")
let val = timeFormats[0].format;
if (!is24Hrs) {
val = timeFormats[1].format
}
console.log("val", val)
setDroppedItems((prev) => {
const updatedArray = Array.isArray(prev[selTagKey])
? prev[selTagKey].map((item, i) => {
if (i === selTagIndx) {
const updatedItem = { ...item, [changeTo]: changeWith + " " + val, update: true };
console.log('Updating item at index', i, 'with:', updatedItem);
return updatedItem;
}
return item;
})
: [];
return {
...prev,
[selTagKey]: updatedArray,
};
});
} else {
setDroppedItems((prev) => {
const updatedItems = Array.isArray(prev[selTagKey])
? prev[selTagKey].map((item, i) =>
i === selTagIndx ? { ...item, [changeTo]: changeWith, update: true } : item
)
: [];
console.log('Updated items:', updatedItems);
return {
...prev,
[selTagKey]: updatedItems,
};
});
}
setDropDownToggle(null)
}
useEffect(() => {
if (selectedTag.subType === TEMPORAL.DATE || selectedTag.subType === TEMPORAL.DATE_TIME || selectedTag.subType === TEMPORAL.TIME) {
if (selectedTag.subType === TEMPORAL.DATE) {
handlePropertyChange("format", dateFormats[0].format)
}
else if (selectedTag.subType === TEMPORAL.DATE_TIME) {
handlePropertyChange("format", dateTimeFormats[0].format)
}
else if (selectedTag.subType === TEMPORAL.TIME) {
handlePropertyChange("format", timeFormats[0].format)
}
}
}, [selectedTag.subType])
useEffect(() => {
if (selectedTag.label === "temporal") {
handlePropertyChange("subType", TEMPORAL.DATE);
handlePropertyChange("format", "DD/MM/YY");
}
}, [])
const handleDecimalPlace = (e: React.ChangeEvent<HTMLInputElement>) => {
const val = Number(e.target.value)
setDecimalPlace(val)
handlePropertyChange("decimalPlace", val)
}
// useEffect(() => {
// if ("styles" in selectedTag) {
// console.log("styles" in selectedTag)
// const fontSize = selectedTag?.styles?.textSize;
// const tagHeight = selectedTag?.dimensions?.height - 18;
// console.log(fontSize)
// if (selectedTag.subType !== TEXT.PASSWORD && selectedTag.subType !== TEXT.PARAGRAPH && tagHeight > (fontSize + fontSize)) {
// handlePropertyChange("subType", TEXT.PARAGRAPH)
// } else if (selectedTag.subType !== TEXT.PASSWORD && selectedTag.subType !== TEXT.SINGLE_LINE && tagHeight <= (fontSize + fontSize)) {
// console.log("Change subType Called from elseif")
// handlePropertyChange("subType", TEXT.SINGLE_LINE)
// }
// }
// }, [selectedTag])
useEffect(() => {
if (!selectedTag) return;
if (!selectedTag.styles) {
handlePropertyChange("styles", defaultStyles);
setStyles(defaultStyles);
} else {
setStyles({ ...defaultStyles, ...selectedTag.styles });
}
// Optional subType logic
const fontSize = selectedTag?.styles?.textSize || defaultStyles.textSize;
const tagHeight = selectedTag?.dimensions?.height - 18;
if (
selectedTag.subType !== TEXT.PASSWORD &&
selectedTag.subType !== TEXT.PARAGRAPH &&
tagHeight > fontSize * 2
) {
handlePropertyChange("subType", TEXT.PARAGRAPH);
} else if (
selectedTag.subType !== TEXT.PASSWORD &&
selectedTag.subType !== TEXT.SINGLE_LINE &&
tagHeight <= fontSize * 2
) {
handlePropertyChange("subType", TEXT.SINGLE_LINE);
}
}, [selectedTag]);
const handleStyleChange = (key, value) => {
const updatedStyles = {
...(selectedTag.styles ?? defaultStyles),
[key]: value
};
setStyles(updatedStyles);
handlePropertyChange("styles", updatedStyles);
};
return (
<>
{/* Right Side Bar Start */}
<div className='col-span-2 w-full h-full bg-white text-sm overflow-y-auto'>
<p className="p-2 font-semibold text-md">Properties</p>
<hr className="text-slate-200" />
<div className="p-3 text-sm text-slate-600 flex flex-col gap-2">
{
<RecipientsAttrCon selectedRecipientId={selectedTag.recipientId} handlePropertyChange={handlePropertyChange} />
}
<DirectionalControls {...DirectionalControlsProps} selectedType={selectedTag.dimensions} />
{selectedTag.label &&
<LabelAttr label={selectedTag.label} handlePropertyChange={handlePropertyChange} />}
{(selectedTag.type !== TagsTypes.SIGNATURE && selectedTag.type !== TagsTypes.INITIALS) &&
<>
<RequiredAttr required={selectedTag.required ? selectedTag.required : false} handlePropertyChange={handlePropertyChange} />
</>
}
{selectedTag.type.toLowerCase() === TagsTypes.TEMPORAL &&
<CurrTimeStampAttr type={selectedTag.type} handlePropertyChange={handlePropertyChange} />}
{
selectedType && Object.keys(selectedType).length > 0 &&
<CommonAttrDropDown
selectedType={selectedType}
subType={selectedTag.subType}
dropDownToggle={dropDownToggle}
setDropDownToggle={setDropDownToggle}
handlePropertyChange={handlePropertyChange} />
}
{/* Mask Type */}
{
selectedTag?.subType === TEXT.PASSWORD &&
<MaskTypePassAttr
maskType={selectedTag.maskType ? selectedTag.maskType : MASKTYPE.ALL}
maskCharacter={selectedTag.maskCharacter ? selectedTag.maskCharacter : MASKCHARACTER.ASTERISK}
dropDownToggle={dropDownToggle}
setDropDownToggle={setDropDownToggle}
handlePropertyChange={handlePropertyChange} />
}
{/* TEMPORAL DATE FORMAT - START */}
{
(selectedTag?.subType === TEMPORAL.DATE ||
selectedTag?.subType === TEMPORAL.TIME ||
selectedTag?.subType === TEMPORAL.DATE_TIME) &&
<TemporalDateAttr
subType={selectedTag.subType}
format={selectedTag.format}
dropDownToggle={dropDownToggle}
setDropDownToggle={setDropDownToggle}
handlePropertyChange={handlePropertyChange} />
}
{/* TEMPORAL DATE FORMAT - END */}
{/* NUMBER - DECIMAL PLACES */}
{
selectedTag?.subType === NUMBER.DECIMAL &&
<div>
<label htmlFor="" className="">Decimal Places</label>
<input
type="number"
onChange={(e) => handleDecimalPlace(e)}
value={decimalPlace}
className="bg-slate-100 w-full outline-none p-2 rounded" />
</div>
}
{
(selectedTag?.subType === SELECT.SINGLE_SELECT || selectedTag?.subType === SELECT.MULTI_SELECT) &&
<SelectTagAttr
options={selectedTag.options}
selTagKey={selTagKey}
selTagIndx={selTagIndx}
setDroppedItems={setDroppedItems}
handlePropertyChange={handlePropertyChange} />
}
{
(selectedTag.type.toLowerCase() === TagsTypes.TEXT || selectedTag.type.toLowerCase() === TagsTypes.COMPANY) &&
<MaxMinLenAttr maxLength={selectedTag.maxLength} minLength={selectedTag.minLength} handlePropertyChange={handlePropertyChange} />
}
{(selectedTag.type.toLowerCase() !== TagsTypes.SIGNATURE && selectedTag.type.toLowerCase() !== TagsTypes.INITIALS) &&
<div className="">
<div className="flex items-center justify-between mr-2 cursor-pointer"
onClick={() => setStyleOpen(!styleOpen)}
>
<label
className="block mb-2">Styles</label>
<IoIosArrowDown className={`${styleOpen ? "rotate-[-90deg]" : ""} transition-all`} />
</div>
{
styleOpen && <>
{/* Font */}
<div className="mb-2">
<label className="mr-2">Font</label>
<input
type="text"
placeholder="e.g. Arial"
className="outline-none border-1 rounded px-2 py-1 border-slate-200"
value={styles.font}
onChange={(e) => handleStyleChange("font", e.target.value)}
/>
</div>
{/* Text Size */}
<div className="mb-2">
<label className="mr-2">Text Size</label>
<input
// value={}
type="number"
className="outline-none border-1 rounded px-2 py-1 border-slate-200"
value={styles.textSize}
onChange={(e) =>
handleStyleChange("textSize", parseInt(e.target.value, 10) || 0)
}
/>
</div>
{/* Color */}
<div className="mb-2">
<label className="mr-2">Color</label>
<input
type="color"
className="outline-none border-1 rounded px-2 py-1 border-slate-200 w-10 h-8"
value={styles.color}
onChange={(e) => handleStyleChange("color", e.target.value)}
/>
</div>
{/* Toggles for Bold, Italic, Underline */}
<div className="flex gap-4 items-center mt-2">
<label className="flex gap-1 items-center">
<input type="checkbox" checked={styles.bold}
onChange={(e) => handleStyleChange("bold", e.target.checked)} />
Bold
</label>
<label className="flex gap-1 items-center">
<input type="checkbox" checked={styles.italic} onChange={(e) => handleStyleChange("italic", e.target.checked)} />
Italic
</label>
<label className="flex gap-1 items-center">
<input type="checkbox" checked={styles.underline}
onChange={(e) =>
handleStyleChange("underline", e.target.checked)
} />
Underline
</label>
</div>
</>
}
</div>
}
</div>
</div>
{/* Right Side Bar End */}
</>
)
}
export default RightSideBar