fix landing banner article
This commit is contained in:
parent
fccb7d60f1
commit
a01825a40a
|
|
@ -45,6 +45,7 @@ export default function HeaderNews() {
|
||||||
search: "",
|
search: "",
|
||||||
limit: "10",
|
limit: "10",
|
||||||
sort: "desc",
|
sort: "desc",
|
||||||
|
isPublish: true,
|
||||||
};
|
};
|
||||||
const response = await getListArticle(req);
|
const response = await getListArticle(req);
|
||||||
setArticle(response?.data?.data);
|
setArticle(response?.data?.data);
|
||||||
|
|
@ -57,6 +58,7 @@ export default function HeaderNews() {
|
||||||
limit: "10",
|
limit: "10",
|
||||||
sortBy: "view_count",
|
sortBy: "view_count",
|
||||||
sort: "desc",
|
sort: "desc",
|
||||||
|
category: "586",
|
||||||
isPublish: true,
|
isPublish: true,
|
||||||
};
|
};
|
||||||
const response = await getListArticle(req);
|
const response = await getListArticle(req);
|
||||||
|
|
|
||||||
|
|
@ -207,6 +207,15 @@ export default function BannerHumasNew() {
|
||||||
</Accordion>
|
</Accordion>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [hasMounted, setHasMounted] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setHasMounted(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Render
|
||||||
|
if (!hasMounted) return null;
|
||||||
return (
|
return (
|
||||||
<div className="h-fit relative text-white overflow-hidden">
|
<div className="h-fit relative text-white overflow-hidden">
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import React, { Component, useEffect, useState } from "react";
|
||||||
import ReactApexChart from "react-apexcharts";
|
import ReactApexChart from "react-apexcharts";
|
||||||
import dummyData from "../../../../const/dummy.json";
|
import dummyData from "../../../../const/dummy.json";
|
||||||
import { getStatisticMonthly } from "@/service/article";
|
import { getStatisticMonthly } from "@/service/article";
|
||||||
|
import { get } from "http";
|
||||||
|
|
||||||
type WeekData = {
|
type WeekData = {
|
||||||
week: number;
|
week: number;
|
||||||
|
|
@ -43,8 +44,12 @@ function processMonthlyData(count: number[]): {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const SuggestionsChart = (props: { type: string; date: string }) => {
|
const SuggestionsChart = (props: {
|
||||||
const { date, type } = props;
|
type: string;
|
||||||
|
date: string;
|
||||||
|
totals: (data: number) => void;
|
||||||
|
}) => {
|
||||||
|
const { date, type, totals } = props;
|
||||||
const [categories, setCategories] = useState<string[]>([]);
|
const [categories, setCategories] = useState<string[]>([]);
|
||||||
const [seriesSuggestions, setSeriesSuggestions] = useState<number[]>([]);
|
const [seriesSuggestions, setSeriesSuggestions] = useState<number[]>([]);
|
||||||
|
|
||||||
|
|
@ -69,15 +74,17 @@ const SuggestionsChart = (props: { type: string; date: string }) => {
|
||||||
];
|
];
|
||||||
const category = [];
|
const category = [];
|
||||||
const temp = [];
|
const temp = [];
|
||||||
|
let totalData = 0;
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
const total = data[i].suggestions.reduce(
|
const total = data[i].suggestions.reduce(
|
||||||
(sum: number, list: number) => sum + list,
|
(sum: number, list: number) => sum + list,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
temp.push(total);
|
temp.push(total);
|
||||||
|
totalData += total;
|
||||||
category.push(months[data[i].month - 1]);
|
category.push(months[data[i].month - 1]);
|
||||||
}
|
}
|
||||||
return { categories: category, series: temp };
|
return { categories: category, series: temp, total: totalData };
|
||||||
}
|
}
|
||||||
|
|
||||||
const initFetch = async () => {
|
const initFetch = async () => {
|
||||||
|
|
@ -86,16 +93,17 @@ const SuggestionsChart = (props: { type: string; date: string }) => {
|
||||||
// const data = res?.data?.data;
|
// const data = res?.data?.data;
|
||||||
const data = dummyData.data;
|
const data = dummyData.data;
|
||||||
if (type === "monthly") {
|
if (type === "monthly") {
|
||||||
const getDatas = data?.filter(
|
const getDatas = data?.filter((a) => a.year === Number(splitDate[1]));
|
||||||
(a: any) => a.year === Number(splitDate[1])
|
console.log("teemp,tota", getDatas);
|
||||||
);
|
|
||||||
if (getDatas) {
|
if (getDatas) {
|
||||||
const temp = processYearlyData(getDatas);
|
const temp = processYearlyData(getDatas);
|
||||||
console.log("temp", temp);
|
|
||||||
setSeriesSuggestions(temp.series);
|
setSeriesSuggestions(temp.series);
|
||||||
setCategories(temp.categories);
|
setCategories(temp.categories);
|
||||||
|
totals(temp.total);
|
||||||
} else {
|
} else {
|
||||||
setSeriesSuggestions([]);
|
setSeriesSuggestions([]);
|
||||||
|
totals(0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const getDatas = data?.find(
|
const getDatas = data?.find(
|
||||||
|
|
@ -104,24 +112,25 @@ const SuggestionsChart = (props: { type: string; date: string }) => {
|
||||||
);
|
);
|
||||||
if (getDatas) {
|
if (getDatas) {
|
||||||
const temp = processMonthlyData(getDatas?.suggestions);
|
const temp = processMonthlyData(getDatas?.suggestions);
|
||||||
|
const sum = getDatas.suggestions.reduce((acc, curr) => acc + curr, 0);
|
||||||
|
totals(sum);
|
||||||
if (type == "weekly") {
|
if (type == "weekly") {
|
||||||
setSeriesSuggestions(
|
setSeriesSuggestions(
|
||||||
temp.weeks.map((list) => {
|
temp.weeks.map((list) => {
|
||||||
return list.total;
|
return list.total;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
setSeriesSuggestions(getDatas.suggestions);
|
|
||||||
}
|
|
||||||
if (type === "weekly") {
|
|
||||||
const category = [];
|
const category = [];
|
||||||
for (let i = 1; i <= temp.weeks.length; i++) {
|
for (let i = 1; i <= temp.weeks.length; i++) {
|
||||||
category.push(`Minggu ke-${i}`);
|
category.push(`Minggu ke-${i}`);
|
||||||
}
|
}
|
||||||
setCategories(category);
|
setCategories(category);
|
||||||
|
} else {
|
||||||
|
setSeriesSuggestions(getDatas.suggestions);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setSeriesSuggestions([]);
|
setSeriesSuggestions([]);
|
||||||
|
totals(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -20,16 +20,25 @@ import { useEffect, useRef, useState } from "react";
|
||||||
import { getListArticle } from "@/service/article";
|
import { getListArticle } from "@/service/article";
|
||||||
import { formatMonthString, htmlToString, textEllipsis } from "@/utils/global";
|
import { formatMonthString, htmlToString, textEllipsis } from "@/utils/global";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { useParams } from "next/navigation";
|
import {
|
||||||
|
useParams,
|
||||||
|
usePathname,
|
||||||
|
useRouter,
|
||||||
|
useSearchParams,
|
||||||
|
} from "next/navigation";
|
||||||
|
|
||||||
export default function ListNews() {
|
export default function ListNews() {
|
||||||
const [article, setArticle] = useState<any>([]);
|
const [article, setArticle] = useState<any>([]);
|
||||||
const [search, setSearch] = useState("");
|
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
|
const router = useRouter();
|
||||||
|
const pathname = usePathname();
|
||||||
const [totalPage, setTotalPage] = useState(1);
|
const [totalPage, setTotalPage] = useState(1);
|
||||||
const topRef = useRef<HTMLDivElement>(null);
|
const topRef = useRef<HTMLDivElement>(null);
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const category = params?.name;
|
const category = params?.name;
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
const search = searchParams.get("search");
|
||||||
|
const [searchValue, setSearchValue] = useState(search || "");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getArticle();
|
getArticle();
|
||||||
|
|
@ -41,9 +50,10 @@ export default function ListNews() {
|
||||||
|
|
||||||
const req = {
|
const req = {
|
||||||
page: page,
|
page: page,
|
||||||
search: search,
|
search: searchValue || "",
|
||||||
limit: "9",
|
limit: "9",
|
||||||
category: String(category),
|
category: String(category),
|
||||||
|
isPublish: true,
|
||||||
};
|
};
|
||||||
const response = await getListArticle(req);
|
const response = await getListArticle(req);
|
||||||
setArticle(response?.data?.data);
|
setArticle(response?.data?.data);
|
||||||
|
|
@ -52,7 +62,7 @@ export default function ListNews() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-white" ref={topRef}>
|
<div className="bg-white border-b-1" ref={topRef}>
|
||||||
<div className="text-black py-5 px-3 lg:w-[75vw] mx-auto bg-white">
|
<div className="text-black py-5 px-3 lg:w-[75vw] mx-auto bg-white">
|
||||||
<div className="flex flex-row gap-4">
|
<div className="flex flex-row gap-4">
|
||||||
<Link href="/" className="text-black font-semibold">
|
<Link href="/" className="text-black font-semibold">
|
||||||
|
|
@ -69,13 +79,22 @@ export default function ListNews() {
|
||||||
inputWrapper: "bg-white hover:!bg-gray-100 border-1",
|
inputWrapper: "bg-white hover:!bg-gray-100 border-1",
|
||||||
input: "text-sm !text-black",
|
input: "text-sm !text-black",
|
||||||
}}
|
}}
|
||||||
|
onKeyDown={(event) => {
|
||||||
|
if (event.key === "Enter") {
|
||||||
|
router.push(pathname + `?search=${searchValue}`);
|
||||||
|
getArticle();
|
||||||
|
}
|
||||||
|
}}
|
||||||
labelPlacement="outside"
|
labelPlacement="outside"
|
||||||
placeholder="Search..."
|
placeholder="Search..."
|
||||||
value={search}
|
value={searchValue || ""}
|
||||||
onValueChange={setSearch}
|
onValueChange={setSearchValue}
|
||||||
endContent={
|
endContent={
|
||||||
<Button
|
<Button
|
||||||
onPress={getArticle}
|
onPress={() => {
|
||||||
|
router.push(pathname + `?search=${searchValue}`);
|
||||||
|
getArticle();
|
||||||
|
}}
|
||||||
size="sm"
|
size="sm"
|
||||||
className="bg-red-500 font-semibold"
|
className="bg-red-500 font-semibold"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@ export default function SuggestionsTable() {
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
const [isReply, setIsReply] = useState(false);
|
const [isReply, setIsReply] = useState(false);
|
||||||
const [replyValue, setReplyValue] = useState("");
|
const [replyValue, setReplyValue] = useState("");
|
||||||
|
const [totalData, setTotalData] = useState(0);
|
||||||
|
|
||||||
const formOptions = {
|
const formOptions = {
|
||||||
resolver: zodResolver(createArticleSchema),
|
resolver: zodResolver(createArticleSchema),
|
||||||
|
|
@ -302,7 +303,7 @@ export default function SuggestionsTable() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex flex-row gap-2">
|
<div className="flex flex-row gap-2 items-center">
|
||||||
<Button
|
<Button
|
||||||
color="primary"
|
color="primary"
|
||||||
variant={typeDate === "monthly" ? "solid" : "bordered"}
|
variant={typeDate === "monthly" ? "solid" : "bordered"}
|
||||||
|
|
@ -342,18 +343,22 @@ export default function SuggestionsTable() {
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
|
<p className="font-semibold">
|
||||||
|
Total : <span className="font-bold">{totalData}</span>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row w-full h-full">
|
<div className="flex flex-row w-full h-full">
|
||||||
<div className="w-full h-[30vh] lg:h-[300px] text-black">
|
<div className="w-full h-[30vh] lg:h-[300px] text-black">
|
||||||
<SuggestionsChart
|
<SuggestionsChart
|
||||||
type={typeDate}
|
type={typeDate}
|
||||||
date={`${startDateValue.month} ${startDateValue.year}`}
|
date={`${startDateValue.month} ${startDateValue.year}`}
|
||||||
|
totals={(data) => setTotalData(data)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="py-3">
|
<div className="py-3">
|
||||||
<div className="flex flex-col items-start rounded-2xl gap-3">
|
<div className="flex flex-col items-start rounded-2xl gap-3">
|
||||||
<div className="flex flex-col md:flex-row gap-3 w-full">
|
<div className="flex flex-col md:flex-row gap-3 w-full lg:items-end">
|
||||||
<div className="flex flex-col gap-1 w-full lg:w-1/3">
|
<div className="flex flex-col gap-1 w-full lg:w-1/3">
|
||||||
<p className="font-semibold text-sm">Pencarian</p>
|
<p className="font-semibold text-sm">Pencarian</p>
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -394,6 +399,9 @@ export default function SuggestionsTable() {
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
<Button color="primary" className="text-white">
|
||||||
|
Export
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<Table
|
<Table
|
||||||
aria-label="micro issue table"
|
aria-label="micro issue table"
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -67,6 +67,7 @@
|
||||||
"tailwind-variants": "^0.1.18",
|
"tailwind-variants": "^0.1.18",
|
||||||
"tailwindcss": "3.3.5",
|
"tailwindcss": "3.3.5",
|
||||||
"typescript": "5.0.4",
|
"typescript": "5.0.4",
|
||||||
|
"xlsx": "^0.18.5",
|
||||||
"zod": "^3.23.8",
|
"zod": "^3.23.8",
|
||||||
"zustand": "^5.0.1"
|
"zustand": "^5.0.1"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ export async function getListArticle(props: PaginationRequest) {
|
||||||
isPublish === undefined ? "" : isPublish
|
isPublish === undefined ? "" : isPublish
|
||||||
}&title=${search}&startDate=${startDate || ""}&endDate=${
|
}&title=${search}&startDate=${startDate || ""}&endDate=${
|
||||||
endDate || ""
|
endDate || ""
|
||||||
}&category=${category || ""}&sortBy=${sortBy || "created_at"}&sort=${
|
}&categoryId=${category || ""}&sortBy=${sortBy || "created_at"}&sort=${
|
||||||
sort || "asc"
|
sort || "asc"
|
||||||
}`,
|
}`,
|
||||||
headers
|
headers
|
||||||
|
|
@ -93,7 +93,7 @@ export async function getArticleByCategory() {
|
||||||
"content-type": "application/json",
|
"content-type": "application/json",
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
};
|
};
|
||||||
return await httpGet(`/article-categories?limit=200`, headers);
|
return await httpGet(`/article-categories?limit=1000`, headers);
|
||||||
}
|
}
|
||||||
export async function getCategoryPagination(data: any) {
|
export async function getCategoryPagination(data: any) {
|
||||||
const headers = {
|
const headers = {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue