updated docs

This commit is contained in:
2025-05-13 18:45:23 +03:00
parent 6dfa17c5e6
commit 3627412fe9
247 changed files with 30258 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
'use client';
import React, { useState, useEffect } from "react";
import { apiPostFetcher } from "@/lib/fetcher";
import { ApiPaginationRequestWithQuery } from "@/validations/mutual/api/requests/validations";
import { TableComponentProps } from "@/validations/mutual/table/type";
import ComponentTable from "../mutual/TableCardPlain";
import PaginationComponent from "../mutual/UpperPagination";
import LowerPagination from "../mutual/LowerPagination";
const TableCardComponent: React.FC<TableComponentProps> = ({
urls,
schemas,
translations,
columns,
initPagination,
}) => {
const defaultPagination = {
page: initPagination?.page || 1,
size: initPagination?.size || 10,
orderFields: initPagination?.orderFields || [],
orderTypes: initPagination?.orderTypes || [],
query: initPagination?.query || {},
}
const [data, setData] = useState<any>(null);
const [pagination, setPagination] = useState<ApiPaginationRequestWithQuery>(defaultPagination);
const [apiPagination, setApiPagination] = useState<any>({
onPage: 1,
onPageCount: 10,
totalPage: 1,
totalCount: 1,
next: false,
back: false,
});
const handleBack = async () => {
setPagination({ ...pagination, page: pagination.page > 1 ? pagination.page - 1 : pagination.page });
await fetchData();
}
const handleNext = async () => {
setPagination({ ...pagination, page: pagination.page < apiPagination.totalPage ? pagination.page + 1 : pagination.page });
await fetchData();
}
const fetchData = async () => {
const response = await apiPostFetcher({
url: urls.list,
isNoCache: true,
body: {
page: pagination.page,
size: pagination.size,
orderFields: pagination.orderFields,
orderTypes: pagination.orderTypes,
query: pagination.query,
},
});
if (response && response.data) {
setData(response.data.data);
if (response.data.pagination) {
setApiPagination(response.data.pagination);
}
}
};
useEffect(() => { fetchData() }, [pagination.page, pagination.size, pagination.orderFields, pagination.orderTypes]);
const upperPaginationProps = {
apiPagination,
pagination,
setPagination,
defaultPagination,
}
const lowerPaginationProps = {
pagination: apiPagination,
handleBack,
handleNext,
}
const tableProps = {
data,
columns,
translations,
}
return (
<div>
<div className="flex flex-col items-center justify-start my-6"><PaginationComponent {...upperPaginationProps} /></div>
<div className="flex flex-col items-center justify-start my-6"><LowerPagination {...lowerPaginationProps} /></div>
<div className="flex flex-col items-center justify-start my-6"><h1>Post Data Page</h1><ComponentTable {...tableProps} /></div>
</div>
);
}
export default TableCardComponent;

View File

