build page updated

This commit is contained in:
berkay 2024-12-18 19:11:37 +03:00
parent 829151bdc8
commit 44c458cd4c
8 changed files with 330 additions and 232 deletions

View File

@ -36,41 +36,28 @@ class HeadersAndValidations {
parseProcesser() { parseProcesser() {
Object.entries(this.properties).map(([key, value]) => { Object.entries(this.properties).map(([key, value]) => {
const multipleTypes: Object[] = value?.anyOf || []; const multipleTypes: Object[] = value?.anyOf || [];
const isRequired: boolean = Object.keys(value).includes("anyOf"); let isRequired: boolean = true;
try {
isRequired = Object.keys(multipleTypes).includes("anyOf");
} catch (error) {}
if (!isRequired) { if (!isRequired) {
multipleTypes.map((row: any) => { multipleTypes.map((row: any) => {
if (row.type !== "null") { if (row.type !== "null") {
this.validated[key] = { this.validated[key] = {
required: false, required: isRequired,
fieldType: row.type, fieldType: row.type,
}; };
} }
}); });
} else { } else {
this.validated[key] = { this.validated[key] = {
required: true, required: isRequired,
fieldType: value, fieldType: value,
}; };
} }
}); });
} }
parseType({ type }: any) {
switch (type) {
case "string":
return string;
case "number":
return number;
case "boolean":
return boolean;
case "array":
return array;
case "object":
return object;
default:
return string;
}
}
} }
export { HeadersAndValidations }; export { HeadersAndValidations };

View File

@ -29,6 +29,7 @@ const Build: React.FC = () => {
updateEndpoint="/building/build/update" updateEndpoint="/building/build/update"
tableFunction={retrieveBuildList} tableFunction={retrieveBuildList}
UpdatePage={PageUpdate} UpdatePage={PageUpdate}
saveFunction={createBuild}
setFormPage={setFormPage} setFormPage={setFormPage}
returnToPage={() => setFormPage(null)} returnToPage={() => setFormPage(null)}
updatePageInfo={{ updatePageInfo={{
@ -53,6 +54,7 @@ const Build: React.FC = () => {
}} }}
endpoint="/building/build/create" endpoint="/building/build/create"
returnToPage={() => setFormPage(null)} returnToPage={() => setFormPage(null)}
saveFunction={createBuild}
/> />
) )
} }

View File

