225 lines
6.7 KiB
TypeScript
225 lines
6.7 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { Card, CardContent } from "@/components/ui/card";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Input } from "@/components/ui/input";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import {
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableHead,
|
|
TableHeader,
|
|
TableRow,
|
|
} from "@/components/ui/table";
|
|
import { Search, Filter, Eye, Pencil, Trash2, Plus } from "lucide-react";
|
|
|
|
export default function NewsImage() {
|
|
const [activeCategory, setActiveCategory] = useState("All");
|
|
|
|
const categories = [
|
|
{ name: "All", count: 24 },
|
|
{ name: "Technology", count: 8 },
|
|
{ name: "Partnership", count: 5 },
|
|
{ name: "Investment", count: 3 },
|
|
{ name: "News", count: 4 },
|
|
{ name: "Event", count: 2 },
|
|
{ name: "CSR", count: 2 },
|
|
];
|
|
|
|
const articles = [
|
|
{
|
|
title:
|
|
"Novita Hardini: Jangan Sampai Pariwisata Meminggirkan Warga Lokal",
|
|
category: "Technology",
|
|
author: "John Kontributor",
|
|
status: "Published",
|
|
date: "2024-01-15",
|
|
},
|
|
{
|
|
title:
|
|
"Bharatu Mardi Hadji Gugur Saat Bertugas, Diganjar Kenaikan Pangkat Luar Biasa",
|
|
category: "Partnership",
|
|
author: "Sarah Editor",
|
|
status: "Pending",
|
|
date: "2024-01-14",
|
|
},
|
|
{
|
|
title:
|
|
"Lestari Moerdijat: Butuh Afirmasi dan Edukasi untuk Dorong Perempuan Aktif di Dunia Politik",
|
|
category: "Investment",
|
|
author: "Mike Writer",
|
|
status: "Draft",
|
|
date: "2024-01-13",
|
|
},
|
|
{
|
|
title: "SEKRETARIS MAHKAMAH AGUNG LANTIK HAKIM TINGGI PENGAWAS",
|
|
category: "CSR",
|
|
author: "Jane Content",
|
|
status: "Published",
|
|
date: "2024-01-12",
|
|
},
|
|
{
|
|
title:
|
|
"Mudik Nyaman Bersama Pertamina: Layanan 24 Jam, Motoris, dan Fasilitas Lengkap",
|
|
category: "Event",
|
|
author: "John Kontributor",
|
|
status: "Rejected",
|
|
date: "2024-01-11",
|
|
},
|
|
];
|
|
|
|
const statusVariant = (status: string) => {
|
|
switch (status) {
|
|
case "Published":
|
|
return "bg-green-100 text-green-700";
|
|
case "Pending":
|
|
return "bg-yellow-100 text-yellow-700";
|
|
case "Draft":
|
|
return "bg-gray-200 text-gray-600";
|
|
case "Rejected":
|
|
return "bg-red-100 text-red-600";
|
|
default:
|
|
return "";
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
{/* ================= HEADER ================= */}
|
|
<div className="flex items-start justify-between">
|
|
<div>
|
|
<h1 className="text-2xl font-semibold text-slate-800">
|
|
News & Articles
|
|
</h1>
|
|
<p className="text-sm text-slate-500 mt-1">
|
|
Create and manage news articles and blog posts
|
|
</p>
|
|
</div>
|
|
|
|
<Button className="bg-blue-600 hover:bg-blue-700 rounded-lg">
|
|
<Plus className="w-4 h-4 mr-2" />
|
|
Create New Article
|
|
</Button>
|
|
</div>
|
|
|
|
{/* ================= CATEGORY FILTER ================= */}
|
|
<div className="flex flex-wrap gap-3">
|
|
{categories.map((cat) => (
|
|
<Button
|
|
key={cat.name}
|
|
variant={activeCategory === cat.name ? "default" : "outline"}
|
|
className="rounded-full text-sm"
|
|
onClick={() => setActiveCategory(cat.name)}
|
|
>
|
|
{cat.name}
|
|
<span className="ml-2 text-xs opacity-70">{cat.count}</span>
|
|
</Button>
|
|
))}
|
|
</div>
|
|
|
|
{/* ================= SEARCH + FILTER ================= */}
|
|
<div className="flex gap-3">
|
|
<div className="relative flex-1">
|
|
<Search className="absolute left-3 top-3 w-4 h-4 text-slate-400" />
|
|
<Input
|
|
placeholder="Search articles by title, author, or content..."
|
|
className="pl-9"
|
|
/>
|
|
</div>
|
|
|
|
<Button variant="outline" className="rounded-lg">
|
|
<Filter className="w-4 h-4 mr-2" />
|
|
Filters
|
|
</Button>
|
|
</div>
|
|
|
|
{/* ================= TABLE ================= */}
|
|
<Card className="rounded-2xl border shadow-sm">
|
|
<CardContent className="p-0">
|
|
<Table>
|
|
<TableHeader>
|
|
<TableRow>
|
|
<TableHead>Article</TableHead>
|
|
<TableHead>Category</TableHead>
|
|
<TableHead>Author</TableHead>
|
|
<TableHead>Status</TableHead>
|
|
<TableHead>Date</TableHead>
|
|
<TableHead className="text-right">Actions</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
|
|
<TableBody>
|
|
{articles.map((article, index) => (
|
|
<TableRow key={index}>
|
|
<TableCell className="font-medium max-w-xs">
|
|
{article.title}
|
|
</TableCell>
|
|
|
|
<TableCell>
|
|
<Badge variant="secondary">{article.category}</Badge>
|
|
</TableCell>
|
|
|
|
<TableCell>{article.author}</TableCell>
|
|
|
|
<TableCell>
|
|
<span
|
|
className={`px-3 py-1 text-xs rounded-full font-medium ${statusVariant(
|
|
article.status,
|
|
)}`}
|
|
>
|
|
{article.status}
|
|
</span>
|
|
</TableCell>
|
|
|
|
<TableCell>{article.date}</TableCell>
|
|
|
|
<TableCell className="text-right space-x-2">
|
|
<Button size="icon" variant="ghost">
|
|
<Eye className="w-4 h-4" />
|
|
</Button>
|
|
<Button size="icon" variant="ghost">
|
|
<Pencil className="w-4 h-4" />
|
|
</Button>
|
|
<Button size="icon" variant="ghost">
|
|
<Trash2 className="w-4 h-4 text-red-500" />
|
|
</Button>
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
|
|
{/* ================= PAGINATION ================= */}
|
|
<div className="flex items-center justify-between p-4 border-t text-sm text-slate-500">
|
|
<p>Showing 1 to 5 of 24 articles</p>
|
|
|
|
<div className="flex gap-2">
|
|
<Button variant="outline" size="sm">
|
|
Previous
|
|
</Button>
|
|
|
|
<Button size="sm" className="bg-blue-600">
|
|
1
|
|
</Button>
|
|
|
|
<Button variant="outline" size="sm">
|
|
2
|
|
</Button>
|
|
|
|
<Button variant="outline" size="sm">
|
|
3
|
|
</Button>
|
|
|
|
<Button variant="outline" size="sm">
|
|
Next
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|