|
|
@@ -0,0 +1,196 @@
|
|
|
+import React from "react";
|
|
|
+import {
|
|
|
+ Alert,
|
|
|
+ Modal,
|
|
|
+ ScrollView,
|
|
|
+ StyleSheet,
|
|
|
+ Text,
|
|
|
+ TouchableOpacity,
|
|
|
+ View,
|
|
|
+} from "react-native";
|
|
|
+
|
|
|
+import { Colors } from "@/constants/Colors";
|
|
|
+import { batchReceiveCoupon, CouponItem } from "@/services/activity";
|
|
|
+
|
|
|
+interface Props {
|
|
|
+ visible: boolean;
|
|
|
+ coupons: CouponItem[];
|
|
|
+ onClose: () => void;
|
|
|
+ onSuccess: () => void;
|
|
|
+}
|
|
|
+
|
|
|
+export function CouponModal({ visible, coupons, onClose, onSuccess }: Props) {
|
|
|
+ const handleReceive = async () => {
|
|
|
+ try {
|
|
|
+ const ids = coupons.map((c) => c.id);
|
|
|
+ const ok = await batchReceiveCoupon(ids);
|
|
|
+ if (ok) {
|
|
|
+ Alert.alert("领取成功", "优惠券已发放到您的账户");
|
|
|
+ onSuccess();
|
|
|
+ }
|
|
|
+ onClose();
|
|
|
+ } catch (e) {
|
|
|
+ console.error("领取优惠券失败:", e);
|
|
|
+ onClose();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const formatTime = (val: string) => (val ? val.slice(0, 10) : "");
|
|
|
+
|
|
|
+ if (!coupons || coupons.length === 0) return null;
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Modal visible={visible} transparent animationType="fade" onRequestClose={onClose}>
|
|
|
+ <View style={styles.overlay}>
|
|
|
+ <View style={styles.dialog}>
|
|
|
+ {/* 标题 */}
|
|
|
+ <View style={styles.titleRow}>
|
|
|
+ <Text style={styles.title}>新人大礼包</Text>
|
|
|
+ <TouchableOpacity onPress={onClose} style={styles.closeBtn}>
|
|
|
+ <Text style={styles.closeBtnText}>✕</Text>
|
|
|
+ </TouchableOpacity>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ {/* 优惠券列表 */}
|
|
|
+ <ScrollView style={styles.scrollArea} showsVerticalScrollIndicator={false}>
|
|
|
+ {coupons.map((item, index) => (
|
|
|
+ <View key={item.id || index} style={styles.couponCard}>
|
|
|
+ <View style={styles.couponLeft}>
|
|
|
+ <Text style={styles.couponLabel}>福利优惠劵</Text>
|
|
|
+ </View>
|
|
|
+ <View style={styles.couponCenter}>
|
|
|
+ <Text style={styles.couponAmount}>
|
|
|
+ ¥ <Text style={styles.couponAmountNum}>{item.amount}</Text>
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+ <View style={styles.couponRight}>
|
|
|
+ <Text style={styles.couponCondition}>
|
|
|
+ {item.fullAmount > 0 ? `满${item.fullAmount}可用` : "无门槛"}
|
|
|
+ </Text>
|
|
|
+ <Text style={styles.couponExpiry}>
|
|
|
+ {formatTime(item.endTime)}过期
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ ))}
|
|
|
+ </ScrollView>
|
|
|
+
|
|
|
+ {/* 一键领取按钮 */}
|
|
|
+ <TouchableOpacity style={styles.receiveBtn} onPress={handleReceive} activeOpacity={0.8}>
|
|
|
+ <Text style={styles.receiveBtnText}>一键领取</Text>
|
|
|
+ </TouchableOpacity>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ </Modal>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+const styles = StyleSheet.create({
|
|
|
+ overlay: {
|
|
|
+ flex: 1,
|
|
|
+ backgroundColor: "rgba(0,0,0,0.6)",
|
|
|
+ justifyContent: "center",
|
|
|
+ alignItems: "center",
|
|
|
+ },
|
|
|
+ dialog: {
|
|
|
+ width: "85%",
|
|
|
+ maxHeight: "70%",
|
|
|
+ backgroundColor: Colors.darkCard,
|
|
|
+ borderRadius: 16,
|
|
|
+ borderWidth: 1,
|
|
|
+ borderColor: "rgba(0, 243, 255, 0.4)",
|
|
|
+ overflow: "hidden",
|
|
|
+ },
|
|
|
+ titleRow: {
|
|
|
+ flexDirection: "row",
|
|
|
+ justifyContent: "center",
|
|
|
+ alignItems: "center",
|
|
|
+ paddingVertical: 16,
|
|
|
+ paddingHorizontal: 16,
|
|
|
+ position: "relative",
|
|
|
+ },
|
|
|
+ title: {
|
|
|
+ fontSize: 22,
|
|
|
+ fontWeight: "bold",
|
|
|
+ color: "#fff",
|
|
|
+ textShadowColor: Colors.neonBlue,
|
|
|
+ textShadowRadius: 8,
|
|
|
+ },
|
|
|
+ closeBtn: {
|
|
|
+ position: "absolute",
|
|
|
+ right: 16,
|
|
|
+ top: 12,
|
|
|
+ width: 28,
|
|
|
+ height: 28,
|
|
|
+ borderRadius: 14,
|
|
|
+ backgroundColor: "rgba(255,255,255,0.1)",
|
|
|
+ justifyContent: "center",
|
|
|
+ alignItems: "center",
|
|
|
+ },
|
|
|
+ closeBtnText: {
|
|
|
+ color: "#fff",
|
|
|
+ fontSize: 14,
|
|
|
+ },
|
|
|
+ scrollArea: {
|
|
|
+ maxHeight: 250,
|
|
|
+ paddingHorizontal: 16,
|
|
|
+ },
|
|
|
+ couponCard: {
|
|
|
+ flexDirection: "row",
|
|
|
+ alignItems: "center",
|
|
|
+ backgroundColor: "rgba(255,255,255,0.05)",
|
|
|
+ borderRadius: 10,
|
|
|
+ marginBottom: 10,
|
|
|
+ padding: 14,
|
|
|
+ borderWidth: 1,
|
|
|
+ borderColor: "rgba(0, 243, 255, 0.15)",
|
|
|
+ },
|
|
|
+ couponLeft: {
|
|
|
+ marginRight: 12,
|
|
|
+ },
|
|
|
+ couponLabel: {
|
|
|
+ color: Colors.neonBlue,
|
|
|
+ fontSize: 11,
|
|
|
+ fontWeight: "bold",
|
|
|
+ writingDirection: "ltr",
|
|
|
+ },
|
|
|
+ couponCenter: {
|
|
|
+ marginRight: 12,
|
|
|
+ },
|
|
|
+ couponAmount: {
|
|
|
+ color: "#fff",
|
|
|
+ fontSize: 14,
|
|
|
+ fontWeight: "bold",
|
|
|
+ },
|
|
|
+ couponAmountNum: {
|
|
|
+ fontSize: 32,
|
|
|
+ fontWeight: "800",
|
|
|
+ color: "#fff",
|
|
|
+ },
|
|
|
+ couponRight: {
|
|
|
+ flex: 1,
|
|
|
+ },
|
|
|
+ couponCondition: {
|
|
|
+ color: "#fff",
|
|
|
+ fontSize: 13,
|
|
|
+ fontWeight: "500",
|
|
|
+ },
|
|
|
+ couponExpiry: {
|
|
|
+ color: Colors.textTertiary,
|
|
|
+ fontSize: 11,
|
|
|
+ marginTop: 3,
|
|
|
+ },
|
|
|
+ receiveBtn: {
|
|
|
+ marginHorizontal: 16,
|
|
|
+ marginVertical: 16,
|
|
|
+ backgroundColor: Colors.neonBlue,
|
|
|
+ borderRadius: 24,
|
|
|
+ paddingVertical: 14,
|
|
|
+ alignItems: "center",
|
|
|
+ },
|
|
|
+ receiveBtnText: {
|
|
|
+ color: "#000",
|
|
|
+ fontSize: 16,
|
|
|
+ fontWeight: "bold",
|
|
|
+ },
|
|
|
+});
|