fix:filter use query urt
This commit is contained in:
parent
1df9197c5b
commit
4c807a7fee
|
|
@ -110,18 +110,15 @@ export default function ListNews() {
|
||||||
|
|
||||||
const getPoldaCategId = async () => {
|
const getPoldaCategId = async () => {
|
||||||
const poldaNow = category as string;
|
const poldaNow = category as string;
|
||||||
console.log("poldanow", poldaNow.split("-").join(" "));
|
|
||||||
const dataNow = await getCategory(poldaNow.split("-").join(" "));
|
const dataNow = await getCategory(poldaNow.split("-").join(" "));
|
||||||
console.log("datanow", dataNow);
|
|
||||||
if (dataNow?.length > 0) {
|
if (dataNow?.length > 0) {
|
||||||
const poldaObj = dataNow[0];
|
const poldaObj = dataNow[0];
|
||||||
|
|
||||||
setPoldaCategId(poldaObj.id);
|
setPoldaCategId(poldaObj.id);
|
||||||
|
|
||||||
const option = setupCategory([poldaObj])[0]; // <-- wajib array
|
const option = setupCategory([poldaObj])[0];
|
||||||
setPoldaCategoryOption(option);
|
setPoldaCategoryOption(option);
|
||||||
|
|
||||||
// pastikan masuk ke selectedCategoryId (kalau belum ada)
|
|
||||||
setSelectedCategoryId((prev: any[]) => {
|
setSelectedCategoryId((prev: any[]) => {
|
||||||
const already = prev.some((x) => x.id === option.id);
|
const already = prev.some((x) => x.id === option.id);
|
||||||
if (already) return prev;
|
if (already) return prev;
|
||||||
|
|
@ -137,7 +134,6 @@ export default function ListNews() {
|
||||||
const yearQ = searchParams.get("year");
|
const yearQ = searchParams.get("year");
|
||||||
const pageQ = searchParams.get("page");
|
const pageQ = searchParams.get("page");
|
||||||
|
|
||||||
// sync UI state dari URL
|
|
||||||
setSearchValue(search);
|
setSearchValue(search);
|
||||||
|
|
||||||
if (pageQ) setPage(Number(pageQ));
|
if (pageQ) setPage(Number(pageQ));
|
||||||
|
|
@ -210,20 +206,17 @@ export default function ListNews() {
|
||||||
const usedPage = props?.page || page;
|
const usedPage = props?.page || page;
|
||||||
const usedSearch = props?.title ?? searchValue ?? "";
|
const usedSearch = props?.title ?? searchValue ?? "";
|
||||||
|
|
||||||
// 1) ambil kategori dari props atau state
|
|
||||||
const baseCategories =
|
const baseCategories =
|
||||||
props?.category && props.category.length > 0
|
props?.category && props.category.length > 0
|
||||||
? props.category
|
? props.category
|
||||||
: selectedCategoryId;
|
: selectedCategoryId;
|
||||||
|
|
||||||
// 2) kalau halaman polda, pastikan poldaCategId selalu ikut
|
|
||||||
let finalCategories = baseCategories;
|
let finalCategories = baseCategories;
|
||||||
|
|
||||||
if (isPoldaPage && poldaCategId) {
|
if (isPoldaPage && poldaCategId) {
|
||||||
const hasPolda = baseCategories.some((x: any) => x.id === poldaCategId);
|
const hasPolda = baseCategories.some((x: any) => x.id === poldaCategId);
|
||||||
|
|
||||||
if (!hasPolda) {
|
if (!hasPolda) {
|
||||||
// polda wajib selalu ada
|
|
||||||
finalCategories = [
|
finalCategories = [
|
||||||
...(poldaCategoryOption ? [poldaCategoryOption] : []),
|
...(poldaCategoryOption ? [poldaCategoryOption] : []),
|
||||||
...baseCategories,
|
...baseCategories,
|
||||||
|
|
@ -380,20 +373,17 @@ export default function ListNews() {
|
||||||
onChange={(val: any) => {
|
onChange={(val: any) => {
|
||||||
const nextValue = val || [];
|
const nextValue = val || [];
|
||||||
|
|
||||||
// kalau bukan halaman polda, normal
|
|
||||||
if (!pathname.includes("/news/polda/")) {
|
if (!pathname.includes("/news/polda/")) {
|
||||||
setSelectedCategoryId(nextValue);
|
setSelectedCategoryId(nextValue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// halaman polda: kategori polda harus tetap ada
|
|
||||||
if (poldaCategoryOption) {
|
if (poldaCategoryOption) {
|
||||||
const hasPolda = nextValue.some(
|
const hasPolda = nextValue.some(
|
||||||
(x: any) => x.id === poldaCategoryOption.id,
|
(x: any) => x.id === poldaCategoryOption.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!hasPolda) {
|
if (!hasPolda) {
|
||||||
// user mencoba hapus kategori polda -> balikin lagi
|
|
||||||
setSelectedCategoryId([poldaCategoryOption, ...nextValue]);
|
setSelectedCategoryId([poldaCategoryOption, ...nextValue]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ import { parseDate } from "@internationalized/date";
|
||||||
import { listMasterUsers } from "@/services/master-user";
|
import { listMasterUsers } from "@/services/master-user";
|
||||||
import ReactSelect from "react-select";
|
import ReactSelect from "react-select";
|
||||||
import makeAnimated from "react-select/animated";
|
import makeAnimated from "react-select/animated";
|
||||||
|
import { useRouter, useSearchParams } from "next/navigation";
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{ name: "No", uid: "no" },
|
{ name: "No", uid: "no" },
|
||||||
|
|
@ -100,11 +101,14 @@ export default function ArticleTable() {
|
||||||
const animatedComponents = makeAnimated();
|
const animatedComponents = makeAnimated();
|
||||||
const roleId = getCookiesDecrypt("urie");
|
const roleId = getCookiesDecrypt("urie");
|
||||||
|
|
||||||
const [page, setPage] = useState(1);
|
const router = useRouter();
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
|
||||||
|
const [page, setPage] = useState(Number(searchParams.get("page")) || 1);
|
||||||
const [totalPage, setTotalPage] = useState(1);
|
const [totalPage, setTotalPage] = useState(1);
|
||||||
const [article, setArticle] = useState<any[]>([]);
|
const [article, setArticle] = useState<any[]>([]);
|
||||||
const [showData, setShowData] = useState("10");
|
const [showData, setShowData] = useState(searchParams.get("limit") || "10");
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState(searchParams.get("search") || "");
|
||||||
const [categories, setCategories] = useState<any>([]);
|
const [categories, setCategories] = useState<any>([]);
|
||||||
const [users, setUsers] = useState<any>([]);
|
const [users, setUsers] = useState<any>([]);
|
||||||
const [selectedCategories, setSelectedCategories] = useState<any>([]);
|
const [selectedCategories, setSelectedCategories] = useState<any>([]);
|
||||||
|
|
@ -116,36 +120,92 @@ export default function ArticleTable() {
|
||||||
|
|
||||||
const [selectedArticles, setSelectedArticles] = useState<any>(new Set([]));
|
const [selectedArticles, setSelectedArticles] = useState<any>(new Set([]));
|
||||||
|
|
||||||
|
// const [articleDate, setArticleDate] = useState<any>({
|
||||||
|
// startDate: parseDate(
|
||||||
|
// convertDateFormatNoTimeV2(
|
||||||
|
// new Date(new Date().setDate(new Date().getDate() - 7)),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// endDate: parseDate(convertDateFormatNoTimeV2(new Date())),
|
||||||
|
// });
|
||||||
const [articleDate, setArticleDate] = useState<any>({
|
const [articleDate, setArticleDate] = useState<any>({
|
||||||
startDate: parseDate(
|
startDate: searchParams.get("startDate")
|
||||||
convertDateFormatNoTimeV2(
|
? parseDate(searchParams.get("startDate")!)
|
||||||
new Date(new Date().setDate(new Date().getDate() - 7))
|
: null,
|
||||||
)
|
endDate: searchParams.get("endDate")
|
||||||
),
|
? parseDate(searchParams.get("endDate")!)
|
||||||
endDate: parseDate(convertDateFormatNoTimeV2(new Date())),
|
: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
initState();
|
|
||||||
}, [page, showData]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (page == 1) {
|
|
||||||
initState();
|
|
||||||
} else {
|
|
||||||
setPage(1);
|
|
||||||
}
|
|
||||||
}, [selectedCategories, selectedUsers, articleDate, startDateValue]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getCategories();
|
getCategories();
|
||||||
getUsers();
|
getUsers();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
initState();
|
||||||
|
}, [searchParams]);
|
||||||
|
|
||||||
|
const updateQuery = (params: Record<string, any>) => {
|
||||||
|
const current = new URLSearchParams(searchParams.toString());
|
||||||
|
|
||||||
|
Object.entries(params).forEach(([key, value]) => {
|
||||||
|
if (
|
||||||
|
value === undefined ||
|
||||||
|
value === null ||
|
||||||
|
value === "" ||
|
||||||
|
(Array.isArray(value) && value.length === 0)
|
||||||
|
) {
|
||||||
|
current.delete(key);
|
||||||
|
} else {
|
||||||
|
current.set(key, String(value));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
current.set("timeStamp", String(getUnixTimestamp()));
|
||||||
|
|
||||||
|
router.push(`?${current.toString()}`);
|
||||||
|
};
|
||||||
|
|
||||||
const setupList = (data: any, type: string) => {
|
const setupList = (data: any, type: string) => {
|
||||||
const temp = [];
|
const temp = [];
|
||||||
|
const categoryIds = searchParams.get("categoryIds") || "";
|
||||||
|
const createdByIds = searchParams.get("createdByIds") || "";
|
||||||
|
let tempCateg: number[] = [];
|
||||||
|
let tempCreated: number[] = [];
|
||||||
|
|
||||||
|
const selectedCat: any[] = [];
|
||||||
|
const selectedUsr: any[] = [];
|
||||||
|
|
||||||
|
if (categoryIds && categoryIds !== "") {
|
||||||
|
tempCateg = categoryIds
|
||||||
|
.split(",")
|
||||||
|
.map((id) => Number(id))
|
||||||
|
.filter((id) => !isNaN(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (createdByIds && createdByIds !== "") {
|
||||||
|
tempCreated = createdByIds
|
||||||
|
.split(",")
|
||||||
|
.map((id) => Number(id))
|
||||||
|
.filter((id) => !isNaN(id));
|
||||||
|
}
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
for (const element of data) {
|
for (const element of data) {
|
||||||
|
if (type === "category" && tempCateg.includes(element.id)) {
|
||||||
|
selectedCat.push({
|
||||||
|
id: element.id,
|
||||||
|
label: element.title,
|
||||||
|
value: element.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (type === "users" && tempCreated.includes(element.id)) {
|
||||||
|
selectedUsr.push({
|
||||||
|
id: element.id,
|
||||||
|
label: element.fullname,
|
||||||
|
value: element.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
temp.push({
|
temp.push({
|
||||||
id: element.id,
|
id: element.id,
|
||||||
label: element.title || element.fullname,
|
label: element.title || element.fullname,
|
||||||
|
|
@ -154,10 +214,12 @@ export default function ArticleTable() {
|
||||||
}
|
}
|
||||||
if (type === "users") {
|
if (type === "users") {
|
||||||
setUsers(temp);
|
setUsers(temp);
|
||||||
|
setSelectedUsers(selectedUsr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === "category") {
|
if (type === "category") {
|
||||||
setCategories(temp);
|
setCategories(temp);
|
||||||
|
setSelectedCategories(selectedCat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -208,16 +270,16 @@ export default function ArticleTable() {
|
||||||
async function initState() {
|
async function initState() {
|
||||||
loading();
|
loading();
|
||||||
const req = {
|
const req = {
|
||||||
limit: showData,
|
limit: searchParams.get("limit") || showData,
|
||||||
page: page,
|
page: Number(searchParams.get("page")) || "",
|
||||||
search: search,
|
search: searchParams.get("search") || "",
|
||||||
startDate: getDate(articleDate.startDate),
|
startDate: searchParams.get("startDate") || "",
|
||||||
endDate: getDate(articleDate.endDate),
|
endDate: searchParams.get("endDate") || "",
|
||||||
categoryIds: getIds(selectedCategories),
|
categoryIds: searchParams.get("categoryIds") || "",
|
||||||
createdByIds: getIds(selectedUsers),
|
createdByIds: searchParams.get("createdByIds") || "",
|
||||||
sort: "desc",
|
sort: "desc",
|
||||||
sortBy: "created_at",
|
sortBy: "created_at",
|
||||||
timeStamp: getUnixTimestamp(),
|
timeStamp: searchParams.get("timeStamp") || getUnixTimestamp(),
|
||||||
};
|
};
|
||||||
const res = await getListArticleAdminPage(req);
|
const res = await getListArticleAdminPage(req);
|
||||||
await getTableNumber(parseInt(showData), res.data?.data);
|
await getTableNumber(parseInt(showData), res.data?.data);
|
||||||
|
|
@ -467,7 +529,7 @@ export default function ArticleTable() {
|
||||||
return cellValue;
|
return cellValue;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[article, page, selectedArticles]
|
[article, page, selectedArticles],
|
||||||
);
|
);
|
||||||
|
|
||||||
let typingTimer: NodeJS.Timeout;
|
let typingTimer: NodeJS.Timeout;
|
||||||
|
|
@ -487,6 +549,19 @@ export default function ArticleTable() {
|
||||||
initState();
|
initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleApplyFilter = () => {
|
||||||
|
setPage(1);
|
||||||
|
updateQuery({
|
||||||
|
page: 1,
|
||||||
|
limit: showData,
|
||||||
|
search,
|
||||||
|
categoryIds: getIds(selectedCategories),
|
||||||
|
createdByIds: getIds(selectedUsers),
|
||||||
|
startDate: getDate(articleDate.startDate),
|
||||||
|
endDate: getDate(articleDate.endDate),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const [hasMounted, setHasMounted] = useState(false);
|
const [hasMounted, setHasMounted] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -507,16 +582,17 @@ export default function ArticleTable() {
|
||||||
aria-label="Search"
|
aria-label="Search"
|
||||||
classNames={{
|
classNames={{
|
||||||
inputWrapper: "bg-default-100",
|
inputWrapper: "bg-default-100",
|
||||||
input: "text-sm",
|
input: "text-sm outline-none",
|
||||||
}}
|
}}
|
||||||
labelPlacement="outside"
|
labelPlacement="outside"
|
||||||
startContent={
|
startContent={
|
||||||
<SearchIcon className="text-base text-default-400 pointer-events-none flex-shrink-0" />
|
<SearchIcon className="text-base text-default-400 pointer-events-none flex-shrink-0" />
|
||||||
}
|
}
|
||||||
type="text"
|
type="text"
|
||||||
|
value={search}
|
||||||
onChange={(e) => setSearch(e.target.value)}
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
onKeyUp={handleKeyUp}
|
// onKeyUp={handleKeyUp}
|
||||||
onKeyDown={handleKeyDown}
|
// onKeyDown={handleKeyDown}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-1 w-full lg:w-[72px]">
|
<div className="flex flex-col gap-1 w-full lg:w-[72px]">
|
||||||
|
|
@ -554,6 +630,7 @@ export default function ArticleTable() {
|
||||||
isClearable={true}
|
isClearable={true}
|
||||||
isSearchable={true}
|
isSearchable={true}
|
||||||
isMulti={true}
|
isMulti={true}
|
||||||
|
value={selectedCategories}
|
||||||
placeholder="Kategori..."
|
placeholder="Kategori..."
|
||||||
name="sub-module"
|
name="sub-module"
|
||||||
options={categories}
|
options={categories}
|
||||||
|
|
@ -564,7 +641,7 @@ export default function ArticleTable() {
|
||||||
<p className="font-semibold text-sm">Author</p>
|
<p className="font-semibold text-sm">Author</p>
|
||||||
|
|
||||||
<ReactSelect
|
<ReactSelect
|
||||||
className="basic-single text-black z-40"
|
className="basic-single text-black z-30"
|
||||||
classNames={{
|
classNames={{
|
||||||
control: (state: any) =>
|
control: (state: any) =>
|
||||||
"!rounded-lg bg-white !border-1 !border-gray-200 dark:!border-stone-500",
|
"!rounded-lg bg-white !border-1 !border-gray-200 dark:!border-stone-500",
|
||||||
|
|
@ -572,6 +649,7 @@ export default function ArticleTable() {
|
||||||
classNamePrefix="select"
|
classNamePrefix="select"
|
||||||
onChange={setSelectedUsers}
|
onChange={setSelectedUsers}
|
||||||
closeMenuOnSelect={false}
|
closeMenuOnSelect={false}
|
||||||
|
value={selectedUsers}
|
||||||
components={animatedComponents}
|
components={animatedComponents}
|
||||||
isClearable={true}
|
isClearable={true}
|
||||||
isSearchable={true}
|
isSearchable={true}
|
||||||
|
|
@ -666,6 +744,42 @@ export default function ArticleTable() {
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex flex-col gap-1 ">
|
||||||
|
<p className="font-semibold text-sm">Filter</p>
|
||||||
|
<div className="flex flex-row gap-1">
|
||||||
|
<Button
|
||||||
|
color="primary"
|
||||||
|
className="h-[42px] w-full"
|
||||||
|
onPress={handleApplyFilter}
|
||||||
|
>
|
||||||
|
Cari
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="bordered"
|
||||||
|
className="w-full"
|
||||||
|
color="warning"
|
||||||
|
onPress={() => {
|
||||||
|
setSearch("");
|
||||||
|
setSelectedCategories([]);
|
||||||
|
setSelectedUsers([]);
|
||||||
|
setArticleDate({ startDate: null, endDate: null });
|
||||||
|
setPage(1);
|
||||||
|
setShowData("10");
|
||||||
|
updateQuery({
|
||||||
|
page: 1,
|
||||||
|
limit: "10",
|
||||||
|
search: "",
|
||||||
|
categoryIds: [],
|
||||||
|
createdByIds: [],
|
||||||
|
startDate: "",
|
||||||
|
endDate: "",
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Reset
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Table
|
<Table
|
||||||
aria-label="micro issue table"
|
aria-label="micro issue table"
|
||||||
|
|
@ -717,7 +831,10 @@ export default function ArticleTable() {
|
||||||
}}
|
}}
|
||||||
page={page}
|
page={page}
|
||||||
total={totalPage}
|
total={totalPage}
|
||||||
onChange={(page) => setPage(page)}
|
onChange={(p) => {
|
||||||
|
setPage(p);
|
||||||
|
updateQuery({ page: p });
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ export async function getListArticle(props: PaginationRequest) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getListArticleAdminPage(props: PaginationRequest) {
|
export async function getListArticleAdminPage(props: any) {
|
||||||
const {
|
const {
|
||||||
page,
|
page,
|
||||||
limit,
|
limit,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue