From d3dc3b501666321a6702e5f3554d1dc99799def9 Mon Sep 17 00:00:00 2001 From: "fredy.siswanto" Date: Thu, 6 Mar 2025 22:49:56 +0700 Subject: [PATCH] feat: enhance news API schema with author and categories details, desc: update dashboard to display author names, and improve pagination button styles --- app/apis/admin/get-news.ts | 30 ++++++++----- app/app.css | 36 +++++++++++++++ app/components/ui/table.tsx | 3 +- app/data/contents.ts | 61 -------------------------- app/pages/dashboard-contents/index.tsx | 17 ++++--- app/pages/news-detail/data.ts | 35 +-------------- app/pages/news-detail/index.tsx | 16 +------ app/types/news.ts | 38 ---------------- app/utils/render.tsx | 5 ++- 9 files changed, 70 insertions(+), 171 deletions(-) diff --git a/app/apis/admin/get-news.ts b/app/apis/admin/get-news.ts index 04a0a06..aa860aa 100644 --- a/app/apis/admin/get-news.ts +++ b/app/apis/admin/get-news.ts @@ -2,19 +2,26 @@ import { z } from 'zod' import { HttpServer, type THttpServer } from '~/libs/http-server' +const authorSchema = z.object({ + id: z.string(), + name: z.string(), + profile_picture: z.string(), +}) + +const categoriesCodeSchema = z.array( + z.object({ + id: z.string(), + name: z.string(), + code: z.string(), + }), +) const newsSchema = z.object({ data: z.array( z.object({ id: z.string(), title: z.string(), content: z.string(), - categories: z.array( - z.object({ - id: z.string(), - name: z.string(), - code: z.string(), - }), - ), + categories: categoriesCodeSchema, tags: z.array( z.object({ id: z.string(), @@ -29,15 +36,14 @@ const newsSchema = z.object({ live_at: z.string(), created_at: z.string(), updated_at: z.string(), - author: z.object({ - id: z.string(), - name: z.string(), - profile_picture: z.string(), - }), + author: authorSchema, }), ), }) +export type TAuthor = z.infer +export type TCategories = z.infer + export const getNews = async (parameters: THttpServer) => { try { const { data } = await HttpServer(parameters).get(`/api/news`) diff --git a/app/app.css b/app/app.css index 74741fe..573dc5b 100644 --- a/app/app.css +++ b/app/app.css @@ -37,3 +37,39 @@ nav[aria-label='pagination'] { display: flex; justify-content: center; } +/* Style untuk tombol aktif (current) */ +.dt-paging-button.current { + background-color: #2e2f7c !important; + color: white !important; +} + +/* Style tombol aktif, kecuali jika disabled */ +div.dt-container .dt-paging .dt-paging-button.current:not(.disabled), +div.dt-container .dt-paging .dt-paging-button.current:not(.disabled):hover { + color: white !important; + background-color: #2e2f7c !important; + min-width: 24px; + padding: 3px 6px; +} + +/* Style tombol disabled */ +div.dt-container .dt-paging .dt-paging-button.disabled { + background-color: transparent !important; + color: #ccc !important; + cursor: not-allowed; + pointer-events: none; /* Agar tidak bisa diklik */ +} + +/* Menghindari hover effect untuk tombol yang disabled */ +div.dt-container .dt-paging .dt-paging-button:not(.disabled):hover { + background-color: #2e2f7c !important; + color: white !important; +} + +/* Style default tombol */ +div.dt-container .dt-paging .dt-paging-button { + min-width: 24px; + padding: 3px 6px; + background-color: transparent !important; + color: #2e2f7c !important; +} diff --git a/app/components/ui/table.tsx b/app/components/ui/table.tsx index 3225929..fcd38ec 100644 --- a/app/components/ui/table.tsx +++ b/app/components/ui/table.tsx @@ -3,8 +3,7 @@ import DataTable from 'datatables.net-react' import React from 'react' export type UiTableProperties = { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - data: any[] + data: any // eslint-disable-line @typescript-eslint/no-explicit-any columns: ConfigColumns[] slots?: any // eslint-disable-line @typescript-eslint/no-explicit-any options?: Config diff --git a/app/data/contents.ts b/app/data/contents.ts index 921ca77..3e33c05 100644 --- a/app/data/contents.ts +++ b/app/data/contents.ts @@ -95,67 +95,6 @@ export const BERITA: TNews = { ], } -export const KAJIAN: TNews = { - title: 'KAJIAN', - description: DUMMY_DESCRIPTION, - items: [ - { - title: 'Travelling as a way of self-discovery and progress ', - content: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', - featured: '/images/news-2.jpg', - tags: ['Hukum Property'], - isPremium: true, - slug: 'travelling-as-a-way-of-self-discovery-and-progress ', - }, - { - title: 'Travelling as a way of self-discovery and progress ', - content: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', - featured: '/images/news-2.jpg', - tags: ['Hukum Property'], - isPremium: true, - slug: 'travelling-as-a-way-of-self-discovery-and-progress ', - }, - { - title: 'Travelling as a way of self-discovery and progress ', - content: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', - featured: '/images/news-2.jpg', - tags: ['Hukum Property'], - isPremium: true, - slug: 'travelling-as-a-way-of-self-discovery-and-progress ', - }, - { - title: 'Travelling as a way of self-discovery and progress ', - content: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', - featured: 'https://placehold.co/600x400.png', - tags: ['Hukum Property'], - isPremium: true, - slug: 'travelling-as-a-way-of-self-discovery-and-progress ', - }, - { - title: 'How does writing influence your personal brand? ', - content: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', - featured: '/images/news-3.jpg', - tags: ['Hukum Property'], - isPremium: true, - slug: 'how-does-writing-influence-your-personal-brand', - }, - { - title: 'Helping a local business reinvent itself ', - content: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', - featured: '/images/news-4.jpg', - tags: ['Hukum Property'], - isPremium: true, - slug: 'helping-a-local-business-reinvent-itself', - }, - ], -} - export const BANNER: TBanner[] = [ { id: 1, diff --git a/app/pages/dashboard-contents/index.tsx b/app/pages/dashboard-contents/index.tsx index e7fa581..d45ac44 100644 --- a/app/pages/dashboard-contents/index.tsx +++ b/app/pages/dashboard-contents/index.tsx @@ -2,11 +2,11 @@ import DT from 'datatables.net-dt' import DataTable from 'datatables.net-react' import { Link, useRouteLoaderData } from 'react-router' +import type { TAuthor, TCategories } from '~/apis/admin/get-news' import { Button } from '~/components/ui/button' import { UiTable } from '~/components/ui/table' import { TitleDashboard } from '~/components/ui/title-dashboard' import type { loader } from '~/routes/_admin.lg-admin._dashboard.contents' -import type { TCategory } from '~/types/news' import { formatDate } from '~/utils/formatter' export const ContentsPage = () => { @@ -19,8 +19,8 @@ export const ContentsPage = () => { const dataTable = newsData const dataColumns = [ { title: 'No', data: 'id' }, - { title: 'Tanggal Konten', data: 'created_at' }, - { title: 'Nama Penulis', data: 'author_id' }, + { title: 'Tanggal Konten', data: 'live_at' }, + { title: 'Nama Penulis', data: 'author' }, { title: 'Judul', data: 'title' }, { title: 'Kategori', data: 'categories' }, { @@ -34,18 +34,17 @@ export const ContentsPage = () => { }, { title: 'Action', - data: 'id', + data: 'slug', }, ] const dataSlot = { 1: (value: string) => { return formatDate(value) }, - - 4: (value: TCategory[]) => { - return value.map((item: { name: string }) => { - return `${item.name}` - }) + 2: (value: TAuthor) => `${value.name}`, + 4: (value: TCategories) => { + const categories = value.map((item) => item.name).join(', ') + return `${categories}` }, 6: (value: string | number) => { return ( diff --git a/app/pages/news-detail/data.ts b/app/pages/news-detail/data.ts index 92f69b4..111f4fc 100644 --- a/app/pages/news-detail/data.ts +++ b/app/pages/news-detail/data.ts @@ -1,5 +1,4 @@ -import { DUMMY_DESCRIPTION } from '~/data/contents' -import type { TNews, TNewsDetail } from '~/types/news' +import type { TNewsDetail } from '~/types/news' export const CONTENT: TNewsDetail = { title: 'Hotman Paris Membuka Perpustakaan di tengah Diskotik', @@ -38,35 +37,3 @@ export const CONTENT: TNewsDetail = { categories: [], tags: ['Category', 'Popular', 'Trending', 'Latest'], } - -export const BERITA: TNews = { - title: 'BERITA', - description: DUMMY_DESCRIPTION, - items: [ - { - title: 'Travelling as a way of self-discovery and progress', - content: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', - featured: '/images/news-2.jpg', - tags: ['Hukum Property'], - slug: 'travelling-as-a-way-of-self-discovery-and-progress', - }, - { - title: 'How does writing influence your personal brand?', - content: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', - featured: '/images/news-3.jpg', - tags: ['Hukum'], - slug: 'how-does-writing-influence-your-personal-brand', - }, - { - title: 'Helping a local business reinvent itself', - content: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.', - featured: '/images/news-4.jpg', - tags: ['Hukum Property'], - isPremium: true, - slug: 'helping-a-local-business-reinvent-itself', - }, - ], -} diff --git a/app/pages/news-detail/index.tsx b/app/pages/news-detail/index.tsx index 954d239..67df854 100644 --- a/app/pages/news-detail/index.tsx +++ b/app/pages/news-detail/index.tsx @@ -34,7 +34,7 @@ export const NewsDetailPage = () => {

- + {/* end next planing create component for this section */}
@@ -50,7 +50,7 @@ export const NewsDetailPage = () => { {htmlParse(content)}
-
+

Share this post

@@ -66,18 +66,6 @@ export const NewsDetailPage = () => { ))}
- -
- {title} -
-

{author}

-

Job title, Company name

-
-
diff --git a/app/types/news.ts b/app/types/news.ts index 327a755..d04e998 100644 --- a/app/types/news.ts +++ b/app/types/news.ts @@ -18,41 +18,3 @@ export type TNewsDetail = { isPremium?: boolean categories?: Array } - -export type TTag = { - id: string - code: string - name: string - created_at: string - updated_at: string -} - -export type TCategory = { - id: string - name: string - code: string - created_at: string - updated_at: string -} - -export type Author = { - id: string - name: string - profile_picture: string -} - -export type TKontents = { - id: string - title: string - content: string - featured_image: string - tags: TTag[] - categories: TCategory[] - is_premium: boolean - slug: string - author_id: string - live_at: string - created_at: string - updated_at: string - author: Author -} diff --git a/app/utils/render.tsx b/app/utils/render.tsx index 6989a95..267b30b 100644 --- a/app/utils/render.tsx +++ b/app/utils/render.tsx @@ -12,7 +12,10 @@ type TGetPremiumAttribute = { export const getPremiumAttribute = (parameters: TGetPremiumAttribute) => { const { isPremium, slug, onClick, userData } = parameters - if (isPremium && (!userData || userData?.subscribe_plan_code === 'basic')) { + if ( + isPremium && + (!userData || userData?.subscribe.subscribe_plan.code === 'basic') + ) { return { onClick, to: '',