feat: add new theme berry (#860)

* feat: add theme berry

* docs: add development notes

* fix: fix blank page

* chore: update implementation

* fix: fix package.json

* chore: update ui copy

---------

Co-authored-by: JustSong <songquanpeng@foxmail.com>
This commit is contained in:
Buer
2024-01-07 14:20:07 +08:00
committed by GitHub
parent 6227eee5bc
commit 48989d4a0b
157 changed files with 13979 additions and 5 deletions

View File

@@ -0,0 +1,80 @@
import { Stack, Typography, Container, Box, OutlinedInput, InputAdornment, Button } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import SubCard from 'ui-component/cards/SubCard';
import inviteImage from 'assets/images/invite/cwok_casual_19.webp';
import { useState } from 'react';
import { API } from 'utils/api';
import { showError, showSuccess } from 'utils/common';
const InviteCard = () => {
const theme = useTheme();
const [inviteUl, setInviteUrl] = useState('');
const handleInviteUrl = async () => {
if (inviteUl) {
navigator.clipboard.writeText(inviteUl);
showSuccess(`邀请链接已复制到剪切板`);
return;
}
const res = await API.get('/api/user/aff');
const { success, message, data } = res.data;
if (success) {
let link = `${window.location.origin}/register?aff=${data}`;
setInviteUrl(link);
navigator.clipboard.writeText(link);
showSuccess(`邀请链接已复制到剪切板`);
} else {
showError(message);
}
};
return (
<Box component="div">
<SubCard
sx={{
background: theme.palette.primary.dark
}}
>
<Stack justifyContent="center" alignItems={'flex-start'} padding={'40px 24px 0px'} spacing={3}>
<Container sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
<img src={inviteImage} alt="invite" width={'250px'} />
</Container>
</Stack>
</SubCard>
<SubCard
sx={{
marginTop: '-20px'
}}
>
<Stack justifyContent="center" alignItems={'center'} spacing={3}>
<Typography variant="h3" sx={{ color: theme.palette.primary.dark }}>
邀请奖励
</Typography>
<Typography variant="body" sx={{ color: theme.palette.primary.dark }}>
分享您的邀请链接邀请好友注册即可获得奖励
</Typography>
<OutlinedInput
id="invite-url"
label="邀请链接"
type="text"
value={inviteUl}
name="invite-url"
placeholder="点击生成邀请链接"
endAdornment={
<InputAdornment position="end">
<Button variant="contained" onClick={handleInviteUrl}>
{inviteUl ? '复制' : '生成'}
</Button>
</InputAdornment>
}
aria-describedby="helper-text-channel-quota-label"
disabled={true}
/>
</Stack>
</SubCard>
</Box>
);
};
export default InviteCard;

View File

@@ -0,0 +1,122 @@
import { Typography, Stack, OutlinedInput, InputAdornment, Button, InputLabel, FormControl } from '@mui/material';
import { IconWallet } from '@tabler/icons-react';
import { useTheme } from '@mui/material/styles';
import SubCard from 'ui-component/cards/SubCard';
import UserCard from 'ui-component/cards/UserCard';
import { API } from 'utils/api';
import React, { useEffect, useState } from 'react';
import { showError, showInfo, showSuccess, renderQuota } from 'utils/common';
const TopupCard = () => {
const theme = useTheme();
const [redemptionCode, setRedemptionCode] = useState('');
const [topUpLink, setTopUpLink] = useState('');
const [userQuota, setUserQuota] = useState(0);
const [isSubmitting, setIsSubmitting] = useState(false);
const topUp = async () => {
if (redemptionCode === '') {
showInfo('请输入充值码!');
return;
}
setIsSubmitting(true);
try {
const res = await API.post('/api/user/topup', {
key: redemptionCode
});
const { success, message, data } = res.data;
if (success) {
showSuccess('充值成功!');
setUserQuota((quota) => {
return quota + data;
});
setRedemptionCode('');
} else {
showError(message);
}
} catch (err) {
showError('请求失败');
} finally {
setIsSubmitting(false);
}
};
const openTopUpLink = () => {
if (!topUpLink) {
showError('超级管理员未设置充值链接!');
return;
}
window.open(topUpLink, '_blank');
};
const getUserQuota = async () => {
let res = await API.get(`/api/user/self`);
const { success, message, data } = res.data;
if (success) {
setUserQuota(data.quota);
} else {
showError(message);
}
};
useEffect(() => {
let status = localStorage.getItem('siteInfo');
if (status) {
status = JSON.parse(status);
if (status.top_up_link) {
setTopUpLink(status.top_up_link);
}
}
getUserQuota().then();
}, []);
return (
<UserCard>
<Stack direction="row" alignItems="center" justifyContent="center" spacing={2} paddingTop={'20px'}>
<IconWallet color={theme.palette.primary.main} />
<Typography variant="h4">当前额度:</Typography>
<Typography variant="h4">{renderQuota(userQuota)}</Typography>
</Stack>
<SubCard
sx={{
marginTop: '40px'
}}
>
<FormControl fullWidth variant="outlined">
<InputLabel htmlFor="key">兑换码</InputLabel>
<OutlinedInput
id="key"
label="兑换码"
type="text"
value={redemptionCode}
onChange={(e) => {
setRedemptionCode(e.target.value);
}}
name="key"
placeholder="请输入兑换码"
endAdornment={
<InputAdornment position="end">
<Button variant="contained" onClick={topUp} disabled={isSubmitting}>
{isSubmitting ? '兑换中...' : '兑换'}
</Button>
</InputAdornment>
}
aria-describedby="helper-text-channel-quota-label"
/>
</FormControl>
<Stack justifyContent="center" alignItems={'center'} spacing={3} paddingTop={'20px'}>
<Typography variant={'h4'} color={theme.palette.grey[700]}>
还没有兑换码 点击获取兑换码
</Typography>
<Button variant="contained" onClick={openTopUpLink}>
获取兑换码
</Button>
</Stack>
</SubCard>
</UserCard>
);
};
export default TopupCard;

View File

@@ -0,0 +1,26 @@
import { Stack, Alert } from '@mui/material';
import Grid from '@mui/material/Unstable_Grid2';
import TopupCard from './component/TopupCard';
import InviteCard from './component/InviteCard';
const Topup = () => {
return (
<Grid container spacing={2}>
<Grid xs={12}>
<Alert severity="warning">
充值记录以及邀请记录请在日志中查询充值记录请在日志中选择类型充值查询邀请记录请在日志中选择系统查询{' '}
</Alert>
</Grid>
<Grid xs={12} md={6} lg={8}>
<Stack spacing={2}>
<TopupCard />
</Stack>
</Grid>
<Grid xs={12} md={6} lg={4}>
<InviteCard />
</Grid>
</Grid>
);
};
export default Topup;