update filter status admin, fix button delete

This commit is contained in:
Anang Yusman 2025-07-24 16:36:05 +08:00
parent f878ab405e
commit 5216bcd8a5
6 changed files with 193 additions and 101 deletions

View File

@ -132,29 +132,36 @@ const useTableColumns = () => {
accessorKey: "statusName",
header: "Status",
cell: ({ row }) => {
const statusColors: Record<string, string> = {
diterima: "bg-green-100 text-green-600",
"menunggu review": "bg-orange-100 text-orange-600",
const statusId = Number(row.original?.statusId);
const reviewedAtLevel = row.original?.reviewedAtLevel || "";
const creatorGroupLevelId = Number(row.original?.creatorGroupLevelId);
const needApprovalFromLevel = Number(
row.original?.needApprovalFromLevel
);
const userHasReviewed = reviewedAtLevel.includes(`:${userLevelId}:`);
const isCreator = creatorGroupLevelId === Number(userLevelId);
const isWaitingForReview =
statusId === 2 && !userHasReviewed && !isCreator;
const isApprovalNeeded =
statusId === 1 && needApprovalFromLevel === Number(userLevelId);
const label =
isWaitingForReview || isApprovalNeeded
? "Menunggu Review"
: statusId === 2
? "Diterima"
: row.original?.statusName;
const colors: Record<string, string> = {
"Menunggu Review": "bg-orange-100 text-orange-600",
Diterima: "bg-green-100 text-green-600",
default: "bg-red-200 text-red-600",
};
const colors = [
"bg-orange-100 text-orange-600",
"bg-orange-100 text-orange-600",
"bg-green-100 text-green-600",
"bg-blue-100 text-blue-600",
"bg-red-200 text-red-600",
];
const status =
Number(row.original?.statusId) == 2 &&
row.original?.reviewedAtLevel !== null &&
!row.original?.reviewedAtLevel?.includes(`:${userLevelId}:`) &&
Number(row.original?.creatorGroupLevelId) != Number(userLevelId)
? "1"
: row.original?.statusId;
const statusStyles =
colors[Number(status)] || "bg-red-200 text-red-600";
// const statusStyles = statusColors[status] || "bg-red-200 text-red-600";
const statusStyles = colors[label] || colors.default;
return (
<Badge
@ -163,18 +170,7 @@ const useTableColumns = () => {
statusStyles
)}
>
{(Number(row.original?.statusId) == 2 &&
!row.original?.reviewedAtLevel !== null &&
!row.original?.reviewedAtLevel?.includes(
`:${Number(userLevelId)}:`
) &&
Number(row.original?.creatorGroupLevelId) !=
Number(userLevelId)) ||
(Number(row.original?.statusId) == 1 &&
Number(row.original?.needApprovalFromLevel) ==
Number(userLevelId))
? "Menunggu Review"
: row.original?.statusName}{" "}
{label}
</Badge>
);
},

View File

@ -24,6 +24,7 @@ import {
} from "@/components/ui/table";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
ChevronDown,
ChevronLeft,
ChevronRight,
Eye,
@ -61,6 +62,7 @@ import {
SelectValue,
} from "@/components/ui/select";
import { useTranslations } from "next-intl";
import { Label } from "@/components/ui/label";
type StatusFilter = string[];
@ -87,7 +89,8 @@ const ContentTable = () => {
const userLevelId = getCookiesDecrypt("ulie");
const [categories, setCategories] = React.useState<string[]>();
const [categoryFilter, setCategoryFilter] = React.useState<string[]>([]);
const [statusFilter, setStatusFilter] = React.useState<StatusFilter>([]);
// const [statusFilter, setStatusFilter] = React.useState<StatusFilter>([]);
const [statusFilter, setStatusFilter] = React.useState<any[]>([]);
const [startDateString, setStartDateString] = React.useState<string>("");
const [endDateString, setEndDateString] = React.useState<string>("");
const [filterByCreator, setFilterByCreator] = React.useState<string>("");
@ -168,6 +171,14 @@ const ContentTable = () => {
table.getColumn("judul")?.setFilterValue(e.target.value);
};
function handleStatusCheckboxChange(value: any) {
setStatusFilter((prev: any) =>
prev.includes(value)
? prev.filter((status: any) => status !== value)
: [...prev, value]
);
}
return (
<div className="w-full overflow-x-auto">
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between md:flex-row md:items-center md:justify-between lg:flex-row items-start lg:justify-between lg:items-center px-5">
@ -185,43 +196,88 @@ const ContentTable = () => {
/>
</InputGroup>
</div>
<div className=" items-center gap-3 w-full md:w-[200px]">
{/* <Select
onValueChange={(value) => {
setStatusFilter([value]);
}}
>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Select a Filter Status" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Status</SelectLabel>
<SelectItem value="1">Menunggu Review</SelectItem>
<SelectItem value="2">Diterima</SelectItem>
<SelectItem value="3">Minta Update</SelectItem>
<SelectItem value="4">Ditolak</SelectItem>
</SelectGroup>
</SelectContent>
</Select> */}
<Select
onValueChange={(value) => {
setFileTypeFilter([value]);
}}
>
<SelectTrigger className="w-full lg:w-[180px]">
<SelectValue placeholder={t("selectFilter")} />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Filter</SelectLabel>
<SelectItem value="1">{t("image")}</SelectItem>
<SelectItem value="2">{t("audio-visual")}</SelectItem>
<SelectItem value="3">{t("text")}</SelectItem>
<SelectItem value="4">Audio</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
<div className="flex flex-row gap-3">
<div className=" items-center gap-3 w-full md:w-[152px] border border-black rounded-lg">
<Select
onValueChange={(value) => {
setFileTypeFilter([value]);
}}
>
<SelectTrigger className="w-full lg:w-[150px]">
<SelectValue placeholder={t("selectFilter")} />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Filter</SelectLabel>
<SelectItem value="1">{t("image")}</SelectItem>
<SelectItem value="2">{t("audio-visual")}</SelectItem>
<SelectItem value="3">{t("text")}</SelectItem>
<SelectItem value="4">{t("audio")}</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" className="ml-auto" size="md">
Filter <ChevronDown />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent
align="end"
className="w-64 h-[150px] overflow-y-auto"
>
<Label className="ml-2 mt-2">Status</Label>
<div className="flex items-center px-4 py-1">
<input
type="checkbox"
id="status-2"
className="mr-2"
checked={statusFilter.includes(1)}
onChange={() => handleStatusCheckboxChange(1)}
/>
<label htmlFor="status-2" className="text-sm">
Menunggu Review
</label>
</div>
<div className="flex items-center px-4 py-1">
<input
type="checkbox"
id="status-2"
className="mr-2"
checked={statusFilter.includes(2)}
onChange={() => handleStatusCheckboxChange(2)}
/>
<label htmlFor="status-2" className="text-sm">
Diterima
</label>
</div>
<div className="flex items-center px-4 py-1">
<input
type="checkbox"
id="status-3"
className="mr-2"
checked={statusFilter.includes(3)}
onChange={() => handleStatusCheckboxChange(3)}
/>
<label htmlFor="status-3" className="text-sm">
Minta Update
</label>
</div>
<div className="flex items-center px-4 py-1">
<input
type="checkbox"
id="status-4"
className="mr-2"
checked={statusFilter.includes(4)}
onChange={() => handleStatusCheckboxChange(4)}
/>
<label htmlFor="status-4" className="text-sm">
Ditolak
</label>
</div>
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
<Table className="overflow-hidden mt-3">

View File

@ -570,6 +570,7 @@ export default function FormAudioUpdate() {
</div>
<Button
type="button"
size="icon"
color="destructive"
variant="outline"
@ -668,7 +669,9 @@ export default function FormAudioUpdate() {
<div className="flex flex-col lg:flex-row gap-10">
<Card className="w-full lg:w-8/12">
<div className="px-6 py-6">
<p className="text-lg font-semibold mb-3">{t("form-audio", { defaultValue: "Form Audio" })}</p>
<p className="text-lg font-semibold mb-3">
{t("form-audio", { defaultValue: "Form Audio" })}
</p>
<div className="gap-5 mb-5">
{/* Input Title */}
<div className="space-y-2 py-3">
@ -707,14 +710,18 @@ export default function FormAudioUpdate() {
</SelectTrigger>
<SelectContent>
{/* Show the category from details if it doesn't exist in categories list */}
{detail && !categories.find(cat => String(cat.id) === String(detail.category.id)) && (
<SelectItem
key={String(detail.category.id)}
value={String(detail.category.id)}
>
{detail.category.name}
</SelectItem>
)}
{detail &&
!categories.find(
(cat) =>
String(cat.id) === String(detail.category.id)
) && (
<SelectItem
key={String(detail.category.id)}
value={String(detail.category.id)}
>
{detail.category.name}
</SelectItem>
)}
{categories.map((category) => (
<SelectItem
key={String(category.id)}
@ -730,7 +737,9 @@ export default function FormAudioUpdate() {
</div>
<div className="py-3 space-y-2">
<Label>{t("description", { defaultValue: "Description" })}</Label>
<Label>
{t("description", { defaultValue: "Description" })}
</Label>
<Controller
control={control}
name="description"
@ -745,7 +754,9 @@ export default function FormAudioUpdate() {
)}
</div>
<div className="py-3 space-y-2">
<Label>{t("select-file", { defaultValue: "Select File" })}</Label>
<Label>
{t("select-file", { defaultValue: "Select File" })}
</Label>
{/* <Input
id="fileInput"
type="file"
@ -761,7 +772,9 @@ export default function FormAudioUpdate() {
{t("drag-file", { defaultValue: "Drag File" })}
</h4>
<div className=" text-xs text-muted-foreground">
{t("upload-file-audio-max", { defaultValue: "Upload File Audio Max" })}
{t("upload-file-audio-max", {
defaultValue: "Upload File Audio Max",
})}
</div>
</div>
</div>
@ -1010,7 +1023,9 @@ export default function FormAudioUpdate() {
</div>
<div className="px-3 py-3">
<div className="flex flex-col gap-6 space-y-2">
<Label>{t("publish-target", { defaultValue: "Publish Target" })}</Label>
<Label>
{t("publish-target", { defaultValue: "Publish Target" })}
</Label>
{options.map((option: Option) => (
<div key={option.id} className="flex gap-2 items-center">
<Checkbox

View File

@ -548,6 +548,7 @@ export default function FormImageUpdate() {
</div>
<Button
type="button"
size="icon"
color="destructive"
variant="outline"

View File

@ -552,6 +552,7 @@ export default function FormTeksUpdate() {
</div>
<Button
type="button"
size="icon"
color="destructive"
variant="outline"
@ -624,7 +625,9 @@ export default function FormTeksUpdate() {
<div className="flex flex-col lg:flex-row gap-10">
<Card className="w-full lg:w-8/12">
<div className="px-6 py-6">
<p className="text-lg font-semibold mb-3">{t("form-text", { defaultValue: "Form Text" })}</p>
<p className="text-lg font-semibold mb-3">
{t("form-text", { defaultValue: "Form Text" })}
</p>
<div className="gap-5 mb-5">
{/* Input Title */}
<div className="space-y-2 py-3">
@ -663,14 +666,18 @@ export default function FormTeksUpdate() {
</SelectTrigger>
<SelectContent>
{/* Show the category from details if it doesn't exist in categories list */}
{detail && !categories.find(cat => String(cat.id) === String(detail.category.id)) && (
<SelectItem
key={String(detail.category.id)}
value={String(detail.category.id)}
>
{detail.category.name}
</SelectItem>
)}
{detail &&
!categories.find(
(cat) =>
String(cat.id) === String(detail.category.id)
) && (
<SelectItem
key={String(detail.category.id)}
value={String(detail.category.id)}
>
{detail.category.name}
</SelectItem>
)}
{categories.map((category) => (
<SelectItem
key={String(category.id)}
@ -685,7 +692,9 @@ export default function FormTeksUpdate() {
</div>
</div>
<div className="py-3 space-y-2">
<Label>{t("description", { defaultValue: "Description" })}</Label>
<Label>
{t("description", { defaultValue: "Description" })}
</Label>
<Controller
control={control}
name="description"
@ -700,7 +709,9 @@ export default function FormTeksUpdate() {
)}
</div>
<div className="py-3 space-y-2">
<Label>{t("select-file", { defaultValue: "Select File" })}</Label>
<Label>
{t("select-file", { defaultValue: "Select File" })}
</Label>
{/* <Input
id="fileInput"
type="file"
@ -716,7 +727,9 @@ export default function FormTeksUpdate() {
{t("drag-file", { defaultValue: "Drag File" })}
</h4>
<div className=" text-xs text-muted-foreground">
{t("upload-file-text-max", { defaultValue: "Upload File Text Max" })}
{t("upload-file-text-max", {
defaultValue: "Upload File Text Max",
})}
</div>
</div>
</div>
@ -725,7 +738,9 @@ export default function FormTeksUpdate() {
<div>{fileList}</div>
<div className=" flex justify-between gap-2">
<div className="flex flex-row items-center gap-3 py-3">
<Label>{t("watermark", { defaultValue: "Watermark" })}</Label>
<Label>
{t("watermark", { defaultValue: "Watermark" })}
</Label>
<div className="flex items-center gap-3">
<Switch defaultChecked color="primary" id="c2" />
</div>
@ -765,7 +780,9 @@ export default function FormTeksUpdate() {
rel="noopener noreferrer"
className="text-blue-500 text-sm"
>
{t("view-file", { defaultValue: "View File" })}
{t("view-file", {
defaultValue: "View File",
})}
</a>
</div>
<div>
@ -783,7 +800,9 @@ export default function FormTeksUpdate() {
}
className="form-checkbox"
/>
<span>{t("all", { defaultValue: "All" })}</span>
<span>
{t("all", { defaultValue: "All" })}
</span>
</Label>
</div>
<div>
@ -923,7 +942,9 @@ export default function FormTeksUpdate() {
</div>
<div className="px-3 py-3">
<div className="flex flex-col gap-6">
<Label>{t("publish-target", { defaultValue: "Publish Target" })}</Label>
<Label>
{t("publish-target", { defaultValue: "Publish Target" })}
</Label>
{options.map((option) => (
<div key={option.id} className="flex gap-2 items-center">
<Checkbox
@ -944,7 +965,9 @@ export default function FormTeksUpdate() {
</div>
<div className="px-3 py-3 flex flex-row items-center text-blue-500 gap-2 text-sm">
<MailIcon />
<p className="">{t("suggestion-box", { defaultValue: "Suggestion Box" })} (0)</p>
<p className="">
{t("suggestion-box", { defaultValue: "Suggestion Box" })} (0)
</p>
</div>
<div className="px-3 py-3">
<p>{t("information", { defaultValue: "Information" })}:</p>

View File

@ -626,6 +626,7 @@ export default function FormVideoUpdate() {
</div>
<Button
type="button"
size="icon"
color="destructive"
variant="outline"