update 7 files

This commit is contained in:
faisolavolut 2025-01-24 08:28:09 +07:00
parent 56388ed38a
commit 34fdaa0cf5
8 changed files with 227 additions and 46 deletions

View File

@ -9,6 +9,7 @@ import { TypeTag } from "./field/TypeTag";
import get from "lodash.get";
import { getNumber } from "@/lib/utils/getNumber";
import { useLocal } from "@/lib/utils/use-local";
import { FieldRadio } from "./field/TypeRadio";
export const Field: React.FC<any> = ({
fm,
@ -80,6 +81,17 @@ export const Field: React.FC<any> = ({
border: 0px !important;
box-shadow: none;
}
`,
style === "gform" &&
css`
.field input {
padding-left: 0px !important;
padding-right: 0px !important;
}
.field textarea {
padding-left: 0px !important;
padding-right: 0px !important;
}
`
)}
>
@ -105,17 +117,26 @@ export const Field: React.FC<any> = ({
: "border border-gray-300 ",
"relative field",
!is_disable
? style === "underline"
? "focus-within:border-b focus-within:border-b-gray-500"
: "focus-within:border focus-within:border-gray-500"
? style === "underline" || style === "gform"
? "focus-within:border-b focus-within:border-b-primary"
: "focus-within:border focus-within:border-primary"
: "",
style === "underline"
style === "underline" || style === "gform"
? "rounded-none border-transparent border-b-gray-300"
: "",
["rating", "color", "single-checkbox", "checkbox"].includes(type) &&
[
"rating",
"color",
"single-checkbox",
"radio",
"checkbox",
].includes(type) &&
css`
border: 0px !important;
`,
["upload"].includes(type) &&
css`
padding: 0px !important;
`
)}
>
@ -192,6 +213,18 @@ export const Field: React.FC<any> = ({
className={className}
/>
</>
) : ["radio"].includes(type) ? (
<>
<FieldRadio
fm={fm}
name={name}
onLoad={onLoad}
placeholder={placeholder}
disabled={is_disable}
onChange={onChange}
className={className}
/>
</>
) : ["single-checkbox"].includes(type) ? (
<>
<FieldCheckbox

View File

@ -114,6 +114,7 @@ export const FieldCheckbox: FC<any> = ({
isChecked && "active"
)}
>
<div className="text-primary">
{isChecked ? (
<svg
xmlns="http://www.w3.org/2000/svg"
@ -140,6 +141,8 @@ export const FieldCheckbox: FC<any> = ({
/>
</svg>
)}
</div>
<div className="">{item.label}</div>
</div>
);

View File

@ -2,7 +2,7 @@ import { useLocal } from "@/lib/utils/use-local";
import Datepicker from "../../ui/Datepicker";
import { Input } from "../../ui/input";
import { Textarea } from "../../ui/text-area";
import { useEffect, useState } from "react";
import { useEffect, useRef, useState } from "react";
import tinycolor from "tinycolor2";
import { FieldColorPicker } from "../../ui/FieldColorPopover";
import { FaRegStar, FaStar } from "react-icons/fa6";
@ -22,6 +22,7 @@ export const TypeInput: React.FC<any> = ({
className,
}) => {
const [hover, setHover] = useState(0); // State untuk menyimpan nilai hover
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
let value: any = fm.data?.[name] || "";
const [rating, setRating] = useState(value); // State untuk menyimpan nilai rating
@ -41,6 +42,13 @@ export const TypeInput: React.FC<any> = ({
rgbValue: "",
selectedEd: "" as string,
});
const handleInput = () => {
const textarea = textareaRef.current;
if (textarea) {
textarea.style.height = "auto"; // Reset height to calculate new height
textarea.style.height = `${textarea.scrollHeight}px`; // Adjust height based on content
}
};
useEffect(() => {
if (type === "color") {
meta.inputValue = value || "";
@ -66,7 +74,9 @@ export const TypeInput: React.FC<any> = ({
return (
<>
<Textarea
ref={textareaRef}
id={name}
onInput={handleInput}
name={name}
disabled={disabled}
required={required}

View File

@ -0,0 +1,131 @@
import { useLocal } from "@/lib/utils/use-local";
import { FC, useEffect } from "react";
import { ButtonBetter } from "../../ui/button";
import { IoRadioButtonOff, IoRadioButtonOn } from "react-icons/io5";
export const FieldRadio: FC<any> = ({
fm,
name,
onLoad,
onChange,
placeholder,
disabled,
className,
mode = "single",
}) => {
const local = useLocal({
list: [] as any[],
reload: async () => {
fm.fields[name] = { ...fm.fields?.[name], ...local };
fm.render();
const callback = (res: any[]) => {
if (Array.isArray(res)) {
local.list = res;
} else {
local.list = [];
}
local.render();
};
const res = onLoad();
if (res instanceof Promise) res.then(callback);
else callback(res);
},
});
useEffect(() => {
fm.fields[name] = { ...fm.fields?.[name], ...local };
const callback = (res: any[]) => {
if (Array.isArray(res)) {
local.list = res;
} else {
local.list = [];
}
local.render();
};
const res = onLoad();
if (res instanceof Promise) res.then(callback);
else callback(res);
}, []);
let value =
mode === "single" && typeof fm.data?.[name] === "string"
? [fm.data?.[name]]
: fm.data?.[name];
let is_tree = false;
const applyChanges = (selected: any[]) => {
selected = selected.filter((e) => e);
const val = selected.map((e) => e.value);
if (mode === "single") {
selected = val?.[0];
fm.data[name] = selected;
} else {
fm.data[name] = val;
}
fm.render();
if (typeof onChange === "function") {
onChange(fm.data[name]);
}
};
return (
<>
<div className={cx("flex items-center w-full flex-row")}>
<div
className={cx(
`flex flex-col p-0.5 flex-1`,
!is_tree && "space-y-1 ",
className
)}
>
{local.list.map((item, idx) => {
let isChecked = false;
try {
isChecked = value.some((e: any) => e === item.value);
} catch (ex) {}
return (
<div
key={idx + "_checkbox"}
onClick={() => {
if (!disabled) {
let selected = Array.isArray(value)
? value.map((row) => {
return local.list.find((e) => e.value === row);
})
: [];
if (isChecked) {
selected = selected.filter(
(e: any) => e.value !== item.value
);
} else {
if (mode === "single") {
selected = [item];
} else {
selected.push(item);
}
}
applyChanges(selected);
}
}}
className={cx(
"text-sm opt-item flex flex-row gap-x-1 cursor-pointer items-center rounded-full p-0.5 ",
isChecked && "active"
)}
>
{isChecked ? (
<IoRadioButtonOn className="text-primary" />
) : (
<IoRadioButtonOff className="text-primary" />
)}
<div className="">{item.label}</div>
</div>
);
})}
</div>
</div>
</>
);
};

View File

@ -179,13 +179,13 @@ export const FieldUploadSingle: FC<{
input.ref.click();
}
}}
className="items-center flex text-base px-1 outline-none rounded cursor-pointer "
className="items-center flex text-base px-1 outline-none rounded cursor-pointer flex-row justify-center"
>
<div className="flex flex-row items-center px-2">
<Upload className="h-4 w-4" />
</div>
<div className="flex flex-row items-center text-md">
Upload File
<div className="flex flex-row items-center text-sm">
Add File
</div>
</div>
</div>

View File

@ -577,7 +577,9 @@ export const Typeahead: FC<{
>
<input
placeholder={
local.mode === "multi" ? placeholder : valueLabel[0]?.label
local.mode === "multi"
? placeholder
: valueLabel[0]?.label || placeholder
}
type="text"
ref={input}

View File

@ -84,12 +84,7 @@ export const TableEditBetter: React.FC<any> = ({
local.render();
},
removeRow: (row: any) => {
// setData((prev) => prev.filter((item) => item !== row)); // Update state lokal
// local.data = local.data.filter((item: any) => item !== row); // Hapus row dari local.data
// local.render(); // Panggil render untuk memperbarui UI
console.log("HALOO");
const data = fm.data?.[name] || [];
// data.push(row);
if (delete_name) {
const ids: any[] = Array.isArray(fm.data?.[delete_name])
? fm.data?.deleted_line_ids
@ -103,9 +98,6 @@ export const TableEditBetter: React.FC<any> = ({
fm.render();
local.data = fm.data[name];
local.render();
console.log({ fm });
// local.data = fm.data[name];
// local.render();
},
reload: async () => {
toast.info(

View File

@ -39,7 +39,17 @@ const MaskedInput: React.FC<MaskedInputProps> = ({
if (input.length > 5) {
input = input.substring(0, 5);
}
// Validasi batas maksimal jam
if (input.length === 5 && !input.includes("_")) {
const [hours, minutes] = input.split(":").map(Number);
// Koreksi jika jam atau menit melebihi batas
const correctedHours = Math.min(hours, 23);
const correctedMinutes = Math.min(minutes, 59);
input = `${String(correctedHours).padStart(2, "0")}:${String(
correctedMinutes
).padStart(2, "0")}`;
}
// Update state lokal
setLocalValue(input);