@@ -0,0 +1,104 @@
'use client';
import React, { useState, useEffect } from "react";
import ComponentTable from "@/components/mutual/tableView/mutual/TablePlain";
import PaginationComponent from "@/components/mutual/tableView/mutual/UpperPagination";
import LowerPagination from "@/components/mutual/tableView/mutual/LowerPagination";
import { apiPostFetcher } from "@/lib/fetcher";
import { ApiPaginationRequestWithQuery } from "@/validations/mutual/api/requests/validations";
import { TableComponentProps } from "@/validations/mutual/table/type";
const TableComponent: React.FC<TableComponentProps> = ({
urls,
schemas,
translations,
columns,
initPagination,
redirectUrls,
setSelectedRow,
}) => {
const defaultPagination = {
page: initPagination?.page || 1,
size: initPagination?.size || 10,
orderFields: initPagination?.orderFields || [],
orderTypes: initPagination?.orderTypes || [],
query: initPagination?.query || {},
}
const [tableData, setTableData] = useState<any>(null);
const [orgTableData, setOrgTableData] = useState<any>(null);
const [tableColumns, setTableColumns] = useState<string[]>([]);
const [pagination, setPagination] = useState<ApiPaginationRequestWithQuery>(defaultPagination);
const [apiPagination, setApiPagination] = useState<any>({
onPage: 1,
onPageCount: 10,
totalPage: 1,
totalCount: 1,
next: false,
back: false,
});
const handleBack = async () => {
setPagination({ ...pagination, page: pagination.page > 1 ? pagination.page - 1 : pagination.page });
await fetchData();
}
const handleNext = async () => {
setPagination({ ...pagination, page: pagination.page < apiPagination.totalPage ? pagination.page + 1 : pagination.page });
await fetchData();
}
const fetchData = async () => {
const response = await apiPostFetcher({
url: urls.list,
isNoCache: true,
body: {
page: pagination.page,
size: pagination.size,
orderFields: pagination.orderFields,
orderTypes: pagination.orderTypes,
query: pagination.query,
},
});
if (response && response.data) {
const oldData = response.data.data
setOrgTableData(oldData)
if (schemas.table) {
const newData = Object.entries(oldData).map(([key]) => {
return schemas.table.safeParse(oldData[key as keyof typeof oldData]).data
})
setTableData(newData)
setTableColumns(columns.table)
}
if (response.data.pagination) {
setApiPagination(response.data.pagination);
}
}
};
useEffect(() => { fetchData() }, [pagination.page, pagination.size, pagination.orderFields, pagination.orderTypes]);
const upperPaginationProps = {
apiPagination,
pagination,
setPagination,
defaultPagination,
}
const lowerPaginationProps = {
pagination: apiPagination,
handleBack,
handleNext,
}
const tableProps = {
data: tableData,
orgData: orgTableData,
columns: tableColumns,
translations,
redirectUrls,
setSelectedRow,
}
return (
<div>
<div className="flex flex-col items-center justify-start my-6"><PaginationComponent {...upperPaginationProps} /></div>
<div className="flex flex-col items-center justify-start my-6"><LowerPagination {...lowerPaginationProps} /></div>
<div className="flex flex-col items-center justify-start my-6"><ComponentTable {...tableProps} /></div>
</div>
);
}
export default TableComponent;

View File

@@ -0,0 +1,40 @@
import React from "react";
import { CreateFormProps } from "@/validations/mutual/forms/type";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Form } from "@/components/mutual/shadcnui/form";
import { renderInputsBySchema } from "@/lib/renderInputs";
import { Button } from "@/components/mutual/shadcnui/button";
const CreateForm: React.FC<CreateFormProps> = ({ schemas, labels, selectedRow }) => {
const createSchema = schemas.create
const findLabels = Object.entries(createSchema?.shape || {}).reduce((acc: any, [key, value]: any) => {
acc[key] = {
label: labels[key] || key,
description: value.description,
}
return acc
}, {})
const handleSubmit = (data: any) => {
console.log(data)
}
const form = useForm<FormData>({
resolver: zodResolver(createSchema),
defaultValues: {},
});
return (
<div>
<div>Create Form</div>
<Form {...form}>
<form onSubmit={form.handleSubmit(handleSubmit)} className="space-y-4">
{renderInputsBySchema(findLabels, form)}
<Button type="submit">Submit</Button>
</form>
</Form>
<div>selectedRow: {JSON.stringify(selectedRow)}</div>
</div>
)
}
export default CreateForm

View File

@@ -0,0 +1,24 @@
'use client'
import { Button } from "@/components/mutual/shadcnui/button";
import { LowerPaginationProps } from "@/validations/mutual/pagination/type";
const LowerPagination: React.FC<LowerPaginationProps> = ({
pagination,
handleBack,
handleNext,
}) => {
const paginationBackComponent = pagination.back ? (
<Button className="w-60" onClick={() => handleBack()}>Back</Button>
) : <></>;
const paginationNextComponent = pagination.next ? (
<Button className="w-60" onClick={() => handleNext()}>Next</Button>
) : <></>;
return (
<div className="flex items-center justify-center gap-2 bg-amber-300 p-6 w-full">
{paginationBackComponent}
{paginationNextComponent}
</div>
)
}
export default LowerPagination

View File

