feat: update management users
This commit is contained in:
parent
89da265615
commit
3285ccc4b3
|
|
@ -0,0 +1,239 @@
|
|||
"use client";
|
||||
|
||||
import { useRouter } from "@/i18n/routing";
|
||||
import { useParams } from "next/navigation";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { getUserDetail } from "@/service/management-user/management-user";
|
||||
import { useEffect, useState } from "react";
|
||||
import { formatDateToIndonesian } from "@/utils/globals";
|
||||
|
||||
export default function UserDetailPage() {
|
||||
const router = useRouter();
|
||||
const params = useParams();
|
||||
const userId = params?.id ? Number(params.id) : undefined;
|
||||
const [user, setUser] = useState<any>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
async function loadUserDetail() {
|
||||
if (!userId) return;
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await getUserDetail(userId);
|
||||
if (response && !response.error && response.data.data) {
|
||||
setUser(response.data.data);
|
||||
} else {
|
||||
console.error("Gagal mengambil detail user:", response?.message || "Unknown error");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error loading user detail:", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
loadUserDetail();
|
||||
}, [userId]);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="container mx-auto py-6">
|
||||
<Card className="p-6">
|
||||
<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>Loading user detail...</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
return (
|
||||
<div className="container mx-auto py-6">
|
||||
<Card className="p-6">
|
||||
<div className="text-center">
|
||||
<p className="text-red-500 mb-4">User tidak ditemukan</p>
|
||||
<Button onClick={() => router.push("/admin/management-user")}>
|
||||
Kembali ke Management User
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container mx-auto py-6">
|
||||
<Card className="p-6">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h1 className="text-2xl font-semibold">Detail User</h1>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => router.push(`/admin/management-user/edit/${userId}`)}
|
||||
>
|
||||
Edit User
|
||||
</Button>
|
||||
<Button onClick={() => router.push("/admin/management-user")}>
|
||||
Kembali
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{/* Basic Information */}
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-lg font-semibold border-b pb-2">Informasi Dasar</h2>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">ID</label>
|
||||
<p className="text-lg font-mono">{user.id}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Nama Lengkap</label>
|
||||
<p className="text-lg font-semibold">{user.fullname}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Username</label>
|
||||
<p className="text-lg font-mono">{user.username}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Email</label>
|
||||
<p className="text-lg">{user.email}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">No. HP</label>
|
||||
<p className="text-lg">{user.phoneNumber}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Alamat</label>
|
||||
<p className="text-lg">{user.address || "-"}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Tanggal Lahir</label>
|
||||
<p className="text-lg">{user.dateOfBirth ? formatDateToIndonesian(user.dateOfBirth) : "-"}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* System Information */}
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-lg font-semibold border-b pb-2">Informasi Sistem</h2>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">User Role ID</label>
|
||||
<p className="text-lg font-mono">{user.userRoleId}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">User Level ID</label>
|
||||
<p className="text-lg font-mono">{user.userLevelId}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Level Group</label>
|
||||
<p className="text-lg">{user.userLevelGroup || "-"}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Status ID</label>
|
||||
<p className="text-lg font-mono">{user.statusId}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Keycloak ID</label>
|
||||
<p className="text-xs font-mono break-all bg-gray-100 p-2 rounded">{user.keycloakId}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Dibuat Oleh</label>
|
||||
<p className="text-lg">{user.createdById ? `User ID: ${user.createdById}` : "System"}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Status & Timeline */}
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-lg font-semibold border-b pb-2">Status & Timeline</h2>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Status Aktif</label>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className={`w-3 h-3 rounded-full ${user.isActive ? 'bg-green-500' : 'bg-red-500'}`}></div>
|
||||
<p className={`text-lg font-semibold ${user.isActive ? 'text-green-600' : 'text-red-600'}`}>
|
||||
{user.isActive ? 'Aktif' : 'Tidak Aktif'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Tanggal Dibuat</label>
|
||||
<p className="text-lg">{formatDateToIndonesian(user.createdAt)}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Tanggal Terakhir Diupdate</label>
|
||||
<p className="text-lg">{formatDateToIndonesian(user.updatedAt)}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Foto Profil</label>
|
||||
<p className="text-lg">{user.profilePicturePath ? "Tersedia" : "Tidak ada"}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Additional Information (only show if data exists) */}
|
||||
{(user.genderType || user.identityType || user.identityNumber || user.lastEducation || user.workType) && (
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-lg font-semibold border-b pb-2">Informasi Tambahan</h2>
|
||||
|
||||
{user.genderType && (
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Jenis Kelamin</label>
|
||||
<p className="text-lg">{user.genderType}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{user.identityType && (
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Tipe Identitas</label>
|
||||
<p className="text-lg">{user.identityType}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{user.identityNumber && (
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Nomor Identitas</label>
|
||||
<p className="text-lg font-mono">{user.identityNumber}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{user.lastEducation && (
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Pendidikan Terakhir</label>
|
||||
<p className="text-lg">{user.lastEducation}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{user.workType && (
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-600">Jenis Pekerjaan</label>
|
||||
<p className="text-lg">{user.workType}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
"use client";
|
||||
|
||||
import { useRouter, useParams } from "@/i18n/routing";
|
||||
import { useRouter } from "@/i18n/routing";
|
||||
import UserForm from "@/components/form/user/user-form";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
|
||||
export default function EditUserPage() {
|
||||
const router = useRouter();
|
||||
const params = useParams();
|
||||
const params = useSearchParams();
|
||||
const userId = params?.id ? Number(params.id) : undefined;
|
||||
|
||||
const handleSuccess = () => {
|
||||
|
|
@ -42,4 +43,4 @@ export default function EditUserPage() {
|
|||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,733 +0,0 @@
|
|||
"use client";
|
||||
|
||||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { Check, ChevronsUpDown } from "lucide-react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
import { cn, getCookiesDecrypt } from "@/lib/utils";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Command,
|
||||
CommandEmpty,
|
||||
CommandGroup,
|
||||
CommandInput,
|
||||
CommandItem,
|
||||
CommandList,
|
||||
} from "@/components/ui/command";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Link, useRouter } from "@/i18n/routing";
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||
import dynamic from "next/dynamic";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import Swal from "sweetalert2";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import { close, error, loading } from "@/config/swal";
|
||||
import { useParams } from "next/navigation";
|
||||
import { AdministrationLevelList, getListCompetencies, getListEducation, getListSchools, getUserById, saveUserInternal } from "@/service/service/management-user/management-user";
|
||||
|
||||
const sns = [
|
||||
{
|
||||
key: 1,
|
||||
id: "comment",
|
||||
typeId: 1,
|
||||
name: "Komentar Konten",
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
id: "fb",
|
||||
typeId: 2,
|
||||
name: "Facebook",
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
id: "ig",
|
||||
typeId: 3,
|
||||
name: "Instagram",
|
||||
},
|
||||
{
|
||||
key: 4,
|
||||
id: "twt",
|
||||
typeId: 4,
|
||||
name: "Twitter",
|
||||
},
|
||||
{
|
||||
key: 5,
|
||||
id: "yt",
|
||||
typeId: 5,
|
||||
name: "Youtube",
|
||||
},
|
||||
{
|
||||
key: 6,
|
||||
id: "emergency",
|
||||
typeId: 6,
|
||||
name: "Emergency Issue",
|
||||
},
|
||||
{
|
||||
key: 7,
|
||||
id: "email",
|
||||
typeId: 7,
|
||||
name: "Email",
|
||||
},
|
||||
{
|
||||
key: 8,
|
||||
id: "inbox",
|
||||
typeId: 8,
|
||||
name: "Pesan Masuk",
|
||||
},
|
||||
{
|
||||
key: 9,
|
||||
id: "whatsapp",
|
||||
typeId: 9,
|
||||
name: "Whatssapp",
|
||||
},
|
||||
{
|
||||
key: 10,
|
||||
id: "tiktok",
|
||||
typeId: 10,
|
||||
name: "Tiktok",
|
||||
},
|
||||
];
|
||||
|
||||
interface RoleData {
|
||||
id: number;
|
||||
label: string;
|
||||
name: string;
|
||||
value: string;
|
||||
levelNumber: number;
|
||||
}
|
||||
|
||||
const FormSchema = z.object({
|
||||
level: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
fullname: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
username: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
role: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
nrp: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
address: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
email: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
phoneNumber: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
password: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
confirmPassword: z.string({
|
||||
required_error: "Required",
|
||||
}),
|
||||
isValidPassword: z.boolean().refine((val) => val === true, {
|
||||
message: "Check Password",
|
||||
}),
|
||||
sns: z.array(z.string()).optional(),
|
||||
education: z.string().optional(),
|
||||
school: z.string().optional(),
|
||||
competency: z.string().optional(),
|
||||
});
|
||||
|
||||
export default function DetailUserForm() {
|
||||
const router = useRouter();
|
||||
const params = useParams();
|
||||
const id = params?.id;
|
||||
const MySwal = withReactContent(Swal);
|
||||
const levelName = getCookiesDecrypt("ulnae");
|
||||
const [roleList, setRoleList] = useState<RoleData[]>([]);
|
||||
|
||||
const [userEducations, setUserEducations] = useState<any>();
|
||||
const [userSchools, setUserSchools] = useState<any>();
|
||||
const [userCompetencies, setUserCompetencies] = useState<any>();
|
||||
|
||||
const form = useForm<z.infer<typeof FormSchema>>({
|
||||
resolver: zodResolver(FormSchema),
|
||||
defaultValues: {
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
sns: [],
|
||||
education: "1",
|
||||
school: "4",
|
||||
competency: "2",
|
||||
},
|
||||
});
|
||||
|
||||
const selectedRole = form.watch("role");
|
||||
|
||||
useEffect(() => {
|
||||
getDataAdditional();
|
||||
initData();
|
||||
}, []);
|
||||
|
||||
const initData = async () => {
|
||||
loading();
|
||||
const response = await getUserById(String(id));
|
||||
const res = response?.data?.data;
|
||||
close();
|
||||
console.log("res", res);
|
||||
if (Number(res.roleId) > 4) {
|
||||
form.setValue("fullname", res?.fullname);
|
||||
form.setValue("username", res?.username);
|
||||
form.setValue("phoneNumber", res?.phoneNumber);
|
||||
form.setValue("nrp", res?.memberIdentity);
|
||||
form.setValue("address", res?.address);
|
||||
form.setValue("email", res?.email);
|
||||
form.setValue("role", res?.role?.code);
|
||||
form.setValue("level", String(res?.userLevelId));
|
||||
} else {
|
||||
initFetch();
|
||||
console.log("sadad", res?.role?.code);
|
||||
form.setValue("fullname", res?.fullname);
|
||||
form.setValue("username", res?.username);
|
||||
form.setValue("phoneNumber", res?.phoneNumber);
|
||||
form.setValue("nrp", res?.memberIdentity);
|
||||
form.setValue("address", res?.address);
|
||||
form.setValue("email", res?.email);
|
||||
form.setValue("role", res?.role?.code);
|
||||
form.setValue("level", String(res?.userLevelId));
|
||||
}
|
||||
};
|
||||
const initFetch = async () => {
|
||||
const response = await AdministrationLevelList();
|
||||
const res = response?.data?.data;
|
||||
var levelsArr: RoleData[] = [];
|
||||
res.forEach((levels: RoleData) => {
|
||||
levelsArr.push({
|
||||
id: levels.id,
|
||||
label: levels.name,
|
||||
name: levels.name,
|
||||
value: String(levels.id),
|
||||
levelNumber: levels.levelNumber,
|
||||
});
|
||||
});
|
||||
setRoleList(levelsArr);
|
||||
};
|
||||
|
||||
async function getDataAdditional() {
|
||||
const resEducations = await getListEducation();
|
||||
setUserEducations(resEducations?.data?.data);
|
||||
const resSchools = await getListSchools();
|
||||
setUserSchools(resSchools?.data?.data);
|
||||
const resCompetencies = await getListCompetencies();
|
||||
setUserCompetencies(resCompetencies?.data?.data);
|
||||
}
|
||||
|
||||
const roles =
|
||||
levelName == "MABES POLRI"
|
||||
? [
|
||||
{
|
||||
id: "ADM-ID",
|
||||
name: "Admin",
|
||||
},
|
||||
{
|
||||
id: "APP-ID",
|
||||
name: "Approver",
|
||||
},
|
||||
{
|
||||
id: "CON-ID",
|
||||
name: "Kontributor",
|
||||
},
|
||||
{
|
||||
id: "SPV-ID",
|
||||
name: "Supervisor Feedback Center",
|
||||
},
|
||||
{
|
||||
id: "OPT-ID",
|
||||
name: "Operator Feedback Center",
|
||||
},
|
||||
{
|
||||
id: "KKUR-ID",
|
||||
name: "Koor Kurator",
|
||||
},
|
||||
{
|
||||
id: "KUR-ID",
|
||||
name: "Kurator",
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
id: "APP-ID",
|
||||
name: "Approver",
|
||||
},
|
||||
{
|
||||
id: "CON-ID",
|
||||
name: "Kontributor",
|
||||
},
|
||||
];
|
||||
|
||||
async function save(data: z.infer<typeof FormSchema>) {
|
||||
let req: any = {
|
||||
id: id,
|
||||
firstName: data.fullname,
|
||||
username: data.username,
|
||||
roleId: data.role,
|
||||
userLevelId: Number(data.level),
|
||||
memberIdentity: data.nrp,
|
||||
address: data.address,
|
||||
email: data.email,
|
||||
password: data.password,
|
||||
passwordConf: data.confirmPassword,
|
||||
isDefault: false,
|
||||
};
|
||||
|
||||
if (data.role == "OPT-ID") {
|
||||
req.handledSocialMedia = data?.sns ? data.sns.join(",") : "";
|
||||
}
|
||||
|
||||
if (data.role == "KUR-ID") {
|
||||
req.userEducationId = Number(data.education);
|
||||
req.userSchoolsId = Number(data.school);
|
||||
req.userCompetencyId = Number(data.competency);
|
||||
}
|
||||
|
||||
loading();
|
||||
const response = await saveUserInternal(req);
|
||||
|
||||
if (response?.error) {
|
||||
error(response.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
close();
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
icon: "success",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "Simpan",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
router.push("/admin/management-user");
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
async function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||
MySwal.fire({
|
||||
title: "Simpan Data?",
|
||||
text: "",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "Simpan",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
save(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<Form {...form}>
|
||||
<form
|
||||
onSubmit={form.handleSubmit(onSubmit)}
|
||||
className="space-y-6 bg-white p-10 w-full"
|
||||
>
|
||||
<p className="text-xl">Data Pengelola Media Hub</p>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="level"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-col">
|
||||
<FormLabel>Pilih Level</FormLabel>
|
||||
<Popover>
|
||||
<PopoverTrigger asChild disabled>
|
||||
<FormControl>
|
||||
<Button
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
className={cn(
|
||||
"w-[400px] justify-between",
|
||||
!field.value && "text-muted-foreground"
|
||||
)}
|
||||
>
|
||||
{field.value
|
||||
? roleList.find((role) => role.value === field.value)
|
||||
?.label
|
||||
: "Pilih level"}
|
||||
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</FormControl>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-[400px] p-0">
|
||||
<Command>
|
||||
<CommandInput />
|
||||
<CommandList>
|
||||
<CommandEmpty>No role found.</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{roleList.map((role) => (
|
||||
<CommandItem
|
||||
value={role.label}
|
||||
key={role.value}
|
||||
onSelect={() => {
|
||||
form.setValue("level", role.value);
|
||||
}}
|
||||
>
|
||||
{role.label}
|
||||
<Check
|
||||
className={cn(
|
||||
"ml-auto",
|
||||
role.value === field.value
|
||||
? "opacity-100"
|
||||
: "opacity-0"
|
||||
)}
|
||||
/>
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="fullname"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Nama Lengkap</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder="Masukkan nama lengkap"
|
||||
{...field}
|
||||
readOnly
|
||||
className="w-1/2"
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="username"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder="Masukkan username"
|
||||
{...field}
|
||||
readOnly
|
||||
className="w-1/2"
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="role"
|
||||
render={({ field }) => (
|
||||
<FormItem className="space-y-3">
|
||||
<FormLabel>Role</FormLabel>
|
||||
<FormControl>
|
||||
<RadioGroup
|
||||
onValueChange={field.onChange}
|
||||
value={field.value}
|
||||
className="flex flex-wrap gap-3 w-1/2"
|
||||
disabled
|
||||
>
|
||||
{roles.map((role) => (
|
||||
<FormItem
|
||||
key={role.id}
|
||||
className="flex items-center space-x-3 space-y-0"
|
||||
>
|
||||
<FormControl>
|
||||
<RadioGroupItem value={role.id} />
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal">
|
||||
{role.name}
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
))}
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{selectedRole === "OPT-ID" && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="sns"
|
||||
render={() => (
|
||||
<FormItem>
|
||||
<div className="mb-4">
|
||||
<FormLabel>Social Media Yang Ditangani</FormLabel>
|
||||
</div>
|
||||
<div className="grid grid-cols-5 gap-2 w-1/2">
|
||||
{sns.map((item) => (
|
||||
<FormField
|
||||
key={item.id}
|
||||
control={form.control}
|
||||
name="sns"
|
||||
render={({ field }) => {
|
||||
return (
|
||||
<FormItem
|
||||
key={item.typeId}
|
||||
className="flex flex-row items-start space-x-3 space-y-0"
|
||||
>
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
disabled
|
||||
checked={field.value?.includes(
|
||||
String(item.typeId)
|
||||
)}
|
||||
onCheckedChange={(checked) => {
|
||||
return checked
|
||||
? field.onChange([
|
||||
...(field.value || []),
|
||||
String(item.typeId),
|
||||
])
|
||||
: field.onChange(
|
||||
(field.value || []).filter(
|
||||
(value) =>
|
||||
value !== String(item.typeId)
|
||||
)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormLabel className="font-normal">
|
||||
{item.name}
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{selectedRole === "KUR-ID" && (
|
||||
<>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="education"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Pendidikan Terakhir</FormLabel>
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
value={field.value}
|
||||
disabled
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{userEducations?.map((edu: any) => (
|
||||
<SelectItem key={edu.id} value={String(edu.id)}>
|
||||
{edu.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="school"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Universitas / Perguruan Tinggi</FormLabel>
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
value={field.value}
|
||||
disabled
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{userSchools?.map((edu: any) => (
|
||||
<SelectItem key={edu.id} value={String(edu.id)}>
|
||||
{edu.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="competency"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Kompetensi</FormLabel>
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
value={field.value}
|
||||
disabled
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{userCompetencies?.map((edu: any) => (
|
||||
<SelectItem key={edu.id} value={String(edu.id)}>
|
||||
{edu.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="nrp"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Nomor Regitrasi Polri {`(NRP)`}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
type="number"
|
||||
placeholder="Masukkan NRP"
|
||||
readOnly
|
||||
{...field}
|
||||
className="w-1/2"
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="address"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Alamat</FormLabel>
|
||||
<FormControl>
|
||||
<Textarea
|
||||
placeholder="Masukkan alamat"
|
||||
readOnly
|
||||
className="resize-none w-1/2"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Email</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
type="email"
|
||||
readOnly
|
||||
placeholder="Masukkan email"
|
||||
{...field}
|
||||
className="w-1/2"
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="phoneNumber"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>No. Handphone</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
type="number"
|
||||
placeholder="Masukkan nomor handphone"
|
||||
{...field}
|
||||
readOnly
|
||||
className="w-1/2 mb-2"
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Link href="/admin/management-user">
|
||||
<Button type="button" color="primary" variant="outline">
|
||||
Back
|
||||
</Button>
|
||||
</Link>
|
||||
</form>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -32,17 +32,13 @@ export default function ManagementUser() {
|
|||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<section id="viz">
|
||||
<ManagementUserVisualization />
|
||||
</section>
|
||||
|
||||
<section className="flex flex-col gap-2 bg-slate-50 dark:bg-black rounded-lg p-3 mt-5 border">
|
||||
<div className="flex justify-between py-3">
|
||||
<p className="text-lg">
|
||||
Data User {isInternal ? "Internal" : "Eksternal"}
|
||||
Data User
|
||||
</p>
|
||||
{isInternal && (
|
||||
<Link href="/admin/management-user/internal/create">
|
||||
<Link href="/admin/management-user/create">
|
||||
<Button color="primary" size="md">
|
||||
<PlusIcon />
|
||||
Add User
|
||||
|
|
@ -51,31 +47,7 @@ export default function ManagementUser() {
|
|||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row gap-1 border-2 rounded-md w-fit mb-5">
|
||||
<Button
|
||||
rounded="md"
|
||||
onClick={() => setIsInternal(true)}
|
||||
className={`hover:text-white ${
|
||||
!isInternal ? "bg-white text-black" : "bg-black text-white"
|
||||
}`}
|
||||
>
|
||||
User Internal
|
||||
</Button>
|
||||
|
||||
{showExternalButton && (
|
||||
<Button
|
||||
rounded="md"
|
||||
onClick={() => setIsInternal(false)}
|
||||
className={`hover:text-white ${
|
||||
!isInternal ? "bg-black text-white" : "bg-white text-black"
|
||||
}`}
|
||||
>
|
||||
User Eksternal
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{isInternal ? <UserInternalTable /> : <UserExternalTable />}
|
||||
<UserInternalTable />
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -148,10 +148,8 @@ export default function FormImage() {
|
|||
|
||||
const options: Option[] = [
|
||||
{ id: "all", label: "SEMUA" },
|
||||
{ id: "5", label: "UMUM" },
|
||||
{ id: "6", label: "JOURNALIS" },
|
||||
{ id: "7", label: "POLRI" },
|
||||
{ id: "8", label: "KSP" },
|
||||
{ id: "4", label: "UMUM" },
|
||||
{ id: "5", label: "JOURNALIS" },
|
||||
];
|
||||
|
||||
type FileWithPreview = File & {
|
||||
|
|
|
|||
|
|
@ -17,12 +17,25 @@ import {
|
|||
createUser,
|
||||
updateUser,
|
||||
getUserDetail,
|
||||
AdministrationLevelList,
|
||||
CreateUserRequest,
|
||||
UpdateUserRequest
|
||||
} from "@/service/service/management-user/management-user";
|
||||
} from "@/service/management-user/management-user";
|
||||
import { getInfoProfile } from "@/service/auth";
|
||||
import { getUserLevels } from "@/service/approval-workflows";
|
||||
|
||||
const userSchema = z.object({
|
||||
const createUserSchema = z.object({
|
||||
address: z.string().trim().min(1, { message: "Address wajib diisi" }),
|
||||
clientId: z.string().trim().min(1, { message: "Client ID wajib diisi" }),
|
||||
dateOfBirth: z.string().trim().min(1, { message: "Date of Birth wajib diisi" }),
|
||||
email: z.string().email({ message: "Email tidak valid" }),
|
||||
fullname: z.string().trim().min(1, { message: "Full Name wajib diisi" }),
|
||||
password: z.string().min(6, { message: "Password minimal 6 karakter" }),
|
||||
phoneNumber: z.string().trim().min(1, { message: "Phone Number wajib diisi" }),
|
||||
userLevelId: z.number({ invalid_type_error: "User Level harus dipilih" }),
|
||||
username: z.string().trim().min(1, { message: "Username wajib diisi" }),
|
||||
});
|
||||
|
||||
const editUserSchema = z.object({
|
||||
address: z.string().trim().min(1, { message: "Address wajib diisi" }),
|
||||
clientId: z.string().trim().min(1, { message: "Client ID wajib diisi" }),
|
||||
dateOfBirth: z.string().trim().min(1, { message: "Date of Birth wajib diisi" }),
|
||||
|
|
@ -34,7 +47,9 @@ const userSchema = z.object({
|
|||
username: z.string().trim().min(1, { message: "Username wajib diisi" }),
|
||||
});
|
||||
|
||||
type UserSchema = z.infer<typeof userSchema>;
|
||||
type CreateUserSchema = z.infer<typeof createUserSchema>;
|
||||
type EditUserSchema = z.infer<typeof editUserSchema>;
|
||||
type UserSchema = CreateUserSchema | EditUserSchema;
|
||||
|
||||
interface UserFormProps {
|
||||
id?: number;
|
||||
|
|
@ -53,6 +68,7 @@ export default function UserForm({
|
|||
const MySwal = withReactContent(Swal);
|
||||
const [loadingData, setLoadingData] = useState(false);
|
||||
const [userLevels, setUserLevels] = useState<{id: number; name: string}[]>([]);
|
||||
const [currentClientId, setCurrentClientId] = useState<string>("");
|
||||
|
||||
const {
|
||||
control,
|
||||
|
|
@ -60,7 +76,7 @@ export default function UserForm({
|
|||
setValue,
|
||||
formState: { errors },
|
||||
} = useForm<UserSchema>({
|
||||
resolver: zodResolver(userSchema),
|
||||
resolver: zodResolver(mode === "create" ? createUserSchema : editUserSchema),
|
||||
defaultValues: {
|
||||
address: "",
|
||||
clientId: "",
|
||||
|
|
@ -78,30 +94,48 @@ export default function UserForm({
|
|||
async function loadData() {
|
||||
setLoadingData(true);
|
||||
try {
|
||||
const [userLevelsResponse] = await Promise.all([
|
||||
AdministrationLevelList(),
|
||||
const [userLevelsResponse, userInfoResponse] = await Promise.all([
|
||||
getUserLevels(),
|
||||
getInfoProfile(),
|
||||
]);
|
||||
|
||||
if (!userLevelsResponse?.error) {
|
||||
setUserLevels(userLevelsResponse?.data?.data || []);
|
||||
}
|
||||
|
||||
// Get clientId from current user info
|
||||
if (!userInfoResponse?.error && userInfoResponse?.data?.data) {
|
||||
const userInfo = userInfoResponse.data.data;
|
||||
const clientId = userInfo.instituteId || "78356d32-52fa-4dfc-b836-6cebf4e3eead"; // fallback to default
|
||||
setCurrentClientId(clientId);
|
||||
setValue("clientId", clientId);
|
||||
} else {
|
||||
// Fallback to default clientId if UserInfo fails
|
||||
const defaultClientId = "78356d32-52fa-4dfc-b836-6cebf4e3eead";
|
||||
setCurrentClientId(defaultClientId);
|
||||
setValue("clientId", defaultClientId);
|
||||
}
|
||||
|
||||
// Load user detail if in edit mode
|
||||
if (mode === "edit" && id) {
|
||||
const userResponse = await getUserDetail(id);
|
||||
if (!userResponse.error && userResponse.data) {
|
||||
const user = userResponse.data;
|
||||
setValue("address", user.address || "");
|
||||
setValue("clientId", user.clientId || "");
|
||||
setValue("dateOfBirth", user.dateOfBirth || "");
|
||||
setValue("email", user.email || "");
|
||||
setValue("fullname", user.fullname || "");
|
||||
setValue("phoneNumber", user.phoneNumber || "");
|
||||
setValue("userLevelId", user.userLevelId || 0);
|
||||
setValue("username", user.username || "");
|
||||
// Don't set password for edit mode
|
||||
} else {
|
||||
console.error("Gagal mengambil detail user:", userResponse.message);
|
||||
try {
|
||||
const userResponse = await getUserDetail(id);
|
||||
if (userResponse && !userResponse.error && userResponse.data) {
|
||||
const user = userResponse.data;
|
||||
setValue("address", user.address || "");
|
||||
setValue("clientId", user.clientId || "");
|
||||
setValue("dateOfBirth", user.dateOfBirth || "");
|
||||
setValue("email", user.email || "");
|
||||
setValue("fullname", user.fullname || "");
|
||||
setValue("phoneNumber", user.phoneNumber || "");
|
||||
setValue("userLevelId", user.userLevelId || 0);
|
||||
setValue("username", user.username || "");
|
||||
// Don't set password for edit mode
|
||||
} else {
|
||||
console.error("Gagal mengambil detail user:", userResponse?.message || "Unknown error");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error loading user detail:", error);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
|
|
@ -294,12 +328,20 @@ export default function UserForm({
|
|||
control={control}
|
||||
name="clientId"
|
||||
render={({ field }) => (
|
||||
<Input {...field} placeholder="Masukkan client ID" />
|
||||
<Input
|
||||
{...field}
|
||||
placeholder="Client ID akan diambil dari profil Anda"
|
||||
readOnly
|
||||
className="bg-gray-50"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.clientId && (
|
||||
<p className="text-red-500 text-sm">{errors.clientId.message}</p>
|
||||
)}
|
||||
<p className="text-xs text-gray-500 mt-1">
|
||||
Client ID diambil dari profil pengguna yang sedang login
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* User Level */}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ const columns: ColumnDef<any>[] = [
|
|||
header: "Username",
|
||||
cell: ({ row }) => (
|
||||
<span className="normal-case">
|
||||
{row.original?.userKeycloak?.username || ""}
|
||||
{row.getValue("username")}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
|
|
@ -52,10 +52,17 @@ const columns: ColumnDef<any>[] = [
|
|||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "level",
|
||||
header: "Level Pengguna",
|
||||
accessorKey: "userLevelGroup",
|
||||
header: "Level Group",
|
||||
cell: ({ row }) => (
|
||||
<span className="normal-case">{row.original.userLevel.name}</span>
|
||||
<span className="normal-case">{row.getValue("userLevelGroup") || "-"}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "statusId",
|
||||
header: "Status ID",
|
||||
cell: ({ row }) => (
|
||||
<span>{row.getValue("statusId")}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
|
|
@ -138,14 +145,14 @@ const columns: ColumnDef<any>[] = [
|
|||
<DropdownMenuContent className="p-0" align="end">
|
||||
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||
<Link
|
||||
href={`/admin/management-user/internal/detail/${row.original.id}`}
|
||||
href={`/admin/management-user/detail/${row.original.id}`}
|
||||
>
|
||||
Detail
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||
<Link
|
||||
href={`/admin/management-user/internal/edit/${row.original.id}`}
|
||||
href={`/admin/management-user/edit/${row.original.id}`}
|
||||
>
|
||||
Edit
|
||||
</Link>
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ const UserInternalTable = () => {
|
|||
totalPage: 10,
|
||||
});
|
||||
|
||||
const data = res?.data;
|
||||
const data = res?.data?.data;
|
||||
const contentData = Array.isArray(data)
|
||||
? data
|
||||
: data?.content || data?.items || [];
|
||||
|
|
|
|||
270
lib/menus.ts
270
lib/menus.ts
|
|
@ -55,43 +55,43 @@ export function getMenuList(pathname: string, t: any): Group[] {
|
|||
},
|
||||
],
|
||||
},
|
||||
...(roleId === 2
|
||||
...(roleId === 3
|
||||
? [
|
||||
{
|
||||
groupLabel: "Content Management",
|
||||
groupLabel: "",
|
||||
id: "content",
|
||||
menus: [
|
||||
{
|
||||
id: "content",
|
||||
href: "/admin/content/image",
|
||||
label: "Content",
|
||||
label: t("content"),
|
||||
active: pathname.includes("/content"),
|
||||
icon: "line-md:youtube",
|
||||
submenus: [
|
||||
{
|
||||
href: "/admin/content/image",
|
||||
label: "Image",
|
||||
label: t("image"),
|
||||
active: pathname.includes("/content/image"),
|
||||
icon: "ic:outline-image",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "/admin/content/audio-visual",
|
||||
label: "Audio Visual",
|
||||
active: pathname.includes("/content/audio-visual"),
|
||||
href: "/admin/content/video",
|
||||
label: t("video"),
|
||||
active: pathname.includes("/content/video"),
|
||||
icon: "line-md:youtube",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "/admin/content/document",
|
||||
label: "Document",
|
||||
active: pathname.includes("/content/document"),
|
||||
href: "/admin/content/teks",
|
||||
label: t("text"),
|
||||
active: pathname.includes("/content/teks"),
|
||||
icon: "heroicons:document",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "/admin/content/audio",
|
||||
label: "Audio",
|
||||
label: t("audio"),
|
||||
active: pathname.includes("/content/audio"),
|
||||
icon: "heroicons:share",
|
||||
children: [],
|
||||
|
|
@ -100,10 +100,45 @@ export function getMenuList(pathname: string, t: any): Group[] {
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
groupLabel: "",
|
||||
id: "settings",
|
||||
menus: [
|
||||
{
|
||||
id: "settings",
|
||||
href: "/admin/settings",
|
||||
label: t("settings"),
|
||||
active: pathname.includes("/settinng"),
|
||||
icon: "material-symbols:settings",
|
||||
submenus: [
|
||||
{
|
||||
href: "/admin/categories",
|
||||
label: t("category"),
|
||||
active: pathname === "/admin/settings/category",
|
||||
icon: "heroicons:arrow-trending-up",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "/admin/settings/tag",
|
||||
label: "Tag",
|
||||
active: pathname === "/admin/settings/tag",
|
||||
icon: "heroicons:arrow-trending-up",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "/admin/settings/banner",
|
||||
label: "Banner",
|
||||
active: pathname === "/admin/settings/banner",
|
||||
icon: "heroicons:arrow-trending-up",
|
||||
children: [],
|
||||
},
|
||||
]
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
: []),
|
||||
|
||||
...(roleId === 3
|
||||
...(roleId === 2
|
||||
? [
|
||||
{
|
||||
groupLabel: "",
|
||||
|
|
@ -119,124 +154,6 @@ export function getMenuList(pathname: string, t: any): Group[] {
|
|||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
// {
|
||||
// groupLabel: "Master Data",
|
||||
// id: "master-data",
|
||||
// menus: [
|
||||
// {
|
||||
// id: "categories",
|
||||
// href: "/admin/categories",
|
||||
// label: "Master Data",
|
||||
// active: pathname.includes("/categories"),
|
||||
// icon: "pixelarticons:calendar-text",
|
||||
// submenus: [
|
||||
// {
|
||||
// href: "/admin/categories",
|
||||
// label: "Categories",
|
||||
// active: pathname.includes("/categories"),
|
||||
// icon: "ic:outline-image",
|
||||
// children: [],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// groupLabel: "",
|
||||
// id: "agenda-setting",
|
||||
// menus: [
|
||||
// {
|
||||
// id: "agenda-setting",
|
||||
// href: "/admin/agenda-setting",
|
||||
// label: t("agenda-setting"),
|
||||
// active: pathname.includes("/agenda-setting"),
|
||||
// icon: "iconoir:journal-page",
|
||||
// submenus: [],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// groupLabel: "",
|
||||
// id: "schedule",
|
||||
// menus: [
|
||||
// {
|
||||
// id: "schedule",
|
||||
// href: "/admin/schedule",
|
||||
// label: t("schedule"),
|
||||
// active: pathname.includes("/schedule"),
|
||||
// icon: "uil:schedule",
|
||||
// submenus: [
|
||||
// {
|
||||
// href: "/admin/schedule/live-report",
|
||||
// label: t("live-report"),
|
||||
// active: pathname.includes("/schedule/live-report"),
|
||||
// icon: "heroicons:arrow-trending-up",
|
||||
// children: [],
|
||||
// },
|
||||
// // {
|
||||
// // href: "/contributor/schedule/press-conference",
|
||||
// // label: t("press-conference"),
|
||||
// // active: pathname.includes("/schedule/press-conference"),
|
||||
// // icon: "heroicons:arrow-trending-up",
|
||||
// // children: [],
|
||||
// // },
|
||||
// // {
|
||||
// // href: "/contributor/schedule/event",
|
||||
// // label: "event",
|
||||
// // active: pathname.includes("/schedule/event"),
|
||||
// // icon: "heroicons:shopping-cart",
|
||||
// // children: [],
|
||||
// // },
|
||||
// // {
|
||||
// // href: "/contributor/schedule/press-release",
|
||||
// // label: t("press-release"),
|
||||
// // active: pathname.includes("/schedule/press-release"),
|
||||
// // icon: "heroicons:shopping-cart",
|
||||
// // children: [],
|
||||
// // },
|
||||
// // {
|
||||
// // href: "/contributor/schedule/calendar-polri",
|
||||
// // label: t("calendar-polri"),
|
||||
// // active: pathname.includes("/schedule/calendar-polri"),
|
||||
// // icon: "heroicons:arrow-trending-up",
|
||||
// // children: [],
|
||||
// // },
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// groupLabel: "",
|
||||
// id: "task",
|
||||
// menus: [
|
||||
// {
|
||||
// id: "task",
|
||||
// href: "/admin/task",
|
||||
// label: t("task"),
|
||||
// active: pathname.includes("/task"),
|
||||
// icon: "fluent:clipboard-task-add-24-regular",
|
||||
// submenus: [],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// groupLabel: "",
|
||||
// id: "communication",
|
||||
// menus: [
|
||||
// {
|
||||
// id: "communication",
|
||||
// href: "/admin/shared/communication",
|
||||
// label: t("communication"),
|
||||
// active: pathname.includes("/communication"),
|
||||
// icon: "token:chat",
|
||||
// submenus: [],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
...(roleId === 3
|
||||
? [
|
||||
{
|
||||
groupLabel: "",
|
||||
id: "tenant",
|
||||
|
|
@ -246,57 +163,44 @@ export function getMenuList(pathname: string, t: any): Group[] {
|
|||
href: "/admin/settings/tenant",
|
||||
label: "Tenant",
|
||||
active: pathname.includes("/tenant"),
|
||||
icon: "token:chat",
|
||||
icon: "material-symbols:domain",
|
||||
submenus: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(roleId === 2
|
||||
? [
|
||||
{
|
||||
groupLabel: "Settings",
|
||||
id: "settings",
|
||||
menus: [
|
||||
{
|
||||
id: "settings",
|
||||
href: "/admin/settings",
|
||||
label: "Settings",
|
||||
active: pathname.includes("/settings"),
|
||||
icon: "heroicons:cog-6-tooth",
|
||||
submenus: [
|
||||
{
|
||||
href: "/admin/categories",
|
||||
label: "Categories",
|
||||
active: pathname.includes("/categories"),
|
||||
icon: "ic:outline-image",
|
||||
children: [],
|
||||
},
|
||||
// kalau nanti Tenant mau dimunculkan lagi:
|
||||
// {
|
||||
// href: "/admin/settings/tenant",
|
||||
// label: "Tenant",
|
||||
// active: pathname.includes("/tenant"),
|
||||
// icon: "ic:outline-image",
|
||||
// children: [],
|
||||
// },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
// ...(roleId === 2
|
||||
// ? [
|
||||
// {
|
||||
// groupLabel: "Settings",
|
||||
// id: "settings",
|
||||
// menus: [
|
||||
// {
|
||||
// id: "settings",
|
||||
// href: "/admin/settings",
|
||||
// label: "Settings",
|
||||
// active: pathname.includes("/settings"),
|
||||
// icon: "heroicons:cog-6-tooth",
|
||||
// submenus: [
|
||||
// {
|
||||
// href: "/admin/categories",
|
||||
// label: "Categories",
|
||||
// active: pathname.includes("/categories"),
|
||||
// icon: "ic:outline-image",
|
||||
// children: [],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ]
|
||||
// : []),
|
||||
];
|
||||
return menusSelected;
|
||||
}
|
||||
|
||||
if (
|
||||
(Number(roleId) == 3 || Number(roleId) == 14) &&
|
||||
Number(levelNumber) == 1
|
||||
) {
|
||||
const hideForRole14 = Number(roleId) === 14;
|
||||
|
||||
if (Number(roleId) == 3 && Number(levelNumber) == 1) {
|
||||
menusSelected = [
|
||||
{
|
||||
groupLabel: t("apps"),
|
||||
|
|
@ -351,17 +255,17 @@ export function getMenuList(pathname: string, t: any): Group[] {
|
|||
icon: "heroicons:share",
|
||||
children: [],
|
||||
},
|
||||
...(!hideForRole14
|
||||
? [
|
||||
{
|
||||
href: "/contributor/content/spit",
|
||||
label: "spit",
|
||||
active: pathname.includes("/content/spit"),
|
||||
icon: "heroicons:credit-card",
|
||||
children: [],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
// ...(!hideForRole14
|
||||
// ? [
|
||||
// {
|
||||
// href: "/contributor/content/spit",
|
||||
// label: "spit",
|
||||
// active: pathname.includes("/content/spit"),
|
||||
// icon: "heroicons:credit-card",
|
||||
// children: [],
|
||||
// },
|
||||
// ]
|
||||
// : []),
|
||||
// {
|
||||
// href: "/contributor/content/nulis-ai",
|
||||
// label: "nulis ai",
|
||||
|
|
|
|||
|
|
@ -2,8 +2,28 @@ import {
|
|||
httpDeleteInterceptor,
|
||||
httpGetInterceptor,
|
||||
httpPostInterceptor,
|
||||
httpPutInterceptor,
|
||||
} from "../http-config/http-interceptor-service";
|
||||
|
||||
|
||||
// User CRUD Operations
|
||||
export interface CreateUserRequest {
|
||||
address: string;
|
||||
clientId: string;
|
||||
dateOfBirth: string;
|
||||
email: string;
|
||||
fullname: string;
|
||||
password: string;
|
||||
phoneNumber: string;
|
||||
userLevelId: number;
|
||||
userRoleId: number;
|
||||
username: string;
|
||||
}
|
||||
|
||||
export interface UpdateUserRequest extends Partial<CreateUserRequest> {
|
||||
id?: number;
|
||||
}
|
||||
|
||||
export async function getUserListAll() {
|
||||
const url = `users/pagination/all?enablePage=0`;
|
||||
return httpGetInterceptor(url);
|
||||
|
|
@ -108,3 +128,23 @@ export async function getOperatorUser(typeId: any) {
|
|||
const url = `users/search-operator-user?code=opt-id&typeId=${typeId}`;
|
||||
return httpGetInterceptor(url);
|
||||
}
|
||||
|
||||
export async function createUser(data: CreateUserRequest) {
|
||||
const url = "users";
|
||||
return httpPostInterceptor(url, data);
|
||||
}
|
||||
|
||||
export async function updateUser(id: number, data: UpdateUserRequest) {
|
||||
const url = `users/${id}`;
|
||||
return httpPutInterceptor(url, data);
|
||||
}
|
||||
|
||||
export async function deleteUserById(id: number) {
|
||||
const url = `users/${id}`;
|
||||
return httpDeleteInterceptor(url);
|
||||
}
|
||||
|
||||
export async function getUserDetail(id: number) {
|
||||
const url = `users/detail/${id}`;
|
||||
return httpGetInterceptor(url);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue