fix
This commit is contained in:
parent
ab80962b47
commit
a721b6284f
|
|
@ -1,76 +0,0 @@
|
||||||
import { useLocal } from "@/utils/use-local";
|
|
||||||
import { FC, useEffect } from "react";
|
|
||||||
import { icon } from "../icon";
|
|
||||||
|
|
||||||
type TableProps = {
|
|
||||||
map_val: Array<{ name: string }>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Table: FC<TableProps> = (_args) => {
|
|
||||||
const { map_val } = _args;
|
|
||||||
|
|
||||||
const local = useLocal({
|
|
||||||
list: [
|
|
||||||
{
|
|
||||||
name: "test1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "test2",
|
|
||||||
},
|
|
||||||
] as { name: string }[],
|
|
||||||
status: "init" as "init" | "loading" | "ready",
|
|
||||||
});
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// (async () => {
|
|
||||||
// if (local.status === "init") {
|
|
||||||
// local.status = "loading";
|
|
||||||
// local.render();
|
|
||||||
|
|
||||||
// local.list = await map_val;
|
|
||||||
// local.render();
|
|
||||||
|
|
||||||
// local.status = "ready";
|
|
||||||
// local.render();
|
|
||||||
// }
|
|
||||||
// })();
|
|
||||||
// }, [map_val]);
|
|
||||||
|
|
||||||
console.log(local.list, "tes");
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="c-overflow-x-auto c-w-full">
|
|
||||||
<table className="c-table-auto c-w-full c-border-collapse c-rounded-lg c-border c-border-gray-300">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th className="c-px-4 c-py-2 c-text-center">Nomor</th>
|
|
||||||
<th className="c-px-4 c-py-2 c-text-center">Header 1</th>
|
|
||||||
<th className="c-px-4 c-py-2 c-text-center">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{!!local.list &&
|
|
||||||
local.list.map((item, index) => (
|
|
||||||
<tr
|
|
||||||
key={index}
|
|
||||||
className={index % 2 === 0 ? "c-bg-gray-100" : ""}
|
|
||||||
>
|
|
||||||
<td className="c-border c-px-4 c-py-2 c-text-center">
|
|
||||||
{index + 1}
|
|
||||||
</td>
|
|
||||||
<td className="c-border c-px-4 c-py-2">{item.name}</td>
|
|
||||||
<td className="c-border c-px-4 c-py-2 c-flex c-flex-col c-justify-center c-items-center c-space-y-2">
|
|
||||||
<button className="c-w-[50px] c-rounded c-flex c-justify-center c-bg-blue-300">
|
|
||||||
<span className="c-p-2">{icon.update}</span>
|
|
||||||
</button>
|
|
||||||
<button className="c-w-[50px] c-rounded c-flex c-justify-center c-bg-red-300">
|
|
||||||
<span className="c-p-2">{icon.delete}</span>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
import { useLocal } from "@/utils/use-local";
|
||||||
|
import { FC, ReactNode, useEffect } from "react";
|
||||||
|
import { icon } from "../icon";
|
||||||
|
import { Skeleton } from "../ui/skeleton";
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCaption,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from "@/comps/ui/table";
|
||||||
|
|
||||||
|
type TableListProps = {
|
||||||
|
mapping: () => Promise<Column[]>;
|
||||||
|
on_load: () => Promise<any[]>;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Column = {
|
||||||
|
name: string;
|
||||||
|
title?: string;
|
||||||
|
jsx?: ReactNode;
|
||||||
|
type?: "number" | "default";
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TableList: FC<TableListProps> = (_args) => {
|
||||||
|
const { mapping, on_load } = _args;
|
||||||
|
|
||||||
|
const local = useLocal({
|
||||||
|
columns: [] as Column[],
|
||||||
|
list: [] as Record<string, any>[],
|
||||||
|
status: "init" as "init" | "loading" | "ready",
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
if (local.status === "init") {
|
||||||
|
local.status = "loading";
|
||||||
|
local.render();
|
||||||
|
|
||||||
|
local.columns = await mapping();
|
||||||
|
local.list = await on_load();
|
||||||
|
local.render();
|
||||||
|
|
||||||
|
local.status = "ready";
|
||||||
|
local.render();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, [mapping]);
|
||||||
|
|
||||||
|
console.log(local.columns, local.list, "s");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="c-overflow-x-auto c-w-full">
|
||||||
|
{local.status !== "ready" ? (
|
||||||
|
<Skeleton className="c-h-4 c-w-[80%]" />
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Table>
|
||||||
|
{/* /** ini header */}
|
||||||
|
{!!local.columns && (
|
||||||
|
<TableHeader className="c-w-full">
|
||||||
|
<TableRow>
|
||||||
|
{local.columns.map((item: Column, index: number) => {
|
||||||
|
return (
|
||||||
|
<TableHead key={index} className="c-text-center">
|
||||||
|
{item.name}
|
||||||
|
</TableHead>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
)}
|
||||||
|
<TableBody>
|
||||||
|
{!!local.list &&
|
||||||
|
local.list.map((item, idx) => (
|
||||||
|
<TableRow key={idx} className="c-flex c-flex-col">
|
||||||
|
{local.columns.map((col, col_idx) => (
|
||||||
|
<TableCell
|
||||||
|
key={col_idx}
|
||||||
|
className="c-flex c-flex-col c-text-center"
|
||||||
|
>
|
||||||
|
{!!col.title
|
||||||
|
? col.title
|
||||||
|
: !!col.jsx
|
||||||
|
? col.jsx
|
||||||
|
: item[col.name]}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -35,11 +35,22 @@ export const Field: FC<{
|
||||||
| "datetime"
|
| "datetime"
|
||||||
| "money"
|
| "money"
|
||||||
| "slider"
|
| "slider"
|
||||||
| "master-linkF";
|
| "master-link";
|
||||||
required: "y" | "n";
|
required: "y" | "n";
|
||||||
options: () => Promise<{ value: string; label: string }[]>;
|
options: () => Promise<{ value: string; label: string }[]>;
|
||||||
slider_options: () => Promise<SliderOptions>;
|
slider: () => Promise<SliderOptions>;
|
||||||
}> = ({ name, form, desc, label, type, required, options, slider_options }) => {
|
on_change: (arg: { value: any }) => void | Promise<void>;
|
||||||
|
}> = ({
|
||||||
|
name,
|
||||||
|
form,
|
||||||
|
desc,
|
||||||
|
label,
|
||||||
|
type,
|
||||||
|
required,
|
||||||
|
options,
|
||||||
|
slider,
|
||||||
|
on_change,
|
||||||
|
}) => {
|
||||||
const value = form?.hook.getValues()[name];
|
const value = form?.hook.getValues()[name];
|
||||||
const local = useLocal({
|
const local = useLocal({
|
||||||
dropdown: {
|
dropdown: {
|
||||||
|
|
@ -71,12 +82,12 @@ export const Field: FC<{
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (type === "slider") {
|
if (type === "slider") {
|
||||||
local.slider.value = parseSliderValue(value, local.slider.opt);
|
local.slider.value = parseSliderValue(value, local.slider.opt);
|
||||||
if (typeof slider_options === "function") {
|
if (typeof slider === "function") {
|
||||||
if (local.slider.status === "init") {
|
if (local.slider.status === "init") {
|
||||||
local.slider.status = "ready";
|
local.slider.status = "ready";
|
||||||
local.render();
|
local.render();
|
||||||
(async () => {
|
(async () => {
|
||||||
const res = await slider_options();
|
const res = await slider();
|
||||||
|
|
||||||
local.slider.opt = res;
|
local.slider.opt = res;
|
||||||
local.render();
|
local.render();
|
||||||
|
|
@ -105,7 +116,7 @@ export const Field: FC<{
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<FormField
|
<FormField
|
||||||
control={form?.hook.control || {} as any}
|
control={form?.hook.control || ({} as any)}
|
||||||
name={name}
|
name={name}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="c-flex c-flex-1 c-flex-col">
|
<FormItem className="c-flex c-flex-1 c-flex-col">
|
||||||
|
|
@ -152,7 +163,18 @@ export const Field: FC<{
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{["text", "password"].includes(type) && (
|
{["text", "password"].includes(type) && (
|
||||||
<Input {...field} type={type} />
|
<Input
|
||||||
|
{...field}
|
||||||
|
type={type}
|
||||||
|
onChangeCapture={
|
||||||
|
typeof on_change === "function"
|
||||||
|
? (e) => {
|
||||||
|
console.log(e.currentTarget.value);
|
||||||
|
on_change({ value: e.currentTarget.value });
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{type === "textarea" && (
|
{type === "textarea" && (
|
||||||
|
|
|
||||||
|
|
@ -42,10 +42,16 @@ import {
|
||||||
Plus,
|
Plus,
|
||||||
Delete,
|
Delete,
|
||||||
Edit,
|
Edit,
|
||||||
|
BetweenHorizontalEnd,
|
||||||
|
BetweenHorizontalStart,
|
||||||
|
Outdent,
|
||||||
|
Indent,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
|
|
||||||
export const icon = {
|
export const icon = {
|
||||||
home: <Home />,
|
home: <Home />,
|
||||||
|
in: <Indent />,
|
||||||
|
out: <Outdent />,
|
||||||
dashboard: <LayoutDashboard />,
|
dashboard: <LayoutDashboard />,
|
||||||
dashboardSmall: <LayoutDashboard className={`c-w-4`} fill="currentColor" />,
|
dashboardSmall: <LayoutDashboard className={`c-w-4`} fill="currentColor" />,
|
||||||
dashboardSmallTransparent: <LayoutDashboard className={`c-w-4`} />,
|
dashboardSmallTransparent: <LayoutDashboard className={`c-w-4`} />,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,117 @@
|
||||||
|
import * as React from "react"
|
||||||
|
|
||||||
|
import { cn } from "@/utils"
|
||||||
|
|
||||||
|
const Table = React.forwardRef<
|
||||||
|
HTMLTableElement,
|
||||||
|
React.HTMLAttributes<HTMLTableElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div className="c-relative c-w-full c-overflow-auto">
|
||||||
|
<table
|
||||||
|
ref={ref}
|
||||||
|
className={cn("c-w-full c-caption-bottom c-text-sm", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
Table.displayName = "Table"
|
||||||
|
|
||||||
|
const TableHeader = React.forwardRef<
|
||||||
|
HTMLTableSectionElement,
|
||||||
|
React.HTMLAttributes<HTMLTableSectionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<thead ref={ref} className={cn("[&_tr]:c-border-b", className)} {...props} />
|
||||||
|
))
|
||||||
|
TableHeader.displayName = "TableHeader"
|
||||||
|
|
||||||
|
const TableBody = React.forwardRef<
|
||||||
|
HTMLTableSectionElement,
|
||||||
|
React.HTMLAttributes<HTMLTableSectionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<tbody
|
||||||
|
ref={ref}
|
||||||
|
className={cn("[&_tr:last-child]:c-border-0", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableBody.displayName = "TableBody"
|
||||||
|
|
||||||
|
const TableFooter = React.forwardRef<
|
||||||
|
HTMLTableSectionElement,
|
||||||
|
React.HTMLAttributes<HTMLTableSectionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<tfoot
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"c-border-t c-bg-muted/50 c-font-medium [&>tr]:last:c-border-b-0",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableFooter.displayName = "TableFooter"
|
||||||
|
|
||||||
|
const TableRow = React.forwardRef<
|
||||||
|
HTMLTableRowElement,
|
||||||
|
React.HTMLAttributes<HTMLTableRowElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<tr
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"c-border-b c-transition-colors hover:c-bg-muted/50 data-[state=selected]:c-bg-muted",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableRow.displayName = "TableRow"
|
||||||
|
|
||||||
|
const TableHead = React.forwardRef<
|
||||||
|
HTMLTableCellElement,
|
||||||
|
React.ThHTMLAttributes<HTMLTableCellElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<th
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"c-h-12 c-px-4 c-text-left c-align-middle c-font-medium c-text-muted-foreground [&:has([role=checkbox])]:c-pr-0",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableHead.displayName = "TableHead"
|
||||||
|
|
||||||
|
const TableCell = React.forwardRef<
|
||||||
|
HTMLTableCellElement,
|
||||||
|
React.TdHTMLAttributes<HTMLTableCellElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<td
|
||||||
|
ref={ref}
|
||||||
|
className={cn("c-p-4 c-align-middle [&:has([role=checkbox])]:c-pr-0", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableCell.displayName = "TableCell"
|
||||||
|
|
||||||
|
const TableCaption = React.forwardRef<
|
||||||
|
HTMLTableCaptionElement,
|
||||||
|
React.HTMLAttributes<HTMLTableCaptionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<caption
|
||||||
|
ref={ref}
|
||||||
|
className={cn("c-mt-4 c-text-sm c-text-muted-foreground", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableCaption.displayName = "TableCaption"
|
||||||
|
|
||||||
|
export {
|
||||||
|
Table,
|
||||||
|
TableHeader,
|
||||||
|
TableBody,
|
||||||
|
TableFooter,
|
||||||
|
TableHead,
|
||||||
|
TableRow,
|
||||||
|
TableCell,
|
||||||
|
TableCaption,
|
||||||
|
}
|
||||||
|
|
@ -12,4 +12,4 @@ export { Button, FloatButton } from "@/comps/ui/button";
|
||||||
export { getPathname } from "@/utils/pathname";
|
export { getPathname } from "@/utils/pathname";
|
||||||
export { Breadcrumb } from "./comps/custom/Breadcrumb";
|
export { Breadcrumb } from "./comps/custom/Breadcrumb";
|
||||||
export { Header } from "./comps/custom/Header";
|
export { Header } from "./comps/custom/Header";
|
||||||
export { Table } from "./comps/custom/Table";
|
export { TableList } from "./comps/custom/TableList";
|
||||||
Loading…
Reference in New Issue