MenuCell.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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.setting || "",
  56. title: "实名认证",
  57. type: "4_10",
  58. },
  59. {
  60. icon: Images.mine.opinion || "",
  61. title: "意见反馈",
  62. type: "4_9",
  63. },
  64. {
  65. icon: Images.mine.setting || "",
  66. title: "设置",
  67. type: "4_5",
  68. },
  69. ];
  70. return (
  71. <View style={styles.container}>
  72. {menuList.map((item, index) => (
  73. <TouchableOpacity
  74. key={index}
  75. style={[
  76. styles.menuItem,
  77. index === menuList.length - 1 && styles.lastItem,
  78. ]}
  79. onPress={() => onItemPress(item.type)}
  80. activeOpacity={0.7}
  81. >
  82. <View style={styles.content}>
  83. <Image
  84. source={{ uri: item.icon }}
  85. style={styles.icon}
  86. contentFit="contain"
  87. // Tint icons to neon blue for consistency if they are monochrome
  88. tintColor={Colors.neonBlue}
  89. />
  90. <Text style={styles.title}>{item.title}</Text>
  91. </View>
  92. <View style={styles.arrow}>
  93. <Text style={styles.arrowText}>›</Text>
  94. </View>
  95. </TouchableOpacity>
  96. ))}
  97. </View>
  98. );
  99. }
  100. const styles = StyleSheet.create({
  101. container: {
  102. paddingVertical: 0,
  103. },
  104. menuItem: {
  105. flexDirection: "row",
  106. alignItems: "center",
  107. justifyContent: "space-between",
  108. minHeight: 55,
  109. backgroundColor: "transparent",
  110. borderBottomWidth: 1,
  111. borderBottomColor: "rgba(255, 255, 255, 0.05)",
  112. paddingHorizontal: 15,
  113. },
  114. lastItem: {
  115. borderBottomWidth: 0,
  116. },
  117. content: {
  118. flexDirection: "row",
  119. alignItems: "center",
  120. },
  121. icon: {
  122. width: 20,
  123. height: 20,
  124. marginRight: 12,
  125. },
  126. title: {
  127. fontSize: 14,
  128. fontWeight: "500",
  129. color: Colors.textSecondary,
  130. },
  131. arrow: {
  132. justifyContent: "center",
  133. alignItems: "center",
  134. },
  135. arrowText: {
  136. fontSize: 20,
  137. color: Colors.textTertiary,
  138. marginBottom: 4, // Visual alignment
  139. },
  140. });