This commit is contained in:
Anang Yusman 2025-10-06 23:32:35 +08:00
parent ebef7bdf4c
commit 8c2a543be7
5 changed files with 142 additions and 19 deletions

View File

@ -5,6 +5,7 @@ import Link from "next/link";
import { getArticleById, getListArticle } from "@/service/article";
import { close, loading } from "@/config/swal";
import { useParams } from "next/navigation";
import { Link2, MailIcon } from "lucide-react";
type TabKey = "trending" | "comments" | "latest";
@ -366,6 +367,47 @@ export default function DetailContent() {
/>
</div>
{/* <Author /> */}
<div className="w-full bg-white py-6">
<p className="mx-10 text-2xl mb-4 ">AUTHOR</p>
<div className=" border border-black p-6 flex items-center gap-6 max-w-[1200px] mx-auto">
{/* Foto Profil */}
<div className="w-20 h-20 relative ">
<Image
src="/profile.jpg"
alt="Author"
fill
className="rounded-full object-cover"
/>
</div>
{/* Info Author */}
<div className="flex-1">
<h3 className="text-lg font-semibold text-gray-800">
{articleDetail?.createdByName}
</h3>
<div className="mt-2 flex items-center gap-4 flex-wrap">
{/* Button lihat semua post */}
<button className="text-sm font-medium text-white hover:underline bg-[#655997] py-1 px-5 rounded-xl">
Lihat Semua Pos
</button>
<div className="bg-[#655997] rounded-full p-1">
<MailIcon
size={18}
className="text-white hover:text-black cursor-pointer "
></MailIcon>
</div>
<div className="bg-[#655997] rounded-full p-1">
<Link2
size={18}
className="text-white hover:text-black cursor-pointer "
></Link2>
</div>
</div>
</div>
</div>
</div>
<div className="flex flex-row gap-2 items-center">
<span className="font-semibold text-sm text-gray-700">
Tags:

View File

@ -46,6 +46,7 @@ import {
TableCell,
} from "@/components/ui/table";
import CustomPagination from "../layout/custom-pagination";
import DatePicker from "react-datepicker";
const columns = [
{ name: "No", uid: "no" },
@ -60,6 +61,7 @@ const columns = [
const columnsOtherRole = [
{ name: "No", uid: "no" },
{ name: "Judul", uid: "title" },
{ name: "Source", uid: "source" },
{ name: "Kategori", uid: "category" },
{ name: "Tanggal Unggah", uid: "createdAt" },
{ name: "Kreator", uid: "createdByName" },
@ -84,7 +86,9 @@ export default function ArticleTable() {
const [search, setSearch] = useState("");
const [categories, setCategories] = useState<any>([]);
const [selectedCategories, setSelectedCategories] = useState<any>("");
const [startDateValue, setStartDateValue] = useState({
const [selectedSource, setSelectedSource] = useState<any>("");
const [selectedStatus, setSelectedStatus] = useState<string>("");
const [dateRange, setDateRange] = useState<any>({
startDate: null,
endDate: null,
});
@ -98,24 +102,49 @@ export default function ArticleTable() {
const res = await getArticleByCategory();
const data = res?.data?.data;
setCategories(data);
console.log("category", data);
}
useEffect(() => {
initState();
}, [
page,
showData,
search,
selectedCategories,
selectedSource,
dateRange,
selectedStatus,
]);
async function initState() {
loading();
const req = {
limit: showData,
page: page,
search: search,
categorySlug: Array.from(selectedCategories).join(","),
category: selectedCategories || "",
source: selectedSource || "",
isPublish:
selectedStatus !== "" ? selectedStatus === "publish" : undefined,
startDate: dateRange.startDate
? new Date(dateRange.startDate).toISOString()
: "",
endDate: dateRange.endDate
? new Date(dateRange.endDate).toISOString()
: "",
sort: "desc",
sortBy: "created_at",
};
const res = await getArticlePagination(req);
await getTableNumber(parseInt(showData), res.data?.data);
let data = res.data?.data || [];
await getTableNumber(parseInt(showData), data);
setTotalPage(res?.data?.meta?.totalPage);
close();
}
// panggil ulang setiap state berubah
useEffect(() => {
initState();
@ -346,24 +375,63 @@ export default function ArticleTable() {
</SelectTrigger>
<SelectContent>
{categories
?.filter((category: any) => category.slug != null)
?.filter((category: any) => category.title != null)
.map((category: any) => (
<SelectItem key={category.slug} value={category.slug}>
<SelectItem key={category.id} value={category.title}>
{category.title}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* <div className="flex flex-col gap-1 w-full lg:w-[240px]">
<div className="flex flex-col gap-1 w-full lg:w-[150px]">
<p className="font-semibold text-sm">Source</p>
<Select
value={selectedSource}
onValueChange={(value) => setSelectedSource(value)}
>
<SelectTrigger className="w-full text-sm border">
<SelectValue placeholder="Pilih Source" />
</SelectTrigger>
<SelectContent>
<SelectItem value="INTERNAL">INTERNAL</SelectItem>
<SelectItem value="EXTERNAL">EXTERNAL</SelectItem>
</SelectContent>
</Select>
</div>
<div className="flex flex-col gap-1 w-full lg:w-[150px]">
<p className="font-semibold text-sm">Status</p>
<Select
value={selectedStatus}
onValueChange={(value) => setSelectedStatus(value)}
>
<SelectTrigger className="w-full text-sm border">
<SelectValue placeholder="Pilih Status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="publish">PUBLISH</SelectItem>
<SelectItem value="draft">DRAFT</SelectItem>
</SelectContent>
</Select>
</div>
<div className="flex flex-col gap-1 w-full lg:w-[240px]">
<p className="font-semibold text-sm">Tanggal</p>
<Datepicker
value={startDateValue}
displayFormat="DD/MM/YYYY"
onChange={(e: any) => setStartDateValue(e)}
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"
<DatePicker
selectsRange
startDate={dateRange.startDate}
endDate={dateRange.endDate}
onChange={(update: [Date | null, Date | null]) => {
setDateRange({
startDate: update[0],
endDate: update[1],
});
}}
isClearable
dateFormat="dd/MM/yyyy"
className="z-50 w-full text-sm bg-transparent border border-gray-200 px-2 py-[6px] rounded-xl h-[40px] text-gray-600 dark:text-gray-300"
placeholderText="Pilih rentang tanggal"
/>
</div> */}
</div>
</div>
<div className="w-full overflow-x-hidden">
<div className="w-full mx-auto overflow-x-hidden">

BIN
public/profile.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -1,6 +1,11 @@
import { PaginationRequest } from "@/types/globals";
import { httpGet } from "./http-config/http-base-services";
import { httpDeleteInterceptor, httpGetInterceptor, httpPostInterceptor, httpPutInterceptor } from "./http-config/http-interceptor-services";
import {
httpDeleteInterceptor,
httpGetInterceptor,
httpPostInterceptor,
httpPutInterceptor,
} from "./http-config/http-interceptor-services";
export async function getListArticle(props: PaginationRequest) {
const {
@ -40,13 +45,20 @@ export async function getArticlePagination(props: PaginationRequest) {
sort,
categorySlug,
isBanner,
isPublish,
source,
} = props;
return await httpGetInterceptor(
`/articles?limit=${limit}&page=${page}&title=${search}&startDate=${startDate || ""}&endDate=${
endDate || ""
}&categoryId=${category || ""}&sortBy=${sortBy || "created_at"}&sort=${
sort || "asc"
}&category=${categorySlug || ""}&isBanner=${isBanner || ""}`
`/articles?limit=${limit}&page=${page}&title=${search}&startDate=${
startDate || ""
}&endDate=${endDate || ""}&categoryId=${category || ""}&source=${
source || ""
}&isPublish=${isPublish !== undefined ? isPublish : ""}&sortBy=${
sortBy || "created_at"
}&sort=${sort || "asc"}&category=${categorySlug || ""}&isBanner=${
isBanner || ""
}`
);
}

View File

@ -310,6 +310,7 @@ export type PaginationRequest = {
category?: string;
sortBy?: string;
sort?: string;
source?: string;
categorySlug?: string;
isBanner?: boolean;
};