fix: all bugs in fe
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
8d2fce74bb
commit
b670a175fa
|
|
@ -69,7 +69,7 @@ const FormSchema = z.object({
|
|||
.refine((val) => !/\s/.test(val), {
|
||||
message: "Username tidak boleh mengandung spasi",
|
||||
}),
|
||||
// .transform((val) => val.toLowerCase()),
|
||||
// .transform((val) => val.toLowerCase()),
|
||||
|
||||
password: z
|
||||
.string({ required_error: "Required" })
|
||||
|
|
@ -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"
|
||||
|
|
@ -462,8 +481,8 @@ export default function AddExpertForm() {
|
|||
passwordStrength === "weak"
|
||||
? "bg-red-500 w-1/4"
|
||||
: passwordStrength === "medium"
|
||||
? "bg-yellow-500 w-2/4"
|
||||
: "bg-green-500 w-full"
|
||||
? "bg-yellow-500 w-2/4"
|
||||
: "bg-green-500 w-full"
|
||||
}`}
|
||||
/>
|
||||
|
||||
|
|
@ -472,8 +491,8 @@ export default function AddExpertForm() {
|
|||
passwordStrength === "weak"
|
||||
? "text-red-500"
|
||||
: passwordStrength === "medium"
|
||||
? "text-yellow-600"
|
||||
: "text-green-600"
|
||||
? "text-yellow-600"
|
||||
: "text-green-600"
|
||||
}`}
|
||||
>
|
||||
{passwordStrength === "weak" && "Weak Password"}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
@ -430,10 +451,10 @@ const TableImage = () => {
|
|||
id === 1
|
||||
? "Menunggu Review"
|
||||
: id === 2
|
||||
? "Diterima"
|
||||
: id === 3
|
||||
? "Minta Update"
|
||||
: "Ditolak";
|
||||
? "Diterima"
|
||||
: id === 3
|
||||
? "Minta Update"
|
||||
: "Ditolak";
|
||||
return (
|
||||
<div key={id} className="flex items-center px-4 py-1">
|
||||
<input
|
||||
|
|
@ -491,7 +512,7 @@ const TableImage = () => {
|
|||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
header.getContext(),
|
||||
)}
|
||||
</TableHead>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -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 && (
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
</>
|
||||
)}
|
||||
<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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue