39420-vm/src/components/ModGrid.tsx
gpt-engineer-app[bot] 02fe60178a Added CurseForge edge proxy
Co-authored-by: felix-fx-top <253056634+felix-fx-top@users.noreply.github.com>
2026-03-31 10:39:32 +00:00

134 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import ModCard from "./ModCard";
import { Skeleton } from "@/components/ui/skeleton";
import { Button } from "@/components/ui/button";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
import { LayoutGrid, List, Monitor, Smartphone } from "lucide-react";
import { useState } from "react";
interface Mod {
id: string;
slug: string;
title: string;
description: string;
icon_url?: string;
downloads: number;
followers: number;
categories: string[];
project_type: string;
source?: "modrinth" | "curseforge";
}
interface ModGridProps {
mods: Mod[];
isLoading?: boolean;
title?: string;
showViewToggle?: boolean;
showPlatformFilter?: boolean;
onPlatformChange?: (platform: string) => void;
selectedPlatform?: string;
}
const ModGrid = ({
mods,
isLoading,
title,
showViewToggle = true,
showPlatformFilter = false,
onPlatformChange,
selectedPlatform = "all",
}: ModGridProps) => {
const [viewMode, setViewMode] = useState<"grid" | "list">("grid");
return (
<section className="py-6 sm:py-8">
<div className="mb-4 flex flex-col gap-3 sm:mb-6 sm:flex-row sm:items-center sm:justify-between">
{title && (
<h2 className="text-xl font-bold sm:text-2xl">{title}</h2>
)}
<div className="flex flex-wrap items-center gap-2">
{showPlatformFilter && (
<ToggleGroup
type="single"
value={selectedPlatform}
onValueChange={(val) => val && onPlatformChange?.(val)}
className="rounded-lg border border-border bg-secondary/50 p-0.5"
>
<ToggleGroupItem value="all" className="h-8 px-3 text-xs data-[state=on]:bg-primary data-[state=on]:text-primary-foreground">
الكل
</ToggleGroupItem>
<ToggleGroupItem value="java" className="h-8 px-3 text-xs data-[state=on]:bg-primary data-[state=on]:text-primary-foreground">
<Monitor className="ml-1 h-3 w-3" />
جافا
</ToggleGroupItem>
<ToggleGroupItem value="bedrock" className="h-8 px-3 text-xs data-[state=on]:bg-primary data-[state=on]:text-primary-foreground">
<Smartphone className="ml-1 h-3 w-3" />
بيدروك
</ToggleGroupItem>
</ToggleGroup>
)}
{showViewToggle && (
<ToggleGroup
type="single"
value={viewMode}
onValueChange={(val) => val && setViewMode(val as "grid" | "list")}
className="rounded-lg border border-border bg-secondary/50 p-0.5"
>
<ToggleGroupItem value="grid" className="h-8 w-8 p-0 data-[state=on]:bg-primary data-[state=on]:text-primary-foreground">
<LayoutGrid className="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="list" className="h-8 w-8 p-0 data-[state=on]:bg-primary data-[state=on]:text-primary-foreground">
<List className="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
)}
</div>
</div>
{isLoading ? (
<div className={viewMode === "grid"
? "grid gap-3 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
: "flex flex-col gap-2"
}>
{Array.from({ length: 6 }).map((_, i) => (
<div key={i} className="flex gap-3 rounded-lg border border-border bg-card p-3 sm:gap-4 sm:p-4">
<Skeleton className="h-12 w-12 shrink-0 rounded-lg sm:h-16 sm:w-16" />
<div className="flex-1 space-y-2">
<Skeleton className="h-4 w-3/4 sm:h-5" />
<Skeleton className="h-3 w-full sm:h-4" />
<Skeleton className="h-3 w-1/2" />
</div>
</div>
))}
</div>
) : mods.length === 0 ? (
<div className="py-12 text-center text-muted-foreground">
لا توجد إضافات حالياً
</div>
) : (
<div className={viewMode === "grid"
? "grid gap-3 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
: "flex flex-col gap-2"
}>
{mods.map((mod) => (
<ModCard
key={mod.id}
id={mod.id}
slug={mod.slug}
title={mod.title}
description={mod.description}
iconUrl={mod.icon_url}
downloads={mod.downloads}
followers={mod.followers}
categories={mod.categories || []}
projectType={mod.project_type}
viewMode={viewMode}
/>
))}
</div>
)}
</section>
);
};
export default ModGrid;