fix:conten detail image, feat:author, date filter

This commit is contained in:
Rama Priyanto 2025-05-23 00:24:14 +07:00
parent b23b1d63a1
commit b38b72f708
2 changed files with 145 additions and 54 deletions

View File

@ -4,7 +4,6 @@ import {
formatMonthString, formatMonthString,
formatTextToHtmlTag, formatTextToHtmlTag,
} from "@/utils/global"; } from "@/utils/global";
import Image from "next/image";
import { import {
CalendarIcon, CalendarIcon,
ChevronLeftIcon, ChevronLeftIcon,
@ -26,6 +25,7 @@ import { useEffect, useState } from "react";
import { image } from "@heroui/theme"; import { image } from "@heroui/theme";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import { saveActivity } from "@/services/activity-log"; import { saveActivity } from "@/services/activity-log";
import { Image } from "@heroui/react";
const token = Cookies.get("access_token"); const token = Cookies.get("access_token");
const uid = Cookies.get("uie"); const uid = Cookies.get("uie");
@ -155,8 +155,10 @@ export default function DetailNews(props: { data: any; listArticle: any }) {
<div className="flex justify-center my-2 lg:my-5"> <div className="flex justify-center my-2 lg:my-5">
{data?.files?.length > 0 && ( {data?.files?.length > 0 && (
<Image <Image
width={1440} classNames={{
height={1080} wrapper: "!w-full !max-w-full",
img: "!w-full",
}}
alt="Main Image" alt="Main Image"
src={data?.files[imageNow]?.file_url} src={data?.files[imageNow]?.file_url}
className="object-cover w-[100%] rounded-md" className="object-cover w-[100%] rounded-md"
@ -172,8 +174,6 @@ export default function DetailNews(props: { data: any; listArticle: any }) {
className="cursor-pointer" className="cursor-pointer"
> >
<Image <Image
width={480}
height={480}
alt="NextUI hero Image" alt="NextUI hero Image"
src={file?.file_url} src={file?.file_url}
className="object-cover w-[75px] lg:w-[150px] h-[50px] lg:h-[100px] rounded-md" className="object-cover w-[75px] lg:w-[150px] h-[50px] lg:h-[100px] rounded-md"

View File

@ -16,9 +16,16 @@ import {
updateIsBannerArticle, updateIsBannerArticle,
} from "@/services/article"; } from "@/services/article";
import { Article } from "@/types/globals"; import { Article } from "@/types/globals";
import { convertDateFormat } from "@/utils/global"; import {
convertDateFormat,
convertDateFormatNoTime,
convertDateFormatNoTimeV2,
} from "@/utils/global";
import { Button } from "@heroui/button"; import { Button } from "@heroui/button";
import { import {
Autocomplete,
AutocompleteItem,
Calendar,
Chip, Chip,
ChipProps, ChipProps,
Dropdown, Dropdown,
@ -27,6 +34,9 @@ import {
DropdownTrigger, DropdownTrigger,
Input, Input,
Pagination, Pagination,
Popover,
PopoverContent,
PopoverTrigger,
Select, Select,
SelectItem, SelectItem,
Spinner, Spinner,
@ -43,6 +53,7 @@ import Datepicker from "react-tailwindcss-datepicker";
import Swal from "sweetalert2"; import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content"; import withReactContent from "sweetalert2-react-content";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import { parseDate } from "@internationalized/date";
const columns = [ const columns = [
{ name: "No", uid: "no" }, { name: "No", uid: "no" },
@ -86,15 +97,24 @@ export default function ArticleTable() {
const [showData, setShowData] = useState("10"); const [showData, setShowData] = useState("10");
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
const [categories, setCategories] = useState<any>([]); const [categories, setCategories] = useState<any>([]);
const [selectedCategories, setSelectedCategories] = useState<any>([]); const [selectedCategories, setSelectedCategories] = useState<string>("");
const [startDateValue, setStartDateValue] = useState({ const [startDateValue, setStartDateValue] = useState({
startDate: null, startDate: null,
endDate: null, endDate: null,
}); });
const [articleDate, setArticleDate] = useState({
startDate: parseDate(
convertDateFormatNoTimeV2(
new Date(new Date().setDate(new Date().getDate() - 7))
)
),
endDate: parseDate(convertDateFormatNoTimeV2(new Date())),
});
useEffect(() => { useEffect(() => {
initState(); initState();
}, [page, showData, startDateValue, selectedCategories]); }, [page, showData, startDateValue, selectedCategories, articleDate]);
useEffect(() => { useEffect(() => {
getCategories(); getCategories();
@ -106,16 +126,26 @@ export default function ArticleTable() {
setCategories(data); setCategories(data);
} }
const onSelectionChange = (id: Key | null) => {
setSelectedCategories(String(id));
};
const getDate = (data: any) => {
return `${data.year}-${data.month < 10 ? `0${data.month}` : data.month}-${
data.day < 10 ? `0${data.day}` : data.day
}`;
};
async function initState() { async function initState() {
loading(); loading();
console.log("test", selectedCategories);
const req = { const req = {
limit: showData, limit: showData,
page: page, page: page,
search: search, search: search,
// startDate: startDate: getDate(articleDate.startDate),
// startDateValue.startDate === null ? "" : startDateValue.startDate, endDate: getDate(articleDate.endDate),
// endDate: startDateValue.endDate === null ? "" : startDateValue.endDate, category: selectedCategories,
categorySlug: Array.from(selectedCategories).join(","),
sort: "desc", sort: "desc",
sortBy: "created_at", sortBy: "created_at",
}; };
@ -248,13 +278,13 @@ export default function ArticleTable() {
<DropdownItem <DropdownItem
key="edit" key="edit"
className={ className={
username === "admin-mabes" || username?.includes("mabes") ||
Number(userId) === article.createdById Number(userId) === article.createdById
? "" ? ""
: "hidden" : "hidden"
} }
> >
{(username === "admin-mabes" || {(username?.includes("mabes") ||
Number(userId) === article.createdById) && ( Number(userId) === article.createdById) && (
<Link href={`/admin/article/edit/${article.id}`}> <Link href={`/admin/article/edit/${article.id}`}>
<CreateIconIon className="inline mr-2 mb-1" /> <CreateIconIon className="inline mr-2 mb-1" />
@ -267,9 +297,9 @@ export default function ArticleTable() {
onPress={() => onPress={() =>
handleBanner(article?.id, !article?.isBanner) handleBanner(article?.id, !article?.isBanner)
} }
className={username === "admin-mabes" ? "" : "hidden"} className={username?.includes("mabes") ? "" : "hidden"}
> >
{username === "admin-mabes" && ( {username?.includes("mabes") && (
<> <>
<BannerIcon size={24} className="inline mr-2 mb-1" /> <BannerIcon size={24} className="inline mr-2 mb-1" />
{article?.isBanner {article?.isBanner
@ -282,13 +312,13 @@ export default function ArticleTable() {
key="delete" key="delete"
onPress={() => handleDelete(article.id)} onPress={() => handleDelete(article.id)}
className={ className={
username === "admin-mabes" || username?.includes("mabes") ||
Number(userId) === article.createdById Number(userId) === article.createdById
? "" ? ""
: "hidden" : "hidden"
} }
> >
{(username === "admin-mabes" || {(username?.includes("mabes") ||
Number(userId) === article.createdById) && ( Number(userId) === article.createdById) && (
<> <>
{" "} {" "}
@ -330,6 +360,15 @@ export default function ArticleTable() {
initState(); initState();
} }
const [hasMounted, setHasMounted] = useState(false);
useEffect(() => {
setHasMounted(true);
}, []);
// Render
if (!hasMounted) return null;
return ( return (
<> <>
<div className="py-3"> <div className="py-3">
@ -375,44 +414,96 @@ export default function ArticleTable() {
</div> </div>
<div className="flex flex-col gap-1 w-full lg:w-[230px]"> <div className="flex flex-col gap-1 w-full lg:w-[230px]">
<p className="font-semibold text-sm">Kategori</p> <p className="font-semibold text-sm">Kategori</p>
<Select
label="" <Autocomplete
variant="bordered"
labelPlacement="outside"
placeholder="Kategori"
selectionMode="single"
selectedKeys={selectedCategories}
className="w-full" className="w-full"
items={categories} defaultItems={categories}
classNames={{ trigger: "border-1" }} label=""
onSelectionChange={setSelectedCategories} labelPlacement="outside"
renderValue={(items) => { variant="bordered"
return items.map((item) => ( inputProps={{ classNames: { inputWrapper: "border-1" } }}
<span onSelectionChange={onSelectionChange}
key={item.props?.value}
className="text-black dark:text-white text-xs"
> >
{item.textValue} {(item: any) => (
</span> <AutocompleteItem key={item.id}>
)); {item.title}
}} </AutocompleteItem>
> )}
{categories?.map((category: any) => ( </Autocomplete>
<SelectItem key={category?.slug}>
{category?.title}
</SelectItem>
))}
</Select>
</div> </div>
{/* <div className="flex flex-col gap-1 w-full lg:w-[240px]"> {username?.includes("mabes") && (
<p className="font-semibold text-sm">Tanggal</p> <div className="flex flex-col gap-1 w-full lg:w-[230px]">
<Datepicker <p className="font-semibold text-sm">Author</p>
value={startDateValue}
displayFormat="DD/MM/YYYY" <Autocomplete
onChange={(e: any) => setStartDateValue(e)} className="w-full"
inputClassName="z-50 w-full text-sm bg-transparent border-1 border-gray-200 px-2 py-[6px] rounded-xl h-[40px] text-gray-600 dark:text-gray-300" inputProps={{ classNames: { inputWrapper: "border-1" } }}
defaultItems={categories}
label=""
labelPlacement="outside"
variant="bordered"
onSelectionChange={onSelectionChange}
>
{(item: any) => (
<AutocompleteItem key={item.id}>
{item.title}
</AutocompleteItem>
)}
</Autocomplete>
</div>
)}
<div className="flex flex-col gap-1 w-full lg:w-[120px]">
<p className="font-semibold text-sm">Start Date</p>
<Popover
placement="bottom"
classNames={{ content: ["!bg-transparent", "p-0"] }}
>
<PopoverTrigger>
<a className="cursor-pointer border-1 px-2 py-2 rounded-xl">
{convertDateFormatNoTime(articleDate.startDate)}
</a>
</PopoverTrigger>
<PopoverContent className="bg-transparent">
<Calendar
value={articleDate.startDate}
onChange={(e) =>
setArticleDate({
startDate: e,
endDate: articleDate.endDate,
})
}
maxValue={articleDate.endDate}
/> />
</div> */} </PopoverContent>
</Popover>
</div>
<div className="flex flex-col gap-1 w-full lg:w-[120px]">
<p className="font-semibold text-sm">End Date</p>
<Popover
placement="bottom"
classNames={{ content: ["!bg-transparent", "p-0"] }}
>
<PopoverTrigger>
<a className="cursor-pointer border-1 px-2 py-2 rounded-xl">
{convertDateFormatNoTime(articleDate.endDate)}
</a>
</PopoverTrigger>
<PopoverContent className="bg-transparent">
<Calendar
value={articleDate.endDate}
onChange={(e) =>
setArticleDate({
startDate: articleDate.startDate,
endDate: e,
})
}
minValue={articleDate.startDate}
/>
</PopoverContent>
</Popover>
</div>
</div> </div>
<Table <Table
aria-label="micro issue table" aria-label="micro issue table"
@ -425,7 +516,7 @@ export default function ArticleTable() {
}} }}
> >
<TableHeader <TableHeader
columns={username === "admin-mabes" ? columns : columnsOtherRole} columns={username?.includes("mabes") ? columns : columnsOtherRole}
> >
{(column) => ( {(column) => (
<TableColumn key={column.uid}>{column.name}</TableColumn> <TableColumn key={column.uid}>{column.name}</TableColumn>