fix: all bugs in fe
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Sabda Yagra 2026-02-25 14:53:07 +07:00
parent 8d2fce74bb
commit b670a175fa
8 changed files with 167 additions and 36 deletions

View File

@ -85,6 +85,7 @@ const FormSchema = z.object({
skills: z.string({ required_error: "Required" }),
experiences: z.string({ required_error: "Required" }),
company: z.string({ required_error: "Required" }),
address: z.string({ required_error: "Required" }),
});
// .refine((data) => data.password === data.confirmPassword, {
// path: ["confirmPassword"],
@ -116,7 +117,7 @@ export default function AddExpertForm() {
const togglePasswordType = () => {
setPasswordType((prevType) =>
prevType === "password" ? "text" : "password"
prevType === "password" ? "text" : "password",
);
};
@ -155,7 +156,7 @@ export default function AddExpertForm() {
username: data.username,
email: data.email,
password: data.password,
address: "",
address: data.address,
roleId: "EXP-ID",
phoneNumber: data.phoneNumber,
userCompetencyId: data.skills,
@ -264,12 +265,12 @@ export default function AddExpertForm() {
const handleSelectionChange = (
index: number,
type: "roleId" | "userLevelId",
value: string
value: string,
) => {
setPlacementRows((prevRows) =>
prevRows.map((row) =>
row.index === index ? { ...row, [type]: value } : row
)
row.index === index ? { ...row, [type]: value } : row,
),
);
};
@ -424,6 +425,24 @@ export default function AddExpertForm() {
</FormItem>
)}
/>
<FormField
control={form.control}
name="address"
render={({ field }) => (
<FormItem>
<FormLabel>Alamat</FormLabel>
<Input
type="text"
value={field.value}
placeholder="Masukkan Alamat"
onChange={field.onChange}
/>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="password"

View File

@ -53,7 +53,7 @@ const TableImage = () => {
const [totalPage, setTotalPage] = React.useState(1);
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
[],
);
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
@ -64,7 +64,7 @@ const TableImage = () => {
const [searchTimeout, setSearchTimeout] = React.useState<any>(null);
const [categories, setCategories] = React.useState<any[]>([]);
const [selectedCategories, setSelectedCategories] = React.useState<number[]>(
[]
[],
);
const [categoryFilter, setCategoryFilter] = React.useState<string>("");
const [statusFilter, setStatusFilter] = React.useState<any[]>([]);
@ -170,6 +170,10 @@ const TableImage = () => {
}
const isForSelf = Number(roleId) === 4;
const isNeedApproval = statusFilter.includes(1);
const needApprovalFrom = isNeedApproval ? userLevelId : "";
const res = await listDataImage(
parseInt(showData) || 10,
page - 1,
@ -177,16 +181,33 @@ const TableImage = () => {
!isForSelf,
categoryFilter,
statusFilter,
statusFilter?.sort().join(",").includes("1") ? userLevelId : "",
needApprovalFrom,
filterByCreator,
filterBySource,
formattedStartDate,
formattedEndDate,
customSearch ?? search,
filterByCreatorGroup,
locale == "en"
locale == "en",
);
// const res = await listDataImage(
// parseInt(showData) || 10,
// page - 1,
// isForSelf,
// !isForSelf,
// categoryFilter,
// statusFilter,
// statusFilter?.sort().join(",").includes("1") ? userLevelId : "",
// filterByCreator,
// filterBySource,
// formattedStartDate,
// formattedEndDate,
// customSearch ?? search,
// filterByCreatorGroup,
// locale == "en"
// );
const data = res?.data?.data;
const contentData = data?.content || [];
const newData = contentData.map((item: any, index: number) => ({
@ -209,7 +230,7 @@ const TableImage = () => {
setSelectedCategories((prev) =>
prev.includes(categoryId)
? prev.filter((id) => id !== categoryId)
: [...prev, categoryId]
: [...prev, categoryId],
);
setCategoryFilter((prev) => {
@ -225,7 +246,7 @@ const TableImage = () => {
setStatusFilter((prev: any) =>
prev.includes(value)
? prev.filter((status: any) => status !== value)
: [...prev, value]
: [...prev, value],
);
};
@ -253,14 +274,14 @@ const TableImage = () => {
};
const handleSearchFilterByCreator = (
e: React.ChangeEvent<HTMLInputElement>
e: React.ChangeEvent<HTMLInputElement>,
) => {
setFilterByCreator(e.target.value);
fetchData();
};
const handleSearchFilterBySource = (
e: React.ChangeEvent<HTMLInputElement>
e: React.ChangeEvent<HTMLInputElement>,
) => {
setFilterBySource(e.target.value);
fetchData();
@ -491,7 +512,7 @@ const TableImage = () => {
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
header.getContext(),
)}
</TableHead>
))}

View File

@ -235,12 +235,35 @@ const useTableColumns = (
<DropdownMenuContent align="end" className="p-0">
{/* VIEW */}
<Link href={`/contributor/task-ta/detail/${row.original.id}`}>
{/* <Link href={`/contributor/task-ta/detail/${row.original.id}`}>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Eye className="w-4 h-4 me-1.5" />
View
</DropdownMenuItem>
</Link> */}
{/* VIEW */}
<Link
href={
activeTab === "special"
? `/contributor/task/detail/${row.original.id}`
: `/contributor/task-ta/detail/${row.original.id}`
}
>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Eye className="w-4 h-4 me-1.5" />
View
</DropdownMenuItem>
</Link>
{roleId === 19 && (
<Link
href={`/contributor/task-ta/upload-task/${row.original.id}`}
>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Upload className="w-4 h-4 me-1.5" />
Upload Tugas
</DropdownMenuItem>
</Link>
)}
{/* UPLOAD (MABES → KOOR TAB) */}
{activeTab === "mabes-koor" && roleId === 11 && (

View File

@ -60,6 +60,7 @@ export default function TaskTaTable() {
const roleId = Number(getCookiesDecrypt("urie"));
const userId = Number(getCookiesDecrypt("uie"));
const isKoorKuratorRole11 = roleId === 11;
const isRole19 = roleId === 19;
const isMabesApprover =
userLevelId === MABES_LEVEL_ID && roleId === APPROVER_ROLE_ID;
@ -301,7 +302,7 @@ export default function TaskTaTable() {
<label className="inline-flex text-md cursor-pointer">
<div className="flex mb-6 flex-wrap gap-2">
{/* ❗ JIKA MABES APPROVER → HANYA 1 TAB */}
{isMabesApprover ? (
{/* {isMabesApprover ? (
<button
onClick={() => setActiveTab("mabes-koor")}
className={`px-4 py-1 rounded transition ${
@ -314,7 +315,6 @@ export default function TaskTaTable() {
</button>
) : (
<>
{/* 👇 USER SELAIN MABES APPROVER */}
<button
onClick={() => setActiveTab("special")}
className={`px-4 py-1 rounded transition ${
@ -361,6 +361,73 @@ export default function TaskTaTable() {
</button>
)}
</>
)} */}
{isMabesApprover ? (
<button
onClick={() => setActiveTab("mabes-koor")}
className={`px-4 py-1 rounded transition ${
activeTab === "mabes-koor"
? "bg-default-900 text-white dark:text-black"
: "border dark:text-default-700"
}`}
>
Atensi Khusus Mabes Koor Kurator
</button>
) : (
<>
{/* ❗ HIDE untuk role 19 */}
{!isRole19 && (
<>
<button
onClick={() => setActiveTab("special")}
className={`px-4 py-1 rounded transition ${
activeTab === "special"
? "bg-default-900 text-white dark:text-black"
: "border dark:text-default-700"
}`}
>
Atensi Khusus Mabes
</button>
<button
onClick={() => setActiveTab("mabes-koor")}
className={`px-4 py-1 rounded transition ${
activeTab === "mabes-koor"
? "bg-default-900 text-white dark:text-black"
: "border dark:text-default-700"
}`}
>
Atensi Khusus Mabes Koor Kurator
</button>
</>
)}
{/* ✅ TA tetap tampil untuk semua */}
<button
onClick={() => setActiveTab("ta")}
className={`px-4 py-1 rounded transition ${
activeTab === "ta"
? "bg-default-900 text-white dark:text-black"
: "border dark:text-default-700"
}`}
>
Atensi Khusus TA
</button>
{/* ❗ Daily juga hide untuk role 19 */}
{!isKoorKuratorRole11 && !isRole19 && (
<button
onClick={() => setActiveTab("daily")}
className={`px-4 py-1 rounded transition ${
activeTab === "daily"
? "bg-default-900 text-white dark:text-black"
: "border dark:text-default-700"
}`}
>
{t("daily-tasks", { defaultValue: "Daily Tasks" })}
</button>
)}
</>
)}
</div>
</label>

View File

@ -63,15 +63,14 @@ const DashboardPage = () => {
>
{t("indeks", { defaultValue: "Indeks" })}
</TabsTrigger>
</>
)}
<TabsTrigger
value="report"
className="data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-md px-6"
>
{t("report", { defaultValue: "Report" })}
</TabsTrigger>
</>
)}
</TabsList>
</Card>
<TabsContent value="routine-task">

View File

@ -10,6 +10,7 @@ import { useTranslations } from "next-intl";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useRouter } from "@/i18n/routing";
import Image from "next/image";
interface IFormInput {
name: string;
@ -112,7 +113,7 @@ const ContactForm = () => {
<Reveal>
{/* Header */}
<div className="flex items-center justify-center mb-6">
<img src="/assets/icons-contact.png" alt="contact" />
<Image src="/assets/icons-contact.png" alt="contact" />
<h2 className="ml-4 text-2xl font-bold">
{t("contactUs", { defaultValue: "Contact Us" })}
</h2>

View File

@ -5,6 +5,7 @@ import { error, loading, successCallback } from "@/config/swal";
import { getFeedback, postUserFeedback } from "@/service/landing/landing";
import React, { useEffect, useState } from "react";
import { useTranslations } from "next-intl";
import Image from "next/image";
interface RatingProps {
label: string;
@ -119,7 +120,7 @@ const FeedbackForm: React.FC = () => {
<Reveal>
<div className="max-w-6xl flex flex-col mx-auto p-4 lg:p-40 gap-5 ">
<div className="flex items-center justify-center mb-6">
<img src="/assets/icons-feedback.png" alt="Feedback" />
<Image src="/assets/icons-feedback.png" alt="Feedback" />
<h2 className="ml-4 text-[15px] lg:text-[32px] font-bold text-gray-800 dark:text-white">{t("userFeedback", { defaultValue: "User Feedback" })}</h2>
</div>
<div className="text-black dark:text-white">

View File

@ -1645,7 +1645,7 @@ export default function FormTaskTaDetail() {
variant={"default"}
onClick={() => {
setIsTableResult(!isTableResult);
if (!isTableResult) fetchAllData(); // Panggil API saat tombol diklik
if (!isTableResult) fetchAllData();
}}
>
Hasil Upload