tiefen_space_app/screeens/CreateSpace/index.jsx

481 lines
17 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
View,
Text,
ScrollView,
ActivityIndicator,
TextInput,
KeyboardAvoidingView,
Platform,
TouchableOpacity,
} from "react-native";
import React, { useState, useRef, useMemo } from "react";
import { useTailwind } from "tailwind-rn";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import Toast from "react-native-toast-message";
import baseRequest from "../../utils/baseRequest";
import { generateSignature } from "../../utils/crypto";
import { Button, Divider, CheckBox, Switch } from "@rneui/themed";
const superSingles = [
{ key: 0, index: 0, text: "永久" },
{ key: 4, index: 1, text: "按年生效" },
{ key: 3, index: 2, text: "按半年生效" },
{ key: 2, index: 3, text: "按季度生效" },
{ key: 1, index: 4, text: "按月生效" },
];
const ListItemWithCheckbox = ({
superSingle,
superSinglesContr,
setSuperSinglesContr,
superSingleCheckeds,
setSuperSingleCheckeds,
index,
}) => {
const tailwind = useTailwind();
return (
<View style={tailwind("mt-4")}>
<View>
<View style={tailwind("flex-row items-center")}>
<CheckBox
checked={superSingleCheckeds.includes(index)}
onPress={(e) => {
e.stopPropagation();
const newSuperSinglesContr = [...superSinglesContr];
newSuperSinglesContr[index].enable =
!superSingleCheckeds.includes(index);
// newSuperSinglesContr[index].price = "0";
// newSuperSinglesContr[index].wechatFree = false;
setSuperSinglesContr(newSuperSinglesContr);
if (superSingleCheckeds.includes(index)) {
setSuperSingleCheckeds(() => {
const newSuperSingleCheckeds = [...superSingleCheckeds];
newSuperSingleCheckeds.splice(
newSuperSingleCheckeds.indexOf(index),
1
);
return newSuperSingleCheckeds;
});
} else {
setSuperSingleCheckeds(superSingleCheckeds.concat(index));
}
}}
// checkedIcon="dot-circle-o"
// uncheckedIcon="circle-o"
iconType="ionicon"
checkedIcon="checkmark-circle"
uncheckedIcon="ellipse-outline"
checkedColor="#FF669E"
containerStyle={tailwind("p-0 m-0 bg-transparent")}
size={24}
></CheckBox>
<Text style={tailwind("ml-1 text-white")}>{superSingle.text}</Text>
</View>
<View
// className={`mt-2 px-4 h-12 py-3 rounded-[0.8rem] bg-[#FFFFFF1a] flex justify-between items-center ${
// superSingleCheckeds != index
// ? "mt-0 px-0 py-0 hidden"
// : ""
// }`}
style={tailwind(
`mt-2 px-4 h-12 py-3 rounded-lg bg-[#FFFFFF1A] flex-row justify-between items-center ${
!superSingleCheckeds.includes(index) ? "mt-0 p-0 hidden" : ""
}`
)}
>
<View style={tailwind("flex-row items-center")}>
<Text style={tailwind("mr-2 text-[#FFFFFF80] text-sm")}>¥</Text>
<TextInput
placeholderTextColor="#FFFFFF80"
underlineColorAndroid="transparent"
keyboardType="numeric"
value={superSinglesContr[index].price}
onChangeText={(value) => {
const newSuperSinglesContr = [...superSinglesContr];
newSuperSinglesContr[index].price = value;
setSuperSinglesContr(newSuperSinglesContr);
}}
style={{
...tailwind("text-2xl text-white"),
// maxWidth: 200,
minWidth: 150,
}}
/>
</View>
<View style={tailwind("flex-row items-center")}>
<Text style={tailwind("text-[#FFFFFF80] mr-2")}>|</Text>
<CheckBox
block
checked={superSinglesContr[index].wechatFree}
onPress={() => {
const newSuperSinglesContr = [...superSinglesContr];
newSuperSinglesContr[index].wechatFree =
!newSuperSinglesContr[index].wechatFree;
setSuperSinglesContr(newSuperSinglesContr);
}}
iconType="ionicon"
checkedIcon="checkmark-circle"
uncheckedIcon="ellipse-outline"
checkedColor="#FF669E"
containerStyle={tailwind("p-0 m-0 bg-transparent")}
size={20}
></CheckBox>
<Text style={tailwind("ml-1 text-sm text-white")}>赠送微信</Text>
</View>
</View>
</View>
</View>
);
};
export default function CreateSpace({ navigation, route }) {
const tailwind = useTailwind();
const insets = useSafeAreaInsets();
const spacePriceRef = useRef(null);
const ironFanPriceRef = useRef(null);
const [isSubmitting, setIsSubmitting] = useState(false);
const [superSingleCheckeds, setSuperSingleCheckeds] = useState([]);
const [openSuper, setOpenSuper] = useState(true);
const [superSinglesContr, setSuperSinglesContr] = useState([
{ enable: false, price: "0", wechatFree: false, key: 0 },
{ enable: false, price: "0", wechatFree: false, key: 4 },
{ enable: false, price: "0", wechatFree: false, key: 3 },
{ enable: false, price: "0", wechatFree: false, key: 2 },
{ enable: false, price: "0", wechatFree: false, key: 1 },
]);
//空间介绍
const [spaceIntro, setSpaceIntro] = useState();
//解锁空间价格
const [spacePrice, setSpacePrice] = useState();
//铁粉价格
const [ironFanPrice, setIronFanPrice] = useState();
//启用超粉功能
const [isSuperFanOn, setIsSuperFanOn] = useState(true);
//超粉价格
const [superFanPrice, setSuperFanPrice] = useState();
//超粉单次开通有效期
const [superFanExpiration, setSuperFanExpiration] = useState(0);
//是否开通超粉送微信
const [unlockWechat, setUnlockWechat] = useState(false);
const [spacePriceAble, setSpacePriceAble] = useState(false);
const listItemWithCheckboxMemo = useMemo(() => {
return superSingles.map((item, index) => (
<View key={item.key}>
<ListItemWithCheckbox
superSingle={item}
superSinglesContr={superSinglesContr}
setSuperSinglesContr={setSuperSinglesContr}
// superSingleCheckeds={superSingleChecked}
superSingleCheckeds={superSingleCheckeds}
setSuperSingleCheckeds={setSuperSingleCheckeds}
index={index}
/>
</View>
));
}, [superSingleCheckeds, superSinglesContr]);
const handleSubmit = async () => {
const superSingle = [...superSinglesContr];
const openSuperEveryFalse = Object.values(superSingle).every(
(it) => !it.enable
);
if (
!spaceIntro ||
!spacePrice ||
!ironFanPrice ||
(openSuper && openSuperEveryFalse)
) {
Toast.show({
type: "error",
text1: "请完善内容后提交",
topOffset: 60,
});
return;
}
const _spacePrice = parseInt(spacePrice * 100, 10);
if (isNaN(_spacePrice) || _spacePrice < 0 || _spacePrice > 388800) {
Toast.show({
type: "error",
text1: "请输入有效的解锁空间价格",
topOffset: 60,
});
return;
}
const _ironFanPrice = parseInt(ironFanPrice * 100, 10);
if (isNaN(_ironFanPrice) || _ironFanPrice < 100 || _ironFanPrice > 388800) {
Toast.show({
type: "error",
text1: "请输入有效的铁粉价格",
topOffset: 60,
});
return;
}
let isPrice = false;
if (openSuper) {
Object.values(superSingle).forEach((it) => {
if (it.enable) {
const superFanPrice = it.price;
if (!superFanPrice) {
Toast.show({
type: "error",
text1: "请填写超粉价格",
topOffset: 60,
});
isPrice = true;
return;
} else {
const _superFanPrice = parseInt(superFanPrice * 100, 10);
if (
openSuper &&
(isNaN(_superFanPrice) ||
_superFanPrice < 100 ||
_superFanPrice > 388800)
) {
isPrice = true;
Toast.show({
type: "error",
text1: "请输入有效的超粉价格",
topOffset: 60,
});
return;
}
if (openSuper && _superFanPrice <= _ironFanPrice) {
isPrice = true;
Toast.show({
type: "error",
text1: "请输入大于铁粉价格的超粉价格",
topOffset: 60,
});
return;
}
}
}
});
}
if (isPrice) return;
if (isSubmitting) return;
setIsSubmitting(true);
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
const superfan_price_list = superSingle.map((it, index) => ({
period: index,
enable: it.enable ? 1 : 0,
price: parseInt(it.price * 100, 10),
is_superfanship_give_wechat: it.wechatFree ? 1 : 0,
}));
try {
const base = await baseRequest();
const body = {
profile: spaceIntro,
admission_price: parseInt(spacePrice * 100, 10),
ironfanship_price: parseInt(ironFanPrice * 100, 10),
is_superfanship_enabled: isSuperFanOn ? 1 : 0,
// superfanship_price: parseInt(superFanPrice * 100, 10),
// superfanship_valid_period: superFanExpiration,
// is_superfanship_give_wechat: unlockWechat ? 1 : 0,
superfan_price_list,
...base,
};
const signature = await generateSignature(body);
const _response = await fetch(
`${apiUrl}/api/zone/create?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}
);
const _data = await _response.json();
if (_data.ret === -1) {
Toast.show({
type: "error",
text1: _data.msg,
topOffset: 60,
});
return;
}
navigation.goBack();
} catch (error) {
console.error(error);
} finally {
setIsSubmitting(false);
}
};
return (
<KeyboardAvoidingView
style={tailwind("flex-1")}
behavior={Platform.OS == "ios" ? "padding" : "height"}
keyboardVerticalOffset={insets.bottom + 60}
>
<ScrollView
style={{
paddingBottom: insets.bottom,
paddingLeft: insets.left,
paddingRight: insets.right,
}}
>
<View style={tailwind("p-4")}>
<Text style={tailwind("text-base font-medium text-white")}>
<Text style={tailwind("text-[#F53030]")}>*</Text>
</Text>
<TextInput
value={spaceIntro}
onChangeText={(value) => setSpaceIntro(value)}
placeholder="介绍下你的空间吧~"
placeholderTextColor="#FFFFFF80"
underlineColorAndroid="transparent"
multiline
textAlignVertical="top"
style={tailwind(
"h-32 bg-[#FFFFFF1A] text-white rounded-2xl mt-2 p-2"
)}
/>
<View style={tailwind("mt-4")}>
<View
style={tailwind("flex flex-row justify-between items-center")}
>
<View style={tailwind("flex-row text-sm")}>
<Text style={tailwind("text-white")}>解锁空间价格</Text>
<Text style={tailwind("text-[#F53030]")}>*</Text>
</View>
<Text style={tailwind("text-white text-xs")}>
成为空间成员可查看免费帖
</Text>
</View>
<TouchableOpacity
onPress={() => {
spacePriceRef.current && spacePriceRef.current.focus();
}}
style={tailwind(
"mt-2 px-4 py-3 h-12 rounded-lg bg-[#FFFFFF1A] flex-row justify-between items-center"
)}
>
<View style={tailwind("flex-row items-center")}>
<Text style={tailwind("text-[#FFFFFF80] text-sm mr-1")}>¥</Text>
<TextInput
ref={spacePriceRef}
focusable={spacePriceAble}
value={spacePrice}
onChangeText={setSpacePrice}
keyboardType="numeric"
placeholder="0~3888仅支持整数"
placeholderTextColor="#FFFFFF80"
underlineColorAndroid="transparent"
style={{
...tailwind("text-white"),
// maxWidth: 250,
minWidth: 150,
}}
/>
</View>
<View>
<Text style={tailwind("text-[#FFFFFF80] text-xs")}>
点击编辑
</Text>
</View>
</TouchableOpacity>
</View>
<View style={tailwind("my-4")}>
<View
style={tailwind("flex flex-row justify-between items-center")}
>
<View style={tailwind("flex-row text-sm")}>
<Text style={tailwind("text-white")}>铁粉价格</Text>
<Text style={tailwind("text-[#F53030]")}>*</Text>
</View>
<Text style={tailwind("text-white text-xs")}>
累计消费达成后解锁铁粉权益
</Text>
</View>
<TouchableOpacity
onPress={() => {
ironFanPriceRef.current && ironFanPriceRef.current.focus();
}}
style={tailwind(
"mt-2 px-4 py-3 h-12 rounded-lg bg-[#FFFFFF1A] flex-row justify-between items-center"
)}
>
<View style={tailwind("flex-row items-center")}>
<Text style={tailwind("text-[#FFFFFF80] text-sm mr-1")}>¥</Text>
<TextInput
ref={ironFanPriceRef}
value={ironFanPrice}
onChangeText={setIronFanPrice}
keyboardType="numeric"
placeholder="1~3888仅支持整数"
placeholderTextColor="#FFFFFF80"
underlineColorAndroid="transparent"
style={{
...tailwind("text-white"),
// maxWidth: 250,
minWidth: 150,
}}
/>
</View>
<View>
<Text style={tailwind("text-[#FFFFFF80] text-xs")}>
点击编辑
</Text>
</View>
</TouchableOpacity>
</View>
<View style={tailwind("my-4 flex-row justify-between items-center")}>
<View style={tailwind("text-sm")}>
<Text style={tailwind("text-white")}>超粉功能</Text>
</View>
<View style={tailwind("flex-row items-center")}>
<Text style={tailwind("text-white text-xs mr-2")}>是否启用</Text>
<View>
<Switch
value={openSuper}
onValueChange={(value) => setOpenSuper(value)}
thumbColor="#ffffff"
trackColor={{ true: "#FF669E", false: "#FFFFFF1A" }}
/>
</View>
</View>
</View>
{openSuper && (
<View style={tailwind("mt-4")}>
<View style={tailwind("flex-row justify-between items-center")}>
<View style={tailwind("flex-row items-center text-sm")}>
<Text style={tailwind("text-white")}>超粉单次开通类型</Text>
<Text style={tailwind("text-[#F53030]")}>*</Text>
</View>
<Text style={tailwind("text-white text-xs")}>
付费后解锁对应期限超粉权益
</Text>
</View>
<View>{listItemWithCheckboxMemo}</View>
</View>
)}
<Button
color="#FF669E"
radius="999"
size="md"
disabled={isSubmitting}
disabledStyle={tailwind("bg-[#FFFFFF80]")}
disabledTitleStyle={tailwind("text-white")}
onPress={handleSubmit}
titleStyle={tailwind("text-base")}
containerStyle={tailwind("mt-4")}
>
{isSubmitting && <ActivityIndicator size="small" color="white" />}
{isSubmitting ? "正在开通..." : "立即开通"}
</Button>
</View>
</ScrollView>
</KeyboardAvoidingView>
);
}