update
This commit is contained in:
parent
97653728d3
commit
7e1f6df655
|
|
@ -0,0 +1,29 @@
|
|||
stages:
|
||||
- build
|
||||
- deploy
|
||||
|
||||
build-dev:
|
||||
stage: build
|
||||
when: on_success
|
||||
only:
|
||||
- main
|
||||
image: docker:stable
|
||||
services:
|
||||
- name: docker:dind
|
||||
command: ["--insecure-registry=103.82.242.92:8900"]
|
||||
script:
|
||||
- docker logout
|
||||
- docker login -u $DEPLOY_USERNAME -p $DEPLOY_TOKEN 103.82.242.92:8900
|
||||
- docker build -t 103.82.242.92:8900/medols/web-fokus-aja:dev .
|
||||
- docker push 103.82.242.92:8900/medols/web-fokus-aja:dev
|
||||
|
||||
auto-deploy:
|
||||
stage: deploy
|
||||
when: on_success
|
||||
only:
|
||||
- main
|
||||
image: curlimages/curl:latest
|
||||
services:
|
||||
- docker:dind
|
||||
script:
|
||||
- curl --user admin:$JENKINS_PWD http://38.47.180.165:8080/job/auto-deploy-fokus-aja/build?token=autodeploymedols
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
# Menggunakan image Node.js yang lebih ringan
|
||||
FROM node:23.5.0-alpine
|
||||
|
||||
# Mengatur port
|
||||
ENV PORT 3000
|
||||
|
||||
# Install pnpm secara global
|
||||
RUN npm install -g pnpm
|
||||
|
||||
# Membuat direktori aplikasi dan mengatur sebagai working directory
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Menyalin file penting terlebih dahulu untuk caching
|
||||
COPY package.json ./
|
||||
|
||||
# Menyalin direktori ckeditor5 jika diperlukan
|
||||
COPY vendor/ckeditor5 ./vendor/ckeditor5
|
||||
|
||||
# Menyalin env
|
||||
COPY .env .env
|
||||
|
||||
# Install dependencies
|
||||
RUN pnpm install
|
||||
# RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Menyalin source code aplikasi
|
||||
COPY . .
|
||||
|
||||
# Build aplikasi
|
||||
RUN NODE_OPTIONS="--max-old-space-size=4096" pnpm next build
|
||||
|
||||
# Expose port untuk server
|
||||
EXPOSE 3000
|
||||
|
||||
# Perintah untuk menjalankan aplikasi
|
||||
CMD ["pnpm", "run", "start"]
|
||||
|
|
@ -6,17 +6,6 @@ import Image from "next/image";
|
|||
export default function Home() {
|
||||
return (
|
||||
<div className="relative min-h-screen font-[family-name:var(--font-geist-sans)]">
|
||||
<div className="fixed top-0 left-0 w-full h-auto z-0">
|
||||
<Image
|
||||
src="/rumput.jpg"
|
||||
alt="Background"
|
||||
width={1450}
|
||||
height={600}
|
||||
className="w-full h-auto object-cover"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="relative z-10 bg-[#F2F4F3] max-w-7xl mx-auto">
|
||||
<Navbar />
|
||||
<div className="flex-1">
|
||||
|
|
|
|||
BIN
app/favicon.ico
BIN
app/favicon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 69 KiB |
|
|
@ -13,8 +13,8 @@ const geistMono = Geist_Mono({
|
|||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
title: "Fokus Aja",
|
||||
description: "Fokus Aja",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import Link from "next/link";
|
|||
import { getArticleById, getListArticle } from "@/service/article";
|
||||
import { close, loading } from "@/config/swal";
|
||||
import { useParams } from "next/navigation";
|
||||
import { CommentIcon } from "../icons/sidebar-icon";
|
||||
import { Link2, MailIcon } from "lucide-react";
|
||||
|
||||
type TabKey = "trending" | "comments" | "latest";
|
||||
|
|
@ -13,7 +14,6 @@ type Article = {
|
|||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
htmlDescription: string;
|
||||
categoryName: string;
|
||||
createdAt: string;
|
||||
createdByName: string;
|
||||
|
|
@ -41,9 +41,9 @@ export default function DetailContent() {
|
|||
const [articles, setArticles] = useState<Article[]>([]);
|
||||
const [articleDetail, setArticleDetail] = useState<any>(null);
|
||||
const [showData, setShowData] = useState("5");
|
||||
const [search, setSearch] = useState("-");
|
||||
const [search, setSearch] = useState("");
|
||||
const [listCategory, setListCategory] = useState<CategoryType[]>([]);
|
||||
const [selectedCategories, setSelectedCategories] = useState<any>("-");
|
||||
const [selectedCategories, setSelectedCategories] = useState<any>("");
|
||||
const [startDateValue, setStartDateValue] = useState({
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
|
|
@ -69,46 +69,29 @@ export default function DetailContent() {
|
|||
];
|
||||
|
||||
useEffect(() => {
|
||||
fetchTabArticles();
|
||||
}, [activeTab]);
|
||||
initState();
|
||||
}, [page, showData, startDateValue, selectedCategories]);
|
||||
|
||||
async function fetchTabArticles() {
|
||||
const req: any = {
|
||||
async function initState() {
|
||||
// loading();
|
||||
const req = {
|
||||
limit: showData,
|
||||
page,
|
||||
search,
|
||||
categorySlug: Array.from(selectedCategories).join(","),
|
||||
sort: "desc",
|
||||
isPublish: true,
|
||||
sortBy: "created_at",
|
||||
};
|
||||
|
||||
// Sesuaikan sortBy berdasarkan tab
|
||||
if (activeTab === "trending") {
|
||||
req.sortBy = "view_count";
|
||||
} else if (activeTab === "comments") {
|
||||
req.sortBy = "comment_count";
|
||||
} else {
|
||||
req.sortBy = "created_at";
|
||||
}
|
||||
|
||||
// Hanya kirimkan search jika valid
|
||||
if (search && search !== "-" && search !== "") {
|
||||
req.search = search;
|
||||
}
|
||||
|
||||
if (selectedCategories && selectedCategories !== "-") {
|
||||
req.categorySlug = selectedCategories;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await getListArticle(req);
|
||||
setTabArticles(res?.data?.data || []);
|
||||
} catch (error) {
|
||||
console.error("Failed fetching tab articles:", error);
|
||||
setTabArticles([]); // Optional fallback
|
||||
setArticles(res?.data?.data || []);
|
||||
setTotalPage(res?.data?.meta?.totalPage || 1);
|
||||
} finally {
|
||||
// close();
|
||||
}
|
||||
}
|
||||
|
||||
const content: Record<
|
||||
TabKey,
|
||||
{ image: string; title: string; date: string }[]
|
||||
|
|
@ -154,30 +137,6 @@ export default function DetailContent() {
|
|||
],
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
initState();
|
||||
}, [page, showData, startDateValue, selectedCategories]);
|
||||
|
||||
async function initState() {
|
||||
// loading();
|
||||
const req = {
|
||||
limit: showData,
|
||||
page,
|
||||
search,
|
||||
categorySlug: Array.from(selectedCategories).join(","),
|
||||
sort: "desc",
|
||||
sortBy: "created_at",
|
||||
};
|
||||
|
||||
try {
|
||||
const res = await getListArticle(req);
|
||||
setArticles(res?.data?.data || []);
|
||||
setTotalPage(res?.data?.meta?.totalPage || 1);
|
||||
} finally {
|
||||
// close();
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
initStateData();
|
||||
}, [listCategory]);
|
||||
|
|
@ -194,79 +153,65 @@ export default function DetailContent() {
|
|||
close();
|
||||
}
|
||||
|
||||
if (!articleDetail?.files || articleDetail.files.length === 0) {
|
||||
return (
|
||||
<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>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex items-center bg-[#F2F4F3] w-full overflow-hidden mb-4 py-6 px-8">
|
||||
<Image
|
||||
src={"/mikul.png"}
|
||||
alt="Background"
|
||||
width={272}
|
||||
height={90}
|
||||
className="w-full md:w-[272px] h-[90px] object-cover border"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
<div className="bg-white grid grid-cols-1 md:grid-cols-3 gap-6 px-8 py-8">
|
||||
<div className="md:col-span-2">
|
||||
<p className="text-sm text-gray-500 mb-2">Home {">"}Detail</p>
|
||||
<h1 className="text-3xl md:text-4xl font-bold text-[#1a1a1a] leading-tight mb-4">
|
||||
{articleDetail?.title}
|
||||
</h1>
|
||||
<div className="flex items-center space-x-2 text-sm text-gray-500 mb-4">
|
||||
<div className="text-[#31942E]">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<g
|
||||
fill="none"
|
||||
// fill-rule="evenodd"
|
||||
<div className="flex flex-row justify-between items-center space-x-2 text-sm text-black mb-4">
|
||||
<div className="flex flex-row gap-3">
|
||||
<div className="text-[#31942E]">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="m12.594 23.258l-.012.002l-.071.035l-.02.004l-.014-.004l-.071-.036q-.016-.004-.024.006l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.016-.018m.264-.113l-.014.002l-.184.093l-.01.01l-.003.011l.018.43l.005.012l.008.008l.201.092q.019.005.029-.008l.004-.014l-.034-.614q-.005-.019-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.003-.011l.018-.43l-.003-.012l-.01-.01z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10s10-4.477 10-10S17.523 2 12 2M8.5 9.5a3.5 3.5 0 1 1 7 0a3.5 3.5 0 0 1-7 0m9.758 7.484A7.99 7.99 0 0 1 12 20a7.99 7.99 0 0 1-6.258-3.016C7.363 15.821 9.575 15 12 15s4.637.821 6.258 1.984"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<g
|
||||
fill="none"
|
||||
// fill-rule="evenodd"
|
||||
>
|
||||
<path d="m12.594 23.258l-.012.002l-.071.035l-.02.004l-.014-.004l-.071-.036q-.016-.004-.024.006l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.016-.018m.264-.113l-.014.002l-.184.093l-.01.01l-.003.011l.018.43l.005.012l.008.008l.201.092q.019.005.029-.008l.004-.014l-.034-.614q-.005-.019-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.003-.011l.018-.43l-.003-.012l-.01-.01z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10s10-4.477 10-10S17.523 2 12 2M8.5 9.5a3.5 3.5 0 1 1 7 0a3.5 3.5 0 0 1-7 0m9.758 7.484A7.99 7.99 0 0 1 12 20a7.99 7.99 0 0 1-6.258-3.016C7.363 15.821 9.575 15 12 15s4.637.821 6.258 1.984"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<span className="text-[#31942E] font-medium">
|
||||
{articleDetail?.createdByName}
|
||||
</span>
|
||||
<span>•</span>
|
||||
<span>
|
||||
<span>
|
||||
{new Date(articleDetail?.createdAt).toLocaleDateString(
|
||||
"id-ID",
|
||||
{
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
}
|
||||
)}
|
||||
<span className="text-[#31942E] font-medium">
|
||||
{articleDetail?.createdByName}
|
||||
</span>
|
||||
</span>
|
||||
<span>•</span>
|
||||
<span>{articleDetail?.categories?.[0]?.title}</span>
|
||||
<span>-</span>
|
||||
<span>
|
||||
<span>
|
||||
{new Date(articleDetail?.createdAt).toLocaleDateString(
|
||||
"id-ID",
|
||||
{
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
}
|
||||
)}
|
||||
</span>
|
||||
</span>
|
||||
<span className="text-gray-500">in</span>
|
||||
<span>{articleDetail?.categories?.[0]?.title}</span>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<CommentIcon />0
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full h-auto mb-6">
|
||||
{/* Gambar utama */}
|
||||
<div className="w-full">
|
||||
<Image
|
||||
src={articleDetail.files[selectedIndex].fileUrl}
|
||||
alt={articleDetail.files[selectedIndex].fileAlt || "Berita"}
|
||||
src={articleDetail?.files[selectedIndex].fileUrl}
|
||||
alt={articleDetail?.files[selectedIndex].fileAlt || "Berita"}
|
||||
width={800}
|
||||
height={400}
|
||||
className="rounded-lg w-full object-cover"
|
||||
|
|
@ -275,7 +220,7 @@ export default function DetailContent() {
|
|||
|
||||
{/* Thumbnail */}
|
||||
<div className="flex gap-2 mt-3 overflow-x-auto">
|
||||
{articleDetail.files.map((file: any, index: number) => (
|
||||
{articleDetail?.files.map((file: any, index: number) => (
|
||||
<button
|
||||
key={file.id || index}
|
||||
onClick={() => setSelectedIndex(index)}
|
||||
|
|
@ -296,13 +241,15 @@ export default function DetailContent() {
|
|||
))}
|
||||
</div>
|
||||
|
||||
{/* Slug */}
|
||||
<p className="text-sm text-gray-500 mt-2 text-end">
|
||||
{articleDetail?.slug}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex relative">
|
||||
<div className=" flex flex-col w-fit rounded overflow-hidden mr-5">
|
||||
<div className=" flex flex-row w-fit rounded overflow-hidden mr-5 gap-3 mt-3">
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<p className="text-red-500 font-semibold">0</p>
|
||||
<p className="text-red-500 font-semibold">SHARES</p>
|
||||
</div>
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<p className="text-black font-semibold">3</p>
|
||||
<p className="text-black font-semibold">VIEWS</p>
|
||||
</div>
|
||||
<Link
|
||||
href="#"
|
||||
aria-label="Facebook"
|
||||
|
|
@ -337,46 +284,88 @@ export default function DetailContent() {
|
|||
|
||||
<Link
|
||||
href="#"
|
||||
aria-label="Google"
|
||||
className="bg-[#fce9e7] p-4 flex justify-center items-center text-white"
|
||||
aria-label="WhatsApp"
|
||||
className="bg-green-700 p-4 flex justify-center items-center text-white"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path 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" />
|
||||
<g fill="none">
|
||||
<g
|
||||
// clip-path="url(#SVGXv8lpc2Y)"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
// fill-rule="evenodd"
|
||||
d="M17.415 14.382c-.298-.149-1.759-.867-2.031-.967s-.47-.148-.669.15c-.198.297-.767.966-.94 1.164c-.174.199-.347.223-.644.075c-.297-.15-1.255-.463-2.39-1.475c-.883-.788-1.48-1.761-1.653-2.059c-.173-.297-.019-.458.13-.606c.134-.133.297-.347.446-.52s.198-.298.297-.497c.1-.198.05-.371-.025-.52c-.074-.149-.668-1.612-.916-2.207c-.241-.579-.486-.5-.668-.51c-.174-.008-.372-.01-.57-.01s-.52.074-.792.372c-.273.297-1.04 1.016-1.04 2.479c0 1.462 1.064 2.875 1.213 3.074s2.095 3.2 5.076 4.487c.71.306 1.263.489 1.694.625c.712.227 1.36.195 1.872.118c.57-.085 1.758-.719 2.006-1.413s.247-1.289.173-1.413s-.272-.198-.57-.347m-5.422 7.403h-.004a9.87 9.87 0 0 1-5.032-1.378l-.36-.214l-3.742.982l.999-3.648l-.235-.374a9.86 9.86 0 0 1-1.511-5.26c.002-5.45 4.436-9.884 9.889-9.884a9.8 9.8 0 0 1 6.988 2.899a9.82 9.82 0 0 1 2.892 6.992c-.002 5.45-4.436 9.885-9.884 9.885m8.412-18.297A11.82 11.82 0 0 0 11.992 0C5.438 0 .102 5.335.1 11.892a11.86 11.86 0 0 0 1.587 5.945L0 24l6.304-1.654a11.9 11.9 0 0 0 5.684 1.448h.005c6.554 0 11.89-5.335 11.892-11.893a11.82 11.82 0 0 0-3.48-8.413"
|
||||
// clip-rule="evenodd"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="SVGXv8lpc2Y">
|
||||
<path fill="#fff" d="M0 0h24v24H0z" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</g>
|
||||
</svg>
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
href="#"
|
||||
aria-label="Share"
|
||||
className="bg-[#cccccc] p-4 flex justify-center items-center text-white"
|
||||
aria-label="Telegram"
|
||||
className="bg-blue-400 p-4 flex justify-center items-center text-white"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
viewBox="0 0 256 256"
|
||||
>
|
||||
<path d="m21 12l-7-7v4C7 10 4 15 3 20c2.5-3.5 6-5.1 11-5.1V19z" />
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="SVGuySfwdaH"
|
||||
x1="50%"
|
||||
x2="50%"
|
||||
y1="0%"
|
||||
y2="100%"
|
||||
>
|
||||
<stop
|
||||
offset="0%"
|
||||
// stop-color="#2aabee"
|
||||
/>
|
||||
<stop
|
||||
offset="100%"
|
||||
// stop-color="#229ed9"
|
||||
/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#SVGuySfwdaH)"
|
||||
d="M128 0C94.06 0 61.48 13.494 37.5 37.49A128.04 128.04 0 0 0 0 128c0 33.934 13.5 66.514 37.5 90.51C61.48 242.506 94.06 256 128 256s66.52-13.494 90.5-37.49c24-23.996 37.5-56.576 37.5-90.51s-13.5-66.514-37.5-90.51C194.52 13.494 161.94 0 128 0"
|
||||
/>
|
||||
<path
|
||||
fill="#fff"
|
||||
d="M57.94 126.648q55.98-24.384 74.64-32.152c35.56-14.786 42.94-17.354 47.76-17.441c1.06-.017 3.42.245 4.96 1.49c1.28 1.05 1.64 2.47 1.82 3.467c.16.996.38 3.266.2 5.038c-1.92 20.24-10.26 69.356-14.5 92.026c-1.78 9.592-5.32 12.808-8.74 13.122c-7.44.684-13.08-4.912-20.28-9.63c-11.26-7.386-17.62-11.982-28.56-19.188c-12.64-8.328-4.44-12.906 2.76-20.386c1.88-1.958 34.64-31.748 35.26-34.45c.08-.338.16-1.598-.6-2.262c-.74-.666-1.84-.438-2.64-.258c-1.14.256-19.12 12.152-54 35.686c-5.1 3.508-9.72 5.218-13.88 5.128c-4.56-.098-13.36-2.584-19.9-4.708c-8-2.606-14.38-3.984-13.82-8.41c.28-2.304 3.46-4.662 9.52-7.072"
|
||||
/>
|
||||
</svg>
|
||||
</Link>
|
||||
</div>
|
||||
<p className="text-sm text-gray-500 mt-2 text-start">
|
||||
{articleDetail?.slug}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex relative">
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
<div className="prose max-w-none text-justify">
|
||||
<div className="text-gray-700 leading-relaxed text-justify">
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: articleDetail?.htmlDescription || "",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* <Author /> */}
|
||||
<div className="w-full bg-white py-6">
|
||||
<p className="mx-10 text-2xl mb-4 ">AUTHOR</p>
|
||||
<div className=" border border-black p-6 flex items-center gap-6 max-w-[1200px] mx-auto">
|
||||
|
|
@ -443,25 +432,10 @@ export default function DetailContent() {
|
|||
/>
|
||||
</div>
|
||||
<div className="mt-10">
|
||||
{/* <div className="flex items-center space-x-4 p-4 border rounded-lg mb-6">
|
||||
<Image
|
||||
src={"/author.png"}
|
||||
alt="Author"
|
||||
width={60}
|
||||
height={60}
|
||||
className="rounded-full"
|
||||
/>
|
||||
<div>
|
||||
<p className="text-green-600 font-bold text-lg">
|
||||
christine natalia
|
||||
</p>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
<h2 className="text-2xl font-bold mb-2">Tinggalkan Balasan</h2>
|
||||
<p className="text-gray-600 mb-4 text-sm">
|
||||
Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib
|
||||
ditandai <span className="text-green-600">*</span>
|
||||
ditandai <span className="text-red-500">*</span>
|
||||
</p>
|
||||
|
||||
<form className="space-y-6 mt-6">
|
||||
|
|
@ -470,11 +444,11 @@ export default function DetailContent() {
|
|||
htmlFor="komentar"
|
||||
className="block text-sm font-medium mb-1"
|
||||
>
|
||||
Komentar <span className="text-green-600">*</span>
|
||||
Komentar <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<textarea
|
||||
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-red-600"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -484,7 +458,7 @@ export default function DetailContent() {
|
|||
htmlFor="nama"
|
||||
className="block text-sm font-medium mb-1"
|
||||
>
|
||||
Nama <span className="text-green-600">*</span>
|
||||
Nama <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
|
|
@ -500,7 +474,7 @@ export default function DetailContent() {
|
|||
htmlFor="email"
|
||||
className="block text-sm font-medium mb-1"
|
||||
>
|
||||
Email <span className="text-green-600">*</span>
|
||||
Email <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
|
|
@ -539,7 +513,7 @@ export default function DetailContent() {
|
|||
|
||||
<button
|
||||
type="submit"
|
||||
className="bg-green-600 hover:bg-green-700 text-white font-semibold px-6 py-2 rounded-md transition mt-2"
|
||||
className="bg-red-500 hover:bg-red-700 text-white font-semibold px-6 py-2 rounded-md transition mt-2"
|
||||
>
|
||||
KIRIM KOMENTAR
|
||||
</button>
|
||||
|
|
@ -549,193 +523,49 @@ export default function DetailContent() {
|
|||
|
||||
<div className="md:col-span-1 space-y-6">
|
||||
<div className="sticky top-0 space-y-6">
|
||||
<div className="bg-white shadow p-4 rounded-lg">
|
||||
<Image
|
||||
src={"/kolom.png"}
|
||||
alt="Iklan"
|
||||
width={345}
|
||||
height={345}
|
||||
className="rounded"
|
||||
/>
|
||||
<button className="mt-4 w-full bg-black text-white py-2 rounded hover:opacity-90">
|
||||
Learn More
|
||||
</button>
|
||||
</div>
|
||||
<div className="space-y-6">
|
||||
{articles?.map((article) => (
|
||||
<div key={article.id}>
|
||||
<div>
|
||||
<Link
|
||||
className="flex space-x-3 mb-2"
|
||||
href={`/detail/${article.id}`}
|
||||
>
|
||||
<Image
|
||||
src={article.thumbnailUrl || "/default-thumb.png"}
|
||||
alt={article.title}
|
||||
width={120}
|
||||
height={80}
|
||||
className="rounded object-cover w-[120px] h-[80px]"
|
||||
/>
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-bold leading-snug hover:text-red-700">
|
||||
{article.title}
|
||||
</p>
|
||||
|
||||
<div className="bg-white shadow p-4 rounded-lg">
|
||||
<h2 className="text-lg font-semibold mb-2">Connect with us</h2>
|
||||
<div className="flex space-x-2">
|
||||
<div className="bg-[#0057ff] text-white px-3 py-2 rounded">
|
||||
<p className="text-sm font-bold">Bē</p>
|
||||
<p className="text-xs">139 Followers</p>
|
||||
<div className="flex items-center text-xs text-gray-500 mt-1 space-x-2">
|
||||
<span>
|
||||
📅{" "}
|
||||
{new Date(article.createdAt).toLocaleDateString(
|
||||
"id-ID",
|
||||
{
|
||||
day: "2-digit",
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
}
|
||||
)}
|
||||
</span>
|
||||
<span>💬 0</span>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<p className="text-sm text-gray-700 line-clamp-2">
|
||||
{article.description.slice(0, 120)}...
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-[#ff0000] text-white px-3 py-2 rounded">
|
||||
<p className="text-sm font-bold">YouTube</p>
|
||||
<p className="text-xs">205k Subscribers</p>
|
||||
</div>
|
||||
<div className="bg-[#f9a825] text-white px-3 py-2 rounded">
|
||||
<p className="text-sm font-bold">RSS</p>
|
||||
<p className="text-xs">23.9k Followers</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-white shadow p-4 rounded-lg">
|
||||
<div className="flex space-x-4 border-b mb-4">
|
||||
{tabs.map((tab) => (
|
||||
<button
|
||||
key={tab.id}
|
||||
onClick={() => setActiveTab(tab.id)}
|
||||
className={`pb-2 text-sm font-medium ${
|
||||
activeTab === tab.id
|
||||
? "border-b-2 border-green-600 text-green-600"
|
||||
: "text-gray-600"
|
||||
}`}
|
||||
>
|
||||
{tab.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
{tabArticles.map((item, idx) => (
|
||||
<div key={idx} className="flex space-x-3">
|
||||
<Image
|
||||
src={item.thumbnailUrl || "/default-thumb.png"}
|
||||
alt={item.title}
|
||||
width={70}
|
||||
height={70}
|
||||
className="rounded w-[70px] h-[70px] object-cover"
|
||||
/>
|
||||
<div>
|
||||
<p className="text-sm font-semibold leading-snug">
|
||||
{item.title}
|
||||
</p>
|
||||
<p className="text-xs text-gray-500 mt-1">
|
||||
{new Date(item.createdAt).toLocaleDateString("id-ID", {
|
||||
day: "2-digit",
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{tabArticles.length === 0 ? (
|
||||
<p className="text-sm text-gray-500">
|
||||
Artikel tidak ditemukan.
|
||||
</p>
|
||||
) : (
|
||||
tabArticles.map((item, idx) => (
|
||||
<div key={idx} className="flex space-x-3">
|
||||
<Image
|
||||
src={item.thumbnailUrl || "/default-thumb.png"}
|
||||
alt={item.title}
|
||||
width={70}
|
||||
height={70}
|
||||
className="rounded w-[70px] h-[70px] object-cover"
|
||||
/>
|
||||
<div>
|
||||
<p className="text-sm font-semibold leading-snug">
|
||||
{item.title}
|
||||
</p>
|
||||
<p className="text-xs text-gray-500 mt-1">
|
||||
{new Date(item.createdAt).toLocaleDateString("id-ID", {
|
||||
day: "2-digit",
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mt-6">
|
||||
<h3 className="text-base font-semibold mb-2 text-gray-800 border-b pb-1 border-green-600 inline-block">
|
||||
Recommended
|
||||
</h3>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="relative">
|
||||
<Image
|
||||
src={"/gaza.png"}
|
||||
alt="Recommended Article"
|
||||
width={400}
|
||||
height={200}
|
||||
className="rounded-lg w-full h-auto object-cover"
|
||||
/>
|
||||
<div className="absolute bottom-0 left-0 right-0 bg-black bg-opacity-60 text-white p-3 rounded-b-lg">
|
||||
<p className="text-sm font-semibold leading-tight">
|
||||
Bom Bunuh Diri Guncang Gereja di Damaskus, 20 Orang Tewas
|
||||
dan Puluhan Terluka
|
||||
</p>
|
||||
<p className="text-xs text-gray-300 mt-1">
|
||||
📅 23 JUNI 2025
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<div className="flex space-x-3">
|
||||
<Image
|
||||
src={"/perang.png"}
|
||||
alt="OPM Serang Gereja"
|
||||
width={80}
|
||||
height={60}
|
||||
className="rounded object-cover w-[80px] h-[60px]"
|
||||
/>
|
||||
<div>
|
||||
<p className="text-sm font-semibold leading-snug">
|
||||
OPM Mulai Kehilangan Simpati dari Masyarakat Papua Usai
|
||||
Serang Gereja
|
||||
</p>
|
||||
<p className="text-xs text-gray-500 mt-1">
|
||||
📅 15 JUNI 2025
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex space-x-3">
|
||||
<Image
|
||||
src={"/jateng.png"}
|
||||
alt="Denda Merokok"
|
||||
width={80}
|
||||
height={60}
|
||||
className="rounded object-cover w-[80px] h-[60px]"
|
||||
/>
|
||||
<div>
|
||||
<p className="text-sm font-semibold leading-snug">
|
||||
Jakarta Terapkan Denda Rp 250.000 bagi Warga yang
|
||||
Merokok Sembarangan
|
||||
</p>
|
||||
<p className="text-xs text-gray-500 mt-1">
|
||||
📅 13 JUNI 2025
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex space-x-3">
|
||||
<Image
|
||||
src={"/investasi.jpg"}
|
||||
alt="Pengguna Internet"
|
||||
width={80}
|
||||
height={60}
|
||||
className="rounded object-cover w-[80px] h-[60px]"
|
||||
/>
|
||||
<div>
|
||||
<p className="text-sm font-semibold leading-snug">
|
||||
Warga Indonesia Jadi Pengguna Internet via Ponsel
|
||||
Terbanyak di Dunia
|
||||
</p>
|
||||
<p className="text-xs text-gray-500 mt-1">
|
||||
📅 26 MEI 2025
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"use client";
|
||||
import { getListArticle } from "@/service/article";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
type Article = {
|
||||
|
|
@ -64,22 +65,31 @@ export default function Header() {
|
|||
key={index}
|
||||
className="border border-gray-200 overflow-hidden shadow-sm bg-white h-[440px]"
|
||||
>
|
||||
<Image
|
||||
src={article.thumbnailUrl}
|
||||
alt={article.title}
|
||||
width={267}
|
||||
height={191}
|
||||
className="w-full h-48 object-cover"
|
||||
/>
|
||||
<div className="p-4 text-center">
|
||||
<p className="text-xs text-gray-400 font-medium tracking-wider uppercase py-2">
|
||||
{article?.categories?.[0]?.title || "TANPA KATEGORI"}
|
||||
</p>
|
||||
<h3 className="text-lg font-semibold text-gray-900 mb-4 leading-snug px-8">
|
||||
{article.title}
|
||||
</h3>
|
||||
<p className="text-xs text-gray-400">{article.createdAt}</p>
|
||||
</div>
|
||||
<Link href={`/detail/${article?.id}`}>
|
||||
<Image
|
||||
src={article.thumbnailUrl}
|
||||
alt={article.title}
|
||||
width={267}
|
||||
height={191}
|
||||
className="w-full h-48 object-cover"
|
||||
/>
|
||||
<div className="p-4 text-center">
|
||||
<p className="text-xs text-gray-400 font-medium tracking-wider uppercase py-2">
|
||||
{article?.categories?.[0]?.title || "TANPA KATEGORI"}
|
||||
</p>
|
||||
<h3 className="text-lg font-semibold text-gray-900 mb-4 leading-snug px-8">
|
||||
{article.title}
|
||||
</h3>
|
||||
<p className="text-xs text-gray-400">
|
||||
{" "}
|
||||
{new Date(article.createdAt).toLocaleDateString("id-ID", {
|
||||
day: "2-digit",
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { Card } from "../ui/card";
|
|||
import Image from "next/image";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { getListArticle } from "@/service/article";
|
||||
import Link from "next/link";
|
||||
|
||||
type Article = {
|
||||
id: number;
|
||||
|
|
@ -80,18 +81,23 @@ export default function Beranda() {
|
|||
</h2>
|
||||
<ul className="space-y-4">
|
||||
{articles.map((news, i) => (
|
||||
<li key={i} className="flex gap-3 items-start">
|
||||
<Image
|
||||
src={news?.thumbnailUrl as string}
|
||||
width={100}
|
||||
height={71}
|
||||
alt={news.title}
|
||||
className="w-[100px] h-[71px] object-cover"
|
||||
/>
|
||||
<li key={i}>
|
||||
<Link
|
||||
className="flex gap-3 items-start"
|
||||
href={`/detail/${news?.id}`}
|
||||
>
|
||||
<Image
|
||||
src={news?.thumbnailUrl as string}
|
||||
width={100}
|
||||
height={71}
|
||||
alt={news.title}
|
||||
className="w-[100px] h-[71px] object-cover"
|
||||
/>
|
||||
|
||||
<p className="text-sm leading-snug font-semibold px-2">
|
||||
{news.title}
|
||||
</p>
|
||||
<p className="text-sm leading-snug font-semibold px-2">
|
||||
{news.title}
|
||||
</p>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
|
@ -100,28 +106,30 @@ export default function Beranda() {
|
|||
<h2 className="text-lg font-semibold border-b ">Berita Opini</h2>
|
||||
<ul className="space-y-3 ">
|
||||
{articles.map((news, i) => (
|
||||
<li
|
||||
key={i}
|
||||
className="flex items-start gap-2 text-sm font-medium border-b"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
<li key={i}>
|
||||
<Link
|
||||
className="flex items-start gap-2 text-sm font-medium border-b"
|
||||
href={`/detail/${news?.id}`}
|
||||
>
|
||||
<g
|
||||
fill="none"
|
||||
// fill-rule="evenodd"
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M5.669 4.76a1.47 1.47 0 0 1 2.04-1.177c1.062.454 3.442 1.533 6.462 3.276c3.021 1.744 5.146 3.267 6.069 3.958c.788.591.79 1.763.001 2.356c-.914.687-3.013 2.19-6.07 3.956c-3.06 1.766-5.412 2.832-6.464 3.28c-.906.387-1.92-.2-2.038-1.177c-.138-1.142-.396-3.735-.396-7.237c0-3.5.257-6.092.396-7.235"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
{news.title}
|
||||
<g
|
||||
fill="none"
|
||||
// fill-rule="evenodd"
|
||||
>
|
||||
<path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M5.669 4.76a1.47 1.47 0 0 1 2.04-1.177c1.062.454 3.442 1.533 6.462 3.276c3.021 1.744 5.146 3.267 6.069 3.958c.788.591.79 1.763.001 2.356c-.914.687-3.013 2.19-6.07 3.956c-3.06 1.766-5.412 2.832-6.464 3.28c-.906.387-1.92-.2-2.038-1.177c-.138-1.142-.396-3.735-.396-7.237c0-3.5.257-6.092.396-7.235"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
{news.title}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
|
@ -133,66 +141,82 @@ export default function Beranda() {
|
|||
</h2>
|
||||
<div className="space-y-4 ">
|
||||
<div>
|
||||
<div className="relative">
|
||||
<img
|
||||
src={articles[0]?.thumbnailUrl}
|
||||
alt={articles[0]?.title}
|
||||
className="w-full h-auto object-cover"
|
||||
/>
|
||||
<span className="absolute bottom-1 left-1 bg-black text-white text-xs px-2 py-1">
|
||||
{articles[0]?.categories?.[0]?.title || "TANPA KATEGORI"}
|
||||
</span>
|
||||
</div>
|
||||
<h3 className="text-base font-bold mt-2">{articles[0]?.title}</h3>
|
||||
<p className="text-xs text-[#A0A0A0] mt-1 flex items-center gap-1">
|
||||
{" "}
|
||||
<span className="text-black">
|
||||
{articles[0]?.createdByName}{" "}
|
||||
</span>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<g fill="none">
|
||||
<path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2m0 2a8 8 0 1 0 0 16a8 8 0 0 0 0-16m0 2a1 1 0 0 1 .993.883L13 7v4.586l2.707 2.707a1 1 0 0 1-1.32 1.497l-.094-.083l-3-3a1 1 0 0 1-.284-.576L11 12V7a1 1 0 0 1 1-1"
|
||||
/>
|
||||
</g>
|
||||
</svg>{" "}
|
||||
{articles[0]?.createdAt}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-4 w-4"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
|
||||
<Link href={`/detail/${articles[0]?.id}`}>
|
||||
<div className="relative">
|
||||
<img
|
||||
src={articles[0]?.thumbnailUrl}
|
||||
alt={articles[0]?.title}
|
||||
className="w-full h-auto object-cover"
|
||||
/>
|
||||
</svg>
|
||||
0
|
||||
</p>
|
||||
<p className="text-sm font-serif text-[#A0A0A0] mt-3 line-clamp-3">
|
||||
{articles[0]?.description}
|
||||
</p>
|
||||
<span className="absolute bottom-1 left-1 bg-black text-white text-xs px-2 py-1">
|
||||
{articles[0]?.categories?.[0]?.title || "TANPA KATEGORI"}
|
||||
</span>
|
||||
</div>
|
||||
<h3 className="text-base font-bold mt-2">
|
||||
{articles[0]?.title}
|
||||
</h3>
|
||||
<p className="text-xs text-[#A0A0A0] mt-1 flex items-center gap-1">
|
||||
{" "}
|
||||
<span className="text-black">
|
||||
{articles[0]?.createdByName}{" "}
|
||||
</span>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<g fill="none">
|
||||
<path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2m0 2a8 8 0 1 0 0 16a8 8 0 0 0 0-16m0 2a1 1 0 0 1 .993.883L13 7v4.586l2.707 2.707a1 1 0 0 1-1.32 1.497l-.094-.083l-3-3a1 1 0 0 1-.284-.576L11 12V7a1 1 0 0 1 1-1"
|
||||
/>
|
||||
</g>
|
||||
</svg>{" "}
|
||||
{new Date(articles[0]?.createdAt).toLocaleDateString(
|
||||
"id-ID",
|
||||
{
|
||||
day: "2-digit",
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
}
|
||||
)}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-4 w-4"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
|
||||
/>
|
||||
</svg>
|
||||
0
|
||||
</p>
|
||||
<p className="text-sm font-serif text-[#A0A0A0] mt-3 line-clamp-3">
|
||||
{articles[0]?.description}
|
||||
</p>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{articles.slice(1).map((item, i) => (
|
||||
<div key={i} className="flex items-start gap-3">
|
||||
<img
|
||||
src={item.thumbnailUrl}
|
||||
alt={item.title}
|
||||
className="w-24 h-16 object-cover"
|
||||
/>
|
||||
<p className="text-sm font-semibold">{item.title}</p>
|
||||
<div key={i}>
|
||||
<Link
|
||||
className="flex items-start gap-3"
|
||||
href={`/detail/${item?.id}`}
|
||||
>
|
||||
<img
|
||||
src={item.thumbnailUrl}
|
||||
alt={item.title}
|
||||
className="w-24 h-16 object-cover"
|
||||
/>
|
||||
<p className="text-sm font-semibold">{item.title}</p>
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -222,18 +246,20 @@ export default function Beranda() {
|
|||
>
|
||||
{articles.length > 0 ? (
|
||||
articles.map((article) => (
|
||||
<div
|
||||
key={article.id}
|
||||
className="flex-shrink-0 flex items-start gap-3 w-[188px]"
|
||||
>
|
||||
<img
|
||||
src={article.thumbnailUrl || "/placeholder.jpg"}
|
||||
alt={article.title}
|
||||
className="w-14 h-14 object-cover rounded"
|
||||
/>
|
||||
<p className="text-xs font-medium w-[150px] line-clamp-3">
|
||||
{article.title}
|
||||
</p>
|
||||
<div key={article.id}>
|
||||
<Link
|
||||
className="flex-shrink-0 flex items-start gap-3 w-[188px]"
|
||||
href={`/detail/${article?.id}`}
|
||||
>
|
||||
<img
|
||||
src={article.thumbnailUrl || "/placeholder.jpg"}
|
||||
alt={article.title}
|
||||
className="w-14 h-14 object-cover rounded"
|
||||
/>
|
||||
<p className="text-xs font-medium w-[150px] line-clamp-3">
|
||||
{article.title}
|
||||
</p>
|
||||
</Link>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
|
|
@ -252,57 +278,59 @@ export default function Beranda() {
|
|||
{articles.length > 0 ? (
|
||||
articles.map((article) => (
|
||||
<div key={article.id}>
|
||||
<img
|
||||
src={article.thumbnailUrl || "/komjen-pol.jpg"}
|
||||
alt={article.title}
|
||||
className="w-full h-64 object-cover mb-4"
|
||||
/>
|
||||
<div className="p-8">
|
||||
<p className="text-xs text-gray-500 uppercase mb-1">
|
||||
{article.categories?.map((cat) => cat.title).join(", ") ||
|
||||
"Beranda"}
|
||||
</p>
|
||||
<h1 className="text-xl font-bold mt-1">{article.title}</h1>
|
||||
<p className="text-[10px] md:text-sm text-gray-500 mt-1 flex items-center gap-3">
|
||||
BY{" "}
|
||||
<span className="text-black font-semibold text-[10px] md:text-sm">
|
||||
{article.createdByName}
|
||||
</span>{" "}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2m0 2a8 8 0 1 0 0 16a8 8 0 0 0 0-16m0 2a1 1 0 0 1 .993.883L13 7v4.586l2.707 2.707a1 1 0 0 1-1.32 1.497l-.094-.083l-3-3a1 1 0 0 1-.284-.576L11 12V7a1 1 0 0 1 1-1"
|
||||
/>
|
||||
</svg>{" "}
|
||||
{new Date(article.createdAt).toLocaleDateString("id-ID")}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-4 w-4"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
|
||||
/>
|
||||
</svg>
|
||||
0
|
||||
</p>
|
||||
<p className="text-sm text-[#666666] mt-2 line-clamp-3">
|
||||
{article.description}
|
||||
</p>
|
||||
<button className="mt-4 text-xs w-6/12 md:w-3/12 border px-3 hover:bg-gray-100 transition py-2">
|
||||
READ MORE
|
||||
</button>
|
||||
</div>
|
||||
<Link href={`/detail/${article?.id}`}>
|
||||
<img
|
||||
src={article.thumbnailUrl || "/komjen-pol.jpg"}
|
||||
alt={article.title}
|
||||
className="w-full h-64 object-cover mb-4"
|
||||
/>
|
||||
<div className="p-8">
|
||||
<p className="text-xs text-gray-500 uppercase mb-1">
|
||||
{article.categories?.map((cat) => cat.title).join(", ") ||
|
||||
"Beranda"}
|
||||
</p>
|
||||
<h1 className="text-xl font-bold mt-1">{article.title}</h1>
|
||||
<p className="text-[10px] md:text-sm text-gray-500 mt-1 flex items-center gap-3">
|
||||
BY{" "}
|
||||
<span className="text-black font-semibold text-[10px] md:text-sm">
|
||||
{article.createdByName}
|
||||
</span>{" "}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2m0 2a8 8 0 1 0 0 16a8 8 0 0 0 0-16m0 2a1 1 0 0 1 .993.883L13 7v4.586l2.707 2.707a1 1 0 0 1-1.32 1.497l-.094-.083l-3-3a1 1 0 0 1-.284-.576L11 12V7a1 1 0 0 1 1-1"
|
||||
/>
|
||||
</svg>{" "}
|
||||
{new Date(article.createdAt).toLocaleDateString("id-ID")}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-4 w-4"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
|
||||
/>
|
||||
</svg>
|
||||
0
|
||||
</p>
|
||||
<p className="text-sm text-[#666666] mt-2 line-clamp-3">
|
||||
{article.description}
|
||||
</p>
|
||||
<button className="mt-4 text-xs w-6/12 md:w-3/12 border px-3 hover:bg-gray-100 transition py-2">
|
||||
READ MORE
|
||||
</button>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
|
|
@ -325,38 +353,43 @@ export default function Beranda() {
|
|||
key={i}
|
||||
className="bg-white shadow-md rounded-none overflow-hidden border"
|
||||
>
|
||||
<div className="relative">
|
||||
<img
|
||||
src={news?.thumbnailUrl || "/komjen-pol.jpg"}
|
||||
alt={news.title}
|
||||
className="w-full h-[223px] object-cover"
|
||||
/>
|
||||
<span className="absolute bottom-0 left-1/2 -translate-x-1/2 bg-black text-white text-[10px] px-2 py-[2px] rounded-none uppercase">
|
||||
{news?.categories?.[0]?.title || "TANPA KATEGORI"}
|
||||
</span>
|
||||
</div>
|
||||
<div className="p-4 text-center">
|
||||
<h3 className="text-lg font-semibold text-gray-900 mb-3 leading-snug px-9">
|
||||
{news.title}
|
||||
</h3>
|
||||
<div className="flex flex-row items-center justify-center text-gray-500 gap-1">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<g fill="none">
|
||||
<path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2m0 2a8 8 0 1 0 0 16a8 8 0 0 0 0-16m0 2a1 1 0 0 1 .993.883L13 7v4.586l2.707 2.707a1 1 0 0 1-1.32 1.497l-.094-.083l-3-3a1 1 0 0 1-.284-.576L11 12V7a1 1 0 0 1 1-1"
|
||||
/>
|
||||
</g>
|
||||
</svg>{" "}
|
||||
<p className="text-xs text-gray-400">{news.createdAt}</p>
|
||||
<Link
|
||||
className="bg-white shadow-md rounded-none overflow-hidden border"
|
||||
href={`/detail/${news?.id}`}
|
||||
>
|
||||
<div className="relative">
|
||||
<img
|
||||
src={news?.thumbnailUrl || "/komjen-pol.jpg"}
|
||||
alt={news.title}
|
||||
className="w-full h-[223px] object-cover"
|
||||
/>
|
||||
<span className="absolute bottom-0 left-1/2 -translate-x-1/2 bg-black text-white text-[10px] px-2 py-[2px] rounded-none uppercase">
|
||||
{news?.categories?.[0]?.title || "TANPA KATEGORI"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-4 text-center">
|
||||
<h3 className="text-lg font-semibold text-gray-900 mb-3 leading-snug px-9">
|
||||
{news.title}
|
||||
</h3>
|
||||
<div className="flex flex-row items-center justify-center text-gray-500 gap-1">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<g fill="none">
|
||||
<path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2m0 2a8 8 0 1 0 0 16a8 8 0 0 0 0-16m0 2a1 1 0 0 1 .993.883L13 7v4.586l2.707 2.707a1 1 0 0 1-1.32 1.497l-.094-.083l-3-3a1 1 0 0 1-.284-.576L11 12V7a1 1 0 0 1 1-1"
|
||||
/>
|
||||
</g>
|
||||
</svg>{" "}
|
||||
<p className="text-xs text-gray-400">{news.createdAt}</p>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -366,15 +399,17 @@ export default function Beranda() {
|
|||
</h2>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
|
||||
{articles.map((news, i) => (
|
||||
<div key={i} className="flex gap-4">
|
||||
<img
|
||||
src={news.thumbnailUrl}
|
||||
alt={news.title}
|
||||
className="w-[100px] h-[70px] object-cover flex-shrink-0"
|
||||
/>
|
||||
<p className="text-sm font-semibold text-gray-900 hover:underline leading-snug">
|
||||
{news.title}
|
||||
</p>
|
||||
<div key={i}>
|
||||
<Link className="flex gap-4" href={`/detail/${news?.id}`}>
|
||||
<img
|
||||
src={news.thumbnailUrl}
|
||||
alt={news.title}
|
||||
className="w-[100px] h-[70px] object-cover flex-shrink-0"
|
||||
/>
|
||||
<p className="text-sm font-semibold text-gray-900 hover:underline leading-snug">
|
||||
{news.title}
|
||||
</p>
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -396,27 +431,32 @@ export default function Beranda() {
|
|||
</h2>
|
||||
|
||||
{articles.map((recentNews, i) => (
|
||||
<div key={i} className="flex flex-col sm:flex-row gap-4 mt-4">
|
||||
<img
|
||||
src={recentNews.thumbnailUrl || "/komjen-pol.jpg"}
|
||||
alt={recentNews.title}
|
||||
className="w-full sm:w-[220px] h-[157px] object-cover"
|
||||
/>
|
||||
<div className="flex-1">
|
||||
<h3 className="text-base font-bold">{recentNews.title}</h3>
|
||||
<p className="text-xs text-gray-500 mt-1 flex flex-wrap items-center gap-2 mb-3">
|
||||
BY{" "}
|
||||
<span className="font-semibold text-black">
|
||||
{recentNews.createdByName}
|
||||
</span>
|
||||
<Clock className="w-3 h-3" />
|
||||
{recentNews.createdAt}
|
||||
<MessageCircle className="w-3 h-3" />0
|
||||
</p>
|
||||
<p className="text-sm text-gray-600 line-clamp-3">
|
||||
{recentNews.description}
|
||||
</p>
|
||||
</div>
|
||||
<div key={i}>
|
||||
<Link
|
||||
className="flex flex-col sm:flex-row gap-4 mt-4"
|
||||
href={`/detail/${recentNews?.id}`}
|
||||
>
|
||||
<img
|
||||
src={recentNews.thumbnailUrl || "/komjen-pol.jpg"}
|
||||
alt={recentNews.title}
|
||||
className="w-full sm:w-[220px] h-[157px] object-cover"
|
||||
/>
|
||||
<div className="flex-1">
|
||||
<h3 className="text-base font-bold">{recentNews.title}</h3>
|
||||
<p className="text-xs text-gray-500 mt-1 flex flex-wrap items-center gap-2 mb-3">
|
||||
BY{" "}
|
||||
<span className="font-semibold text-black">
|
||||
{recentNews.createdByName}
|
||||
</span>
|
||||
<Clock className="w-3 h-3" />
|
||||
{recentNews.createdAt}
|
||||
<MessageCircle className="w-3 h-3" />0
|
||||
</p>
|
||||
<p className="text-sm text-gray-600 line-clamp-3">
|
||||
{recentNews.description}
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
|
||||
|
|
@ -438,39 +478,43 @@ export default function Beranda() {
|
|||
|
||||
<aside className="w-full md:w-full lg:w-full xl:w-[312px] space-y-6 shrink-0">
|
||||
{articles.map((news, i) => (
|
||||
<Card
|
||||
key={i}
|
||||
className="rounded-none overflow-hidden bg-white shadow-sm p-0 gap-1"
|
||||
>
|
||||
<div className="relative">
|
||||
{news?.thumbnailUrl && (
|
||||
<img
|
||||
src={news?.thumbnailUrl}
|
||||
alt={news.title}
|
||||
className="w-full h-[224px] object-cover"
|
||||
/>
|
||||
)}
|
||||
{news?.categories?.[0]?.title && (
|
||||
<span className="absolute top-2 left-2 bg-black text-white text-[10px] px-2 py-1 rounded-none uppercase tracking-wide">
|
||||
{news?.categories?.[0]?.title}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<h3 className="text-base font-bold leading-snug">{news.title}</h3>
|
||||
{news.createdByName && news.createdAt && (
|
||||
<p className="text-xs text-gray-500 mt-2 font-medium mb-4">
|
||||
BY <span className="text-black">{news.createdByName}</span> ·{" "}
|
||||
{news.createdAt}
|
||||
</p>
|
||||
)}
|
||||
{news.description && (
|
||||
<p className="text-sm text-gray-600 mt-2 line-clamp-5">
|
||||
{news.description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
<div className="border" key={i}>
|
||||
<Link
|
||||
className="rounded-none overflow-hidden bg-white shadow-sm p-0 gap-1"
|
||||
href={`/detail/${news?.id}`}
|
||||
>
|
||||
<div className="relative">
|
||||
{news?.thumbnailUrl && (
|
||||
<img
|
||||
src={news?.thumbnailUrl}
|
||||
alt={news.title}
|
||||
className="w-full h-[224px] object-cover"
|
||||
/>
|
||||
)}
|
||||
{news?.categories?.[0]?.title && (
|
||||
<span className="absolute top-2 left-2 bg-black text-white text-[10px] px-2 py-1 rounded-none uppercase tracking-wide">
|
||||
{news?.categories?.[0]?.title}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<h3 className="text-base font-bold leading-snug">
|
||||
{news.title}
|
||||
</h3>
|
||||
{news.createdByName && news.createdAt && (
|
||||
<p className="text-xs text-gray-500 mt-2 font-medium mb-4">
|
||||
BY <span className="text-black">{news.createdByName}</span>{" "}
|
||||
· {news.createdAt}
|
||||
</p>
|
||||
)}
|
||||
{news.description && (
|
||||
<p className="text-sm text-gray-600 mt-2 line-clamp-5">
|
||||
{news.description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
<div className="relative w-auto max-w-full h-[300px] overflow-hidden flex items-center mx-auto border my-6 rounded">
|
||||
<Image
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
Loading…
Reference in New Issue