@ -0,0 +1,187 @@
"use client";
import React from "react";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import * as z from "zod";
import { Input } from "@/components/ui/input";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
interface FormPageInterface {
validatedData: any;
zodValidation: any;
apiValidation: any;
apiHeaders: any;
}
const FormPage: React.FC<FormPageInterface> = ({
validatedData,
zodValidation,
apiValidation,
apiHeaders,
}) => {
const validSchemaZod = z.object({ ...zodValidation });
const form = useForm<z.infer<typeof validSchemaZod>>({
resolver: zodResolver(validSchemaZod),
defaultValues: {
...validatedData,
},
});
function submitUpdate(formData: FormData) {
let newFormData: any = {};
Object.entries(Object.fromEntries(formData)).forEach(([key, value]) => {
if (apiValidation[key].fieldType === "integer") {
const newNumber = typeof value === "string" ? 0 : Number(value);
newFormData[key] = newNumber;
} else {
newFormData[key] = value;
}
});
const validated = validSchemaZod.safeParse(newFormData);
console.log("validated", validated);
console.log("validated", validated.error);
}
return (
<>
{
<div>
<Form {...form}>
<form
action={submitUpdate}
// onSubmit={form.handleSubmit(submitUpdate)}
className="space-y-5 max-w-3xl mx-auto py-10"
>
<div className=" absolute w-[80px] right-20 bg-emerald-700">
<span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="lucide lucide-check"
>
<path d="M20 6 9 17l-5-5" />
</svg>
</span>
<input
type="submit"
value="Kaydet"
className="w-full cursor-pointer rounded-lg border p-4 text-white transition hover:bg-opacity-90"
/>
</div>
{Object.keys(zodValidation).map((key: string) => {
if (apiValidation[key]?.fieldType === "string") {
return (
<div className="mb-4" key={`${key}-header`}>
<label className="mb-2.5 block font-medium text-black dark:text-white">
{apiHeaders[key]}
</label>
<div className="relative" key={key}>
<FormField
control={form.control}
name={key as keyof z.infer<typeof zodValidation>}
render={({ field }) => (
<FormItem>
<FormControl>
<input
type="text"
className="w-full rounded-lg border border-stroke bg-transparent py-4 pl-6 pr-10 text-black outline-none focus:border-primary focus-visible:shadow-none dark:border-form-strokedark dark:bg-form-input dark:text-white dark:focus:border-primary"
{...field}
value={field.value}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<span className="absolute right-4 top-4">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="lucide lucide-pencil"
>
<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" />
<path d="m15 5 4 4" />
</svg>
</span>
</div>
</div>
);
} else if (apiValidation[key]?.fieldType === "integer") {
return (
<div className="mb-4" key={`${key}-header`}>
<label className="mb-2.5 block font-medium text-black dark:text-white">
{apiHeaders[key]}
</label>
<div className="relative" key={key}>
<FormField
control={form.control}
name={key as keyof z.infer<typeof zodValidation>}
render={({ field }) => (
<FormItem>
<FormControl>
<input
type="number"
className="w-full rounded-lg border border-stroke bg-transparent py-4 pl-6 pr-10 text-black outline-none focus:border-primary focus-visible:shadow-none dark:border-form-strokedark dark:bg-form-input dark:text-white dark:focus:border-primary"
{...field}
value={field.value || ""}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<span className="absolute right-4 top-4">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="lucide lucide-pencil"
>
<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" />
<path d="m15 5 4 4" />
</svg>
</span>
</div>
</div>
);
}
})}
</form>
</Form>
</div>
}
</>
);
};
export default FormPage;

View File

@ -103,7 +103,10 @@ const CreatePage: React.FC<CreatePageProps> = ({
</div> </div>
{ {
<Form {...form}> <Form {...form}>
<form className="space-y-5 max-w-3xl mx-auto py-10"> <form
onSubmit={form.handleSubmit()}
className="space-y-5 max-w-3xl mx-auto py-10"
>
{Object.keys(apiValidation).map((key: string) => { {Object.keys(apiValidation).map((key: string) => {
const keyValidation = apiValidation[key] || { const keyValidation = apiValidation[key] || {
fieldType: { type: "string" }, fieldType: { type: "string" },

View File

@ -1,19 +1,10 @@
import React, { FormEvent } from "react"; "use client";
import IsNotAllowed from "./PageisNotAllowed"; import React from "react";
import EventButton from "./ButtonEvent"; import EventButton from "./ButtonEvent";
import { import FormPage from "./FormPage";
Form,
FormControl, import * as z from "zod";
FormDescription, import { retrieveValidationsByEndpointWithData } from "../functions/retrieveEndpointAndValidations";
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { retrieveValidationsByEndpoint } from "../functions/retrieveEndpointAndValidations";
interface UpdatePageButtonProps { interface UpdatePageButtonProps {
endpoint: string; endpoint: string;
@ -31,7 +22,7 @@ const PageUpdate: React.FC<UpdatePageButtonProps> = ({
saveFunction, saveFunction,
}) => { }) => {
const [validatedData, setValidatedData] = React.useState({}); const [validatedData, setValidatedData] = React.useState({});
const [zodValidation, setZodValidation] = React.useState(z.object({})); const [zodValidation, setZodValidation] = React.useState(null);
const [apiValidation, setApiValidation] = React.useState<{ const [apiValidation, setApiValidation] = React.useState<{
[key: string]: any; [key: string]: any;
}>({}); }>({});
@ -39,48 +30,19 @@ const PageUpdate: React.FC<UpdatePageButtonProps> = ({
[key: string]: any; [key: string]: any;
}>({}); }>({});
React.useEffect(() => {
retrieveValidationsByEndpoint(endpoint).then((validations: any) => {
setZodValidation(validations.zodValidation as any);
setApiHeaders(validations.apiValidation?.headers as Object);
setApiValidation(validations.apiValidation?.validated as Object);
});
}, []);
React.useEffect(() => { React.useEffect(() => {
if (Object.keys(validatedData).length === 0) { if (Object.keys(validatedData).length === 0) {
setValidatedData(selectedRow); retrieveValidationsByEndpointWithData(endpoint, selectedRow).then(
let zodValidationInternal: any = {}; (validations: any) => {
setValidatedData(selectedRow);
Object.keys(selectedRow).map((key: string) => { setZodValidation(validations.zodValidation);
zodValidationInternal[key] = null; setApiValidation(validations.apiValidation?.validated);
const keyValidation = apiValidation[key] || { setApiHeaders(validations.apiValidation?.headers);
fieldType: { type: "string" },
required: false,
};
const fieldType: String = keyValidation.fieldType?.type || "string";
const required = keyValidation.required || false;
if (fieldType === "string") {
zodValidationInternal[key] = required
? z.string()
: z.string().optional();
} else if (fieldType === "integer") {
zodValidationInternal[key] = required
? z.number()
: z.number().optional();
} }
}); );
setZodValidation(zodValidationInternal);
} }
}, []); }, []);
const form = useForm<z.infer<typeof zodValidation>>({
resolver: zodResolver(zodValidation),
});
// function onSubmit(values: z.infer<typeof zodValidation>) {
function onSubmit() {}
return ( return (
<> <>
<h1 className="text-center text-3xl">{pageInfo?.title}</h1> <h1 className="text-center text-3xl">{pageInfo?.title}</h1>
@ -108,137 +70,15 @@ const PageUpdate: React.FC<UpdatePageButtonProps> = ({
</svg> </svg>
} }
/> />
<div className="absolute right-0">
<EventButton
onClick={() => onSubmit()}
label="Kaydet"
bgColor="bg-emerald-700"
icon={
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="lucide lucide-check"
>
<path d="M20 6 9 17l-5-5" />
</svg>
}
/>
</div>
</div>
<div>
<Form {...form}>
<form
// onSubmit={onSubmit}
className="space-y-5 max-w-3xl mx-auto py-10"
>
{Object.keys(apiValidation).map((key: string) => {
const keyValidation = apiValidation[key] || {
fieldType: { type: "string" },
required: false,
};
const fieldType = keyValidation.fieldType?.type || "string";
if (fieldType === "string" && apiValidation[key]) {
return (
<div className="mb-4" key={`${key}-header`}>
<label className="mb-2.5 block font-medium text-black dark:text-white">
{apiHeaders[key]}
</label>
<div className="relative" key={key}>
<FormField
control={form.control}
name={key as keyof z.infer<typeof zodValidation>}
render={({ field }) => (
<FormItem>
<FormControl>
<input
type="text"
className="w-full rounded-lg border border-stroke bg-transparent py-4 pl-6 pr-10 text-black outline-none focus:border-primary focus-visible:shadow-none dark:border-form-strokedark dark:bg-form-input dark:text-white dark:focus:border-primary"
{...field}
defaultValue={validatedData[key] || ""}
value={field.value}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<span className="absolute right-4 top-4">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="lucide lucide-pencil"
>
<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" />
<path d="m15 5 4 4" />
</svg>
</span>
</div>
</div>
);
} else if (fieldType === "integer" && apiValidation[key]) {
return (
<div className="mb-4" key={`${key}-header`}>
<label className="mb-2.5 block font-medium text-black dark:text-white">
{apiHeaders[key]}
</label>
<div className="relative" key={key}>
<FormField
control={form.control}
name={key as keyof z.infer<typeof zodValidation>}
render={({ field }) => (
<FormItem>
<FormControl>
<input
type="text"
className="w-full rounded-lg border border-stroke bg-transparent py-4 pl-6 pr-10 text-black outline-none focus:border-primary focus-visible:shadow-none dark:border-form-strokedark dark:bg-form-input dark:text-white dark:focus:border-primary"
{...field}
defaultValue={validatedData[key] || ""}
value={field.value}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<span className="absolute right-4 top-4">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="lucide lucide-pencil"
>
<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" />
<path d="m15 5 4 4" />
</svg>
</span>
</div>
</div>
);
}
})}
</form>
</Form>
</div> </div>
{zodValidation && apiValidation && (
<FormPage
validatedData={selectedRow}
zodValidation={zodValidation}
apiValidation={apiValidation}
apiHeaders={apiHeaders}
/>
)}
</> </>
); );
}; };

View File

@ -18,6 +18,7 @@ interface TableProps {
createEndpoint: string; createEndpoint: string;
updateEndpoint: string; updateEndpoint: string;
tableFunction: any; tableFunction: any;
saveFunction: any;
UpdatePage: any; UpdatePage: any;
setFormPage: any; setFormPage: any;
updatePageInfo: any; updatePageInfo: any;
@ -32,6 +33,7 @@ const Table: React.FC<TableProps> = ({
createEndpoint, createEndpoint,
updateEndpoint, updateEndpoint,
tableFunction, tableFunction,
saveFunction,
UpdatePage, UpdatePage,
setFormPage, setFormPage,
updatePageInfo, updatePageInfo,
@ -57,12 +59,7 @@ const Table: React.FC<TableProps> = ({
React.useEffect(() => { React.useEffect(() => {
retrieveHeadersByEndpoint(createEndpoint).then((validations: any) => { retrieveHeadersByEndpoint(createEndpoint).then((validations: any) => {
if (validations?.headers.length !== 0) { if (validations?.headers.length !== 0) {
tableFunction({ tableFunction({})
page: 1,
limit: 10,
order_field: "uu_id",
order_type: "desc",
})
.then((response: any) => { .then((response: any) => {
settabledata(response?.data || []); settabledata(response?.data || []);
for (const key in response?.data[0]) { for (const key in response?.data[0]) {
@ -90,7 +87,7 @@ const Table: React.FC<TableProps> = ({
cleanSearch(); cleanSearch();
} else { } else {
if (searchText.length > 3) { if (searchText.length > 3) {
setQuery({ searchDropDown: searchText }); // setQuery({ searchDropDown: searchText });
retrieveData(); retrieveData();
} }
} }
@ -103,7 +100,7 @@ const Table: React.FC<TableProps> = ({
pageInfo={updatePageInfo} pageInfo={updatePageInfo}
selectedRow={selectedComponent} selectedRow={selectedComponent}
returnToPage={returnToPage} returnToPage={returnToPage}
saveFunction={() => console.log("saveFunction")} saveFunction={saveFunction}
/> />
); );
} }

View File

@ -1,5 +1,5 @@
"use client"; "use client";
import { z } from "zod"; import * as z from "zod";
import { import {
retrieveHeadersAndValidationByEndpoint, retrieveHeadersAndValidationByEndpoint,
retrieveHeadersEndpoint, retrieveHeadersEndpoint,
@ -8,25 +8,101 @@ import {
async function retrieveValidationsByEndpoint(endpoint: string) { async function retrieveValidationsByEndpoint(endpoint: string) {
let apiValidation: any = {}; let apiValidation: any = {};
let zodValidation: any = {}; let zodValidation: any = {};
let zodSchema: any = {};
await retrieveHeadersAndValidationByEndpoint({ await retrieveHeadersAndValidationByEndpoint({
endpoint: endpoint, endpoint: endpoint,
}) })
.then((validator) => { .then((validator) => {
if (JSON.stringify(validator?.validated) !== "{}") { const apiValidated = validator?.validated || {};
if (JSON.stringify(apiValidated) !== "{}") {
apiValidation = validator; apiValidation = validator;
Object.keys(validator?.validated).map((key: string) => { Object.keys(apiValidated).map((key: string) => {
zodValidation[key] = null; const fieldType: String = apiValidated[key].fieldType || "string";
const keyValidation = validator?.validated[key] || { const required = apiValidated[key].required || false;
fieldType: { type: "string" },
required: false,
};
const fieldType: String = keyValidation.fieldType?.type || "string";
const required = keyValidation.required || false;
if (fieldType === "string") { if (fieldType === "string") {
zodValidation[key] = required ? z.string() : z.string().optional(); zodValidation[key] = required
? z
.string()
.min(1)
.refine((val) => val !== "" || val !== null)
: z
.string()
.min(1)
.optional()
.refine((val) => val !== "" || val !== null);
} else if (fieldType === "integer") { } else if (fieldType === "integer") {
zodValidation[key] = required ? z.number() : z.number().optional(); zodValidation[key] = required
? z
.number()
.min(1)
.transform((val) =>
Number(val) !== 0 || val !== null ? Number(val) : null
)
: z
.number()
.min(1)
.optional()
.transform((val) =>
Number(val) !== 0 || val !== null ? Number(val) : null
);
}
});
const validSchemaZod = z.object({
...zodValidation,
});
return {
zodValidation: validSchemaZod,
apiValidation: apiValidation,
zodSchema: zodValidation,
};
}
})
.catch(() => {});
return {
zodValidation: zodValidation,
apiValidation: apiValidation,
zodSchema: zodSchema,
};
}
async function retrieveValidationsByEndpointWithData(
endpoint: string,
data: any
) {
let apiValidation: any = {};
let zodValidation: any = {};
await retrieveHeadersAndValidationByEndpoint({
endpoint: endpoint,
})
.then((validator) => {
const apiValidated = validator?.validated || {};
if (JSON.stringify(apiValidated) !== "{}") {
apiValidation = validator;
Object.keys(apiValidated).map((key: string) => {
if (Object.keys(data).includes(key)) {
const fieldType: String = apiValidated[key].fieldType || "string";
const required = apiValidated[key].required || false;
if (fieldType === "string") {
zodValidation[key] = required
? z
.string()
.min(1)
.refine((val) => val !== "" || val !== null)
: z
.string()
.min(1)
.optional()
.refine((val) => val !== "" || val !== null);
} else if (fieldType === "integer") {
zodValidation[key] = required
? z.number().transform((val) => Number(val))
: z
.number()
.optional()
.transform((val) => Number(val));
}
} }
}); });
return { return {
@ -35,7 +111,9 @@ async function retrieveValidationsByEndpoint(endpoint: string) {
}; };
} }
}) })
.catch(() => {}); .catch((error) => {
console.log("error", error);
});
return { return {
zodValidation: zodValidation, zodValidation: zodValidation,
apiValidation: apiValidation, apiValidation: apiValidation,
@ -62,4 +140,8 @@ async function retrieveHeadersByEndpoint(endpoint: string) {
}; };
} }
export { retrieveValidationsByEndpoint, retrieveHeadersByEndpoint }; export {
retrieveValidationsByEndpoint,
retrieveHeadersByEndpoint,
retrieveValidationsByEndpointWithData,
};

View File

@ -1,6 +1,6 @@
import * as React from "react" import * as React from "react";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>( const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
({ className, type, ...props }, ref) => { ({ className, type, ...props }, ref) => {
@ -8,15 +8,15 @@ const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
<input <input
type={type} type={type}
className={cn( className={cn(
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", "flex h-14 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className className
)} )}
ref={ref} ref={ref}
{...props} {...props}
/> />
) );
} }
) );
Input.displayName = "Input" Input.displayName = "Input";
export { Input } export { Input };