MenuCell.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import { Colors } from "@/constants/Colors";
  2. import { Images } from "@/constants/images";
  3. import { Image } from "expo-image";
  4. import React from "react";
  5. import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
  6. interface MenuItem {
  7. icon: string;
  8. title: string;
  9. type: string;
  10. tip?: string;
  11. }
  12. interface MenuCellProps {
  13. onItemPress: (type: string) => void;
  14. showWallet?: boolean;
  15. showExchange?: boolean;
  16. }
  17. export function MenuCell({ onItemPress, showWallet = false, showExchange = false }: MenuCellProps) {
  18. const menuList: MenuItem[] = [
  19. ...(showWallet
  20. ? [
  21. {
  22. icon: Images.mine.wallet || "",
  23. title: "钱包",
  24. type: "1_1",
  25. },
  26. ]
  27. : []),
  28. {
  29. icon: Images.mine.kaixinOrders || "",
  30. title: "全部订单",
  31. type: "2_0",
  32. },
  33. ...(showExchange
  34. ? [
  35. {
  36. icon: Images.mine.exchangeIcon || "",
  37. title: "兑换码",
  38. tip: "10:00 ~ 18:00",
  39. type: "6_1",
  40. },
  41. ]
  42. : []),
  43. {
  44. icon: Images.mine.customerService || "",
  45. title: "联系客服",
  46. tip: "10:00 ~ 18:00",
  47. type: "4_4",
  48. },
  49. {
  50. icon: Images.mine.address || "",
  51. title: "地址",
  52. type: "4_3",
  53. },
  54. {
  55. icon: Images.mine.opinion || "",
  56. title: "意见反馈",
  57. type: "4_9",
  58. },
  59. {
  60. icon: Images.mine.setting || "",
  61. title: "设置",
  62. type: "4_5",
  63. },
  64. ];
  65. return (
  66. <View style={styles.container}>
  67. {menuList.map((item, index) => (
  68. <TouchableOpacity
  69. key={index}
  70. style={[
  71. styles.menuItem,
  72. index === menuList.length - 1 && styles.lastItem,
  73. ]}
  74. onPress={() => onItemPress(item.type)}
  75. activeOpacity={0.7}
  76. >
  77. <View style={styles.content}>
  78. <Image
  79. source={{ uri: item.icon }}
  80. style={styles.icon}
  81. contentFit="contain"
  82. // Tint icons to neon blue for consistency if they are monochrome
  83. tintColor={Colors.neonBlue}
  84. />
  85. <Text style={styles.title}>{item.title}</Text>
  86. </View>
  87. <View style={styles.arrow}>
  88. <Text style={styles.arrowText}>›</Text>
  89. </View>
  90. </TouchableOpacity>
  91. ))}
  92. </View>
  93. );
  94. }
  95. const styles = StyleSheet.create({
  96. container: {
  97. paddingVertical: 0,
  98. },
  99. menuItem: {
  100. flexDirection: "row",
  101. alignItems: "center",
  102. justifyContent: "space-between",
  103. minHeight: 55,
  104. backgroundColor: "transparent",
  105. borderBottomWidth: 1,
  106. borderBottomColor: "rgba(255, 255, 255, 0.05)",
  107. paddingHorizontal: 15,
  108. },
  109. lastItem: {
  110. borderBottomWidth: 0,
  111. },
  112. content: {
  113. flexDirection: "row",
  114. alignItems: "center",
  115. },
  116. icon: {
  117. width: 20,
  118. height: 20,
  119. marginRight: 12,
  120. },
  121. title: {
  122. fontSize: 14,
  123. fontWeight: "500",
  124. color: Colors.textSecondary,
  125. },
  126. arrow: {
  127. justifyContent: "center",
  128. alignItems: "center",
  129. },
  130. arrowText: {
  131. fontSize: 20,
  132. color: Colors.textTertiary,
  133. marginBottom: 4, // Visual alignment
  134. },
  135. });