fixing
This commit is contained in:
parent
e21ff675a9
commit
e66e77e796
|
|
@ -9,7 +9,7 @@ import Link from "next/link";
|
||||||
const ReactTableAudioPage = () => {
|
const ReactTableAudioPage = () => {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gray-50">
|
<div className="min-h-screen bg-gray-50">
|
||||||
{/* <SiteBreadcrumb /> */}
|
<SiteBreadcrumb />
|
||||||
<div className="p-6">
|
<div className="p-6">
|
||||||
<div className="max-w-7xl mx-auto">
|
<div className="max-w-7xl mx-auto">
|
||||||
<Card className="shadow-sm border-0">
|
<Card className="shadow-sm border-0">
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,6 @@ const TableImage = () => {
|
||||||
const [filterByCreator, setFilterByCreator] = React.useState("");
|
const [filterByCreator, setFilterByCreator] = React.useState("");
|
||||||
const [filterBySource, setFilterBySource] = React.useState("");
|
const [filterBySource, setFilterBySource] = React.useState("");
|
||||||
const [filterByCreatorGroup, setFilterByCreatorGroup] = React.useState("");
|
const [filterByCreatorGroup, setFilterByCreatorGroup] = React.useState("");
|
||||||
|
|
||||||
const roleId = getCookiesDecrypt("urie");
|
const roleId = getCookiesDecrypt("urie");
|
||||||
const columns = useTableColumns();
|
const columns = useTableColumns();
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import Link from "next/link";
|
||||||
const ReactTableImagePage = () => {
|
const ReactTableImagePage = () => {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gray-50">
|
<div className="min-h-screen bg-gray-50">
|
||||||
{/* <SiteBreadcrumb /> */}
|
<SiteBreadcrumb />
|
||||||
<div className="p-6">
|
<div className="p-6">
|
||||||
<div className="max-w-7xl mx-auto">
|
<div className="max-w-7xl mx-auto">
|
||||||
<Card className="shadow-sm border-0">
|
<Card className="shadow-sm border-0">
|
||||||
|
|
|
||||||
|
|
@ -259,7 +259,7 @@ const useTableColumns = () => {
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className="p-0" align="end">
|
<DropdownMenuContent className="p-0" align="end">
|
||||||
<Link href={`/admin/content/document/detail/${row.original.id}`}>
|
<Link href={`/admin/content/text/detail/${row.original.id}`}>
|
||||||
<DropdownMenuItem className="p-2 border-b text-default-700 group rounded-none">
|
<DropdownMenuItem className="p-2 border-b text-default-700 group rounded-none">
|
||||||
<Eye className="w-4 h-4 me-1.5" />
|
<Eye className="w-4 h-4 me-1.5" />
|
||||||
View
|
View
|
||||||
|
|
@ -268,7 +268,7 @@ const useTableColumns = () => {
|
||||||
{(Number(row.original.uploadedById) === Number(userId) ||
|
{(Number(row.original.uploadedById) === Number(userId) ||
|
||||||
isMabesApprover) && (
|
isMabesApprover) && (
|
||||||
<Link
|
<Link
|
||||||
href={`/admin/content/document/update/${row.original.id}`}
|
href={`/admin/content/text/update/${row.original.id}`}
|
||||||
>
|
>
|
||||||
<DropdownMenuItem className="p-2 border-b text-default-700 group rounded-none">
|
<DropdownMenuItem className="p-2 border-b text-default-700 group rounded-none">
|
||||||
<SquarePen className="w-4 h-4 me-1.5" />
|
<SquarePen className="w-4 h-4 me-1.5" />
|
||||||
|
|
@ -26,7 +26,7 @@ const ReactTableDocumentPage = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-none">
|
<div className="flex-none">
|
||||||
<Link href={"/admin/content/document/create"}>
|
<Link href={"/admin/content/text/create"}>
|
||||||
<Button color="primary" className="text-white shadow-sm hover:shadow-md transition-shadow">
|
<Button color="primary" className="text-white shadow-sm hover:shadow-md transition-shadow">
|
||||||
<UploadIcon size={18} className="mr-2" />
|
<UploadIcon size={18} className="mr-2" />
|
||||||
Create Document
|
Create Document
|
||||||
|
|
@ -254,7 +254,7 @@ const useTableColumns = () => {
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className="p-0" align="end">
|
<DropdownMenuContent className="p-0" align="end">
|
||||||
<Link
|
<Link
|
||||||
href={`/admin/content/audio-visual/detail/${row.original.id}`}
|
href={`/admin/content/video/detail/${row.original.id}`}
|
||||||
>
|
>
|
||||||
<DropdownMenuItem className="p-2 border-b text-default-700 group rounded-none">
|
<DropdownMenuItem className="p-2 border-b text-default-700 group rounded-none">
|
||||||
<Eye className="w-4 h-4 me-1.5" />
|
<Eye className="w-4 h-4 me-1.5" />
|
||||||
|
|
@ -272,7 +272,7 @@ const useTableColumns = () => {
|
||||||
{/* {(Number(row.original.uploadedById) === Number(userId) ||
|
{/* {(Number(row.original.uploadedById) === Number(userId) ||
|
||||||
isMabesApprover) && ( */}
|
isMabesApprover) && ( */}
|
||||||
<Link
|
<Link
|
||||||
href={`/admin/content/audio-visual/update/${row.original.id}`}
|
href={`/admin/content/video/update/${row.original.id}`}
|
||||||
>
|
>
|
||||||
<DropdownMenuItem className="p-2 border-b text-default-700 group rounded-none">
|
<DropdownMenuItem className="p-2 border-b text-default-700 group rounded-none">
|
||||||
<SquarePen className="w-4 h-4 me-1.5" />
|
<SquarePen className="w-4 h-4 me-1.5" />
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
import FormVideoDetail from "@/components/form/content/audio-visual/video-detail-form";
|
import FormVideoDetail from "@/components/form/content/audio-visual/video-detail-form";
|
||||||
|
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||||
|
|
||||||
const VideoDetailPage = async () => {
|
const VideoDetailPage = async () => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{/* <SiteBreadcrumb /> */}
|
<SiteBreadcrumb />
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<FormVideoDetail />
|
<FormVideoDetail />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -9,7 +9,7 @@ import Link from "next/link";
|
||||||
const ReactTableAudioVisualPage = () => {
|
const ReactTableAudioVisualPage = () => {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gray-50">
|
<div className="min-h-screen bg-gray-50">
|
||||||
{/* <SiteBreadcrumb /> */}
|
<SiteBreadcrumb />
|
||||||
<div className="p-6">
|
<div className="p-6">
|
||||||
<div className="max-w-7xl mx-auto">
|
<div className="max-w-7xl mx-auto">
|
||||||
<Card className="shadow-sm border-0">
|
<Card className="shadow-sm border-0">
|
||||||
|
|
@ -26,7 +26,7 @@ const ReactTableAudioVisualPage = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-none">
|
<div className="flex-none">
|
||||||
<Link href={"/admin/content/audio-visual/create"}>
|
<Link href={"/admin/content/video/create"}>
|
||||||
<Button color="primary" className="text-white shadow-sm hover:shadow-md transition-shadow">
|
<Button color="primary" className="text-white shadow-sm hover:shadow-md transition-shadow">
|
||||||
<UploadIcon size={18} className="mr-2" />
|
<UploadIcon size={18} className="mr-2" />
|
||||||
Create Audio-Visual
|
Create Audio-Visual
|
||||||
|
|
@ -296,7 +296,7 @@ const useTableColumns = (onEdit?: (data: any) => void) => {
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setOpen(false); // ⬅️ tutup dropdown manual
|
setOpen(false);
|
||||||
onEdit?.(row.original);
|
onEdit?.(row.original);
|
||||||
}}
|
}}
|
||||||
className="p-2 border-b text-default-700 rounded-none cursor-pointer"
|
className="p-2 border-b text-default-700 rounded-none cursor-pointer"
|
||||||
|
|
@ -307,7 +307,7 @@ const useTableColumns = (onEdit?: (data: any) => void) => {
|
||||||
|
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setOpen(false); // ⬅️ pastikan dropdown tertutup sebelum alert
|
setOpen(false);
|
||||||
handleDeleteMedia(row.original.id);
|
handleDeleteMedia(row.original.id);
|
||||||
}}
|
}}
|
||||||
className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-white rounded-none"
|
className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-white rounded-none"
|
||||||
|
|
@ -338,7 +338,7 @@ const useTableColumns = (onEdit?: (data: any) => void) => {
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<span className="font-medium">Parent Level:</span>{" "}
|
<span className="font-medium">Parent Level:</span>{" "}
|
||||||
{detailData.parentLevelName || "-"}
|
{detailData.parentLevelId || "-"}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<span className="font-medium">Created At:</span>{" "}
|
<span className="font-medium">Created At:</span>{" "}
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ import useTableColumns from "./columns";
|
||||||
import TenantUpdateForm from "@/components/form/tenant/tenant-update-form";
|
import TenantUpdateForm from "@/components/form/tenant/tenant-update-form";
|
||||||
import { errorAutoClose, successAutoClose } from "@/lib/swal";
|
import { errorAutoClose, successAutoClose } from "@/lib/swal";
|
||||||
import { close, loading } from "@/config/swal";
|
import { close, loading } from "@/config/swal";
|
||||||
|
import DetailTenant from "@/components/form/tenant/tenant-detail-update-form";
|
||||||
|
|
||||||
function TenantSettingsContentTable() {
|
function TenantSettingsContentTable() {
|
||||||
const [activeTab, setActiveTab] = useState("workflows");
|
const [activeTab, setActiveTab] = useState("workflows");
|
||||||
|
|
@ -217,7 +218,14 @@ function TenantSettingsContentTable() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
|
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
|
||||||
<TabsList className="grid w-full grid-cols-2">
|
<TabsList className="grid w-full grid-cols-3">
|
||||||
|
<TabsTrigger
|
||||||
|
value="tenant"
|
||||||
|
className="flex items-center gap-2 border rounded-lg"
|
||||||
|
>
|
||||||
|
<WorkflowIcon className="h-4 w-4" />
|
||||||
|
Detail Tenant
|
||||||
|
</TabsTrigger>
|
||||||
<TabsTrigger
|
<TabsTrigger
|
||||||
value="workflows"
|
value="workflows"
|
||||||
className="flex items-center gap-2 border rounded-lg"
|
className="flex items-center gap-2 border rounded-lg"
|
||||||
|
|
@ -235,6 +243,9 @@ function TenantSettingsContentTable() {
|
||||||
</TabsList>
|
</TabsList>
|
||||||
|
|
||||||
{/* Approval Workflows Tab */}
|
{/* Approval Workflows Tab */}
|
||||||
|
<TabsContent value="tenant" className="space-y-6 border rounded-lg">
|
||||||
|
<DetailTenant id={10} />
|
||||||
|
</TabsContent>
|
||||||
<TabsContent value="workflows" className="space-y-6 border rounded-lg">
|
<TabsContent value="workflows" className="space-y-6 border rounded-lg">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<h2 className="text-2xl font-semibold ml-2 mt-4">
|
<h2 className="text-2xl font-semibold ml-2 mt-4">
|
||||||
|
|
@ -718,90 +729,92 @@ function TenantSettingsContentTable() {
|
||||||
<CardHeader className="cursor-pointer hover:bg-gray-50 transition-colors">
|
<CardHeader className="cursor-pointer hover:bg-gray-50 transition-colors">
|
||||||
<CardTitle className="flex items-center justify-between">
|
<CardTitle className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<UsersIcon className="h-5 w-5" />
|
<UsersIcon className="h-5 w-5" />
|
||||||
User Levels Hierarchy
|
User Levels Hierarchy
|
||||||
</div>
|
</div>
|
||||||
{isHierarchyExpanded ? (
|
{isHierarchyExpanded ? (
|
||||||
<ChevronUpIcon className="h-4 w-4" />
|
<ChevronUpIcon className="h-4 w-4" />
|
||||||
) : (
|
) : (
|
||||||
<ChevronDownIcon className="h-4 w-4" />
|
<ChevronDownIcon className="h-4 w-4" />
|
||||||
)}
|
)}
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
</CollapsibleTrigger>
|
</CollapsibleTrigger>
|
||||||
<CollapsibleContent>
|
<CollapsibleContent>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
{userLevels
|
{userLevels
|
||||||
.filter((ul) => !ul.parentLevelId) // Root levels
|
.filter((ul) => !ul.parentLevelId) // Root levels
|
||||||
.sort((a, b) => a.levelNumber - b.levelNumber)
|
.sort((a, b) => a.levelNumber - b.levelNumber)
|
||||||
.map((rootLevel) => (
|
.map((rootLevel) => (
|
||||||
<div key={rootLevel.id} className="space-y-2">
|
<div key={rootLevel.id} className="space-y-2">
|
||||||
{/* Root Level */}
|
{/* Root Level */}
|
||||||
<div className="flex items-center gap-3 p-3 bg-blue-50 rounded-lg border-l-4 border-blue-500">
|
<div className="flex items-center gap-3 p-3 bg-blue-50 rounded-lg border-l-4 border-blue-500">
|
||||||
<div className="w-8 h-8 bg-blue-100 text-blue-600 rounded-full flex items-center justify-center text-sm font-medium">
|
<div className="w-8 h-8 bg-blue-100 text-blue-600 rounded-full flex items-center justify-center text-sm font-medium">
|
||||||
{rootLevel.levelNumber}
|
{rootLevel.levelNumber}
|
||||||
</div>
|
|
||||||
<div className="flex-1">
|
|
||||||
<div className="font-medium">{rootLevel.name}</div>
|
|
||||||
<div className="text-sm text-gray-500">
|
|
||||||
{rootLevel.aliasName} •{" "}
|
|
||||||
{rootLevel.group || "No group"}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
{rootLevel.isActive && (
|
|
||||||
<span className="px-2 py-1 text-xs bg-green-100 text-green-800 rounded-full">
|
|
||||||
Active
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{rootLevel.isApprovalActive && (
|
|
||||||
<span className="px-2 py-1 text-xs bg-purple-100 text-purple-800 rounded-full">
|
|
||||||
Approval Active
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Child Levels */}
|
|
||||||
{userLevels
|
|
||||||
.filter((ul) => ul.parentLevelId === rootLevel.id)
|
|
||||||
.sort((a, b) => a.levelNumber - b.levelNumber)
|
|
||||||
.map((childLevel) => (
|
|
||||||
<div
|
|
||||||
key={childLevel.id}
|
|
||||||
className="ml-8 flex items-center gap-3 p-3 bg-gray-50 rounded-lg border-l-4 border-gray-300"
|
|
||||||
>
|
|
||||||
<div className="w-6 h-6 bg-gray-100 text-gray-600 rounded-full flex items-center justify-center text-xs font-medium">
|
|
||||||
{childLevel.levelNumber}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<div className="font-medium text-sm">
|
<div className="font-medium">
|
||||||
{childLevel.name}
|
{rootLevel.name}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs text-gray-500">
|
<div className="text-sm text-gray-500">
|
||||||
{childLevel.aliasName} •{" "}
|
{rootLevel.aliasName} •{" "}
|
||||||
{childLevel.group || "No group"}
|
{rootLevel.group || "No group"}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-2">
|
||||||
{childLevel.isActive && (
|
{rootLevel.isActive && (
|
||||||
<span className="px-1 py-0.5 text-xs bg-green-100 text-green-800 rounded-full">
|
<span className="px-2 py-1 text-xs bg-green-100 text-green-800 rounded-full">
|
||||||
Active
|
Active
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{childLevel.isApprovalActive && (
|
{rootLevel.isApprovalActive && (
|
||||||
<span className="px-1 py-0.5 text-xs bg-purple-100 text-purple-800 rounded-full">
|
<span className="px-2 py-1 text-xs bg-purple-100 text-purple-800 rounded-full">
|
||||||
Approval
|
Approval Active
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
|
||||||
</div>
|
{/* Child Levels */}
|
||||||
))}
|
{userLevels
|
||||||
</div>
|
.filter((ul) => ul.parentLevelId === rootLevel.id)
|
||||||
</CardContent>
|
.sort((a, b) => a.levelNumber - b.levelNumber)
|
||||||
|
.map((childLevel) => (
|
||||||
|
<div
|
||||||
|
key={childLevel.id}
|
||||||
|
className="ml-8 flex items-center gap-3 p-3 bg-gray-50 rounded-lg border-l-4 border-gray-300"
|
||||||
|
>
|
||||||
|
<div className="w-6 h-6 bg-gray-100 text-gray-600 rounded-full flex items-center justify-center text-xs font-medium">
|
||||||
|
{childLevel.levelNumber}
|
||||||
|
</div>
|
||||||
|
<div className="flex-1">
|
||||||
|
<div className="font-medium text-sm">
|
||||||
|
{childLevel.name}
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-gray-500">
|
||||||
|
{childLevel.aliasName} •{" "}
|
||||||
|
{childLevel.group || "No group"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
{childLevel.isActive && (
|
||||||
|
<span className="px-1 py-0.5 text-xs bg-green-100 text-green-800 rounded-full">
|
||||||
|
Active
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{childLevel.isApprovalActive && (
|
||||||
|
<span className="px-1 py-0.5 text-xs bg-purple-100 text-purple-800 rounded-full">
|
||||||
|
Approval
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
</CollapsibleContent>
|
</CollapsibleContent>
|
||||||
</Collapsible>
|
</Collapsible>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export default function Home() {
|
||||||
return (
|
return (
|
||||||
<div className="relative min-h-screen font-[family-name:var(--font-geist-sans)]">
|
<div className="relative min-h-screen font-[family-name:var(--font-geist-sans)]">
|
||||||
<div className="relative z-10 bg-white w-full mx-auto">
|
<div className="relative z-10 bg-white w-full mx-auto">
|
||||||
<Navbar />
|
{/* <Navbar /> */}
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<Header />
|
<Header />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -152,10 +152,8 @@ export default function FormVideo() {
|
||||||
|
|
||||||
const options: Option[] = [
|
const options: Option[] = [
|
||||||
{ id: "all", label: "SEMUA" },
|
{ id: "all", label: "SEMUA" },
|
||||||
{ id: "5", label: "UMUM" },
|
{ id: "4", label: "UMUM" },
|
||||||
{ id: "6", label: "JOURNALIS" },
|
{ id: "5", label: "JOURNALIS" },
|
||||||
{ id: "7", label: "POLRI" },
|
|
||||||
{ id: "8", label: "KSP" },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const MAX_FILE_SIZE = 100 * 1024 * 1024;
|
const MAX_FILE_SIZE = 100 * 1024 * 1024;
|
||||||
|
|
@ -654,7 +652,7 @@ export default function FormVideo() {
|
||||||
.replace(/[^a-z0-9-]/g, ""),
|
.replace(/[^a-z0-9-]/g, ""),
|
||||||
tags: finalTags,
|
tags: finalTags,
|
||||||
title: finalTitle,
|
title: finalTitle,
|
||||||
typeId: 1, // Image content type
|
typeId: 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use new Articles API
|
// Use new Articles API
|
||||||
|
|
@ -749,7 +747,7 @@ export default function FormVideo() {
|
||||||
confirmButtonColor: "#3085d6",
|
confirmButtonColor: "#3085d6",
|
||||||
confirmButtonText: "OK",
|
confirmButtonText: "OK",
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
router.push("/admin/content/audio-visual");
|
router.push("/admin/content/video");
|
||||||
});
|
});
|
||||||
|
|
||||||
Cookies.remove("idCreate");
|
Cookies.remove("idCreate");
|
||||||
|
|
@ -1000,8 +998,8 @@ export default function FormVideo() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
<div className="flex flex-col lg:flex-row gap-10">
|
<div className="flex flex-col lg:flex-row gap-10 border">
|
||||||
<Card className="w-full lg:w-8/12">
|
<Card className="w-full lg:w-8/12 m-2">
|
||||||
<div className="px-6 py-6">
|
<div className="px-6 py-6">
|
||||||
<p className="text-lg font-semibold mb-3">Form Video</p>
|
<p className="text-lg font-semibold mb-3">Form Video</p>
|
||||||
<div className="gap-5 mb-5">
|
<div className="gap-5 mb-5">
|
||||||
|
|
@ -1453,7 +1451,7 @@ export default function FormVideo() {
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<div className="w-full lg:w-4/12">
|
<div className="w-full lg:w-4/12 m-2">
|
||||||
<Card className="h-fit">
|
<Card className="h-fit">
|
||||||
<div className="px-3 py-3">
|
<div className="px-3 py-3">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
|
@ -1594,7 +1592,8 @@ export default function FormVideo() {
|
||||||
<Checkbox
|
<Checkbox
|
||||||
id={option.id}
|
id={option.id}
|
||||||
checked={isChecked}
|
checked={isChecked}
|
||||||
onCheckedChange={handleChange}
|
onCheckedChange={handleChange}
|
||||||
|
className="border"
|
||||||
/>
|
/>
|
||||||
<Label htmlFor={option.id}>{option.label}</Label>
|
<Label htmlFor={option.id}>{option.label}</Label>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ export default function FormAudio() {
|
||||||
polres: false,
|
polres: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
let fileTypeId = "3";
|
let fileTypeId = "4";
|
||||||
let progressInfo: any = [];
|
let progressInfo: any = [];
|
||||||
let counterUpdateProgress = 0;
|
let counterUpdateProgress = 0;
|
||||||
const [progressList, setProgressList] = useState<any>([]);
|
const [progressList, setProgressList] = useState<any>([]);
|
||||||
|
|
@ -149,12 +149,10 @@ export default function FormAudio() {
|
||||||
type FileWithPreview = File & { preview: string };
|
type FileWithPreview = File & { preview: string };
|
||||||
const userId = Cookies.get("userId");
|
const userId = Cookies.get("userId");
|
||||||
|
|
||||||
const options: Option[] = [
|
const options: Option[] = [
|
||||||
{ id: "all", label: "SEMUA" },
|
{ id: "all", label: "SEMUA" },
|
||||||
{ id: "5", label: "UMUM" },
|
{ id: "4", label: "UMUM" },
|
||||||
{ id: "6", label: "JOURNALIS" },
|
{ id: "5", label: "JOURNALIS" },
|
||||||
{ id: "7", label: "POLRI" },
|
|
||||||
{ id: "8", label: "KSP" },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const audioRefs = useRef<HTMLAudioElement[]>([]);
|
const audioRefs = useRef<HTMLAudioElement[]>([]);
|
||||||
|
|
@ -651,7 +649,7 @@ export default function FormAudio() {
|
||||||
.replace(/[^a-z0-9-]/g, ""),
|
.replace(/[^a-z0-9-]/g, ""),
|
||||||
tags: finalTags,
|
tags: finalTags,
|
||||||
title: finalTitle,
|
title: finalTitle,
|
||||||
typeId: 1, // Image content type
|
typeId: 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use new Articles API
|
// Use new Articles API
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ export default function FormTeks() {
|
||||||
polres: false,
|
polres: false,
|
||||||
});
|
});
|
||||||
const userId = Cookies.get("userId");
|
const userId = Cookies.get("userId");
|
||||||
let fileTypeId = "2";
|
let fileTypeId = "3";
|
||||||
let progressInfo: any = [];
|
let progressInfo: any = [];
|
||||||
let counterUpdateProgress = 0;
|
let counterUpdateProgress = 0;
|
||||||
const [progressList, setProgressList] = useState<any>([]);
|
const [progressList, setProgressList] = useState<any>([]);
|
||||||
|
|
|
||||||
|
|
@ -602,7 +602,6 @@ export default function FormImageDetail() {
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<div className="py-3 w-full space-y-2">
|
<div className="py-3 w-full space-y-2">
|
||||||
<Label>Category</Label>
|
<Label>Category</Label>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
disabled
|
disabled
|
||||||
value={String(detail?.categoryId || detail?.category?.id)}
|
value={String(detail?.categoryId || detail?.category?.id)}
|
||||||
|
|
@ -779,24 +778,7 @@ export default function FormImageDetail() {
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="6">JOURNALIS</Label>
|
<Label htmlFor="6">JOURNALIS</Label>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-2 items-center">
|
|
||||||
<Checkbox
|
|
||||||
id="7"
|
|
||||||
checked={selectedPublishers.includes(7)}
|
|
||||||
onChange={() => handleCheckboxChange(7)}
|
|
||||||
className="border"
|
|
||||||
/>
|
|
||||||
<Label htmlFor="7">POLRI</Label>
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-2 items-center">
|
|
||||||
<Checkbox
|
|
||||||
id="8"
|
|
||||||
checked={selectedPublishers.includes(8)}
|
|
||||||
onChange={() => handleCheckboxChange(8)}
|
|
||||||
className="border"
|
|
||||||
/>
|
|
||||||
<Label htmlFor="8">KSP</Label>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,305 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { useForm, Controller } from "react-hook-form";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import * as z from "zod";
|
||||||
|
import {
|
||||||
|
Card,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
CardContent,
|
||||||
|
CardFooter,
|
||||||
|
} from "@/components/ui/card";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Label } from "@/components/ui/label";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
|
import Swal from "sweetalert2";
|
||||||
|
import withReactContent from "sweetalert2-react-content";
|
||||||
|
import { errorAutoClose, loading, successAutoClose } from "@/lib/swal";
|
||||||
|
import { close } from "@/config/swal";
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
|
// ✅ Zod Schema Validasi
|
||||||
|
const companySchema = z.object({
|
||||||
|
companyName: z.string().trim().min(1, "Nama perusahaan wajib diisi"),
|
||||||
|
address: z.string().trim().min(1, "Alamat perusahaan wajib diisi"),
|
||||||
|
phone: z
|
||||||
|
.string()
|
||||||
|
.regex(/^[0-9+\-\s]+$/, "Nomor telepon tidak valid")
|
||||||
|
.min(6, "Nomor telepon minimal 6 karakter"),
|
||||||
|
website: z
|
||||||
|
.string()
|
||||||
|
.url("Masukkan URL website yang valid")
|
||||||
|
.optional()
|
||||||
|
.or(z.literal("")),
|
||||||
|
description: z.string().trim().optional(),
|
||||||
|
isActive: z.boolean().default(true),
|
||||||
|
logo: z.any().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
type CompanySchema = z.infer<typeof companySchema>;
|
||||||
|
|
||||||
|
interface TenantCompanyUpdateFormProps {
|
||||||
|
id: number;
|
||||||
|
initialData?: any;
|
||||||
|
onSuccess?: () => void;
|
||||||
|
onCancel?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function TenantCompanyUpdateForm({
|
||||||
|
id,
|
||||||
|
initialData,
|
||||||
|
onSuccess,
|
||||||
|
onCancel,
|
||||||
|
}: TenantCompanyUpdateFormProps) {
|
||||||
|
const MySwal = withReactContent(Swal);
|
||||||
|
const [previewLogo, setPreviewLogo] = useState<string | null>(null);
|
||||||
|
const [loadingData, setLoadingData] = useState(false);
|
||||||
|
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
handleSubmit,
|
||||||
|
setValue,
|
||||||
|
formState: { errors },
|
||||||
|
watch,
|
||||||
|
} = useForm<CompanySchema>({
|
||||||
|
resolver: zodResolver(companySchema),
|
||||||
|
defaultValues: {
|
||||||
|
companyName: "",
|
||||||
|
address: "",
|
||||||
|
phone: "",
|
||||||
|
website: "",
|
||||||
|
description: "",
|
||||||
|
isActive: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// ✅ Load data awal dari server
|
||||||
|
useEffect(() => {
|
||||||
|
async function fetchCompanyData() {
|
||||||
|
setLoadingData(true);
|
||||||
|
try {
|
||||||
|
// TODO: ganti dengan service API kamu (misalnya getTenantCompanyDetail)
|
||||||
|
const response = initialData; // simulasi
|
||||||
|
if (response) {
|
||||||
|
setValue("companyName", response.companyName || "");
|
||||||
|
setValue("address", response.address || "");
|
||||||
|
setValue("phone", response.phone || "");
|
||||||
|
setValue("website", response.website || "");
|
||||||
|
setValue("description", response.description || "");
|
||||||
|
setValue("isActive", response.isActive ?? true);
|
||||||
|
setPreviewLogo(response.logoUrl || null);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("❌ Gagal memuat data perusahaan:", err);
|
||||||
|
} finally {
|
||||||
|
setLoadingData(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchCompanyData();
|
||||||
|
}, [initialData, setValue]);
|
||||||
|
|
||||||
|
// ✅ Fungsi Upload Logo
|
||||||
|
const handleLogoChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const file = e.target.files?.[0];
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
if (!file.type.startsWith("image/")) {
|
||||||
|
MySwal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Format tidak valid",
|
||||||
|
text: "File harus berupa gambar (jpg, png, webp, dll)",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setValue("logo", file);
|
||||||
|
setPreviewLogo(URL.createObjectURL(file));
|
||||||
|
};
|
||||||
|
|
||||||
|
// ✅ Submit Form
|
||||||
|
const onSubmit = async (data: CompanySchema) => {
|
||||||
|
try {
|
||||||
|
loading();
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("companyName", data.companyName);
|
||||||
|
formData.append("address", data.address);
|
||||||
|
formData.append("phone", data.phone);
|
||||||
|
formData.append("website", data.website || "");
|
||||||
|
formData.append("description", data.description || "");
|
||||||
|
formData.append("isActive", data.isActive ? "true" : "false");
|
||||||
|
if (data.logo) formData.append("logo", data.logo);
|
||||||
|
|
||||||
|
console.log("📦 Payload:", Object.fromEntries(formData.entries()));
|
||||||
|
|
||||||
|
// TODO: Ganti dengan service API kamu → misalnya updateTenantCompany(formData)
|
||||||
|
// const response = await updateTenantCompany(id, formData);
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1000)); // simulate
|
||||||
|
close();
|
||||||
|
|
||||||
|
successAutoClose("Data perusahaan berhasil diperbarui.");
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (onSuccess) onSuccess();
|
||||||
|
}, 2000);
|
||||||
|
} catch (err) {
|
||||||
|
close();
|
||||||
|
console.error("❌ Gagal update perusahaan:", err);
|
||||||
|
errorAutoClose("Terjadi kesalahan saat memperbarui data perusahaan.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (loadingData) {
|
||||||
|
return (
|
||||||
|
<Card className="p-6 w-full lg:w-2/3">
|
||||||
|
<div className="flex items-center justify-center py-8">
|
||||||
|
<div className="text-center">
|
||||||
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900 mx-auto mb-4"></div>
|
||||||
|
<p>Memuat data perusahaan...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<Card className="p-6 w-full lg:w-2/3">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className="text-lg font-semibold">
|
||||||
|
Update Informasi Perusahaan
|
||||||
|
</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
|
||||||
|
<CardContent className="space-y-4">
|
||||||
|
{/* Logo Upload */}
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label>Logo Perusahaan</Label>
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<Input
|
||||||
|
type="file"
|
||||||
|
accept="image/*"
|
||||||
|
onChange={handleLogoChange}
|
||||||
|
className="max-w-xs"
|
||||||
|
/>
|
||||||
|
{previewLogo && (
|
||||||
|
<div className="relative w-20 h-20 rounded-lg overflow-hidden border">
|
||||||
|
<Image
|
||||||
|
src={previewLogo}
|
||||||
|
alt="Company Logo"
|
||||||
|
fill
|
||||||
|
className="object-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Nama Perusahaan */}
|
||||||
|
<div>
|
||||||
|
<Label>Nama Perusahaan</Label>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="companyName"
|
||||||
|
render={({ field }) => (
|
||||||
|
<Input {...field} placeholder="Masukkan nama perusahaan" />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{errors.companyName && (
|
||||||
|
<p className="text-red-500 text-sm">
|
||||||
|
{errors.companyName.message}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Alamat */}
|
||||||
|
<div>
|
||||||
|
<Label>Alamat</Label>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="address"
|
||||||
|
render={({ field }) => (
|
||||||
|
<Textarea {...field} placeholder="Masukkan alamat lengkap" />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{errors.address && (
|
||||||
|
<p className="text-red-500 text-sm">{errors.address.message}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Nomor Telepon */}
|
||||||
|
<div>
|
||||||
|
<Label>Nomor Telepon</Label>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="phone"
|
||||||
|
render={({ field }) => (
|
||||||
|
<Input {...field} placeholder="Masukkan nomor telepon" />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{errors.phone && (
|
||||||
|
<p className="text-red-500 text-sm">{errors.phone.message}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Website */}
|
||||||
|
<div>
|
||||||
|
<Label>Website Resmi</Label>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="website"
|
||||||
|
render={({ field }) => (
|
||||||
|
<Input {...field} placeholder="https://example.com" />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{errors.website && (
|
||||||
|
<p className="text-red-500 text-sm">{errors.website.message}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Deskripsi Perusahaan */}
|
||||||
|
<div>
|
||||||
|
<Label>Biodata / Deskripsi Perusahaan</Label>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="description"
|
||||||
|
render={({ field }) => (
|
||||||
|
<Textarea
|
||||||
|
{...field}
|
||||||
|
placeholder="Ceritakan tentang perusahaan Anda..."
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Status Aktif */}
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="isActive"
|
||||||
|
render={({ field }) => (
|
||||||
|
<Checkbox
|
||||||
|
checked={field.value}
|
||||||
|
onCheckedChange={field.onChange}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Label>Aktif</Label>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
|
||||||
|
<CardFooter className="flex justify-end gap-3">
|
||||||
|
<Button type="submit">Update</Button>
|
||||||
|
<Button type="button" variant="outline" onClick={() => onCancel?.()}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</CardFooter>
|
||||||
|
</Card>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -13,8 +13,18 @@ import withReactContent from "sweetalert2-react-content";
|
||||||
import { errorAutoClose, loading, successAutoClose } from "@/lib/swal";
|
import { errorAutoClose, loading, successAutoClose } from "@/lib/swal";
|
||||||
import { close } from "@/config/swal";
|
import { close } from "@/config/swal";
|
||||||
import { getUserLevelDetail, updateUserLevel } from "@/service/tenant";
|
import { getUserLevelDetail, updateUserLevel } from "@/service/tenant";
|
||||||
import { UserLevelsCreateRequest, getUserLevels, getProvinces } from "@/service/approval-workflows";
|
import {
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
UserLevelsCreateRequest,
|
||||||
|
getUserLevels,
|
||||||
|
getProvinces,
|
||||||
|
} from "@/service/approval-workflows";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
|
|
||||||
const tenantSchema = z.object({
|
const tenantSchema = z.object({
|
||||||
|
|
@ -48,8 +58,12 @@ export default function TenantUpdateForm({
|
||||||
}: TenantUpdateFormProps) {
|
}: TenantUpdateFormProps) {
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
const [loadingData, setLoadingData] = useState(false);
|
const [loadingData, setLoadingData] = useState(false);
|
||||||
const [userLevels, setUserLevels] = useState<{id: number; name: string}[]>([]);
|
const [userLevels, setUserLevels] = useState<{ id: number; name: string }[]>(
|
||||||
const [provinces, setProvinces] = useState<{id: number; name: string}[]>([]);
|
[]
|
||||||
|
);
|
||||||
|
const [provinces, setProvinces] = useState<{ id: number; prov_name: string }[]>(
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
|
|
@ -59,6 +73,7 @@ export default function TenantUpdateForm({
|
||||||
} = useForm<TenantSchema>({
|
} = useForm<TenantSchema>({
|
||||||
resolver: zodResolver(tenantSchema),
|
resolver: zodResolver(tenantSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
|
|
||||||
aliasName: "",
|
aliasName: "",
|
||||||
levelNumber: 1,
|
levelNumber: 1,
|
||||||
name: "",
|
name: "",
|
||||||
|
|
@ -74,14 +89,15 @@ export default function TenantUpdateForm({
|
||||||
async function loadData() {
|
async function loadData() {
|
||||||
setLoadingData(true);
|
setLoadingData(true);
|
||||||
try {
|
try {
|
||||||
const [detailResponse, userLevelsResponse, provincesResponse] = await Promise.all([
|
const [detailResponse, userLevelsResponse, provincesResponse] =
|
||||||
getUserLevelDetail(id),
|
await Promise.all([
|
||||||
getUserLevels(),
|
getUserLevelDetail(id),
|
||||||
getProvinces(),
|
getUserLevels(),
|
||||||
]);
|
getProvinces(),
|
||||||
|
]);
|
||||||
|
|
||||||
if (!detailResponse.error && detailResponse.data) {
|
if (!detailResponse.error && detailResponse.data) {
|
||||||
const detail = detailResponse.data;
|
const detail = detailResponse.data.data;
|
||||||
setValue("aliasName", detail.aliasName ?? "");
|
setValue("aliasName", detail.aliasName ?? "");
|
||||||
setValue("levelNumber", detail.levelNumber ?? 1);
|
setValue("levelNumber", detail.levelNumber ?? 1);
|
||||||
setValue("name", detail.name ?? "");
|
setValue("name", detail.name ?? "");
|
||||||
|
|
@ -90,6 +106,7 @@ export default function TenantUpdateForm({
|
||||||
setValue("group", detail.group ?? "");
|
setValue("group", detail.group ?? "");
|
||||||
setValue("isApprovalActive", detail.isApprovalActive ?? true);
|
setValue("isApprovalActive", detail.isApprovalActive ?? true);
|
||||||
setValue("isActive", detail.isActive ?? true);
|
setValue("isActive", detail.isActive ?? true);
|
||||||
|
console.log("OOOO", detailResponse.data);
|
||||||
} else {
|
} else {
|
||||||
console.error("Gagal mengambil detail:", detailResponse.message);
|
console.error("Gagal mengambil detail:", detailResponse.message);
|
||||||
}
|
}
|
||||||
|
|
@ -114,7 +131,8 @@ export default function TenantUpdateForm({
|
||||||
try {
|
try {
|
||||||
loading();
|
loading();
|
||||||
|
|
||||||
const payload: UserLevelsCreateRequest = {
|
const payload = {
|
||||||
|
id: id,
|
||||||
aliasName: data.aliasName,
|
aliasName: data.aliasName,
|
||||||
levelNumber: data.levelNumber,
|
levelNumber: data.levelNumber,
|
||||||
name: data.name,
|
name: data.name,
|
||||||
|
|
@ -228,7 +246,14 @@ export default function TenantUpdateForm({
|
||||||
control={control}
|
control={control}
|
||||||
name="parentLevelId"
|
name="parentLevelId"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<Select onValueChange={(value) => field.onChange(value && value !== "no-data" ? Number(value) : undefined)} value={field.value?.toString() || ""}>
|
<Select
|
||||||
|
onValueChange={(value) =>
|
||||||
|
field.onChange(
|
||||||
|
value && value !== "no-data" ? Number(value) : undefined
|
||||||
|
)
|
||||||
|
}
|
||||||
|
value={field.value?.toString() || ""}
|
||||||
|
>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="Pilih parent level" />
|
<SelectValue placeholder="Pilih parent level" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
|
|
@ -249,7 +274,9 @@ export default function TenantUpdateForm({
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{errors.parentLevelId && (
|
{errors.parentLevelId && (
|
||||||
<p className="text-red-500 text-sm">{errors.parentLevelId.message}</p>
|
<p className="text-red-500 text-sm">
|
||||||
|
{errors.parentLevelId.message}
|
||||||
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -260,15 +287,25 @@ export default function TenantUpdateForm({
|
||||||
control={control}
|
control={control}
|
||||||
name="provinceId"
|
name="provinceId"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<Select onValueChange={(value) => field.onChange(value && value !== "no-data" ? Number(value) : undefined)} value={field.value?.toString() || ""}>
|
<Select
|
||||||
|
onValueChange={(value) =>
|
||||||
|
field.onChange(
|
||||||
|
value && value !== "no-data" ? Number(value) : undefined
|
||||||
|
)
|
||||||
|
}
|
||||||
|
value={field.value?.toString() || ""}
|
||||||
|
>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="Pilih provinsi" />
|
<SelectValue placeholder="Pilih provinsi" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{provinces.length > 0 ? (
|
{provinces.length > 0 ? (
|
||||||
provinces.map((province) => (
|
provinces.map((province) => (
|
||||||
<SelectItem key={province.id} value={province.id.toString()}>
|
<SelectItem
|
||||||
{province.name}
|
key={province.id}
|
||||||
|
value={province.id.toString()}
|
||||||
|
>
|
||||||
|
{province.prov_name}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -281,7 +318,9 @@ export default function TenantUpdateForm({
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{errors.provinceId && (
|
{errors.provinceId && (
|
||||||
<p className="text-red-500 text-sm">{errors.provinceId.message}</p>
|
<p className="text-red-500 text-sm">
|
||||||
|
{errors.provinceId.message}
|
||||||
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -314,7 +353,9 @@ export default function TenantUpdateForm({
|
||||||
/>
|
/>
|
||||||
<Label>Approval Active</Label>
|
<Label>Approval Active</Label>
|
||||||
{errors.isApprovalActive && (
|
{errors.isApprovalActive && (
|
||||||
<p className="text-red-500 text-sm">{errors.isApprovalActive.message}</p>
|
<p className="text-red-500 text-sm">
|
||||||
|
{errors.isApprovalActive.message}
|
||||||
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import { useAutoWorkflowCheck } from "@/hooks/useWorkflowStatusCheck";
|
||||||
|
|
||||||
const DashCodeHeader = () => {
|
const DashCodeHeader = () => {
|
||||||
// Auto-check workflow status when header mounts
|
// Auto-check workflow status when header mounts
|
||||||
useAutoWorkflowCheck();
|
// useAutoWorkflowCheck();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
||||||
|
|
@ -44,13 +44,10 @@ export const useAuth = (): AuthContextType => {
|
||||||
error: null,
|
error: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check if user is authenticated on mount
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const checkAuth = async () => {
|
const checkAuth = async () => {
|
||||||
try {
|
try {
|
||||||
setState((prev) => ({ ...prev, loading: true }));
|
setState((prev) => ({ ...prev, loading: true }));
|
||||||
// Add logic to check if user is authenticated
|
|
||||||
// This could check for valid tokens, etc.
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setState((prev) => ({
|
setState((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
|
|
|
||||||
|
|
@ -84,9 +84,9 @@ export function getMenuList(pathname: string, t: any): Group[] {
|
||||||
children: [],
|
children: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
href: "/admin/content/teks",
|
href: "/admin/content/text",
|
||||||
label: t("text"),
|
label: t("text"),
|
||||||
active: pathname.includes("/content/teks"),
|
active: pathname.includes("/content/text"),
|
||||||
icon: "heroicons:document",
|
icon: "heroicons:document",
|
||||||
children: [],
|
children: [],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue