update filter status admin, fix button delete
This commit is contained in:
parent
f878ab405e
commit
5216bcd8a5
|
|
@ -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>
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -548,6 +548,7 @@ export default function FormImageUpdate() {
|
|||
</div>
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
size="icon"
|
||||
color="destructive"
|
||||
variant="outline"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -626,6 +626,7 @@ export default function FormVideoUpdate() {
|
|||
</div>
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
size="icon"
|
||||
color="destructive"
|
||||
variant="outline"
|
||||
|
|
|
|||
Loading…
Reference in New Issue