update pay ui
This commit is contained in:
1176
concept_hierarchy.json
Normal file
1176
concept_hierarchy.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,7 @@ import {
|
||||
Input,
|
||||
Icon,
|
||||
Container,
|
||||
useBreakpointValue,
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
FaWeixin,
|
||||
@@ -42,6 +43,87 @@ import { useAuth } from '../../contexts/AuthContext';
|
||||
import { useSubscriptionEvents } from '../../hooks/useSubscriptionEvents';
|
||||
import { subscriptionConfig, themeColors } from '../../views/Pages/Account/subscription-content';
|
||||
|
||||
// 计费周期选择器组件 - 移动端垂直布局(年付在上),桌面端水平布局
|
||||
interface CycleSelectorProps {
|
||||
options: any[];
|
||||
selectedCycle: string;
|
||||
onSelectCycle: (cycle: string) => void;
|
||||
}
|
||||
|
||||
function CycleSelector({ options, selectedCycle, onSelectCycle }: CycleSelectorProps) {
|
||||
// 使用 useBreakpointValue 动态获取是否是移动端
|
||||
const isMobile = useBreakpointValue({ base: true, md: false });
|
||||
|
||||
// 移动端倒序显示(年付在上),桌面端正常顺序
|
||||
const displayOptions = isMobile ? [...options].reverse() : options;
|
||||
|
||||
return (
|
||||
<Flex
|
||||
direction={{ base: 'column', md: 'row' }}
|
||||
gap={3}
|
||||
p={2}
|
||||
bg="rgba(255, 255, 255, 0.03)"
|
||||
borderRadius="xl"
|
||||
border="1px solid"
|
||||
borderColor="rgba(255, 255, 255, 0.1)"
|
||||
backdropFilter="blur(10px)"
|
||||
justify="center"
|
||||
align="center"
|
||||
w={{ base: 'full', md: 'auto' }}
|
||||
maxW={{ base: '320px', md: 'none' }}
|
||||
mx="auto"
|
||||
>
|
||||
{displayOptions.map((option: any) => (
|
||||
<Box key={option.cycleKey} position="relative" w={{ base: 'full', md: 'auto' }}>
|
||||
{option.discountPercent > 0 && (
|
||||
<Badge
|
||||
position="absolute"
|
||||
top={{ base: '50%', md: '-10px' }}
|
||||
right={{ base: '10px', md: '-10px' }}
|
||||
transform={{ base: 'translateY(-50%)', md: 'none' }}
|
||||
colorScheme="red"
|
||||
fontSize="xs"
|
||||
px={2}
|
||||
py={1}
|
||||
borderRadius="full"
|
||||
fontWeight="bold"
|
||||
zIndex={1}
|
||||
>
|
||||
省{option.discountPercent}%
|
||||
</Badge>
|
||||
)}
|
||||
|
||||
<Button
|
||||
size="lg"
|
||||
w={{ base: 'full', md: 'auto' }}
|
||||
px={6}
|
||||
py={6}
|
||||
borderRadius="lg"
|
||||
bg={selectedCycle === option.cycleKey ? 'linear-gradient(135deg, #D4AF37, #B8941F)' : 'transparent'}
|
||||
color={selectedCycle === option.cycleKey ? '#000' : '#fff'}
|
||||
border="1px solid"
|
||||
borderColor={selectedCycle === option.cycleKey ? 'rgba(212, 175, 55, 0.3)' : 'rgba(255, 255, 255, 0.1)'}
|
||||
onClick={() => onSelectCycle(option.cycleKey)}
|
||||
_hover={{
|
||||
transform: 'translateY(-2px)',
|
||||
borderColor: 'rgba(212, 175, 55, 0.5)',
|
||||
shadow: selectedCycle === option.cycleKey
|
||||
? '0 0 20px rgba(212, 175, 55, 0.3)'
|
||||
: '0 4px 12px rgba(0, 0, 0, 0.5)',
|
||||
}}
|
||||
transition="all 0.3s"
|
||||
fontWeight="bold"
|
||||
justifyContent={{ base: 'flex-start', md: 'center' }}
|
||||
pl={{ base: 6, md: 6 }}
|
||||
>
|
||||
{option.label}
|
||||
</Button>
|
||||
</Box>
|
||||
))}
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
export default function SubscriptionContentNew() {
|
||||
const { user } = useAuth();
|
||||
const subscriptionEvents = useSubscriptionEvents({
|
||||
@@ -51,7 +133,7 @@ export default function SubscriptionContentNew() {
|
||||
},
|
||||
});
|
||||
|
||||
const [selectedCycle, setSelectedCycle] = useState('monthly');
|
||||
const [selectedCycle, setSelectedCycle] = useState('yearly');
|
||||
const [selectedPlan, setSelectedPlan] = useState(null);
|
||||
const [subscriptionPlans, setSubscriptionPlans] = useState([]);
|
||||
const [priceInfo, setPriceInfo] = useState(null);
|
||||
@@ -751,61 +833,11 @@ export default function SubscriptionContentNew() {
|
||||
选择计费周期 · 时长越长优惠越大
|
||||
</Text>
|
||||
|
||||
<HStack
|
||||
spacing={3}
|
||||
p={2}
|
||||
bg="rgba(255, 255, 255, 0.03)"
|
||||
borderRadius="xl"
|
||||
border="1px solid"
|
||||
borderColor="rgba(255, 255, 255, 0.1)"
|
||||
backdropFilter="blur(10px)"
|
||||
flexWrap="wrap"
|
||||
justify="center"
|
||||
>
|
||||
{getMergedPlans()[1]?.pricingOptions?.map((option: any, index: number) => (
|
||||
<Box key={index} position="relative">
|
||||
{option.discountPercent > 0 && (
|
||||
<Badge
|
||||
position="absolute"
|
||||
top="-10px"
|
||||
right="-10px"
|
||||
colorScheme="red"
|
||||
fontSize="xs"
|
||||
px={2}
|
||||
py={1}
|
||||
borderRadius="full"
|
||||
fontWeight="bold"
|
||||
zIndex={1}
|
||||
>
|
||||
省{option.discountPercent}%
|
||||
</Badge>
|
||||
)}
|
||||
|
||||
<Button
|
||||
size="lg"
|
||||
px={6}
|
||||
py={6}
|
||||
borderRadius="lg"
|
||||
bg={selectedCycle === option.cycleKey ? 'linear-gradient(135deg, #D4AF37, #B8941F)' : 'transparent'}
|
||||
color={selectedCycle === option.cycleKey ? '#000' : '#fff'}
|
||||
border="1px solid"
|
||||
borderColor={selectedCycle === option.cycleKey ? 'rgba(212, 175, 55, 0.3)' : 'rgba(255, 255, 255, 0.1)'}
|
||||
onClick={() => setSelectedCycle(option.cycleKey)}
|
||||
_hover={{
|
||||
transform: 'translateY(-2px)',
|
||||
borderColor: 'rgba(212, 175, 55, 0.5)',
|
||||
shadow: selectedCycle === option.cycleKey
|
||||
? '0 0 20px rgba(212, 175, 55, 0.3)'
|
||||
: '0 4px 12px rgba(0, 0, 0, 0.5)',
|
||||
}}
|
||||
transition="all 0.3s"
|
||||
fontWeight="bold"
|
||||
>
|
||||
{option.label}
|
||||
</Button>
|
||||
</Box>
|
||||
))}
|
||||
</HStack>
|
||||
<CycleSelector
|
||||
options={getMergedPlans()[1]?.pricingOptions || []}
|
||||
selectedCycle={selectedCycle}
|
||||
onSelectCycle={setSelectedCycle}
|
||||
/>
|
||||
|
||||
{(() => {
|
||||
const currentOption = getMergedPlans()[1]?.pricingOptions?.find(
|
||||
|
||||
Reference in New Issue
Block a user