update 7 files
This commit is contained in:
parent
65b84b16ca
commit
f98c4cd871
|
|
@ -154,7 +154,7 @@ export const Field: React.FC<any> = ({
|
||||||
css`
|
css`
|
||||||
height: 2.13rem;
|
height: 2.13rem;
|
||||||
`,
|
`,
|
||||||
is_disable ? "" : ""
|
is_disable ? "bg-gray-200/50 " : "bg-gray-200/50 "
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{before}
|
{before}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { useLocal } from "@/lib/utils/use-local";
|
import { useLocal } from "@/lib/utils/use-local";
|
||||||
import { AlertTriangle, Check, Loader2 } from "lucide-react";
|
import { AlertTriangle, Check, Loader2 } from "lucide-react";
|
||||||
import { ReactNode, useEffect, useState } from "react";
|
import { useEffect } from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import {
|
import {
|
||||||
ResizableHandle,
|
ResizableHandle,
|
||||||
|
|
@ -71,7 +71,7 @@ export const Form: React.FC<any> = ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}, 1000);
|
}, 100);
|
||||||
} catch (ex: any) {
|
} catch (ex: any) {
|
||||||
const msg = get(ex, "response.data.meta.message") || ex.message;
|
const msg = get(ex, "response.data.meta.message") || ex.message;
|
||||||
toast.error(
|
toast.error(
|
||||||
|
|
@ -117,22 +117,26 @@ export const Form: React.FC<any> = ({
|
||||||
);
|
);
|
||||||
local.data = null;
|
local.data = null;
|
||||||
local.render();
|
local.render();
|
||||||
const res = onLoad();
|
const res = await onLoad();
|
||||||
if (res instanceof Promise) {
|
|
||||||
res.then((data) => {
|
|
||||||
local.ready = true;
|
|
||||||
local.data = data;
|
|
||||||
local.render(); // Panggil render setelah data diperbarui
|
|
||||||
// toast.dismiss();
|
|
||||||
// toast.success("Data Loaded Successfully!");
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
local.ready = true;
|
local.ready = true;
|
||||||
local.data = res;
|
local.data = res;
|
||||||
local.render(); // Panggil render untuk memicu re-render
|
local.render();
|
||||||
toast.dismiss();
|
toast.dismiss();
|
||||||
toast.success("Data Loaded Successfully!");
|
// if (res instanceof Promise) {
|
||||||
}
|
// res.then((data) => {
|
||||||
|
// local.ready = true;
|
||||||
|
// local.data = data;
|
||||||
|
// local.render(); // Panggil render setelah data diperbarui
|
||||||
|
// // toast.dismiss();
|
||||||
|
// // toast.success("Data Loaded Successfully!");
|
||||||
|
// });
|
||||||
|
// } else {
|
||||||
|
// local.ready = true;
|
||||||
|
// local.data = res;
|
||||||
|
// local.render(); // Panggil render untuk memicu re-render
|
||||||
|
// toast.dismiss();
|
||||||
|
// toast.success("Data Loaded Successfully!");
|
||||||
|
// }
|
||||||
},
|
},
|
||||||
fields: {} as any,
|
fields: {} as any,
|
||||||
render: () => {},
|
render: () => {},
|
||||||
|
|
@ -144,6 +148,7 @@ export const Form: React.FC<any> = ({
|
||||||
local.onChange();
|
local.onChange();
|
||||||
}, [local.data]);
|
}, [local.data]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
const run = async () => {
|
||||||
if (typeof onInit === "function") {
|
if (typeof onInit === "function") {
|
||||||
onInit(local);
|
onInit(local);
|
||||||
}
|
}
|
||||||
|
|
@ -170,22 +175,29 @@ export const Form: React.FC<any> = ({
|
||||||
{"Loading..."}
|
{"Loading..."}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
const res = onLoad();
|
const res = await onLoad();
|
||||||
if (res instanceof Promise) {
|
|
||||||
res.then((data) => {
|
|
||||||
local.ready = true;
|
|
||||||
local.data = data;
|
|
||||||
local.render(); // Panggil render setelah data diperbarui
|
|
||||||
// toast.dismiss();
|
|
||||||
// toast.success("Data Loaded Successfully!");
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
local.ready = true;
|
local.ready = true;
|
||||||
local.data = res;
|
local.data = res;
|
||||||
local.render(); // Panggil render untuk memicu re-render
|
local.render(); // Panggil render setelah data diperbarui
|
||||||
toast.dismiss();
|
toast.dismiss();
|
||||||
toast.success("Data Loaded Successfully!");
|
// if (res instanceof Promise) {
|
||||||
}
|
// res.then((data) => {
|
||||||
|
// local.ready = true;
|
||||||
|
// local.data = data;
|
||||||
|
// local.render(); // Panggil render setelah data diperbarui
|
||||||
|
// toast.dismiss();
|
||||||
|
// // toast.success("Data Loaded Successfully!");
|
||||||
|
// });
|
||||||
|
// } else {
|
||||||
|
// local.ready = true;
|
||||||
|
// local.data = res;
|
||||||
|
// local.render(); // Panggil render untuk memicu re-render
|
||||||
|
// toast.dismiss();
|
||||||
|
// toast.success("Data Loaded Successfully!");
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
run();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Tambahkan dependency ke header agar reaktif
|
// Tambahkan dependency ke header agar reaktif
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,6 @@ export const TypeInput: React.FC<any> = ({
|
||||||
} else if (type === "time") {
|
} else if (type === "time") {
|
||||||
if (fm.data?.[name]) fm.data[name] = convertToTimeOnly(fm.data[name]);
|
if (fm.data?.[name]) fm.data[name] = convertToTimeOnly(fm.data[name]);
|
||||||
fm.render();
|
fm.render();
|
||||||
console.log({
|
|
||||||
data: fm.data,
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
setRating(value ? value - 1 : value);
|
setRating(value ? value - 1 : value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ export const TableList: React.FC<any> = ({
|
||||||
setData(res);
|
setData(res);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
toast.dismiss();
|
toast.dismiss();
|
||||||
}, 1000);
|
}, 100);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { FC } from "react";
|
||||||
|
import { Bar } from "react-chartjs-2";
|
||||||
|
import {
|
||||||
|
Chart as ChartJS,
|
||||||
|
CategoryScale,
|
||||||
|
LinearScale,
|
||||||
|
BarElement,
|
||||||
|
Title,
|
||||||
|
Tooltip,
|
||||||
|
Legend,
|
||||||
|
ChartOptions,
|
||||||
|
ChartData,
|
||||||
|
} from "chart.js";
|
||||||
|
|
||||||
|
ChartJS.register(
|
||||||
|
CategoryScale,
|
||||||
|
LinearScale,
|
||||||
|
BarElement,
|
||||||
|
Title,
|
||||||
|
Tooltip,
|
||||||
|
Legend
|
||||||
|
);
|
||||||
|
|
||||||
|
const BarChart: FC<{ data: ChartData<"bar">; option: ChartOptions<"bar"> }> = ({
|
||||||
|
data,
|
||||||
|
option,
|
||||||
|
}) => {
|
||||||
|
return <Bar data={data} options={option} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BarChart;
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import * as React from "react"
|
import * as React from "react";
|
||||||
|
|
||||||
import { cn } from "@/lib/utils/utils"
|
import { cn } from "@/lib/utils/utils";
|
||||||
|
|
||||||
const Card = React.forwardRef<
|
const Card = React.forwardRef<
|
||||||
HTMLDivElement,
|
HTMLDivElement,
|
||||||
|
|
@ -14,8 +14,8 @@ const Card = React.forwardRef<
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
))
|
));
|
||||||
Card.displayName = "Card"
|
Card.displayName = "Card";
|
||||||
|
|
||||||
const CardHeader = React.forwardRef<
|
const CardHeader = React.forwardRef<
|
||||||
HTMLDivElement,
|
HTMLDivElement,
|
||||||
|
|
@ -26,8 +26,8 @@ const CardHeader = React.forwardRef<
|
||||||
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
))
|
));
|
||||||
CardHeader.displayName = "CardHeader"
|
CardHeader.displayName = "CardHeader";
|
||||||
|
|
||||||
const CardTitle = React.forwardRef<
|
const CardTitle = React.forwardRef<
|
||||||
HTMLDivElement,
|
HTMLDivElement,
|
||||||
|
|
@ -38,8 +38,8 @@ const CardTitle = React.forwardRef<
|
||||||
className={cn("font-semibold leading-none tracking-tight", className)}
|
className={cn("font-semibold leading-none tracking-tight", className)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
))
|
));
|
||||||
CardTitle.displayName = "CardTitle"
|
CardTitle.displayName = "CardTitle";
|
||||||
|
|
||||||
const CardDescription = React.forwardRef<
|
const CardDescription = React.forwardRef<
|
||||||
HTMLDivElement,
|
HTMLDivElement,
|
||||||
|
|
@ -50,16 +50,16 @@ const CardDescription = React.forwardRef<
|
||||||
className={cn("text-sm text-muted-foreground", className)}
|
className={cn("text-sm text-muted-foreground", className)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
))
|
));
|
||||||
CardDescription.displayName = "CardDescription"
|
CardDescription.displayName = "CardDescription";
|
||||||
|
|
||||||
const CardContent = React.forwardRef<
|
const CardContent = React.forwardRef<
|
||||||
HTMLDivElement,
|
HTMLDivElement,
|
||||||
React.HTMLAttributes<HTMLDivElement>
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
>(({ className, ...props }, ref) => (
|
>(({ className, ...props }, ref) => (
|
||||||
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
||||||
))
|
));
|
||||||
CardContent.displayName = "CardContent"
|
CardContent.displayName = "CardContent";
|
||||||
|
|
||||||
const CardFooter = React.forwardRef<
|
const CardFooter = React.forwardRef<
|
||||||
HTMLDivElement,
|
HTMLDivElement,
|
||||||
|
|
@ -70,7 +70,25 @@ const CardFooter = React.forwardRef<
|
||||||
className={cn("flex items-center p-6 pt-0", className)}
|
className={cn("flex items-center p-6 pt-0", className)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
))
|
));
|
||||||
CardFooter.displayName = "CardFooter"
|
|
||||||
|
|
||||||
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
|
const CardBetter: React.FC<any> = ({ children, className }) => {
|
||||||
|
return (
|
||||||
|
<Card className={className}>
|
||||||
|
<CardContent className="flex flex-grow flex-col p-0">
|
||||||
|
{children}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
CardFooter.displayName = "CardFooter";
|
||||||
|
|
||||||
|
export {
|
||||||
|
Card,
|
||||||
|
CardBetter,
|
||||||
|
CardHeader,
|
||||||
|
CardFooter,
|
||||||
|
CardTitle,
|
||||||
|
CardDescription,
|
||||||
|
CardContent,
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
import { FC } from "react";
|
||||||
|
import { Doughnut } from "react-chartjs-2";
|
||||||
|
import {
|
||||||
|
Chart as ChartJS,
|
||||||
|
ArcElement,
|
||||||
|
Title,
|
||||||
|
Tooltip,
|
||||||
|
Legend,
|
||||||
|
ChartOptions,
|
||||||
|
Chart as ChartInstance,
|
||||||
|
Plugin,
|
||||||
|
} from "chart.js";
|
||||||
|
|
||||||
|
ChartJS.register(ArcElement, Title, Tooltip, Legend);
|
||||||
|
|
||||||
|
interface ProgressChartProps {
|
||||||
|
percentage: number;
|
||||||
|
color?: string;
|
||||||
|
backgroundColor?: string;
|
||||||
|
options: ChartOptions<"doughnut">;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ProgressChart: FC<ProgressChartProps> = ({
|
||||||
|
percentage,
|
||||||
|
options,
|
||||||
|
color = "#6366F1",
|
||||||
|
backgroundColor = "#E0E7FF",
|
||||||
|
}) => {
|
||||||
|
const data = {
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
data: [percentage, 100 - percentage],
|
||||||
|
backgroundColor: [color, "transparent"],
|
||||||
|
borderWidth: 0,
|
||||||
|
borderRadius: [10, 0],
|
||||||
|
cutout: "70%",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const backgroundCircle: Plugin<"doughnut"> = {
|
||||||
|
id: "backgroundCircle",
|
||||||
|
beforeDatasetsDraw(chart: ChartInstance, args: any, pluginOptions: any) {
|
||||||
|
const { ctx } = chart;
|
||||||
|
ctx.save();
|
||||||
|
|
||||||
|
const meta = chart.getDatasetMeta(0);
|
||||||
|
if (!meta || meta.data.length === 0) return;
|
||||||
|
|
||||||
|
const arc = meta.data[0] as any; // Pastikan ini adalah elemen arc
|
||||||
|
const xCoor = arc.x;
|
||||||
|
const yCoor = arc.y;
|
||||||
|
const innerRadius = arc.innerRadius || 0;
|
||||||
|
const outerRadius = arc.outerRadius || 0;
|
||||||
|
const width = outerRadius - innerRadius;
|
||||||
|
const angle = Math.PI / 180;
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.lineWidth = width;
|
||||||
|
ctx.strokeStyle = backgroundColor;
|
||||||
|
ctx.arc(xCoor, yCoor, outerRadius - width / 2, 0, angle * 360, false);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.restore();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="relative w-24 h-24">
|
||||||
|
<Doughnut data={data} options={options} plugins={[backgroundCircle]} />
|
||||||
|
<div className="absolute inset-0 flex items-center justify-center text-black font-bold">
|
||||||
|
+{percentage}%
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ProgressChart;
|
||||||
|
|
@ -12,8 +12,7 @@ export const userToken = async () => {
|
||||||
`${process.env.NEXT_PUBLIC_API_PORTAL}/api/check-jwt-token`
|
`${process.env.NEXT_PUBLIC_API_PORTAL}/api/check-jwt-token`
|
||||||
);
|
);
|
||||||
const jwt = res.data.data;
|
const jwt = res.data.data;
|
||||||
console.log({ jwt });
|
if (!jwt) return navigate(`${process.env.NEXT_PUBLIC_API_PORTAL}/login`);
|
||||||
if (!jwt) return;
|
|
||||||
try {
|
try {
|
||||||
await api.post(process.env.NEXT_PUBLIC_BASE_URL + "/api/cookies", {
|
await api.post(process.env.NEXT_PUBLIC_BASE_URL + "/api/cookies", {
|
||||||
token: jwt,
|
token: jwt,
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
"@types/lodash.uniqby": "^4.7.9",
|
"@types/lodash.uniqby": "^4.7.9",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"axios": "^1.7.8",
|
"axios": "^1.7.8",
|
||||||
|
"chart.js": "^4.4.7",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"classnames": "^2.5.1",
|
"classnames": "^2.5.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
|
@ -52,6 +53,7 @@
|
||||||
"lucide-react": "^0.462.0",
|
"lucide-react": "^0.462.0",
|
||||||
"next": "15.0.3",
|
"next": "15.0.3",
|
||||||
"react-beautiful-dnd": "^13.1.1",
|
"react-beautiful-dnd": "^13.1.1",
|
||||||
|
"react-chartjs-2": "^5.3.0",
|
||||||
"react-colorful": "^5.6.1",
|
"react-colorful": "^5.6.1",
|
||||||
"react-icons": "^5.3.0",
|
"react-icons": "^5.3.0",
|
||||||
"react-resizable": "^3.0.5",
|
"react-resizable": "^3.0.5",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue