Compare commits
10 Commits
07f340419a
...
04a40eb952
| Author | SHA1 | Date |
|---|---|---|
|
|
04a40eb952 | |
|
|
fb75399e48 | |
|
|
ced07906ad | |
|
|
d1d7d33c41 | |
|
|
8db50bdc90 | |
|
|
fe4b0bd917 | |
|
|
2e8c45ad97 | |
|
|
eb1031cc53 | |
|
|
515c5c8802 | |
|
|
304d972aa5 |
|
|
@ -11,12 +11,12 @@ build-dev:
|
||||||
name: docker:25.0.3-cli
|
name: docker:25.0.3-cli
|
||||||
services:
|
services:
|
||||||
- name: docker:25.0.3-dind
|
- name: docker:25.0.3-dind
|
||||||
command: ["--insecure-registry=103.82.242.92:8900"]
|
command: ["--insecure-registry=38.47.185.86:8900"]
|
||||||
script:
|
script:
|
||||||
- docker logout
|
- docker logout
|
||||||
- docker login -u $DEPLOY_USERNAME -p $DEPLOY_TOKEN 103.82.242.92:8900
|
- docker login -u $DEPLOY_USERNAME -p $DEPLOY_TOKEN 38.47.185.86:8900
|
||||||
- docker build -t 103.82.242.92:8900/medols/web-berita-bumn:dev .
|
- docker build -t 38.47.185.86:8900/medols/web-berita-bumn:dev .
|
||||||
- docker push 103.82.242.92:8900/medols/web-berita-bumn:dev
|
- docker push 38.47.185.86:8900/medols/web-berita-bumn:dev
|
||||||
|
|
||||||
auto-deploy:
|
auto-deploy:
|
||||||
stage: deploy
|
stage: deploy
|
||||||
|
|
@ -27,4 +27,4 @@ auto-deploy:
|
||||||
services:
|
services:
|
||||||
- docker:dind
|
- docker:dind
|
||||||
script:
|
script:
|
||||||
- curl --user admin:$JENKINS_PWD http://103.31.38.120:8080/job/auto-deploy-berita-bumn/build?token=autodeploymedols
|
- curl --user admin:$JENKINS_PWD http://38.47.185.86:8080/job/auto-deploy-berita-bumn/build?token=autodeploymedols
|
||||||
|
|
|
||||||
BIN
app/favicon.ico
BIN
app/favicon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 190 KiB |
|
|
@ -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";
|
||||||
|
|
@ -22,6 +23,7 @@ import {
|
||||||
} from "@/service/master-user";
|
} from "@/service/master-user";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { Badge } from "../ui/badge";
|
import { Badge } from "../ui/badge";
|
||||||
|
import { formatTextToHtmlTag } from "@/utils/global";
|
||||||
|
|
||||||
type TabKey = "trending" | "comments" | "latest";
|
type TabKey = "trending" | "comments" | "latest";
|
||||||
|
|
||||||
|
|
@ -74,13 +76,13 @@ 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);
|
||||||
const [thumbnailImg, setThumbnailImg] = useState<File[]>([]);
|
const [thumbnailImg, setThumbnailImg] = useState<File[]>([]);
|
||||||
const [selectedMainImage, setSelectedMainImage] = useState<number | null>(
|
const [selectedMainImage, setSelectedMainImage] = useState<number | null>(
|
||||||
null
|
null,
|
||||||
);
|
);
|
||||||
|
|
||||||
const [selectedIndex, setSelectedIndex] = useState(0);
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
||||||
|
|
@ -300,16 +302,38 @@ 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);
|
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) {
|
||||||
|
|
@ -320,6 +344,16 @@ export default function DetailContent() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeImgTags(htmlString?: { __html: string }) {
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const doc = parser.parseFromString(String(htmlString?.__html), "text/html");
|
||||||
|
|
||||||
|
const images = doc.querySelectorAll("img");
|
||||||
|
images.forEach((img) => img.remove());
|
||||||
|
|
||||||
|
return { __html: doc.body.innerHTML };
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="bg-white grid grid-cols-1 md:grid-cols-3 gap-6 px-8 py-8">
|
<div className="bg-white grid grid-cols-1 md:grid-cols-3 gap-6 px-8 py-8">
|
||||||
|
|
@ -355,14 +389,20 @@ export default function DetailContent() {
|
||||||
<span>•</span>
|
<span>•</span>
|
||||||
<span>
|
<span>
|
||||||
<span>
|
<span>
|
||||||
{new Date(articleDetail?.publishedAt).toLocaleDateString(
|
{new Date(
|
||||||
"id-ID",
|
articleDetail?.publishedAt || articleDetail?.createdAt,
|
||||||
{
|
)
|
||||||
|
.toLocaleString("id-ID", {
|
||||||
day: "numeric",
|
day: "numeric",
|
||||||
month: "long",
|
month: "long",
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
}
|
hour: "2-digit",
|
||||||
)}
|
minute: "2-digit",
|
||||||
|
hour12: false,
|
||||||
|
timeZone: "Asia/Jakarta",
|
||||||
|
})
|
||||||
|
.replace("pukul ", "")}{" "}
|
||||||
|
WIB
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span>•</span>
|
<span>•</span>
|
||||||
|
|
@ -371,38 +411,43 @@ export default function DetailContent() {
|
||||||
|
|
||||||
<div className="w-full h-auto mb-6">
|
<div className="w-full h-auto mb-6">
|
||||||
{/* Gambar utama */}
|
{/* Gambar utama */}
|
||||||
<div className="w-full">
|
{detailFiles.length > 0 ? (
|
||||||
<Image
|
<>
|
||||||
src={articleDetail.files[selectedIndex].fileUrl}
|
<Image
|
||||||
alt={articleDetail.files[selectedIndex].fileAlt || "Berita"}
|
src={detailFiles[selectedIndex]?.fileUrl}
|
||||||
width={800}
|
alt={detailFiles[selectedIndex]?.fileAlt || "Berita"}
|
||||||
height={400}
|
width={800}
|
||||||
className="rounded-lg w-full object-cover"
|
height={400}
|
||||||
/>
|
className="rounded-lg w-full object-cover"
|
||||||
</div>
|
/>
|
||||||
|
|
||||||
{/* Thumbnail */}
|
<div className="flex gap-2 mt-3 overflow-x-auto">
|
||||||
<div className="flex gap-2 mt-3 overflow-x-auto">
|
{detailFiles.map((file, index) => (
|
||||||
{articleDetail.files.map((file: any, index: number) => (
|
<button
|
||||||
<button
|
key={file.id}
|
||||||
key={file.id || index}
|
onClick={() => setSelectedIndex(index)}
|
||||||
onClick={() => setSelectedIndex(index)}
|
className={`border-2 rounded-lg ${
|
||||||
className={`border-2 rounded-lg overflow-hidden ${
|
selectedIndex === index
|
||||||
selectedIndex === index
|
? "border-red-500"
|
||||||
? "border-red-500"
|
: "border-transparent"
|
||||||
: "border-transparent"
|
}`}
|
||||||
}`}
|
>
|
||||||
>
|
<Image
|
||||||
<Image
|
src={file.fileUrl}
|
||||||
src={file.fileUrl}
|
alt={file.fileAlt || "Thumbnail"}
|
||||||
alt={file.fileAlt || "Thumbnail"}
|
width={100}
|
||||||
width={100}
|
height={80}
|
||||||
height={80}
|
className="object-cover"
|
||||||
className="object-cover"
|
/>
|
||||||
/>
|
</button>
|
||||||
</button>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</>
|
||||||
|
) : (
|
||||||
|
<div className="h-[400px] flex items-center justify-center bg-gray-100 rounded-lg">
|
||||||
|
<p className="text-gray-400">Gambar tidak tersedia</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Slug */}
|
{/* Slug */}
|
||||||
<p className="text-sm text-gray-500 mt-2 text-end">
|
<p className="text-sm text-gray-500 mt-2 text-end">
|
||||||
|
|
@ -476,11 +521,12 @@ export default function DetailContent() {
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1 overflow-y-auto">
|
<div className="flex-1 overflow-y-auto">
|
||||||
<div className="text-gray-700 leading-relaxed text-justify">
|
<div className="prose max-w-none text-justify">
|
||||||
<div
|
<div
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={removeImgTags(
|
||||||
__html: articleDetail?.htmlDescription || "",
|
formatTextToHtmlTag(articleDetail?.htmlDescription),
|
||||||
}}
|
)}
|
||||||
|
className="text-sm lg:text-xl lg:leading-8 text-justify space-y-4"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/* <Author /> */}
|
{/* <Author /> */}
|
||||||
|
|
@ -590,11 +636,11 @@ export default function DetailContent() {
|
||||||
htmlFor="komentar"
|
htmlFor="komentar"
|
||||||
className="block text-sm font-medium mb-1"
|
className="block text-sm font-medium mb-1"
|
||||||
>
|
>
|
||||||
Komentar <span className="text-green-600">*</span>
|
Komentar <span className="text-blue-600">*</span>
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
id="komentar"
|
id="komentar"
|
||||||
className="w-full border border-gray-300 rounded-md p-3 h-40 focus:outline-none focus:ring-2 focus:ring-green-600"
|
className="w-full border border-gray-300 rounded-md p-3 h-40 focus:outline-none focus:ring-2 focus:ring-blue-600"
|
||||||
{...register("comment", { required: true })}
|
{...register("comment", { required: true })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -605,7 +651,7 @@ export default function DetailContent() {
|
||||||
htmlFor="nama"
|
htmlFor="nama"
|
||||||
className="block text-sm font-medium mb-1"
|
className="block text-sm font-medium mb-1"
|
||||||
>
|
>
|
||||||
Nama <span className="text-green-600">*</span>
|
Nama <span className="text-blue-600">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
|
@ -621,7 +667,7 @@ export default function DetailContent() {
|
||||||
htmlFor="email"
|
htmlFor="email"
|
||||||
className="block text-sm font-medium mb-1"
|
className="block text-sm font-medium mb-1"
|
||||||
>
|
>
|
||||||
Email <span className="text-green-600">*</span>
|
Email <span className="text-blue-600">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
|
|
@ -633,7 +679,7 @@ export default function DetailContent() {
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="bg-green-600 hover:bg-green-700 text-white font-semibold px-6 py-2 rounded-md transition mt-2 w-full"
|
className="bg-blue-600 hover:bg-blue-700 text-white font-semibold px-6 py-2 rounded-md transition mt-2 w-full"
|
||||||
>
|
>
|
||||||
KIRIM KOMENTAR
|
KIRIM KOMENTAR
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -666,7 +712,7 @@ export default function DetailContent() {
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="bg-green-600 hover:bg-green-700 text-white font-semibold px-6 py-2 rounded-md transition mt-4 w-full"
|
className="bg-blue-600 hover:bg-blue-700 text-white font-semibold px-6 py-2 rounded-md transition mt-4 w-full"
|
||||||
>
|
>
|
||||||
Kirim
|
Kirim
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -735,7 +781,7 @@ export default function DetailContent() {
|
||||||
onClick={() => setActiveTab(tab.id)}
|
onClick={() => setActiveTab(tab.id)}
|
||||||
className={`pb-2 text-sm font-medium ${
|
className={`pb-2 text-sm font-medium ${
|
||||||
activeTab === tab.id
|
activeTab === tab.id
|
||||||
? "border-b-2 border-green-600 text-green-600"
|
? "border-b-2 border-blue-600 text-blue-600"
|
||||||
: "text-gray-600"
|
: "text-gray-600"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
|
@ -801,7 +847,7 @@ export default function DetailContent() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-6">
|
<div className="mt-6">
|
||||||
<h3 className="text-base font-semibold mb-2 text-gray-800 border-b pb-1 border-green-600 inline-block">
|
<h3 className="text-base font-semibold mb-2 text-gray-800 border-b pb-1 border-blue-600 inline-block">
|
||||||
Recommended
|
Recommended
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
|
|
@ -828,7 +874,7 @@ export default function DetailContent() {
|
||||||
day: "2-digit",
|
day: "2-digit",
|
||||||
month: "long",
|
month: "long",
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
}
|
},
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -858,7 +904,7 @@ export default function DetailContent() {
|
||||||
day: "2-digit",
|
day: "2-digit",
|
||||||
month: "long",
|
month: "long",
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
}
|
},
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// components/custom-editor.js
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
import React from "react";
|
|
||||||
import { CKEditor } from "@ckeditor/ckeditor5-react";
|
import { CKEditor } from "@ckeditor/ckeditor5-react";
|
||||||
|
|
||||||
|
import "@/styles/custom-editor.css";
|
||||||
import Editor from "@/vendor/ckeditor5/build/ckeditor";
|
import Editor from "@/vendor/ckeditor5/build/ckeditor";
|
||||||
|
|
||||||
function CustomEditor(props) {
|
function CustomEditor(props) {
|
||||||
|
|
@ -47,7 +47,7 @@ function CustomEditor(props) {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
margin: 0.5em 0;
|
margin: 0.5em 0 !important;
|
||||||
}
|
}
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6 {
|
||||||
margin: 1em 0 0.5em 0;
|
margin: 1em 0 0.5em 0;
|
||||||
|
|
@ -72,98 +72,6 @@ function CustomEditor(props) {
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<style jsx>{`
|
|
||||||
.ckeditor-wrapper {
|
|
||||||
border-radius: 6px;
|
|
||||||
overflow: hidden;
|
|
||||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1),
|
|
||||||
0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ckeditor-wrapper :global(.ck.ck-editor__main) {
|
|
||||||
min-height: ${props.height || 400}px;
|
|
||||||
max-height: ${maxHeight}px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ckeditor-wrapper :global(.ck.ck-editor__editable) {
|
|
||||||
min-height: ${(props.height || 400) - 50}px;
|
|
||||||
max-height: ${maxHeight - 50}px;
|
|
||||||
overflow-y: auto !important;
|
|
||||||
scrollbar-width: thin;
|
|
||||||
scrollbar-color: #cbd5e1 #f1f5f9;
|
|
||||||
background: #fff !important;
|
|
||||||
color: #111 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dark mode support */
|
|
||||||
:global(.dark) .ckeditor-wrapper :global(.ck.ck-editor__editable) {
|
|
||||||
background: #111 !important;
|
|
||||||
color: #f9fafb !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.dark) .ckeditor-wrapper :global(.ck.ck-editor__editable h1),
|
|
||||||
:global(.dark) .ckeditor-wrapper :global(.ck.ck-editor__editable h2),
|
|
||||||
:global(.dark) .ckeditor-wrapper :global(.ck.ck-editor__editable h3),
|
|
||||||
:global(.dark) .ckeditor-wrapper :global(.ck.ck-editor__editable h4),
|
|
||||||
:global(.dark) .ckeditor-wrapper :global(.ck.ck-editor__editable h5),
|
|
||||||
:global(.dark) .ckeditor-wrapper :global(.ck.ck-editor__editable h6) {
|
|
||||||
color: #f9fafb !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.dark)
|
|
||||||
.ckeditor-wrapper
|
|
||||||
:global(.ck.ck-editor__editable blockquote) {
|
|
||||||
background-color: #1f2937 !important;
|
|
||||||
border-left-color: #374151 !important;
|
|
||||||
color: #f3f4f6 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Custom scrollbar styling for webkit browsers */
|
|
||||||
.ckeditor-wrapper :global(.ck.ck-editor__editable::-webkit-scrollbar) {
|
|
||||||
width: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ckeditor-wrapper
|
|
||||||
:global(.ck.ck-editor__editable::-webkit-scrollbar-track) {
|
|
||||||
background: #f1f5f9;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ckeditor-wrapper
|
|
||||||
:global(.ck.ck-editor__editable::-webkit-scrollbar-thumb) {
|
|
||||||
background: #cbd5e1;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ckeditor-wrapper
|
|
||||||
:global(.ck.ck-editor__editable::-webkit-scrollbar-thumb:hover) {
|
|
||||||
background: #94a3b8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dark mode scrollbar */
|
|
||||||
:global(.dark)
|
|
||||||
.ckeditor-wrapper
|
|
||||||
:global(.ck.ck-editor__editable::-webkit-scrollbar-track) {
|
|
||||||
background: #1f2937;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.dark)
|
|
||||||
.ckeditor-wrapper
|
|
||||||
:global(.ck.ck-editor__editable::-webkit-scrollbar-thumb) {
|
|
||||||
background: #4b5563;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.dark)
|
|
||||||
.ckeditor-wrapper
|
|
||||||
:global(.ck.ck-editor__editable::-webkit-scrollbar-thumb:hover) {
|
|
||||||
background: #6b7280;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure content doesn't overflow */
|
|
||||||
.ckeditor-wrapper :global(.ck.ck-editor__editable .ck-content) {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,8 @@ function ViewEditor(props) {
|
||||||
.ckeditor-view-wrapper {
|
.ckeditor-view-wrapper {
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1),
|
box-shadow:
|
||||||
|
0 1px 3px 0 rgba(0, 0, 0, 0.1),
|
||||||
0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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) => {
|
||||||
|
|
@ -667,9 +690,10 @@ export default function EditArticleForm(props: { isDetail: boolean }) {
|
||||||
name="title"
|
name="title"
|
||||||
render={({ field: { onChange, value } }) => (
|
render={({ field: { onChange, value } }) => (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<label htmlFor="title" className="block text-sm font-medium mb-1">
|
<label htmlFor="title" className="block text-xl font-medium mb-2">
|
||||||
Judul
|
Judul
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
id="title"
|
id="title"
|
||||||
|
|
@ -677,7 +701,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>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ export default function Development() {
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<h2 className="text-xl font-black text-[#000]">JAGA NEGERI</h2>
|
<h2 className="text-xl font-black text-[#000]">JAGA NEGERI</h2>
|
||||||
|
|
||||||
<div className="w-10 h-1 bg-green-600 mt-1 rounded"></div>
|
<div className="w-10 h-1 bg-blue-600 mt-1 rounded"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="border-b border-gray-300 mb-5"></div>
|
<div className="border-b border-gray-300 mb-5"></div>
|
||||||
|
|
@ -95,7 +95,7 @@ export default function Development() {
|
||||||
|
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<p className="text-[11px] font-bold text-black">
|
<p className="text-[11px] font-bold text-black">
|
||||||
<span className="border-b-2 border-green-600 pb-[1px]">
|
<span className="border-b-2 border-blue-600 pb-[1px]">
|
||||||
{item.categories?.[0]?.title || "Kategori"}
|
{item.categories?.[0]?.title || "Kategori"}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ export default function Footer() {
|
||||||
<div className="flex items-center justify-end">
|
<div className="flex items-center justify-end">
|
||||||
<div className="flex justify-center md:justify-end">
|
<div className="flex justify-center md:justify-end">
|
||||||
<Image
|
<Image
|
||||||
src="/bumn.png"
|
src="/berita-bumn-logo.png"
|
||||||
alt="Logo"
|
alt="Logo"
|
||||||
width={230}
|
width={230}
|
||||||
height={230}
|
height={230}
|
||||||
|
|
@ -38,7 +38,7 @@ export default function Footer() {
|
||||||
className="w-full border border-gray-300 rounded-md px-4 py-3 outline-none"
|
className="w-full border border-gray-300 rounded-md px-4 py-3 outline-none"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button className="mt-4 bg-green-600 hover:bg-green-500 text-black px-6 py-3 rounded-md font-medium">
|
<button className="mt-4 bg-blue-600 hover:bg-blue-500 text-white px-6 py-3 rounded-md font-medium">
|
||||||
SIGN UP
|
SIGN UP
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -62,7 +62,7 @@ export default function Footer() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="text-start text-gray-500 text-sm mt-8 pl-5">
|
<p className="text-start text-gray-500 text-sm mt-8 pl-5">
|
||||||
© 2025 Milenial Bersuara - All Rights Reserved.
|
© 2025 Berita Bumn - All Rights Reserved.
|
||||||
</p>
|
</p>
|
||||||
</footer>
|
</footer>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ export default function Header() {
|
||||||
{/* FLASH STRIP */}
|
{/* FLASH STRIP */}
|
||||||
<div className="flex items-center justify-between mt-6 mb-3">
|
<div className="flex items-center justify-between mt-6 mb-3">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<h4 className="text-green-600 font-semibold">Flash</h4>
|
<h4 className="text-blue-600 font-semibold">Flash</h4>
|
||||||
<span className="text-red-500">⚡</span>
|
<span className="text-red-500">⚡</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs text-gray-500 hidden md:block">LOAD MORE ➜</div>
|
<div className="text-xs text-gray-500 hidden md:block">LOAD MORE ➜</div>
|
||||||
|
|
@ -125,7 +125,7 @@ export default function Header() {
|
||||||
|
|
||||||
{/* White Card Overlay */}
|
{/* White Card Overlay */}
|
||||||
<div className="absolute bottom-6 left-6 bg-white bg-opacity-95 backdrop-blur-sm p-6 shadow-lg max-w-lg">
|
<div className="absolute bottom-6 left-6 bg-white bg-opacity-95 backdrop-blur-sm p-6 shadow-lg max-w-lg">
|
||||||
<span className="text-[11px] bg-green-700 text-white px-2 py-1 rounded-sm">
|
<span className="text-[11px] bg-blue-700 text-white px-2 py-1 rounded-sm">
|
||||||
{mainArticle.categoryName ||
|
{mainArticle.categoryName ||
|
||||||
mainArticle.categories?.[0]?.title ||
|
mainArticle.categories?.[0]?.title ||
|
||||||
"Berita"}
|
"Berita"}
|
||||||
|
|
@ -144,14 +144,13 @@ export default function Header() {
|
||||||
</span>
|
</span>
|
||||||
<span>•</span>
|
<span>•</span>
|
||||||
<span>
|
<span>
|
||||||
{new Date(mainArticle.publishedAt).toLocaleDateString(
|
{new Date(
|
||||||
"id-ID",
|
mainArticle.publishedAt || mainArticle.createdAt,
|
||||||
{
|
).toLocaleDateString("id-ID", {
|
||||||
day: "2-digit",
|
day: "2-digit",
|
||||||
month: "long",
|
month: "long",
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
}
|
})}
|
||||||
)}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -190,7 +189,9 @@ export default function Header() {
|
||||||
{item.title}
|
{item.title}
|
||||||
</p>
|
</p>
|
||||||
<span className="text-xs text-gray-500 mt-1">
|
<span className="text-xs text-gray-500 mt-1">
|
||||||
{new Date(item.publishedAt).toLocaleDateString("id-ID", {
|
{new Date(
|
||||||
|
item.publishedAt || item.createdAt,
|
||||||
|
).toLocaleDateString("id-ID", {
|
||||||
day: "2-digit",
|
day: "2-digit",
|
||||||
month: "long",
|
month: "long",
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ export default function NewsTerkini() {
|
||||||
<section className="max-w-7xl mx-auto px-4 grid grid-cols-1 lg:grid-cols-[2fr_1fr] gap-6">
|
<section className="max-w-7xl mx-auto px-4 grid grid-cols-1 lg:grid-cols-[2fr_1fr] gap-6">
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-lg font-bold text-gray-900">BERITA TERKINI</h2>
|
<h2 className="text-lg font-bold text-gray-900">BERITA TERKINI</h2>
|
||||||
<div className="w-14 h-1 bg-green-600 mt-1 mb-4"></div>
|
<div className="w-14 h-1 bg-blue-600 mt-1 mb-4"></div>
|
||||||
|
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{articles.map((item) => (
|
{articles.map((item) => (
|
||||||
|
|
@ -81,7 +81,7 @@ export default function NewsTerkini() {
|
||||||
<div className="flex gap-4">
|
<div className="flex gap-4">
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
{/* CATEGORY */}
|
{/* CATEGORY */}
|
||||||
<p className="text-[11px] text-green-700 font-semibold mb-1">
|
<p className="text-[11px] text-blue-700 font-semibold mb-1">
|
||||||
{item.categories?.[0]?.title || "Kategori"}
|
{item.categories?.[0]?.title || "Kategori"}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -98,7 +98,15 @@ export default function NewsTerkini() {
|
||||||
{/* AUTHOR + DATE */}
|
{/* AUTHOR + DATE */}
|
||||||
<p className="text-xs text-gray-400 mt-2">
|
<p className="text-xs text-gray-400 mt-2">
|
||||||
By {item.customCreatorName || item.createdByName} —{" "}
|
By {item.customCreatorName || item.createdByName} —{" "}
|
||||||
{formatDate(item.publishedAt)}
|
<span>
|
||||||
|
{new Date(
|
||||||
|
item.publishedAt || item.createdAt,
|
||||||
|
).toLocaleDateString("id-ID", {
|
||||||
|
day: "numeric",
|
||||||
|
month: "long",
|
||||||
|
year: "numeric",
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative w-40 h-28 rounded overflow-hidden flex-shrink-0">
|
<div className="relative w-40 h-28 rounded overflow-hidden flex-shrink-0">
|
||||||
|
|
@ -115,14 +123,14 @@ export default function NewsTerkini() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* LOAD MORE */}
|
{/* LOAD MORE */}
|
||||||
<div className="text-center mt-4 text-green-600 text-sm cursor-pointer">
|
<div className="text-center mt-4 text-blue-600 text-sm cursor-pointer">
|
||||||
LOAD MORE ↓
|
LOAD MORE ↓
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="lg:col-span-1">
|
<div className="lg:col-span-1">
|
||||||
<h2 className="text-lg font-bold text-gray-900">TERBANYAK DIBAGIKAN</h2>
|
<h2 className="text-lg font-bold text-gray-900">TERBANYAK DIBAGIKAN</h2>
|
||||||
<div className="w-14 h-1 bg-green-600 mt-1 mb-4"></div>
|
<div className="w-14 h-1 bg-blue-600 mt-1 mb-4"></div>
|
||||||
|
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{popular.map((item, index) => (
|
{popular.map((item, index) => (
|
||||||
|
|
@ -132,7 +140,7 @@ export default function NewsTerkini() {
|
||||||
className="flex gap-3 border-b pb-4"
|
className="flex gap-3 border-b pb-4"
|
||||||
>
|
>
|
||||||
{/* NOMOR */}
|
{/* NOMOR */}
|
||||||
<div className="text-green-600 font-extrabold text-3xl leading-none">
|
<div className="text-blue-600 font-extrabold text-3xl leading-none">
|
||||||
{(index + 1).toString().padStart(2, "0")}
|
{(index + 1).toString().padStart(2, "0")}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ export default function LatestNews() {
|
||||||
{/* TITLE */}
|
{/* TITLE */}
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<h2 className="text-xl font-black text-[#000]">BERITA POPULER</h2>
|
<h2 className="text-xl font-black text-[#000]">BERITA POPULER</h2>
|
||||||
<div className="w-10 h-1 bg-green-600 mt-1 rounded"></div>
|
<div className="w-10 h-1 bg-blue-600 mt-1 rounded"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* GRID 4 KOLOM */}
|
{/* GRID 4 KOLOM */}
|
||||||
|
|
@ -82,7 +82,7 @@ export default function LatestNews() {
|
||||||
|
|
||||||
{/* BADGE CATEGORY DI DALAM GAMBAR */}
|
{/* BADGE CATEGORY DI DALAM GAMBAR */}
|
||||||
<div className="absolute bottom-2 left-2">
|
<div className="absolute bottom-2 left-2">
|
||||||
<span className="px-3 py-1 text-[10px] font-semibold bg-green-600 text-white rounded">
|
<span className="px-3 py-1 text-[10px] font-semibold bg-blue-600 text-white rounded">
|
||||||
{item.categories?.[0]?.title || "Kategori"}
|
{item.categories?.[0]?.title || "Kategori"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -100,7 +100,9 @@ export default function LatestNews() {
|
||||||
</span>
|
</span>
|
||||||
<span className="text-yellow-500">-</span>
|
<span className="text-yellow-500">-</span>
|
||||||
<span>
|
<span>
|
||||||
{new Date(item.publishedAt).toLocaleDateString("id-ID", {
|
{new Date(
|
||||||
|
item.publishedAt || item.createdAt,
|
||||||
|
).toLocaleDateString("id-ID", {
|
||||||
day: "numeric",
|
day: "numeric",
|
||||||
month: "long",
|
month: "long",
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
|
|
|
||||||
|
|
@ -1,129 +1,36 @@
|
||||||
// components/landing-page/navbar.tsx
|
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState } from "react";
|
import { Search } from "lucide-react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { Search, Menu } from "lucide-react";
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { usePathname } from "next/navigation";
|
import { usePathname } from "next/navigation";
|
||||||
|
|
||||||
export default function Navbar() {
|
export default function Navbar() {
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
|
const isActive = (href: any) => {
|
||||||
|
return pathname === href || pathname.startsWith(href + "/");
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="w-full bg-[#022b5f] text-white">
|
<div className="w-full bg-white py-4 border-b">
|
||||||
<div className="max-w-7xl mx-auto px-2 py-2">
|
<div className="max-w-screen-xl mx-auto flex flex-col justify-between px-4">
|
||||||
<div className="flex items-center justify-between px-6 py-2 border-b border-[#053d84]">
|
{/* Left: Logo */}
|
||||||
{/* Logo + Search */}
|
<div className="flex flex-row justify-between mb-3">
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center">
|
||||||
<Image src="/bumn.png" alt="Logo" width={40} height={40} />
|
<Image
|
||||||
<div className="relative">
|
src="/berita-bumn-logo.png"
|
||||||
<input
|
alt="Kritik Tajam Logo"
|
||||||
type="text"
|
width={140}
|
||||||
placeholder="Search..."
|
height={100}
|
||||||
className="px-3 py-2 rounded-md w-[280px] text-black focus:outline-none bg-white"
|
/>
|
||||||
/>
|
|
||||||
<Search
|
|
||||||
className="absolute right-2 top-2.5 text-white"
|
|
||||||
size={18}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Date + Login */}
|
|
||||||
<div className="flex items-center gap-4 text-sm">
|
|
||||||
<span>Jumat, April 18, 2025</span>
|
|
||||||
<Link
|
|
||||||
href="/auth"
|
|
||||||
className="flex items-center gap-1 font-semibold"
|
|
||||||
>
|
|
||||||
Login
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* NAVBAR */}
|
|
||||||
<div className="flex items-center justify-between px-6 py-3">
|
|
||||||
{/* Left: Menu Items */}
|
|
||||||
<div className="flex items-center gap-6">
|
<div className="flex items-center gap-6">
|
||||||
<button onClick={() => setOpen(!open)}>
|
{/* Social Icons */}
|
||||||
<Menu className="text-white" />
|
<div className="hidden md:flex items-center gap-5 text-black text-xl">
|
||||||
</button>
|
<Link href="#">
|
||||||
<nav className="hidden md:flex gap-6 text-sm font-semibold">
|
|
||||||
<Link
|
|
||||||
href="/"
|
|
||||||
className={pathname === "/" ? "text-yellow-400" : ""}
|
|
||||||
>
|
|
||||||
HOME
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
href="/category/bumn"
|
|
||||||
className={
|
|
||||||
pathname === "/category/bumn" ? "text-yellow-400" : ""
|
|
||||||
}
|
|
||||||
>
|
|
||||||
SEPUTAR BUMN
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
href="/category/economy"
|
|
||||||
className={
|
|
||||||
pathname === "/category/economy" ? "text-yellow-400" : ""
|
|
||||||
}
|
|
||||||
>
|
|
||||||
ECONOMY
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
href="/category/business"
|
|
||||||
className={
|
|
||||||
pathname === "/category/business" ? "text-yellow-400" : ""
|
|
||||||
}
|
|
||||||
>
|
|
||||||
BUSINESS
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
href="/category/opinion"
|
|
||||||
className={
|
|
||||||
pathname === "/category/opinion" ? "text-yellow-400" : ""
|
|
||||||
}
|
|
||||||
>
|
|
||||||
OPINION
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
href="/category/markets"
|
|
||||||
className={
|
|
||||||
pathname === "/category/markets" ? "text-yellow-400" : ""
|
|
||||||
}
|
|
||||||
>
|
|
||||||
MARKETS
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
href="/category/tech"
|
|
||||||
className={
|
|
||||||
pathname === "/category/tech" ? "text-yellow-400" : ""
|
|
||||||
}
|
|
||||||
>
|
|
||||||
TECH
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
href="/category/real-estate"
|
|
||||||
className={
|
|
||||||
pathname === "/category/real-estate" ? "text-yellow-400" : ""
|
|
||||||
}
|
|
||||||
>
|
|
||||||
REAL ESTATE
|
|
||||||
</Link>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Right: Socials + Subscribe */}
|
|
||||||
<div className="flex items-center gap-4">
|
|
||||||
<div className="flex gap-3 text-white text-lg">
|
|
||||||
<Link href="#" aria-label="Facebook">
|
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="15"
|
width="18"
|
||||||
height="15"
|
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
|
|
@ -132,11 +39,11 @@ export default function Navbar() {
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</Link>
|
</Link>
|
||||||
<Link href="#" aria-label="Twitter">
|
|
||||||
|
<Link href="#">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="15"
|
width="18"
|
||||||
height="15"
|
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
|
|
@ -145,95 +52,157 @@ export default function Navbar() {
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</Link>
|
</Link>
|
||||||
<Link href="#" aria-label="Google" className="text-[#F5F5F5]">
|
|
||||||
|
<Link href="#">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="15"
|
width="18"
|
||||||
height="15"
|
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
// fill-rule="evenodd"
|
d="M7.8 2h8.4C19.4 2 22 4.6 22 7.8v8.4a5.8 5.8 0 0 1-5.8 5.8H7.8C4.6 22 2 19.4 2 16.2V7.8A5.8 5.8 0 0 1 7.8 2m-.2 2A3.6 3.6 0 0 0 4 7.6v8.8C4 18.39 5.61 20 7.6 20h8.8a3.6 3.6 0 0 0 3.6-3.6V7.6C20 5.61 18.39 4 16.4 4zm9.65 1.5a1.25 1.25 0 0 1 1.25 1.25A1.25 1.25 0 0 1 17.25 8A1.25 1.25 0 0 1 16 6.75a1.25 1.25 0 0 1 1.25-1.25M12 7a5 5 0 0 1 5 5a5 5 0 0 1-5 5a5 5 0 0 1-5-5a5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3a3 3 0 0 0 3 3a3 3 0 0 0 3-3a3 3 0 0 0-3-3"
|
||||||
d="M7.796 14.333v-2.618h7.211c.066.382.12.763.12 1.265c0 4.364-2.923 7.462-7.33 7.462A7.63 7.63 0 0 1 .16 12.806a7.63 7.63 0 0 1 7.636-7.637c2.062 0 3.786.753 5.117 1.997L10.84 9.162c-.567-.546-1.56-1.178-3.044-1.178c-2.607 0-4.734 2.16-4.734 4.822s2.127 4.821 4.734 4.821c3.022 0 4.157-2.17 4.331-3.294zm13.27-2.6H23.2v2.134h-2.133V16h-2.134v-2.133H16.8v-2.134h2.133V9.6h2.134z"
|
|
||||||
// clip-rule="evenodd"
|
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</Link>
|
</Link>
|
||||||
<Link href="#" aria-label="Pinterest">
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="15"
|
|
||||||
height="15"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<defs>
|
|
||||||
<path
|
|
||||||
id="akarIconsPinterestFill0"
|
|
||||||
fill="#fff"
|
|
||||||
d="M0 0h24v24H0z"
|
|
||||||
/>
|
|
||||||
</defs>
|
|
||||||
<g fill="none">
|
|
||||||
<g
|
|
||||||
// clip-path="url(#akarIconsPinterestFill1)"
|
|
||||||
>
|
|
||||||
<g
|
|
||||||
// clip-path="url(#akarIconsPinterestFill2)"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M0 12c0 5.123 3.211 9.497 7.73 11.218c-.11-.937-.227-2.482.025-3.566c.217-.932 1.401-5.938 1.401-5.938s-.357-.715-.357-1.774c0-1.66.962-2.9 2.161-2.9c1.02 0 1.512.765 1.512 1.682c0 1.025-.653 2.557-.99 3.978c-.281 1.189.597 2.159 1.769 2.159c2.123 0 3.756-2.239 3.756-5.471c0-2.861-2.056-4.86-4.991-4.86c-3.398 0-5.393 2.549-5.393 5.184c0 1.027.395 2.127.889 2.726a.36.36 0 0 1 .083.343c-.091.378-.293 1.189-.332 1.355c-.053.218-.173.265-.4.159c-1.492-.694-2.424-2.875-2.424-4.627c0-3.769 2.737-7.229 7.892-7.229c4.144 0 7.365 2.953 7.365 6.899c0 4.117-2.595 7.431-6.199 7.431c-1.211 0-2.348-.63-2.738-1.373c0 0-.599 2.282-.744 2.84c-.282 1.084-1.064 2.456-1.549 3.235C9.584 23.815 10.77 24 12 24c6.627 0 12-5.373 12-12S18.627 0 12 0S0 5.373 0 12"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="akarIconsPinterestFill1">
|
|
||||||
<use href="#akarIconsPinterestFill0" />
|
|
||||||
</clipPath>
|
|
||||||
<clipPath id="akarIconsPinterestFill2">
|
|
||||||
<use href="#akarIconsPinterestFill0" />
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Link href="#" aria-label="Vk">
|
<Link href="#">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="15"
|
width="18"
|
||||||
height="15"
|
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
// fill-rule="evenodd"
|
d="M12.244 4c.534.003 1.87.016 3.29.073l.504.022c1.429.067 2.857.183 3.566.38c.945.266 1.687 1.04 1.938 2.022c.4 1.56.45 4.602.456 5.339l.001.152v.174c-.007.737-.057 3.78-.457 5.339c-.254.985-.997 1.76-1.938 2.022c-.709.197-2.137.313-3.566.38l-.504.023c-1.42.056-2.756.07-3.29.072l-.235.001h-.255c-1.13-.007-5.856-.058-7.36-.476c-.944-.266-1.687-1.04-1.938-2.022c-.4-1.56-.45-4.602-.456-5.339v-.326c.006-.737.056-3.78.456-5.339c.254-.985.997-1.76 1.939-2.021c1.503-.419 6.23-.47 7.36-.476zM9.999 8.5v7l6-3.5z"
|
||||||
d="M23.45 5.948c.166-.546 0-.948-.795-.948H20.03c-.668 0-.976.347-1.143.73c0 0-1.335 3.196-3.226 5.272c-.612.602-.89.793-1.224.793c-.167 0-.418-.191-.418-.738V5.948c0-.656-.184-.948-.74-.948H9.151c-.417 0-.668.304-.668.593c0 .621.946.765 1.043 2.513v3.798c0 .833-.153.984-.487.984c-.89 0-3.055-3.211-4.34-6.885C4.45 5.288 4.198 5 3.527 5H.9c-.75 0-.9.347-.9.73c0 .682.89 4.07 4.145 8.551C6.315 17.341 9.37 19 12.153 19c1.669 0 1.875-.368 1.875-1.003v-2.313c0-.737.158-.884.687-.884c.39 0 1.057.192 2.615 1.667C19.11 18.216 19.403 19 20.405 19h2.625c.75 0 1.126-.368.91-1.096c-.238-.724-1.088-1.775-2.215-3.022c-.612-.71-1.53-1.475-1.809-1.858c-.389-.491-.278-.71 0-1.147c0 0 3.2-4.426 3.533-5.929"
|
|
||||||
// clip-rule="evenodd"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</Link>
|
|
||||||
<Link href="#" aria-label="Wifi">
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="15"
|
|
||||||
height="15"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M12 21q-1.05 0-1.775-.725T9.5 18.5t.725-1.775T12 16t1.775.725t.725 1.775t-.725 1.775T12 21m-5.65-5.65l-2.1-2.15q1.475-1.475 3.463-2.337T12 10t4.288.875t3.462 2.375l-2.1 2.1q-1.1-1.1-2.55-1.725T12 13t-3.1.625t-2.55 1.725M2.1 11.1L0 9q2.3-2.35 5.375-3.675T12 4t6.625 1.325T24 9l-2.1 2.1q-1.925-1.925-4.462-3.012T12 7T6.563 8.088T2.1 11.1"
|
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<button className="bg-yellow-400 text-black px-4 py-2 rounded-sm font-semibold">
|
</div>
|
||||||
SUBSCRIBE
|
</div>
|
||||||
|
{/* Middle Menu */}
|
||||||
|
<div className="flex flex-row justify-between">
|
||||||
|
<nav className="hidden md:flex items-center gap-10 text-sm font-semibold">
|
||||||
|
<Link
|
||||||
|
href="/"
|
||||||
|
className={
|
||||||
|
isActive("/")
|
||||||
|
? "text-blue-400 underline"
|
||||||
|
: "text-black hover:text-blue-500"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
HOME
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<Link
|
||||||
|
href="/category/bumn"
|
||||||
|
className={
|
||||||
|
isActive("/category/bumn")
|
||||||
|
? "text-blue-400 underline"
|
||||||
|
: "text-black hover:text-blue-500"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
SEPUTAR BUMN
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="/category/economy"
|
||||||
|
className={
|
||||||
|
isActive("/category/economy")
|
||||||
|
? "text-blue-400 underline"
|
||||||
|
: "text-black hover:text-blue-500"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
ECONOMY
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="/category/business"
|
||||||
|
className={
|
||||||
|
isActive("/category/business")
|
||||||
|
? "text-blue-400 underline"
|
||||||
|
: "text-black hover:text-blue-500"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
BUSINESS
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="/category/opinion"
|
||||||
|
className={
|
||||||
|
isActive("/category/opinion")
|
||||||
|
? "text-blue-400 underline"
|
||||||
|
: "text-black hover:text-blue-500"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
OPINION
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="/category/markets"
|
||||||
|
className={
|
||||||
|
isActive("/category/markets")
|
||||||
|
? "text-blue-400 underline"
|
||||||
|
: "text-black hover:text-blue-500"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
MARKETS
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="/category/tech"
|
||||||
|
className={
|
||||||
|
isActive("/category/tech")
|
||||||
|
? "text-blue-400 underline"
|
||||||
|
: "text-black hover:text-blue-500"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
TECH
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="/category/real-estate"
|
||||||
|
className={
|
||||||
|
isActive("/category/real-estate")
|
||||||
|
? "text-blue-400 underline"
|
||||||
|
: "text-black hover:text-blue-500"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
REAL ESTATE
|
||||||
|
</Link>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<button
|
||||||
|
// onClick={() => document.documentElement.classList.toggle("dark")}
|
||||||
|
className="w-10 h-5 rounded-full bg-gray-300 dark:bg-gray-700 relative transition-all"
|
||||||
|
>
|
||||||
|
<div className="w-5 h-5 bg-white dark:bg-black rounded-full shadow absolute top-0 left-0 dark:left-5 transition-all"></div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
{/* BURGER BUTTON (mobile menu) */}
|
||||||
|
<button className="md:hidden p-2 rounded-lg border">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth={2}
|
||||||
|
stroke="currentColor"
|
||||||
|
className="w-6 h-6"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M4 6h16M4 12h16M4 18h16"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<button className="p-2 border rounded-full">
|
||||||
|
<Search size={15} />
|
||||||
|
</button>
|
||||||
|
<Link href={"/auth"}>
|
||||||
|
<button className="bg-blue-600 text-white px-5 py-2 rounded-full text-sm font-semibold">
|
||||||
|
LOGIN
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ export default function OpinionNews() {
|
||||||
{/* TITLE */}
|
{/* TITLE */}
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<h2 className="text-xl font-black text-[#000]">BERITA OPINI</h2>
|
<h2 className="text-xl font-black text-[#000]">BERITA OPINI</h2>
|
||||||
<div className="w-10 h-1 bg-green-600 mt-1 rounded"></div>
|
<div className="w-10 h-1 bg-blue-600 mt-1 rounded"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* GRID 4 KOLOM */}
|
{/* GRID 4 KOLOM */}
|
||||||
|
|
@ -82,7 +82,7 @@ export default function OpinionNews() {
|
||||||
|
|
||||||
{/* BADGE CATEGORY DI DALAM GAMBAR */}
|
{/* BADGE CATEGORY DI DALAM GAMBAR */}
|
||||||
<div className="absolute bottom-2 left-2">
|
<div className="absolute bottom-2 left-2">
|
||||||
<span className="px-3 py-1 text-[10px] font-semibold bg-green-600 text-white rounded">
|
<span className="px-3 py-1 text-[10px] font-semibold bg-blue-600 text-white rounded">
|
||||||
{item.categories?.[0]?.title || "Kategori"}
|
{item.categories?.[0]?.title || "Kategori"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -100,7 +100,9 @@ export default function OpinionNews() {
|
||||||
</span>
|
</span>
|
||||||
<span className="text-yellow-500">-</span>
|
<span className="text-yellow-500">-</span>
|
||||||
<span>
|
<span>
|
||||||
{new Date(item.publishedAt).toLocaleDateString("id-ID", {
|
{new Date(
|
||||||
|
item.publishedAt || item.createdAt,
|
||||||
|
).toLocaleDateString("id-ID", {
|
||||||
day: "numeric",
|
day: "numeric",
|
||||||
month: "long",
|
month: "long",
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
|
|
|
||||||
|
|
@ -316,7 +316,7 @@ export default function ArticleTable() {
|
||||||
return cellValue;
|
return cellValue;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[article, page]
|
[article, page],
|
||||||
);
|
);
|
||||||
|
|
||||||
let typingTimer: NodeJS.Timeout;
|
let typingTimer: NodeJS.Timeout;
|
||||||
|
|
@ -445,8 +445,8 @@ export default function ArticleTable() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full overflow-x-hidden">
|
<div className="w-full overflow-x-hidden">
|
||||||
<div className="w-full mx-auto overflow-x-hidden">
|
<div className="w-full overflow-x-auto">
|
||||||
<Table className="w-full table-fixed border text-sm">
|
<Table className="min-w-[1000px] w-full table-auto border text-sm">
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
{(username === "admin-mabes"
|
{(username === "admin-mabes"
|
||||||
|
|
@ -455,7 +455,18 @@ export default function ArticleTable() {
|
||||||
).map((column) => (
|
).map((column) => (
|
||||||
<TableHead
|
<TableHead
|
||||||
key={column.uid}
|
key={column.uid}
|
||||||
className="truncate bg-white dark:bg-black text-black dark:text-white border-b text-md"
|
className={`bg-white dark:bg-black text-black dark:text-white
|
||||||
|
text-sm font-semibold border-b px-3 py-3
|
||||||
|
${
|
||||||
|
column.uid === "no"
|
||||||
|
? "min-w-[60px] text-center"
|
||||||
|
: column.uid === "title"
|
||||||
|
? "min-w-[280px]"
|
||||||
|
: column.uid === "actions"
|
||||||
|
? "min-w-[100px] text-center"
|
||||||
|
: "min-w-[160px]"
|
||||||
|
}
|
||||||
|
`}
|
||||||
>
|
>
|
||||||
{column.name}
|
{column.name}
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
|
@ -472,7 +483,17 @@ export default function ArticleTable() {
|
||||||
).map((column) => (
|
).map((column) => (
|
||||||
<TableCell
|
<TableCell
|
||||||
key={column.uid}
|
key={column.uid}
|
||||||
className="truncate text-black dark:text-white max-w-[200px]"
|
className={`text-black dark:text-white text-sm px-3 py-3 align-top
|
||||||
|
${
|
||||||
|
column.uid === "no"
|
||||||
|
? "min-w-[60px] text-center font-medium"
|
||||||
|
: column.uid === "title"
|
||||||
|
? "min-w-[280px] whitespace-normal break-words leading-snug"
|
||||||
|
: column.uid === "actions"
|
||||||
|
? "min-w-[100px] text-center"
|
||||||
|
: "min-w-[160px] whitespace-normal break-words"
|
||||||
|
}
|
||||||
|
`}
|
||||||
>
|
>
|
||||||
{renderCell(item, column.uid)}
|
{renderCell(item, column.uid)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
import type { NextConfig } from "next";
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = {
|
||||||
const nextConfig: NextConfig = {
|
|
||||||
images: {
|
images: {
|
||||||
domains: ["mikulnews.com", "dev.mikulnews.com"],
|
domains: ["mikulnews.com", "dev.mikulnews.com"],
|
||||||
},
|
},
|
||||||
eslint: {
|
eslint: {
|
||||||
ignoreDuringBuilds: true,
|
ignoreDuringBuilds: true,
|
||||||
},
|
},
|
||||||
// Add experimental features for better chunk handling
|
|
||||||
experimental: {
|
experimental: {
|
||||||
optimizePackageImports: ["@ckeditor/ckeditor5-react", "react-apexcharts"],
|
optimizePackageImports: ["@ckeditor/ckeditor5-react", "react-apexcharts"],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,12 @@
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"lightningcss": "^1.30.1",
|
"lightningcss": "^1.30.1",
|
||||||
"lucide-react": "^0.544.0",
|
"lucide-react": "^0.544.0",
|
||||||
"next": "15.5.3",
|
"next": "^16.1.1",
|
||||||
"react": "19.1.0",
|
"react": "^19.2.3",
|
||||||
"react-apexcharts": "^1.7.0",
|
"react-apexcharts": "^1.7.0",
|
||||||
"react-datepicker": "^8.4.0",
|
"react-datepicker": "^8.4.0",
|
||||||
"react-day-picker": "^9.7.0",
|
"react-day-picker": "^9.7.0",
|
||||||
"react-dom": "19.1.0",
|
"react-dom": "^19.2.4",
|
||||||
"react-dropzone": "^14.3.8",
|
"react-dropzone": "^14.3.8",
|
||||||
"react-hook-form": "^7.59.0",
|
"react-hook-form": "^7.59.0",
|
||||||
"react-password-checklist": "^1.8.1",
|
"react-password-checklist": "^1.8.1",
|
||||||
|
|
@ -1413,9 +1413,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@img/sharp-win32-x64": {
|
"node_modules/@img/sharp-win32-x64": {
|
||||||
"version": "0.34.4",
|
"version": "0.34.5",
|
||||||
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.4.tgz",
|
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
|
||||||
"integrity": "sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig==",
|
"integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
|
@ -1489,9 +1489,9 @@
|
||||||
"integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw=="
|
"integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw=="
|
||||||
},
|
},
|
||||||
"node_modules/@next/env": {
|
"node_modules/@next/env": {
|
||||||
"version": "15.5.3",
|
"version": "16.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.1.1.tgz",
|
||||||
"integrity": "sha512-RSEDTRqyihYXygx/OJXwvVupfr9m04+0vH8vyy0HfZ7keRto6VX9BbEk0J2PUk0VGy6YhklJUSrgForov5F9pw=="
|
"integrity": "sha512-3oxyM97Sr2PqiVyMyrZUtrtM3jqqFxOQJVuKclDsgj/L728iZt/GyslkN4NwarledZATCenbk4Offjk1hQmaAA=="
|
||||||
},
|
},
|
||||||
"node_modules/@next/eslint-plugin-next": {
|
"node_modules/@next/eslint-plugin-next": {
|
||||||
"version": "15.5.3",
|
"version": "15.5.3",
|
||||||
|
|
@ -1502,115 +1502,10 @@
|
||||||
"fast-glob": "3.3.1"
|
"fast-glob": "3.3.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-darwin-arm64": {
|
|
||||||
"version": "15.5.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.3.tgz",
|
|
||||||
"integrity": "sha512-nzbHQo69+au9wJkGKTU9lP7PXv0d1J5ljFpvb+LnEomLtSbJkbZyEs6sbF3plQmiOB2l9OBtN2tNSvCH1nQ9Jg==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"darwin"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-darwin-x64": {
|
|
||||||
"version": "15.5.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.3.tgz",
|
|
||||||
"integrity": "sha512-w83w4SkOOhekJOcA5HBvHyGzgV1W/XvOfpkrxIse4uPWhYTTRwtGEM4v/jiXwNSJvfRvah0H8/uTLBKRXlef8g==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"darwin"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-linux-arm64-gnu": {
|
|
||||||
"version": "15.5.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.3.tgz",
|
|
||||||
"integrity": "sha512-+m7pfIs0/yvgVu26ieaKrifV8C8yiLe7jVp9SpcIzg7XmyyNE7toC1fy5IOQozmr6kWl/JONC51osih2RyoXRw==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-linux-arm64-musl": {
|
|
||||||
"version": "15.5.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.3.tgz",
|
|
||||||
"integrity": "sha512-u3PEIzuguSenoZviZJahNLgCexGFhso5mxWCrrIMdvpZn6lkME5vc/ADZG8UUk5K1uWRy4hqSFECrON6UKQBbQ==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-linux-x64-gnu": {
|
|
||||||
"version": "15.5.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.3.tgz",
|
|
||||||
"integrity": "sha512-lDtOOScYDZxI2BENN9m0pfVPJDSuUkAD1YXSvlJF0DKwZt0WlA7T7o3wrcEr4Q+iHYGzEaVuZcsIbCps4K27sA==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-linux-x64-musl": {
|
|
||||||
"version": "15.5.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.3.tgz",
|
|
||||||
"integrity": "sha512-9vWVUnsx9PrY2NwdVRJ4dUURAQ8Su0sLRPqcCCxtX5zIQUBES12eRVHq6b70bbfaVaxIDGJN2afHui0eDm+cLg==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-win32-arm64-msvc": {
|
|
||||||
"version": "15.5.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.3.tgz",
|
|
||||||
"integrity": "sha512-1CU20FZzY9LFQigRi6jM45oJMU3KziA5/sSG+dXeVaTm661snQP6xu3ykGxxwU5sLG3sh14teO/IOEPVsQMRfA==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"win32"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@next/swc-win32-x64-msvc": {
|
"node_modules/@next/swc-win32-x64-msvc": {
|
||||||
"version": "15.5.3",
|
"version": "16.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.1.tgz",
|
||||||
"integrity": "sha512-JMoLAq3n3y5tKXPQwCK5c+6tmwkuFDa2XAxz8Wm4+IVthdBZdZGh+lmiLUHg9f9IDwIQpUjp+ysd6OkYTyZRZw==",
|
"integrity": "sha512-Ncwbw2WJ57Al5OX0k4chM68DKhEPlrXBaSXDCi2kPi5f4d8b3ejr3RRJGfKBLrn2YJL5ezNS7w2TZLHSti8CMw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
|
@ -3441,6 +3336,14 @@
|
||||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/baseline-browser-mapping": {
|
||||||
|
"version": "2.9.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz",
|
||||||
|
"integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==",
|
||||||
|
"bin": {
|
||||||
|
"baseline-browser-mapping": "dist/cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/blurhash": {
|
"node_modules/blurhash": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/blurhash/-/blurhash-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/blurhash/-/blurhash-2.0.5.tgz",
|
||||||
|
|
@ -3523,9 +3426,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001743",
|
"version": "1.0.30001761",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001743.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001761.tgz",
|
||||||
"integrity": "sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==",
|
"integrity": "sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
|
|
@ -3874,9 +3777,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/detect-libc": {
|
"node_modules/detect-libc": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||||
"integrity": "sha512-vEtk+OcP7VBRtQZ1EJ3bdgzSfBjgnEalLTp5zjJrS+2Z1w2KZly4SBdac/WDU3hhsNAZ9E8SC96ME4Ey8MZ7cg==",
|
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
|
|
@ -5872,12 +5775,13 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/next": {
|
"node_modules/next": {
|
||||||
"version": "15.5.3",
|
"version": "16.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/next/-/next-15.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/next/-/next-16.1.1.tgz",
|
||||||
"integrity": "sha512-r/liNAx16SQj4D+XH/oI1dlpv9tdKJ6cONYPwwcCC46f2NjpaRWY+EKCzULfgQYV6YKXjHBchff2IZBSlZmJNw==",
|
"integrity": "sha512-QI+T7xrxt1pF6SQ/JYFz95ro/mg/1Znk5vBebsWwbpejj1T0A23hO7GYEaVac9QUOT2BIMiuzm0L99ooq7k0/w==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@next/env": "15.5.3",
|
"@next/env": "16.1.1",
|
||||||
"@swc/helpers": "0.5.15",
|
"@swc/helpers": "0.5.15",
|
||||||
|
"baseline-browser-mapping": "^2.8.3",
|
||||||
"caniuse-lite": "^1.0.30001579",
|
"caniuse-lite": "^1.0.30001579",
|
||||||
"postcss": "8.4.31",
|
"postcss": "8.4.31",
|
||||||
"styled-jsx": "5.1.6"
|
"styled-jsx": "5.1.6"
|
||||||
|
|
@ -5886,18 +5790,18 @@
|
||||||
"next": "dist/bin/next"
|
"next": "dist/bin/next"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^19.8.0 || >= 20.0.0"
|
"node": ">=20.9.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@next/swc-darwin-arm64": "15.5.3",
|
"@next/swc-darwin-arm64": "16.1.1",
|
||||||
"@next/swc-darwin-x64": "15.5.3",
|
"@next/swc-darwin-x64": "16.1.1",
|
||||||
"@next/swc-linux-arm64-gnu": "15.5.3",
|
"@next/swc-linux-arm64-gnu": "16.1.1",
|
||||||
"@next/swc-linux-arm64-musl": "15.5.3",
|
"@next/swc-linux-arm64-musl": "16.1.1",
|
||||||
"@next/swc-linux-x64-gnu": "15.5.3",
|
"@next/swc-linux-x64-gnu": "16.1.1",
|
||||||
"@next/swc-linux-x64-musl": "15.5.3",
|
"@next/swc-linux-x64-musl": "16.1.1",
|
||||||
"@next/swc-win32-arm64-msvc": "15.5.3",
|
"@next/swc-win32-arm64-msvc": "16.1.1",
|
||||||
"@next/swc-win32-x64-msvc": "15.5.3",
|
"@next/swc-win32-x64-msvc": "16.1.1",
|
||||||
"sharp": "^0.34.3"
|
"sharp": "^0.34.4"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@opentelemetry/api": "^1.1.0",
|
"@opentelemetry/api": "^1.1.0",
|
||||||
|
|
@ -6294,9 +6198,9 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/react": {
|
"node_modules/react": {
|
||||||
"version": "19.1.0",
|
"version": "19.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
|
||||||
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
|
"integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
|
|
@ -6348,14 +6252,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-dom": {
|
"node_modules/react-dom": {
|
||||||
"version": "19.1.0",
|
"version": "19.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
|
||||||
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
|
"integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"scheduler": "^0.26.0"
|
"scheduler": "^0.27.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^19.1.0"
|
"react": "^19.2.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-dropzone": {
|
"node_modules/react-dropzone": {
|
||||||
|
|
@ -6667,14 +6571,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/scheduler": {
|
"node_modules/scheduler": {
|
||||||
"version": "0.26.0",
|
"version": "0.27.0",
|
||||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
|
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
|
||||||
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="
|
"integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "7.7.2",
|
"version": "7.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
|
|
@ -6730,15 +6634,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sharp": {
|
"node_modules/sharp": {
|
||||||
"version": "0.34.4",
|
"version": "0.34.5",
|
||||||
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.4.tgz",
|
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz",
|
||||||
"integrity": "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==",
|
"integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@img/colour": "^1.0.0",
|
"@img/colour": "^1.0.0",
|
||||||
"detect-libc": "^2.1.0",
|
"detect-libc": "^2.1.2",
|
||||||
"semver": "^7.7.2"
|
"semver": "^7.7.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
|
@ -6747,28 +6651,30 @@
|
||||||
"url": "https://opencollective.com/libvips"
|
"url": "https://opencollective.com/libvips"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@img/sharp-darwin-arm64": "0.34.4",
|
"@img/sharp-darwin-arm64": "0.34.5",
|
||||||
"@img/sharp-darwin-x64": "0.34.4",
|
"@img/sharp-darwin-x64": "0.34.5",
|
||||||
"@img/sharp-libvips-darwin-arm64": "1.2.3",
|
"@img/sharp-libvips-darwin-arm64": "1.2.4",
|
||||||
"@img/sharp-libvips-darwin-x64": "1.2.3",
|
"@img/sharp-libvips-darwin-x64": "1.2.4",
|
||||||
"@img/sharp-libvips-linux-arm": "1.2.3",
|
"@img/sharp-libvips-linux-arm": "1.2.4",
|
||||||
"@img/sharp-libvips-linux-arm64": "1.2.3",
|
"@img/sharp-libvips-linux-arm64": "1.2.4",
|
||||||
"@img/sharp-libvips-linux-ppc64": "1.2.3",
|
"@img/sharp-libvips-linux-ppc64": "1.2.4",
|
||||||
"@img/sharp-libvips-linux-s390x": "1.2.3",
|
"@img/sharp-libvips-linux-riscv64": "1.2.4",
|
||||||
"@img/sharp-libvips-linux-x64": "1.2.3",
|
"@img/sharp-libvips-linux-s390x": "1.2.4",
|
||||||
"@img/sharp-libvips-linuxmusl-arm64": "1.2.3",
|
"@img/sharp-libvips-linux-x64": "1.2.4",
|
||||||
"@img/sharp-libvips-linuxmusl-x64": "1.2.3",
|
"@img/sharp-libvips-linuxmusl-arm64": "1.2.4",
|
||||||
"@img/sharp-linux-arm": "0.34.4",
|
"@img/sharp-libvips-linuxmusl-x64": "1.2.4",
|
||||||
"@img/sharp-linux-arm64": "0.34.4",
|
"@img/sharp-linux-arm": "0.34.5",
|
||||||
"@img/sharp-linux-ppc64": "0.34.4",
|
"@img/sharp-linux-arm64": "0.34.5",
|
||||||
"@img/sharp-linux-s390x": "0.34.4",
|
"@img/sharp-linux-ppc64": "0.34.5",
|
||||||
"@img/sharp-linux-x64": "0.34.4",
|
"@img/sharp-linux-riscv64": "0.34.5",
|
||||||
"@img/sharp-linuxmusl-arm64": "0.34.4",
|
"@img/sharp-linux-s390x": "0.34.5",
|
||||||
"@img/sharp-linuxmusl-x64": "0.34.4",
|
"@img/sharp-linux-x64": "0.34.5",
|
||||||
"@img/sharp-wasm32": "0.34.4",
|
"@img/sharp-linuxmusl-arm64": "0.34.5",
|
||||||
"@img/sharp-win32-arm64": "0.34.4",
|
"@img/sharp-linuxmusl-x64": "0.34.5",
|
||||||
"@img/sharp-win32-ia32": "0.34.4",
|
"@img/sharp-wasm32": "0.34.5",
|
||||||
"@img/sharp-win32-x64": "0.34.4"
|
"@img/sharp-win32-arm64": "0.34.5",
|
||||||
|
"@img/sharp-win32-ia32": "0.34.5",
|
||||||
|
"@img/sharp-win32-x64": "0.34.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
|
|
@ -7623,6 +7529,111 @@
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-darwin-arm64": {
|
||||||
|
"version": "16.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.1.1.tgz",
|
||||||
|
"integrity": "sha512-JS3m42ifsVSJjSTzh27nW+Igfha3NdBOFScr9C80hHGrWx55pTrVL23RJbqir7k7/15SKlrLHhh/MQzqBBYrQA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-darwin-x64": {
|
||||||
|
"version": "16.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.1.1.tgz",
|
||||||
|
"integrity": "sha512-hbyKtrDGUkgkyQi1m1IyD3q4I/3m9ngr+V93z4oKHrPcmxwNL5iMWORvLSGAf2YujL+6HxgVvZuCYZfLfb4bGw==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-linux-arm64-gnu": {
|
||||||
|
"version": "16.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.1.1.tgz",
|
||||||
|
"integrity": "sha512-/fvHet+EYckFvRLQ0jPHJCUI5/B56+2DpI1xDSvi80r/3Ez+Eaa2Yq4tJcRTaB1kqj/HrYKn8Yplm9bNoMJpwQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-linux-arm64-musl": {
|
||||||
|
"version": "16.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.1.1.tgz",
|
||||||
|
"integrity": "sha512-MFHrgL4TXNQbBPzkKKur4Fb5ICEJa87HM7fczFs2+HWblM7mMLdco3dvyTI+QmLBU9xgns/EeeINSZD6Ar+oLg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-linux-x64-gnu": {
|
||||||
|
"version": "16.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.1.1.tgz",
|
||||||
|
"integrity": "sha512-20bYDfgOQAPUkkKBnyP9PTuHiJGM7HzNBbuqmD0jiFVZ0aOldz+VnJhbxzjcSabYsnNjMPsE0cyzEudpYxsrUQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-linux-x64-musl": {
|
||||||
|
"version": "16.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.1.1.tgz",
|
||||||
|
"integrity": "sha512-9pRbK3M4asAHQRkwaXwu601oPZHghuSC8IXNENgbBSyImHv/zY4K5udBusgdHkvJ/Tcr96jJwQYOll0qU8+fPA==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-win32-arm64-msvc": {
|
||||||
|
"version": "16.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.1.1.tgz",
|
||||||
|
"integrity": "sha512-bdfQkggaLgnmYrFkSQfsHfOhk/mCYmjnrbRCGgkMcoOBZ4n+TRRSLmT/CU5SATzlBJ9TpioUyBW/vWFXTqQRiA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,12 +38,12 @@
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"lightningcss": "^1.30.1",
|
"lightningcss": "^1.30.1",
|
||||||
"lucide-react": "^0.544.0",
|
"lucide-react": "^0.544.0",
|
||||||
"next": "15.5.3",
|
"next": "^16.1.1",
|
||||||
"react": "19.1.0",
|
"react": "^19.2.3",
|
||||||
"react-apexcharts": "^1.7.0",
|
"react-apexcharts": "^1.7.0",
|
||||||
"react-datepicker": "^8.4.0",
|
"react-datepicker": "^8.4.0",
|
||||||
"react-day-picker": "^9.7.0",
|
"react-day-picker": "^9.7.0",
|
||||||
"react-dom": "19.1.0",
|
"react-dom": "^19.2.4",
|
||||||
"react-dropzone": "^14.3.8",
|
"react-dropzone": "^14.3.8",
|
||||||
"react-hook-form": "^7.59.0",
|
"react-hook-form": "^7.59.0",
|
||||||
"react-password-checklist": "^1.8.1",
|
"react-password-checklist": "^1.8.1",
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 383 KiB |
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
const baseURL = "https://dev.mikulnews.com/api";
|
const baseURL = "https://beritabumn.com/api";
|
||||||
|
|
||||||
const axiosBaseInstance = axios.create({
|
const axiosBaseInstance = axios.create({
|
||||||
baseURL,
|
baseURL,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import axios from "axios";
|
||||||
import { postSignIn } from "../master-user";
|
import { postSignIn } from "../master-user";
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
|
|
||||||
const baseURL = "https://dev.mikulnews.com/api";
|
const baseURL = "https://beritabumn.com/api";
|
||||||
|
|
||||||
const refreshToken = Cookies.get("refresh_token");
|
const refreshToken = Cookies.get("refresh_token");
|
||||||
|
|
||||||
|
|
@ -28,7 +28,7 @@ axiosInterceptorInstance.interceptors.request.use(
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// Response interceptor
|
// Response interceptor
|
||||||
|
|
@ -66,7 +66,7 @@ axiosInterceptorInstance.interceptors.response.use(
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export default axiosInterceptorInstance;
|
export default axiosInterceptorInstance;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
/* ========== CKEditor Wrapper ========== */
|
||||||
|
.ckeditor-wrapper {
|
||||||
|
border-radius: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow:
|
||||||
|
0 1px 3px 0 rgba(0, 0, 0, 0.1),
|
||||||
|
0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== Main Editor Container ========== */
|
||||||
|
.ckeditor-wrapper .ck.ck-editor__main {
|
||||||
|
min-height: var(--editor-min-height, 400px);
|
||||||
|
max-height: var(--editor-max-height, 600px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== Editable Content Area (ClassicEditor) ========== */
|
||||||
|
.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline {
|
||||||
|
min-height: calc(var(--editor-min-height, 400px) - 50px);
|
||||||
|
max-height: calc(var(--editor-max-height, 600px) - 50px);
|
||||||
|
overflow-y: auto !important;
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: #cbd5e1 #f1f5f9;
|
||||||
|
background: #fff !important;
|
||||||
|
color: #111 !important;
|
||||||
|
font-family:
|
||||||
|
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
padding: 1rem;
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== Headings and Text Formatting ========== */
|
||||||
|
.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h1,
|
||||||
|
.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h2,
|
||||||
|
.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h3,
|
||||||
|
.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h4,
|
||||||
|
.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h5,
|
||||||
|
.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h6 {
|
||||||
|
margin: 1em 0 0.5em 0;
|
||||||
|
color: inherit !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline p {
|
||||||
|
margin: 0.5em 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline ul,
|
||||||
|
.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline ol {
|
||||||
|
margin: 0.5em 0;
|
||||||
|
padding-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline blockquote {
|
||||||
|
margin: 1em 0;
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
border-left: 4px solid #d1d5db;
|
||||||
|
background-color: #f9fafb;
|
||||||
|
color: inherit !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== Dark Mode Support ========== */
|
||||||
|
.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline {
|
||||||
|
background: #111 !important;
|
||||||
|
color: #f9fafb !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h1,
|
||||||
|
.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h2,
|
||||||
|
.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h3,
|
||||||
|
.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h4,
|
||||||
|
.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h5,
|
||||||
|
.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h6 {
|
||||||
|
color: #f9fafb !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline blockquote {
|
||||||
|
background-color: #1f2937 !important;
|
||||||
|
border-left-color: #374151 !important;
|
||||||
|
color: #f3f4f6 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== Custom Scrollbars (Light & Dark) ========== */
|
||||||
|
.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ckeditor-wrapper
|
||||||
|
.ck.ck-content.ck-editor__editable_inline::-webkit-scrollbar-track {
|
||||||
|
background: #f1f5f9;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ckeditor-wrapper
|
||||||
|
.ck.ck-content.ck-editor__editable_inline::-webkit-scrollbar-thumb {
|
||||||
|
background: #cbd5e1;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ckeditor-wrapper
|
||||||
|
.ck.ck-content.ck-editor__editable_inline::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #94a3b8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark
|
||||||
|
.ckeditor-wrapper
|
||||||
|
.ck.ck-content.ck-editor__editable_inline::-webkit-scrollbar-track {
|
||||||
|
background: #1f2937;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark
|
||||||
|
.ckeditor-wrapper
|
||||||
|
.ck.ck-content.ck-editor__editable_inline::-webkit-scrollbar-thumb {
|
||||||
|
background: #4b5563;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark
|
||||||
|
.ckeditor-wrapper
|
||||||
|
.ck.ck-content.ck-editor__editable_inline::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #6b7280;
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2017",
|
"target": "ES2017",
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"esnext"
|
||||||
|
],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
|
@ -11,7 +15,7 @@
|
||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"jsx": "preserve",
|
"jsx": "react-jsx",
|
||||||
"incremental": true,
|
"incremental": true,
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
|
|
@ -19,9 +23,19 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./*"]
|
"@/*": [
|
||||||
|
"./*"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
"include": [
|
||||||
"exclude": ["node_modules"]
|
"next-env.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
".next/types/**/*.ts",
|
||||||
|
".next/dev/types/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue