diff --git a/app/[locale]/(protected)/admin/add-experts/component/column.tsx b/app/[locale]/(protected)/admin/add-experts/component/column.tsx index 309e8f46..f4c66c85 100644 --- a/app/[locale]/(protected)/admin/add-experts/component/column.tsx +++ b/app/[locale]/(protected)/admin/add-experts/component/column.tsx @@ -10,27 +10,7 @@ import { DropdownMenuItem, } from "@/components/ui/dropdown-menu"; import { Button } from "@/components/ui/button"; -import { Badge } from "@/components/ui/badge"; -import { - formatDateToIndonesian, - getOnlyDate, - htmlToString, -} from "@/utils/globals"; -import { Link, useRouter } from "@/i18n/routing"; -import { - Accordion, - AccordionContent, - AccordionItem, - AccordionTrigger, -} from "@/components/ui/accordion"; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog"; -import { Collapsible, CollapsibleContent } from "@/components/ui/collapsible"; +import { Link } from "@/components/navigation"; const columns: ColumnDef[] = [ { @@ -47,25 +27,39 @@ const columns: ColumnDef[] = [ { accessorKey: "address", header: "Wilayah", - cell: ({ row }) => {row.getValue("address")}, + cell: ({ row }) => MABES, }, - { - accessorKey: "role.name", - header: "Bidang Keahlian", - cell: ({ row }) => {row.original.role?.name ?? "-"}, - }, - - { - accessorKey: "experience", - header: "Pengalaman", - cell: ({ row }) => {row.getValue("experience")}, - }, - { accessorKey: "experience", header: "Posisi", cell: ({ row }) => {row.getValue("experience")}, }, + { + accessorKey: "role.name", + header: "Bidang Keahlian", + cell: ({ row }) => ( + + {row.original.userProfilesAdditional?.userCompetency?.name ?? "-"} + + ), + }, + + { + accessorKey: "userExperienceId", + header: "Pengalaman", + cell: ({ row }) => { + const experienceId = + row.original.userProfilesAdditional?.userExperienceId; + + const experienceMap: Record = { + 1: "Akademisi", + 2: "Praktisi", + 3: "Akademisi + Praktisi", + }; + + return {experienceMap[experienceId] ?? "-"}; + }, + }, { id: "actions", @@ -84,8 +78,25 @@ const columns: ColumnDef[] = [ - - Detail + + + + View + + + + + + + Edit + + + handleDeleteMedia(row.original.id)} + className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none" + > + + Delete diff --git a/app/[locale]/(protected)/admin/add-experts/create/page.tsx b/app/[locale]/(protected)/admin/add-experts/create/page.tsx index 994cd5eb..ab33ac6e 100644 --- a/app/[locale]/(protected)/admin/add-experts/create/page.tsx +++ b/app/[locale]/(protected)/admin/add-experts/create/page.tsx @@ -130,6 +130,7 @@ export default function AddExpertForm() { userCompetencyId: data.skills, userExperienceId: data.experiences, companyName: data.company, + isAdmin: true, }; loading(); @@ -272,8 +273,9 @@ export default function AddExpertForm() { Username @@ -290,7 +292,7 @@ export default function AddExpertForm() { @@ -306,7 +308,7 @@ export default function AddExpertForm() { diff --git a/app/[locale]/(protected)/admin/add-experts/detail/[id]/page.tsx b/app/[locale]/(protected)/admin/add-experts/detail/[id]/page.tsx new file mode 100644 index 00000000..3a5aae33 --- /dev/null +++ b/app/[locale]/(protected)/admin/add-experts/detail/[id]/page.tsx @@ -0,0 +1,15 @@ +import SiteBreadcrumb from "@/components/site-breadcrumb"; +import FormDetailExperts from "@/components/form/experts/experts-detail"; + +const ExpertsDetailPage = async () => { + return ( +
+ +
+ +
+
+ ); +}; + +export default ExpertsDetailPage; diff --git a/app/[locale]/(protected)/admin/add-experts/update/[id]/page.tsx b/app/[locale]/(protected)/admin/add-experts/update/[id]/page.tsx new file mode 100644 index 00000000..3af56ee2 --- /dev/null +++ b/app/[locale]/(protected)/admin/add-experts/update/[id]/page.tsx @@ -0,0 +1,597 @@ +"use client"; +import SiteBreadcrumb from "@/components/site-breadcrumb"; +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { z } from "zod"; +import { useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import withReactContent from "sweetalert2-react-content"; +import Swal from "sweetalert2"; +import { useRouter } from "@/i18n/routing"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { useEffect, useState } from "react"; +import { + AdministrationLevelList, + getListCompetencies, + getListExperiences, + getUserById, + saveUserInternal, + saveUserRolePlacements, +} from "@/service/management-user/management-user"; +import { loading } from "@/config/swal"; +import { Eye, EyeOff } from "lucide-react"; +import { useParams } from "next/navigation"; + +const FormSchema = z.object({ + name: z.string({ + required_error: "Required", + }), + username: z.string({ + required_error: "Required", + }), + password: z.string({ + required_error: "Required", + }), + phoneNumber: z.string({ + required_error: "Required", + }), + email: z.string({ + required_error: "Required", + }), + skills: z.string({ + required_error: "Required", + }), + experiences: z.string({ + required_error: "Required", + }), + company: z.string({ + required_error: "Required", + }), +}); + +export type Placements = { + index: number; + roleId?: string; + userLevelId?: number; +}; + +interface Detail { + id: string; + fullname: string; + username: string; + phoneNumber: string; + email: string; + birthPlace: string; + birthDate: string; + education: string; + career: string; + expertise: string; + experience: string; + position: string; + region: string; + cvUrl: string; + photoUrl: string; + isActive: boolean; + userProfilesAdditional?: { + companyName: string; + userExperienceId: any; + userCompetency?: { + id: number; + name: string; + isActive: boolean; + createdAt: string; + }; + }; +} + +export default function UpdateExpertForm() { + const MySwal = withReactContent(Swal); + const router = useRouter(); + const params = useParams(); + const id = params?.id; + const [detail, setDetail] = useState(null); + const form = useForm>({ + resolver: zodResolver(FormSchema), + }); + const [incrementId, setIncrementId] = useState(1); + const [placementRows, setPlacementRows] = useState([ + { index: 0, roleId: "", userLevelId: 0 }, + ]); + const [userCompetencies, setUserCompetencies] = useState(); + const [userExperiences, setUserExperiences] = useState(); + const [userLevels, setUserLevels] = useState(); + const [passwordType, setPasswordType] = useState("password"); + const [showPassword, setShowPassword] = useState(false); + + useEffect(() => { + getDataAdditional(); + }, []); + + useEffect(() => { + async function initState() { + if (id) { + const response = await getUserById(String(id)); + const details = response?.data?.data; + setDetail(details); + } + if (detail?.userProfilesAdditional?.companyName) { + form.setValue("company", detail.userProfilesAdditional.companyName); + } + + if (detail?.userProfilesAdditional?.userCompetency?.id) { + form.setValue( + "skills", + String(detail.userProfilesAdditional.userCompetency.id) + ); + } + + if (detail?.userProfilesAdditional?.userExperienceId) { + form.setValue( + "experiences", + String(detail.userProfilesAdditional.userExperienceId) + ); + } + } + initState(); + }, [id]); + + if (!detail) return
Loading...
; + + const togglePasswordType = () => { + setPasswordType((prevType) => + prevType === "password" ? "text" : "password" + ); + }; + + const roleSelection = [ + { + id: "11", + name: "Koor Kurator", + }, + { + id: "12", + name: "Kurator", + }, + ]; + + const onSubmit = async (data: z.infer) => { + MySwal.fire({ + title: "Simpan Data", + text: "Apakah Anda yakin ingin menyimpan data ini?", + icon: "warning", + showCancelButton: true, + cancelButtonColor: "#d33", + confirmButtonColor: "#3085d6", + confirmButtonText: "Simpan", + }).then((result) => { + if (result.isConfirmed) { + save(data); + } + }); + }; + + const save = async (data: z.infer) => { + console.log("data", data); + + const dataReq = { + id: detail?.id, + firstName: data.name, + username: data.username, + email: data.email, + password: data.password, + address: "", + roleId: "EXP-ID", + phoneNumber: data.phoneNumber, + userCompetencyId: data.skills, + userExperienceId: data.experiences, + companyName: data.company, + }; + + loading(); + const res = await saveUserInternal(dataReq); + const resData = res?.data?.data; + const userProfileId = resData?.id; + + var placementArr: any[] = []; + placementRows.forEach((row: any) => { + placementArr.push({ + roleId: Number(row.roleId), + userLevelId: Number(row.userLevelId), + userProfileId: userProfileId, + }); + }); + + const dataReq2 = { + userId: userProfileId, + placements: placementArr, + }; + const res2 = await saveUserRolePlacements(dataReq2); + const resData2 = res2?.data?.data; + + success("/admin/add-experts"); + }; + + function success(redirect: string): void { + MySwal.fire({ + title: '

Sukses

', + icon: "success", + confirmButtonColor: "#3085d6", + confirmButtonText: 'OK', + allowOutsideClick: false, + }).then((result) => { + if (result.isConfirmed) { + router.push(redirect); + } + }); + } + + async function getDataAdditional() { + const resCompetencies = await getListCompetencies(); + setUserCompetencies(resCompetencies?.data?.data); + + const resExperiences = await getListExperiences(); + setUserExperiences(resExperiences?.data?.data); + console.log("experience", resExperiences?.data?.data); + + const resUserLevels = await AdministrationLevelList(); + const data = resUserLevels?.data?.data; + var levelsArr: any[] = []; + data.forEach((levels: any) => { + levelsArr.push({ + id: levels.id, + label: levels.name, + name: levels.name, + value: String(levels.id), + levelNumber: levels.levelNumber, + }); + }); + setUserLevels(levelsArr); + } + + function successSubmit() { + MySwal.fire({ + title: "Sukses", + icon: "success", + confirmButtonColor: "#3085d6", + confirmButtonText: "OK", + }).then((result) => { + if (result.isConfirmed) { + router.push("/admin/add-experts"); + } + }); + } + + const handleSelectionChange = ( + index: number, + type: "roleId" | "userLevelId", + value: string + ) => { + setPlacementRows((prevRows) => + prevRows.map((row) => + row.index === index ? { ...row, [type]: value } : row + ) + ); + }; + + const handleRemoveRow = (index: number) => { + console.log(index); + console.log(placementRows); + const newPlacements = placementRows.filter((row) => row.index != index); + console.log(newPlacements); + setPlacementRows(newPlacements); + }; + + const handleAddRow = () => { + if (placementRows.length < 2) { + setPlacementRows((prevRows) => [ + ...prevRows, + { index: incrementId, roleId: "", userLevelId: 0 }, + ]); + setIncrementId((prevId) => prevId + 1); + } + }; + + return ( +
+ + +
+ {detail !== undefined ? ( + +

Campaign

+ ( + + Nama Lengkap + + + + + )} + /> + ( + + Username + + + + + )} + /> + ( + + No. HP + + + + )} + /> + ( + + Email + + + + )} + /> + ( + + Password +
+ + +
+ +
+ )} + /> + ( + + Bidang Keahlian + + + )} + /> + + ( + + Pengalaman + + + )} + /> + + ( + + Nama Institusi/Perusahaan + + + + )} + /> + +
+ Posisi + {placementRows?.map((row: any) => ( +
+ + {/* */} + + {placementRows.length > 1 && ( + + )} +
+ ))} + +
+ +
+ + +
+ + ) : ( + "" + )} + +
+ ); +} diff --git a/app/[locale]/(protected)/contributor/schedule/live-report/component/live-report-table.tsx b/app/[locale]/(protected)/contributor/schedule/live-report/component/live-report-table.tsx index 73e5c839..f9e0d13a 100644 --- a/app/[locale]/(protected)/contributor/schedule/live-report/component/live-report-table.tsx +++ b/app/[locale]/(protected)/contributor/schedule/live-report/component/live-report-table.tsx @@ -129,7 +129,7 @@ const LiveReportTable = () => { const res = await paginationSchedule( showData, page - 1, - selectedType, + "", search, statusFilter ); diff --git a/components/form/experts/experts-detail.tsx b/components/form/experts/experts-detail.tsx new file mode 100644 index 00000000..ed66b947 --- /dev/null +++ b/components/form/experts/experts-detail.tsx @@ -0,0 +1,102 @@ +"use client"; + +import React, { useEffect, useState } from "react"; +import { useParams } from "next/navigation"; +import { getUserById } from "@/service/management-user/management-user"; +import { Card } from "@/components/ui/card"; +import { Switch } from "@/components/ui/switch"; +import Image from "next/image"; +import { Button } from "@/components/ui/button"; +import { FileText } from "lucide-react"; + +interface Detail { + fullname: string; + birthPlace: string; + birthDate: string; + education: string; + career: string; + expertise: string; + experience: string; + position: string; + region: string; + cvUrl: string; + photoUrl: string; + isActive: boolean; +} + +export default function FormDetailExperts() { + const params = useParams(); + const id = params?.id; + const [detail, setDetail] = useState(null); + + useEffect(() => { + async function initState() { + if (id) { + const response = await getUserById(String(id)); + const details = response?.data?.data; + setDetail(details); + } + } + initState(); + }, [id]); + + if (!detail) return
Loading...
; + + return ( + +
+ Profile Picture +
+ Not Active + + Active +
+
+ +
+
+ Nama: {detail?.fullname} +
+
+ Tempat / Tanggal Lahir: {detail.birthPlace},{" "} + {detail.birthDate} +
+
+ Pendidikan: {detail.education} +
+
+ Karier: +

{detail.career}

+
+
+ Bidang Keahlian: {detail.expertise} +
+
+ Pengalaman: {detail.experience} +
+
+ Posisi: {detail.position} +
+
+ Wilayah: {detail.region} +
+
+ CV: + +
+
+
+ ); +} diff --git a/components/partials/auth/login-form.tsx b/components/partials/auth/login-form.tsx index 68695b3f..9a79d719 100644 --- a/components/partials/auth/login-form.tsx +++ b/components/partials/auth/login-form.tsx @@ -534,10 +534,10 @@ const LoginForm = () => { diff --git a/public/assets/img/experts.png b/public/assets/img/experts.png new file mode 100644 index 00000000..c9baf3f2 Binary files /dev/null and b/public/assets/img/experts.png differ