diff --git a/app/src/components/ListingCard.tsx b/app/src/components/ListingCard.tsx
new file mode 100644
index 0000000..13a45c4
--- /dev/null
+++ b/app/src/components/ListingCard.tsx
@@ -0,0 +1,109 @@
+import type { GestureResponderEvent } from "react-native";
+import type { JSX } from "react";
+import { Pressable, View } from "react-native";
+import { useRouter } from "expo-router";
+import { Button, Separator, Surface, Typography } from "heroui-native";
+import type { Product } from "@/data/mock";
+import { availabilityInfo } from "@/lib/status";
+import { StatusChip } from "@/components/StatusChip";
+import { useModals } from "@/state/modals";
+
+interface ListingCardProps {
+ product: Product;
+ variant?: "list" | "grid";
+}
+
+export function ListingCard({ product, variant = "grid" }: ListingCardProps): JSX.Element {
+ const router = useRouter();
+ const { requestBuy } = useModals();
+ const availability = availabilityInfo(product.qty);
+ const isOut = product.qty === 0;
+
+ const openListing = () => router.push(`/listing/${product.id}`);
+
+ const handleBuyPress = (event: GestureResponderEvent) => {
+ event.stopPropagation();
+ requestBuy(product.id);
+ };
+
+ if (variant === "list") {
+ return (
+
+
+
+ {product.emoji}
+
+
+
+
+ {product.priceNum}
+
+
+ {product.cur}
+
+
+
+
+
+ {product.name}
+
+
+ {product.desc}
+
+
+
+
+
+
+
+
+
+ );
+ }
+
+ return (
+
+
+
+ {product.emoji}
+
+
+
+ {product.name}
+
+
+ {product.seller}
+
+
+
+ {product.price}
+
+
+
+
+
+
+
+ );
+}