update
This commit is contained in:
parent
7bf6cdae73
commit
f64ff3d6d8
|
|
@ -5,6 +5,7 @@ import Link from "next/link";
|
||||||
import {
|
import {
|
||||||
getArticleById,
|
getArticleById,
|
||||||
getArticleBySlug,
|
getArticleBySlug,
|
||||||
|
getArticleFiles,
|
||||||
getListArticle,
|
getListArticle,
|
||||||
} from "@/service/article";
|
} from "@/service/article";
|
||||||
import { close, error, loading } from "@/config/swal";
|
import { close, error, loading } from "@/config/swal";
|
||||||
|
|
@ -73,7 +74,7 @@ export default function DetailContent() {
|
||||||
startDate: null,
|
startDate: null,
|
||||||
endDate: null,
|
endDate: null,
|
||||||
});
|
});
|
||||||
const [detailfiles, setDetailFiles] = useState<any>([]);
|
const [detailFiles, setDetailFiles] = useState<any[]>([]);
|
||||||
const [mainImage, setMainImage] = useState(0);
|
const [mainImage, setMainImage] = useState(0);
|
||||||
const [thumbnail, setThumbnail] = useState("-");
|
const [thumbnail, setThumbnail] = useState("-");
|
||||||
const [diseId, setDiseId] = useState(0);
|
const [diseId, setDiseId] = useState(0);
|
||||||
|
|
@ -299,25 +300,62 @@ export default function DetailContent() {
|
||||||
initStateData();
|
initStateData();
|
||||||
}, [listCategory]);
|
}, [listCategory]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setSelectedIndex(0);
|
||||||
|
}, [detailFiles]);
|
||||||
|
|
||||||
async function initStateData() {
|
async function initStateData() {
|
||||||
loading();
|
loading();
|
||||||
const res = await getArticleBySlug(slug);
|
try {
|
||||||
const data = res?.data?.data;
|
// 1️⃣ Ambil artikel by slug
|
||||||
|
const res = await getArticleBySlug(slug);
|
||||||
|
const data = res?.data?.data;
|
||||||
|
|
||||||
setThumbnail(data?.thumbnailUrl);
|
if (!data?.id) return;
|
||||||
setDiseId(data?.aiArticleId);
|
|
||||||
setDetailFiles(data?.files);
|
setArticleDetail(data);
|
||||||
setArticleDetail(data); // <-- Add this
|
setThumbnail(data.thumbnailUrl);
|
||||||
close();
|
setDiseId(data.aiArticleId);
|
||||||
|
|
||||||
|
// 2️⃣ Ambil SEMUA article files
|
||||||
|
const filesRes = await getArticleFiles();
|
||||||
|
const allFiles = filesRes?.data?.data ?? [];
|
||||||
|
|
||||||
|
// 3️⃣ FILTER sesuai articleId
|
||||||
|
const filteredFiles = allFiles.filter(
|
||||||
|
(file: any) => file.articleId === data.id
|
||||||
|
);
|
||||||
|
|
||||||
|
setDetailFiles(filteredFiles);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Init state detail error:", error);
|
||||||
|
} finally {
|
||||||
|
close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// if (!articleDetail?.files || articleDetail?.files?.length === 0) {
|
||||||
// if (!articleDetail?.files || articleDetail.files.length === 0) {
|
|
||||||
// return (
|
// return (
|
||||||
// <div className="w-full h-[400px] bg-gray-100 flex items-center justify-center rounded-lg">
|
// <div className="w-full h-[400px] bg-gray-100 flex items-center justify-center rounded-lg">
|
||||||
// <p className="text-gray-400 text-sm">Gambar tidak tersedia</p>
|
// <p className="text-gray-400 text-sm">Gambar tidak tersedia</p>
|
||||||
// </div>
|
// </div>
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
function decodeHtmlString(raw: string = "") {
|
||||||
|
if (!raw) return "";
|
||||||
|
|
||||||
|
// 1️⃣ Hapus newline escape, backslash, dsb
|
||||||
|
let decoded = raw
|
||||||
|
.replace(/\\n/g, "\n")
|
||||||
|
.replace(/\\"/g, '"') // ubah \" jadi "
|
||||||
|
.replace(/\\'/g, "'") // ubah \' jadi '
|
||||||
|
.replace(/\\\\/g, "\\") // ubah \\ jadi \
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
// 2️⃣ Decode entity HTML (misal ")
|
||||||
|
const el = document.createElement("textarea");
|
||||||
|
el.innerHTML = decoded;
|
||||||
|
return el.value;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
||||||
|
|
@ -514,7 +514,7 @@ export default function CreateArticleForm() {
|
||||||
id="title"
|
id="title"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Masukkan judul artikel"
|
placeholder="Masukkan judul artikel"
|
||||||
className="w-full border rounded-lg dark:border-gray-400"
|
className="h-16 px-4 text-2xl leading-tight"
|
||||||
{...field}
|
{...field}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import {
|
||||||
deleteArticleFiles,
|
deleteArticleFiles,
|
||||||
getArticleByCategory,
|
getArticleByCategory,
|
||||||
getArticleById,
|
getArticleById,
|
||||||
|
getArticleFiles,
|
||||||
submitApproval,
|
submitApproval,
|
||||||
unPublishArticle,
|
unPublishArticle,
|
||||||
updateArticle,
|
updateArticle,
|
||||||
|
|
@ -196,27 +197,49 @@ export default function EditArticleForm(props: { isDetail: boolean }) {
|
||||||
|
|
||||||
async function initState() {
|
async function initState() {
|
||||||
loading();
|
loading();
|
||||||
const res = await getArticleById(id);
|
try {
|
||||||
const data = res.data?.data;
|
// 1️⃣ Ambil ARTICLE
|
||||||
setDetailData(data);
|
const articleRes = await getArticleById(id);
|
||||||
setValue("title", data?.title);
|
const articleData = articleRes.data?.data;
|
||||||
setValue("customCreatorName", data?.customCreatorName);
|
|
||||||
setValue("slug", data?.slug);
|
|
||||||
setValue("source", data?.source);
|
|
||||||
const cleanDescription = data?.htmlDescription
|
|
||||||
? data.htmlDescription
|
|
||||||
.replace(/\\"/g, '"')
|
|
||||||
.replace(/\\n/g, "\n", "\\")
|
|
||||||
.trim()
|
|
||||||
: "";
|
|
||||||
setValue("description", cleanDescription);
|
|
||||||
setValue("tags", data?.tags ? data.tags.split(",") : []);
|
|
||||||
setThumbnail(data?.thumbnailUrl);
|
|
||||||
setDiseId(data?.aiArticleId);
|
|
||||||
setDetailFiles(data?.files);
|
|
||||||
|
|
||||||
setupInitCategory(data?.categories);
|
if (!articleData) return;
|
||||||
close();
|
|
||||||
|
// ===== ARTICLE DATA =====
|
||||||
|
setDetailData(articleData);
|
||||||
|
setValue("title", articleData.title);
|
||||||
|
setValue("customCreatorName", articleData.customCreatorName);
|
||||||
|
setValue("slug", articleData.slug);
|
||||||
|
setValue("source", articleData.source);
|
||||||
|
|
||||||
|
const cleanDescription = articleData.htmlDescription
|
||||||
|
? articleData.htmlDescription
|
||||||
|
.replace(/\\"/g, '"')
|
||||||
|
.replace(/\\n/g, "\n")
|
||||||
|
.trim()
|
||||||
|
: "";
|
||||||
|
|
||||||
|
setValue("description", cleanDescription);
|
||||||
|
setValue("tags", articleData.tags ? articleData.tags.split(",") : []);
|
||||||
|
|
||||||
|
setThumbnail(articleData.thumbnailUrl);
|
||||||
|
setDiseId(articleData.aiArticleId);
|
||||||
|
setupInitCategory(articleData.categories);
|
||||||
|
|
||||||
|
// 2️⃣ Ambil SEMUA article files
|
||||||
|
const filesRes = await getArticleFiles();
|
||||||
|
const allFiles = filesRes.data?.data ?? [];
|
||||||
|
|
||||||
|
// 3️⃣ FILTER berdasarkan ARTICLE ID yang sedang dibuka
|
||||||
|
const filteredFiles = allFiles.filter(
|
||||||
|
(file: any) => file.articleId === articleData.id
|
||||||
|
);
|
||||||
|
|
||||||
|
setDetailFiles(filteredFiles);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Init state error:", error);
|
||||||
|
} finally {
|
||||||
|
close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const setupInitCategory = (data: any) => {
|
const setupInitCategory = (data: any) => {
|
||||||
|
|
@ -677,7 +700,7 @@ export default function EditArticleForm(props: { isDetail: boolean }) {
|
||||||
value={value ?? ""}
|
value={value ?? ""}
|
||||||
readOnly={isDetail}
|
readOnly={isDetail}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
className="w-full border rounded-lg"
|
className="h-16 px-4 text-2xl leading-tight"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,13 @@ export async function uploadArticleThumbnail(id: string, data: any) {
|
||||||
return await httpPostInterceptor(`/articles/thumbnail/${id}`, data, headers);
|
return await httpPostInterceptor(`/articles/thumbnail/${id}`, data, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getArticleFiles() {
|
||||||
|
const headers = {
|
||||||
|
"content-type": "application/json",
|
||||||
|
};
|
||||||
|
return await httpGet(`/article-files`, headers);
|
||||||
|
}
|
||||||
|
|
||||||
export async function deleteArticleFiles(id: number) {
|
export async function deleteArticleFiles(id: number) {
|
||||||
const headers = {
|
const headers = {
|
||||||
"content-type": "multipart/form-data",
|
"content-type": "multipart/form-data",
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ const axiosBaseInstance = axios.create({
|
||||||
baseURL,
|
baseURL,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"X-Client-Key": "02080003-5ad6-4b85-8ee6-0e14ec39349d",
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue