diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..4170945 --- /dev/null +++ b/.gitlab-ci.yml @@ -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 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2b874db --- /dev/null +++ b/Dockerfile @@ -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"] \ No newline at end of file diff --git a/app/detail/[id]/page.tsx b/app/detail/[id]/page.tsx index 6adfd1f..6aba50d 100644 --- a/app/detail/[id]/page.tsx +++ b/app/detail/[id]/page.tsx @@ -6,17 +6,6 @@ import Image from "next/image"; export default function Home() { return (
-
- Background -
-
diff --git a/app/favicon.ico b/app/favicon.ico index 718d6fe..86bc01c 100644 Binary files a/app/favicon.ico and b/app/favicon.ico differ diff --git a/app/layout.tsx b/app/layout.tsx index f7fa87e..fbcb119 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -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({ diff --git a/components/details/details-content.tsx b/components/details/details-content.tsx index 89a2b08..a70e778 100644 --- a/components/details/details-content.tsx +++ b/components/details/details-content.tsx @@ -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([]); const [articleDetail, setArticleDetail] = useState(null); const [showData, setShowData] = useState("5"); - const [search, setSearch] = useState("-"); + const [search, setSearch] = useState(""); const [listCategory, setListCategory] = useState([]); - const [selectedCategories, setSelectedCategories] = useState("-"); + const [selectedCategories, setSelectedCategories] = useState(""); 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 ( -
-

Gambar tidak tersedia

-
- ); - } - return ( <> -
- Background -

Home {">"}Detail

{articleDetail?.title}

-
-
- - +
+
+ - - - - -
+ + + + + +
- - {articleDetail?.createdByName} - - โ€ข - - - {new Date(articleDetail?.createdAt).toLocaleDateString( - "id-ID", - { - day: "numeric", - month: "long", - year: "numeric", - } - )} + + {articleDetail?.createdByName} - - โ€ข - {articleDetail?.categories?.[0]?.title} + - + + + {new Date(articleDetail?.createdAt).toLocaleDateString( + "id-ID", + { + day: "numeric", + month: "long", + year: "numeric", + } + )} + + + in + {articleDetail?.categories?.[0]?.title} +
+
+ 0 +
- {/* Gambar utama */}
{articleDetail.files[selectedIndex].fileAlt - {articleDetail.files.map((file: any, index: number) => ( + {articleDetail?.files.map((file: any, index: number) => (
- {/* Slug */} -

- {articleDetail?.slug} -

-
-
-
+
+
+

0

+

SHARES

+
+
+

3

+

VIEWS

+
- + + + + + + + + + + - + + + + + + + +
+

+ {articleDetail?.slug} +

+
+
-
+
- - {/* */}

AUTHOR

@@ -443,25 +432,10 @@ export default function DetailContent() { />
- {/*
- Author -
-

- christine natalia -

-
-
*/} -

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib - ditandai * + ditandai *

@@ -470,11 +444,11 @@ export default function DetailContent() { htmlFor="komentar" className="block text-sm font-medium mb-1" > - Komentar * + Komentar *