Files
menulio/apps/mobile/src/components/menu/MenuItemCard.tsx
T
2026-08-20 01:51:59 +03:00

158 lines
4.6 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 { Image, Pressable, Switch, Text, View } from "react-native";
import { Ionicons } from "@expo/vector-icons";
import * as Haptics from "expo-haptics";
export interface MenuItemData {
id: string;
name: string;
description: string | null;
price: number;
is_active: boolean;
image_url?: string | null;
}
interface MenuItemCardProps {
item: MenuItemData;
onPress: () => void;
onToggleActive: (active: boolean) => void;
}
export function MenuItemCard({ item, onPress, onToggleActive }: MenuItemCardProps) {
const isAvailable = item.is_active;
return (
<Pressable
onPress={() => {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light).catch(() => {});
onPress();
}}
style={({ pressed }) => ({
backgroundColor: isAvailable ? "#FFFFFF" : "#F5F5F4",
borderRadius: 16,
padding: 12,
marginBottom: 10,
borderWidth: 1,
borderColor: isAvailable ? "#E7E5E4" : "#D6D3D1",
opacity: pressed ? 0.88 : 1,
shadowColor: "#000",
shadowOffset: { width: 0, height: 1 },
shadowOpacity: isAvailable ? 0.03 : 0,
shadowRadius: 4,
elevation: isAvailable ? 1 : 0,
})}
>
<View style={{ flexDirection: "row", alignItems: "center" }}>
{/* Item Image Thumbnail if available */}
{item.image_url ? (
<Image
source={{ uri: item.image_url }}
style={{
width: 64,
height: 64,
borderRadius: 12,
marginRight: 12,
backgroundColor: "#F5F5F4",
}}
resizeMode="cover"
/>
) : null}
{/* Item Info */}
<View style={{ flex: 1, marginRight: 10 }}>
<View style={{ flexDirection: "row", alignItems: "center", gap: 6, flexWrap: "wrap" }}>
<Text
style={{
fontSize: 15,
fontWeight: "700",
color: isAvailable ? "#1C1917" : "#78716C",
textDecorationLine: isAvailable ? "none" : "line-through",
}}
>
{item.name}
</Text>
{!isAvailable ? (
<View
style={{
backgroundColor: "#FEE2E2",
paddingHorizontal: 6,
paddingVertical: 2,
borderRadius: 4,
}}
>
<Text style={{ fontSize: 10, fontWeight: "700", color: "#DC2626" }}>
Tükendi (86)
</Text>
</View>
) : null}
</View>
{item.description ? (
<Text
numberOfLines={2}
style={{
fontSize: 12,
color: isAvailable ? "#78716C" : "#A8A29E",
marginTop: 2,
lineHeight: 16,
}}
>
{item.description}
</Text>
) : null}
{/* Price */}
<Text
style={{
fontSize: 15,
fontWeight: "800",
color: isAvailable ? "#C8A96B" : "#A8A29E",
marginTop: 4,
}}
>
{item.price}
</Text>
</View>
{/* Action Column: Stock Switch & Details Chevron */}
<View style={{ alignItems: "flex-end", gap: 6 }}>
<View style={{ flexDirection: "row", alignItems: "center", gap: 4 }}>
<Text
style={{
fontSize: 11,
fontWeight: "600",
color: isAvailable ? "#059669" : "#78716C",
}}
>
{isAvailable ? "Aktif" : "Kapalı"}
</Text>
<Switch
value={isAvailable}
onValueChange={(val) => {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium).catch(() => {});
onToggleActive(val);
}}
trackColor={{ false: "#D6D3D1", true: "#059669" }}
thumbColor="#FFFFFF"
style={{ transform: [{ scaleX: 0.8 }, { scaleY: 0.8 }] }}
/>
</View>
<View
style={{
flexDirection: "row",
alignItems: "center",
gap: 2,
paddingVertical: 2,
paddingHorizontal: 4,
}}
>
<Text style={{ fontSize: 11, color: "#A8A29E", fontWeight: "600" }}>Düzenle</Text>
<Ionicons name="chevron-forward" size={13} color="#A8A29E" />
</View>
</View>
</View>
</Pressable>
);
}