@@ -0,0 +1,34 @@
import { Input } from "@/components/mutual/shadcnui/input";
import { Label } from "@/components/mutual/shadcnui/label";
import { PaginationDetailsProps } from "@/validations/mutual/pagination/type";
const PaginationDetails: React.FC<PaginationDetailsProps> = ({
pagination,
setPagination,
defaultPagination,
}) => {
return (
<div className="grid grid-cols-6 gap-2 items-center justify-evenly">
<Label>Page Size</Label>
<Input
type="number"
value={pagination.size}
onChange={(e) => setPagination({ ...defaultPagination, size: Number(e.target.value) })}
/>
<Label>Order Field</Label>
<Input
type="text"
value={pagination.orderFields.join(",")}
onChange={(e) => setPagination({ ...defaultPagination, orderFields: e.target.value.split(",") })}
/>
<Label>Order Type</Label>
<Input
type="text"
value={pagination.orderTypes.join(",")}
onChange={(e) => setPagination({ ...pagination, orderType: e.target.value.split(",") })}
/>
</div>
)
}
export default PaginationDetails

View File

@@ -0,0 +1,15 @@
import { PaginationShowProps } from "@/validations/mutual/pagination/type"
const PaginationShow: React.FC<PaginationShowProps> = ({ apiPagination }) => {
return (
<div className="grid grid-cols-6 gap-2 items-center justify-evenly">
<p>Page: {apiPagination.onPage}</p>
<p>Page Count: {apiPagination.onPageCount}</p>
<p>Total Page: {apiPagination.totalPage}</p>
<p>Total Count: {apiPagination.totalCount}</p>
<p>Next: {apiPagination.next ? "true" : "false"}</p>
<p>Back: {apiPagination.back ? "true" : "false"}</p>
</div>
)
}
export default PaginationShow

View File

@@ -0,0 +1,24 @@
import { Label } from "@/components/mutual/shadcnui/label";
import { Textarea } from "@/components/mutual/shadcnui/textarea";
import { SearchProps } from "@/validations/mutual/table/type";
const SearchBarComponent: React.FC<SearchProps> = ({ pagination, setPagination }) => {
const handleSearch = (query: string) => {
setTimeout(() => {
setPagination({ ...pagination, query: {} })
}, 2000)
}
return (
<div>
<div className="grid grid-cols-1 w-full px-10 py-2">
<Label>Search</Label>
<Textarea
value={JSON.stringify(pagination.query, null, 2)}
onChange={(e) => handleSearch(e.target.value)}
/>
</div>
</div>
)
}
export default SearchBarComponent

View File

@@ -0,0 +1,47 @@
'use client'
import { Card, CardHeader, CardContent, CardTitle, CardDescription } from "@/components/mutual/shadcnui/card";
import { TableCardProps } from "@/validations/mutual/table/type";
import { useEffect, useState } from "react";
const ComponentTableCardPlain: React.FC<TableCardProps> = ({ data, columns, translations }) => {
const [tableData, setTableData] = useState<any>(data);
useEffect(() => {
setTableData(data);
}, [data]);
const renderCards = () => {
return tableData?.map((item: any, index: number) => (
<Card className="w-full min-w-full my-2 p-5" key={index}>
<CardHeader>
<CardTitle>Row : {index + 1}</CardTitle>
<CardDescription>{item.uuid}</CardDescription>
</CardHeader>
<CardContent>
<div className="flex flex-col items-start justify-start">Email: {item.email}</div>
<div className="flex flex-col items-start justify-start">Phone Number: {item.phoneNumber}</div>
<div>Created At: {item.createdAt}</div>
</CardContent>
</Card>
))
}
const noDataFound = () => (
<>
No Data Found
</>
)
return (
<>
{
tableData ? (
<div className="w-full min-w-full">
<div className="flex flex-col items-center justify-start my-6">{renderCards()}</div>
</div>
) : (noDataFound())
}
</>
)
}
export default ComponentTableCardPlain

View File

