158 lines
4.6 KiB
TypeScript
158 lines
4.6 KiB
TypeScript
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>
|
||
);
|
||
}
|