| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- 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",
- },
- });
|