@@ -0,0 +1,60 @@
'use client'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/mutual/shadcnui/table";
import { useEffect, useState } from "react";
import { TableProps } from "@/validations/mutual/table/type";
const ComponentTablePlain: React.FC<TableProps> = ({
data, orgData, columns, translations, redirectUrls, setSelectedRow
}) => {
const [tableData, setTableData] = useState<any>(data);
useEffect(() => {
setTableData(data);
}, [data]);
const renderColumns = () => {
return [translations?.rows, ...columns].map((column, index) => {
return (
<TableHead key={`headers-${index}`}>{column}</TableHead>
)
})
}
const renderRows = () => (
<>{tableData?.map((item: any, index: number) => {
return (
<TableRow key={`${index}-row`} >
<TableCell>{index + 1}</TableCell>
{
Object.entries(item).map(([key, value]: [string, any]) => (
<TableCell key={`${index}-column-${key}`}>{value}</TableCell>
))
}
{
Object.values(redirectUrls?.table || {}).map((redirectUrl: any, index: number) => {
return (
<TableCell className="cursor-pointer w-4" key={`${index}-action-${index}`}
onClick={() => setSelectedRow?.(orgData[index])}>{redirectUrl}</TableCell>
)
})
}
</TableRow>
)
})}</>
)
const noDataFound = (<>No Data Found</>)
const renderTable = (
<Table><TableHeader><TableRow>{renderColumns()}</TableRow></TableHeader><TableBody>{renderRows()}</TableBody></Table>
)
return (
<>
<div className="flex flex-row justify-between gap-2">
{Object.values(redirectUrls?.page || {}).map((action, index) => (
<div className="flex flex-row justify-center items-center gap-2" key={`page-action-${index}`}>{action}</div>
))}
</div>
{tableData ? renderTable : noDataFound}
</>
)
}
export default ComponentTablePlain

View File

@@ -0,0 +1,46 @@
'use client'
import React, { useEffect } from "react";
import { useRouter } from "next/navigation";
import { UpdateFormProps } from "@/validations/mutual/forms/type";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Form } from "@/components/mutual/shadcnui/form";
import { renderInputsBySchema } from "@/lib/renderInputs";
import { Button } from "@/components/mutual/shadcnui/button";
const UpdateForm: React.FC<UpdateFormProps> = ({ schemas, selectedRow, rollbackTo, labels }) => {
const router = useRouter()
useEffect(() => {
if (!selectedRow) {
router.push(rollbackTo, { scroll: false })
}
}, [selectedRow])
const updateSchema = schemas.update
const findLabels = Object.entries(updateSchema?.shape || {}).reduce((acc: any, [key, value]: any) => {
acc[key] = {
label: labels[key] || key,
description: value.description,
}
return acc
}, {})
const handleSubmit = (data: any) => {
console.log(data)
}
const form = useForm<FormData>({
resolver: zodResolver(updateSchema),
defaultValues: selectedRow,
});
return (
<div>
<div>Update Form</div>
<Form {...form}>
<form onSubmit={form.handleSubmit(handleSubmit)} className="space-y-4">
{selectedRow && renderInputsBySchema(findLabels, form)}
{selectedRow && <Button type="submit">Submit</Button>}
</form>
</Form>
</div>
)
}
export default UpdateForm

View File

@@ -0,0 +1,21 @@
import { PaginationProps } from "@/validations/mutual/pagination/type";
import PaginationDetails from "./PaginationDetails";
import PaginationShow from "./PaginationShow";
import SearchBarComponent from "./Search";
const PaginationComponent: React.FC<PaginationProps> = ({
apiPagination,
pagination,
setPagination,
defaultPagination,
}) => {
return (
<>
<PaginationDetails pagination={pagination} setPagination={setPagination} defaultPagination={defaultPagination} />
<SearchBarComponent pagination={pagination} setPagination={setPagination} />
<PaginationShow apiPagination={apiPagination} />
</ >
)
}
export default PaginationComponent

View File

@@ -0,0 +1,30 @@
'use client'
import React, { useEffect } from "react";
import { useRouter } from "next/navigation";
import { ViewFormProps } from "@/validations/mutual/forms/type";
import { renderInputsBySchemaView } from "@/lib/renderInputs";
const ViewForm: React.FC<ViewFormProps> = ({ schemas, selectedRow, rollbackTo, labels }) => {
const router = useRouter()
useEffect(() => {
if (!selectedRow) {
router.push(rollbackTo, { scroll: false })
}
}, [selectedRow])
const viewSchema = schemas.view
const findLabels = Object.entries(viewSchema?.shape || {}).reduce((acc: any, [key, value]: any) => {
acc[key] = {
label: labels[key] || key,
description: value.description,
}
return acc
}, {})
return (
<div>
<div>View Form</div>
{selectedRow && renderInputsBySchemaView(findLabels, selectedRow)}
</div>
)
}
export default ViewForm