168 lines
6.2 KiB
TypeScript
168 lines
6.2 KiB
TypeScript
import React from "react";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Card, CardContent } from "@/components/ui/card";
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
import { ArrowRight } from "lucide-react";
|
|
import { Link } from "@inertiajs/react";
|
|
|
|
interface SubKategori {
|
|
SubKategoriId: number;
|
|
NamaSubKategori: string;
|
|
}
|
|
|
|
interface Kategori {
|
|
KategoriId: number;
|
|
NamaKategori: string;
|
|
}
|
|
|
|
interface Post {
|
|
PostId: number;
|
|
JudulPost: string;
|
|
DescPost: string;
|
|
SlugPost: string;
|
|
ImagePost: string;
|
|
IsPublish: boolean;
|
|
created_at: string;
|
|
kategori?: Kategori;
|
|
subkategori?: SubKategori;
|
|
}
|
|
|
|
interface CardUndanganProps {
|
|
posts: Post[];
|
|
}
|
|
|
|
const CardUndangan = ({ posts }: CardUndanganProps) => {
|
|
const subcategories = Array.from(
|
|
new Set(posts.map((item) => item.subkategori?.NamaSubKategori))
|
|
).filter(Boolean);
|
|
|
|
const filterPosts = (subkategori: string | null) => {
|
|
if (!subkategori) return posts;
|
|
return posts.filter(
|
|
(item) => item.subkategori?.NamaSubKategori === subkategori
|
|
);
|
|
};
|
|
|
|
const [visibleItems, setVisibleItems] = React.useState(3);
|
|
const [activeTab, setActiveTab] = React.useState("all");
|
|
|
|
const loadMore = () => {
|
|
setVisibleItems((prev) => prev + 3);
|
|
};
|
|
|
|
const PostGrid = ({ items }: { items: Post[] }) => (
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
{items.slice(0, visibleItems).map((item) => (
|
|
<Card key={item.PostId} className="md:p-4">
|
|
<img
|
|
src={`/storage/${item.ImagePost}`}
|
|
alt={item.JudulPost}
|
|
className="rounded-md"
|
|
/>
|
|
<CardContent className="p-4">
|
|
<Badge className="bg-red-600 text-white">
|
|
{item.subkategori?.NamaSubKategori}
|
|
</Badge>
|
|
<p className="text-gray-500 text-sm mt-2">
|
|
{new Date(item.created_at).toLocaleDateString(
|
|
"id-ID",
|
|
{
|
|
day: "numeric",
|
|
month: "long",
|
|
year: "numeric",
|
|
}
|
|
)}
|
|
</p>
|
|
<h3 className="text-md font-semibold mt-2 text-gray-900">
|
|
{item.JudulPost}
|
|
</h3>
|
|
<p className="text-sm text-gray-600 mt-2">
|
|
{item.DescPost.replace(/<[^>]*>/g, "").slice(
|
|
0,
|
|
160
|
|
)}
|
|
...
|
|
</p>
|
|
<Link href={route("undangan.show", item.SlugPost)}>
|
|
<Button
|
|
variant="link"
|
|
className="text-red-600 mt-2 pl-0"
|
|
>
|
|
Baca Selengkapnya{" "}
|
|
<ArrowRight className="ml-2 w-4 h-4" />
|
|
</Button>
|
|
</Link>
|
|
</CardContent>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
);
|
|
|
|
const handleTabChange = (value: string) => {
|
|
setActiveTab(value);
|
|
setVisibleItems(3); // Reset visible items when changing tabs
|
|
};
|
|
|
|
return (
|
|
<section className="container max-w-7xl py-8 px-6">
|
|
<div className="flex justify-center items-center w-full">
|
|
<Tabs
|
|
defaultValue="all"
|
|
className="w-full max-w-6xl"
|
|
onValueChange={handleTabChange}
|
|
>
|
|
<div className="flex justify-center">
|
|
<TabsList className="mb-6">
|
|
<TabsTrigger value="all">Semua</TabsTrigger>
|
|
{subcategories.map((subcat) => (
|
|
<TabsTrigger
|
|
key={subcat}
|
|
value={subcat as string}
|
|
>
|
|
{subcat}
|
|
</TabsTrigger>
|
|
))}
|
|
</TabsList>
|
|
</div>
|
|
|
|
<TabsContent value="all">
|
|
<PostGrid items={filterPosts(null)} />
|
|
{visibleItems < filterPosts(null).length && (
|
|
<div className="flex justify-center mt-8">
|
|
<Button
|
|
variant="link"
|
|
className="text-green-700"
|
|
onClick={loadMore}
|
|
>
|
|
Lihat Lebih Banyak
|
|
</Button>
|
|
</div>
|
|
)}
|
|
</TabsContent>
|
|
|
|
{subcategories.map((subcat) => (
|
|
<TabsContent key={subcat} value={subcat as string}>
|
|
<PostGrid items={filterPosts(subcat as string)} />
|
|
{visibleItems <
|
|
filterPosts(subcat as string).length && (
|
|
<div className="flex justify-center mt-8">
|
|
<Button
|
|
variant="link"
|
|
className="text-green-700"
|
|
onClick={loadMore}
|
|
>
|
|
Lihat Lebih Banyak
|
|
</Button>
|
|
</div>
|
|
)}
|
|
</TabsContent>
|
|
))}
|
|
</Tabs>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export default CardUndangan;
|