fixes of bugs, loading animation, add max storage
This commit is contained in:
parent
26633b4b55
commit
86d3e9bbf4
BIN
frontend/.DS_Store
vendored
BIN
frontend/.DS_Store
vendored
Binary file not shown.
BIN
frontend/public/.DS_Store
vendored
BIN
frontend/public/.DS_Store
vendored
Binary file not shown.
BIN
frontend/src/.DS_Store
vendored
BIN
frontend/src/.DS_Store
vendored
Binary file not shown.
|
@ -32,6 +32,7 @@ function AppComponent() {
|
|||
<Route path='/referral' element={<RoutePage page='referral' />} />
|
||||
<Route path='/auction' element={<RoutePage page='auction' />} />
|
||||
<Route path='/styles' element={<RoutePage page='styles' />} />
|
||||
<Route path='/dev' element={<RoutePage page='dev' />} />
|
||||
<Route path='*' element={<RoutePage page='main' />} />
|
||||
</Routes>
|
||||
<AuctionMainPopups />
|
||||
|
|
BIN
frontend/src/assets/.DS_Store
vendored
Normal file
BIN
frontend/src/assets/.DS_Store
vendored
Normal file
Binary file not shown.
|
@ -83,6 +83,7 @@
|
|||
--grey9A: #9A9A9A;
|
||||
--grey93: #939393;
|
||||
--grey1F: #1F1F1F;
|
||||
--grey27: #272727;
|
||||
}
|
||||
|
||||
body {
|
||||
|
@ -98,6 +99,7 @@ body {
|
|||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
p, h1, h2, h3 {
|
||||
|
|
|
@ -5,10 +5,11 @@ import { ClickerPopup } from '../ClickerPopup';
|
|||
import { getGradient } from '../../../utils/getGradient';
|
||||
import { useAppSelector } from '../../hooks/useAppSelector';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { updateCoinsRequestAsync } from '../../../store/me/actions';
|
||||
import { updateEnergyRequestAsync } from '../../../store/me/actions';
|
||||
import axios from 'axios';
|
||||
import { DevPopup } from '../../Elements/DevPopup';
|
||||
import { saveMult } from '../../../store/mult';
|
||||
import { Spinner } from '../../Elements/Spinner';
|
||||
|
||||
interface IClickerBtn {
|
||||
coins: number,
|
||||
|
@ -17,7 +18,7 @@ interface IClickerBtn {
|
|||
setMult(a: number): void
|
||||
}
|
||||
|
||||
export function ClickerBtn({ coins, setCoins, energy, setMult }: IClickerBtn) {
|
||||
export function ClickerBtn({ setCoins, energy, setMult, coins }: IClickerBtn) {
|
||||
const urlClick = useAppSelector<string>(state => state.urlClick);
|
||||
const token = useAppSelector<string>(state => state.token);
|
||||
const [fill, setFill] = useState(0);
|
||||
|
@ -35,6 +36,7 @@ export function ClickerBtn({ coins, setCoins, energy, setMult }: IClickerBtn) {
|
|||
const [error, setError] = useState(false);
|
||||
const [animClose, setAnimClose] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const savedEnergy = sessionStorage.getItem('eg');
|
||||
|
@ -45,6 +47,12 @@ export function ClickerBtn({ coins, setCoins, energy, setMult }: IClickerBtn) {
|
|||
setFill((maxEnergy - initEnergy) / maxEnergy * 100);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (initEnergy === 0 || fill === 100) {
|
||||
setCloseError(true);
|
||||
}
|
||||
}, [initEnergy, fill]);
|
||||
|
||||
useEffect(() => {
|
||||
setGradient(getGradient())
|
||||
}, [styleIndex]);
|
||||
|
@ -58,7 +66,8 @@ export function ClickerBtn({ coins, setCoins, energy, setMult }: IClickerBtn) {
|
|||
};
|
||||
|
||||
const sendClick = () => {
|
||||
if(token) {
|
||||
if (token && !loading) {
|
||||
setLoading(true);
|
||||
axios.post(`${urlClick}/api/v1/click/`,
|
||||
{},
|
||||
{
|
||||
|
@ -69,6 +78,7 @@ export function ClickerBtn({ coins, setCoins, energy, setMult }: IClickerBtn) {
|
|||
).then((resp) => {
|
||||
//console.log(resp);
|
||||
if(resp.data) {
|
||||
setLoading(false);
|
||||
const click = Number(resp.data.click.value);
|
||||
//
|
||||
const encodeMult = btoa(click.toString());
|
||||
|
@ -80,7 +90,7 @@ export function ClickerBtn({ coins, setCoins, energy, setMult }: IClickerBtn) {
|
|||
const newFill = (maxEnergy - newEnergy) / maxEnergy * 100;
|
||||
if (newFill <= 100) {
|
||||
const newCoins = Number(coins + click);
|
||||
dispatch<any>(updateCoinsRequestAsync(newCoins, newEnergy))
|
||||
dispatch<any>(updateEnergyRequestAsync(newEnergy))
|
||||
setCoins(newCoins);
|
||||
setEnergy(newEnergy)
|
||||
setFill(newFill);
|
||||
|
@ -104,6 +114,7 @@ export function ClickerBtn({ coins, setCoins, energy, setMult }: IClickerBtn) {
|
|||
setError(false)
|
||||
}
|
||||
}).catch((err) => {
|
||||
setLoading(false);
|
||||
setCloseError(false);
|
||||
setError(true);
|
||||
console.log(err);
|
||||
|
@ -120,7 +131,7 @@ export function ClickerBtn({ coins, setCoins, energy, setMult }: IClickerBtn) {
|
|||
},
|
||||
{
|
||||
title: 'Как продолжить кликать',
|
||||
text: <span>Чтобы охладиться, нужно нужно закрыть приложение, нажав по кнопке ниже.</span>,
|
||||
text: <span>Чтобы охладиться, нужно закрыть приложение, нажав по кнопке ниже.</span>,
|
||||
img: 'assets/Monocle.png'
|
||||
},
|
||||
{
|
||||
|
@ -133,7 +144,8 @@ export function ClickerBtn({ coins, setCoins, energy, setMult }: IClickerBtn) {
|
|||
return (
|
||||
<div className={styles.ringContainer}>
|
||||
<div className={`${styles.ringBig} ${fill === 100 && styles.borderNone}`}></div>
|
||||
<div className={`${styles.ringSmall} ${fill === 100 && styles.borderNone}`} style={{ backgroundImage: `url(${img})`, backgroundSize: `${size}px` }} onClick={btnClick}></div>
|
||||
{!loading && <div className={`${styles.ringSmall} ${fill === 100 && styles.borderNone}`} style={{ backgroundImage: `url(${img})`, backgroundSize: `${size}px` }} onClick={btnClick}></div>}
|
||||
{loading && <div className={styles.loadingContainer}> <Spinner size='50px' thickness='10px' color='var(--primary)'/> </div> }
|
||||
<svg className={styles.svg} width="270" height="270" viewBox="0 0 270 270" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="135" cy="135" r="125" stroke={fill < 100 ? "url(#paint0_linear_619_10702)" : '#FF0000'} strokeWidth="20" strokeLinecap="round" style={{ strokeDasharray: `${dashArray} ${circumference}` }} />
|
||||
<defs>
|
||||
|
@ -144,7 +156,7 @@ export function ClickerBtn({ coins, setCoins, energy, setMult }: IClickerBtn) {
|
|||
<ClickerPopup title='Кнопка перегрелась' cards={hotCards} setClose={setClose} isBtn={true}/>
|
||||
} />}
|
||||
{!closeError && <ModalWindow removeBtn={true} setCloseAnimOut={setAnimClose} closeAnimOut={animClose} setClose={setCloseError} modalBlock={
|
||||
<DevPopup setClose={setAnimClose} type='error'/>
|
||||
<DevPopup setClose={setAnimClose} title='Возникла ошибка' text='Мы пока не можем принимать клики, но скоро всё починим.'/>
|
||||
} />}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -67,3 +67,20 @@
|
|||
.borderNone {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.loadingContainer {
|
||||
user-select: none;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: var(--grey27);
|
||||
width: 230px;
|
||||
height: 230px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
border: 2px solid var(--white);
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
background-color: rgba(0, 0, 0, 0.6);*/
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.content {
|
||||
|
|
|
@ -3,25 +3,18 @@ import styles from './clickerfooter.module.css';
|
|||
import { ClickerBtnFooter } from '../ClickerBtnFooter';
|
||||
import { EIcons, Icon } from '../../Icons';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { ModalWindow } from '../../ModalWindow';
|
||||
import { DevPopup } from '../../Elements/DevPopup';
|
||||
|
||||
export function ClickerFooter() {
|
||||
const navigate = useNavigate();
|
||||
const [closeAnimOut, setCloseAnimOut] = useState(false);
|
||||
const [closeDev, setCloseDev] = useState(true);
|
||||
const isDev = true;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<ClickerBtnFooter text='Стили' className={styles.btn} onClick={() => navigate('/styles')}/>
|
||||
<ClickerBtnFooter text='Аукцион' className={styles.btn} onClick={() => { !isDev ? navigate('/auction') : setCloseDev(false) }}/>
|
||||
<ClickerBtnFooter text='Аукцион' className={styles.btn} onClick={() => { !isDev ? navigate('/auction') : navigate('/dev?type=auction') }}/>
|
||||
{ !isDev && <div className={styles.fire}>
|
||||
<Icon icon={EIcons.FireIcon}/>
|
||||
</div>}
|
||||
{!closeDev && <ModalWindow removeBtn={true} setCloseAnimOut={setCloseAnimOut} closeAnimOut={closeAnimOut} setClose={setCloseDev} modalBlock={
|
||||
<DevPopup setClose={setCloseAnimOut} type='dev' />
|
||||
} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,33 +3,42 @@ import styles from './pointszoom.module.css';
|
|||
import { formatNumber } from '../../../utils/formatNumber';
|
||||
import { ETextStyles } from '../../texts';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { updatePointsRequestAsync } from '../../../store/me/actions';
|
||||
import { checkIOS } from '../../../utils/checkMobile';
|
||||
|
||||
interface IPointsZoom {
|
||||
points: number,
|
||||
setClose(a:boolean): void,
|
||||
className ?: string,
|
||||
closePointsAnim: boolean,
|
||||
setClosePointsAnim(a: boolean): void
|
||||
setClosePointsAnim(a: boolean): void,
|
||||
setCoins(a:number):void
|
||||
}
|
||||
|
||||
export function PointsZoom({ points, setClose, className, closePointsAnim, setClosePointsAnim }: IPointsZoom) {
|
||||
export function PointsZoom({ points, setClose, setCoins, className, closePointsAnim, setClosePointsAnim }: IPointsZoom) {
|
||||
const [open, setOpen] = useState(true);
|
||||
const node = document.querySelector('#modal_root');
|
||||
if (!node) return null;
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
setOpen(false);
|
||||
clearInterval(timer);
|
||||
}, 400);
|
||||
|
||||
console.log(checkIOS())
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (closePointsAnim) {
|
||||
dispatch<any>(updatePointsRequestAsync());
|
||||
const timer = setTimeout(() => {
|
||||
setClosePointsAnim(false);
|
||||
setClose(true);
|
||||
clearTimeout(timer);
|
||||
setCoins(0);
|
||||
}, 400);
|
||||
}
|
||||
}, [closePointsAnim]);
|
||||
|
@ -37,9 +46,9 @@ export function PointsZoom({ points, setClose, className, closePointsAnim, setCl
|
|||
return (
|
||||
<div className={`${styles.container} ${className} ${open ? styles.animBack : ''} ${closePointsAnim ? styles.animBackClose : ''}`}>
|
||||
{ReactDOM.createPortal((
|
||||
<div className={`${styles.innerContainer} ${open ? styles.animBlock : ''} ${closePointsAnim ? styles.animBlockClose : ''}`}>
|
||||
<div className={`${styles.innerContainer} ${open ? styles.animBlock : ''} ${closePointsAnim ? styles.animBlockClose : ''} ${checkIOS() && styles.ios}`}>
|
||||
<div className={styles.icon} style={{ backgroundImage: `url('assets/btnIcon.png')` }}></div>
|
||||
<p className={styles.point} style={ETextStyles.InSb18100}>{formatNumber(Number(points.toFixed(2)))}</p>
|
||||
<p className={styles.point} style={ETextStyles.InSb18100}>{`+${formatNumber(Number(points.toFixed(2)))}`}</p>
|
||||
</div>
|
||||
), node)}
|
||||
</div>
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
box-shadow: 0px 0px 30px 15px rgba(128, 135, 192, 0.25);
|
||||
}
|
||||
|
||||
.ios {
|
||||
top: 40px !important;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
|
|
@ -4,25 +4,30 @@ import { ETextStyles } from '../../texts';
|
|||
import { formatNumber } from '../../../utils/formatNumber';
|
||||
import { PersonIcon } from '../../Elements/PersonIcon';
|
||||
import { EIcons, Icon } from '../../Icons';
|
||||
import { useAppSelector } from '../../hooks/useAppSelector';
|
||||
import { Spinner } from '../../Elements/Spinner';
|
||||
|
||||
interface IProfileClicker {
|
||||
name: string,
|
||||
points: number,
|
||||
img: string,
|
||||
className ?: string
|
||||
}
|
||||
|
||||
export function Profile({ name, points, img, className }: IProfileClicker) {
|
||||
export function Profile({ name, img, className }: IProfileClicker) {
|
||||
const points = useAppSelector<string | undefined>(state => state.me.data.points);
|
||||
const loading = useAppSelector<boolean>(state => state.me.loading);
|
||||
|
||||
return (
|
||||
<div className={`${styles.container} ${className}`}>
|
||||
{img ? <PersonIcon img={`${img}`} size={30}/> : <div className={styles.emptyIcon}><Icon icon={EIcons.ProfileIcon}/></div> }
|
||||
{img ? <PersonIcon img={`${img}`} size={30} /> : <Icon icon={EIcons.ProfileIcon} /> }
|
||||
<div className={styles.content}>
|
||||
<p style={ETextStyles.RwSb12120} className={styles.name}>{name}</p>
|
||||
<div className={styles.pointsContainer}>
|
||||
<p className={styles.points} style={ETextStyles.InSb10120}>
|
||||
{formatNumber(Number(points.toFixed(2)))}
|
||||
</p>
|
||||
<div className={styles.icon} style={{ backgroundImage: "url('assets/btnIcon.png')"}}></div>
|
||||
{points && <p className={styles.points} style={ETextStyles.InSb10120}>
|
||||
{formatNumber(Number(Number(points).toFixed(2)))}
|
||||
</p>}
|
||||
{!loading && <div className={styles.icon} style={{ backgroundImage: "url('assets/btnIcon.png')"}}></div>}
|
||||
{loading && <Spinner size='14px' color='#FFFFFF' thickness='2px' />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import styles from './sectionsblock.module.css';
|
||||
import { CardSection } from '../../Elements/CardSection';
|
||||
import { ETextStyles } from '../../texts';
|
||||
|
@ -8,30 +8,40 @@ import { ClickerPopup } from '../ClickerPopup';
|
|||
import { useNavigate } from 'react-router-dom';
|
||||
import { UsersIcons } from '../../Elements/UsersIcons';
|
||||
import { formatNumber } from '../../../utils/formatNumber';
|
||||
import { DevPopup } from '../../Elements/DevPopup';
|
||||
import { useAppSelector } from '../../hooks/useAppSelector';
|
||||
|
||||
interface ISectionsBlock {
|
||||
mult:number;
|
||||
}
|
||||
|
||||
export function SectionsBlock({ mult }: ISectionsBlock) {
|
||||
const scaleRef = 70;
|
||||
const [close, setClose] = useState(true);
|
||||
const navigate = useNavigate();
|
||||
const [closeAnimOut, setCloseAnimOut] = useState(false);
|
||||
const [closeDev, setCloseDev] = useState(true);
|
||||
const referralStorage = Number(useAppSelector<string | undefined>(state => state.me.data.referralStorage));
|
||||
//const referralStorage = 500;
|
||||
const maxReferralStorage = useAppSelector<number>(state => state.me.data.maxStorage);
|
||||
const [referralPercent, serReferralPercent] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if(referralStorage >= maxReferralStorage) {
|
||||
serReferralPercent(100);
|
||||
} else {
|
||||
serReferralPercent(referralStorage / maxReferralStorage * 100);
|
||||
}
|
||||
|
||||
}, [referralStorage, maxReferralStorage]);
|
||||
|
||||
const isDev = true;
|
||||
|
||||
const multipCards = [
|
||||
{
|
||||
title: 'Что он делает',
|
||||
text: <span>Увеличивает получение баллов с одного клика в столько раз, сколько указано в рамке внизу экрана.</span>,
|
||||
text: <span>Увеличивает получение баллов с одного клика в столько раз, сколько указано в рамке.</span>,
|
||||
img: 'assets/Rocket.png'
|
||||
},
|
||||
{
|
||||
title: 'Как его увеличить',
|
||||
text: <span>Чем выше концентрация — клики в час, тем выше мультипликатор, он рассчитывается по формуле.</span>,
|
||||
text: <span>Чем выше концентрация — клики в час, тем выше множитель, он рассчитывается по формуле.</span>,
|
||||
img: 'assets/Monocle.png'
|
||||
},
|
||||
{
|
||||
|
@ -44,7 +54,7 @@ export function SectionsBlock({ mult }: ISectionsBlock) {
|
|||
return (
|
||||
<div className={styles.sectionContainer}>
|
||||
<div className={styles.leftContainer}>
|
||||
<CardSection title='Место в топе' onClick={() => {!isDev ? navigate('/rating') : setCloseDev(false)}}>
|
||||
<CardSection title='Место в топе' onClick={() => {!isDev ? navigate('/rating') : navigate('/dev?type=rating')}}>
|
||||
{<div className={`${styles.bottomRank} ${isDev ? styles.dev : ''}`}>
|
||||
<div style={ETextStyles.InSb12120}>
|
||||
<span className={styles.rank1}>#</span>
|
||||
|
@ -61,22 +71,19 @@ export function SectionsBlock({ mult }: ISectionsBlock) {
|
|||
</CardSection>
|
||||
</div>
|
||||
<CardSection title='Реферальное хранилище' className={styles.rigthEl} onClick={() => { navigate('/referral') }}>
|
||||
{<div className={isDev ? styles.dev : ''}>
|
||||
<PointsBlock points={formatNumber(800)} className={styles.scalePoints} />
|
||||
{<div>
|
||||
<PointsBlock points={formatNumber(referralStorage.toFixed(2))} className={styles.scalePoints} />
|
||||
<div className={styles.scaleContainer}>
|
||||
<div className={styles.scale} style={{ width: `${scaleRef}px` }}></div>
|
||||
<div className={`${styles.scale} ${referralPercent === 100 ? styles.scaleFull : ''}`} style={{ width: `${referralPercent}%` }}></div>
|
||||
</div>
|
||||
<p className={styles.scaleText}>
|
||||
Хранилище заполнено, заберите коины
|
||||
<p className={`${styles.scaleText} ${referralPercent === 100 ? styles.textFull : ''}`}>
|
||||
{referralPercent === 100 ? 'Хранилище заполнено, заберите коины' : 'Когда хранилище заполнится, вы сможете забрать баллы'}
|
||||
</p>
|
||||
</div>}
|
||||
</CardSection>
|
||||
{!close && <ModalWindow setCloseAnimOut={setClose} setClose={setClose} modalBlock={
|
||||
<ClickerPopup title='Что такое множитель' cards={multipCards} setClose={setClose}/>
|
||||
} />}
|
||||
{!closeDev && <ModalWindow removeBtn={true} setCloseAnimOut={setCloseAnimOut} closeAnimOut={closeAnimOut} setClose={setCloseDev} modalBlock={
|
||||
<DevPopup setClose={setCloseAnimOut} type='dev' />
|
||||
} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -48,6 +48,10 @@
|
|||
color: var(--grey6C);
|
||||
}
|
||||
|
||||
.textFull {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.scale {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
@ -56,6 +60,10 @@
|
|||
background: var(--primary);
|
||||
}
|
||||
|
||||
.scaleFull {
|
||||
background: var(--purple);
|
||||
}
|
||||
|
||||
.dev {
|
||||
position: relative;
|
||||
}
|
||||
|
|
|
@ -5,18 +5,19 @@ import { ETextStyles } from '../../texts';
|
|||
|
||||
interface IDevPopup {
|
||||
setClose(a: boolean): void
|
||||
type: 'error' | 'dev'
|
||||
title: string,
|
||||
text: string,
|
||||
}
|
||||
|
||||
export function DevPopup({ setClose, type }: IDevPopup) {
|
||||
export function DevPopup({ setClose, title, text }: IDevPopup) {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.iconContainer}>
|
||||
<div className={styles.icon} style={{backgroundImage: "url('assets/dev.png')"}}></div>
|
||||
<div className={styles.icon} style={{backgroundImage: "url('assets/programming.gif')"}}></div>
|
||||
</div>
|
||||
<h2 className={styles.title} style={ETextStyles.RwSb24100}>{type === 'dev' ? 'Скоро откроем' : 'Возникла ошибка'}</h2>
|
||||
<p className={styles.text} style={ETextStyles.RwSb14120}>{type === 'dev' ? <span>Подготавливаем что-то особенное для вас. Скоро увидимся на новом уровне!</span> : 'Мы пока не можем принимать клики, но скоро всё починим.'}</p>
|
||||
<Button text={type === 'dev' ? 'Продолжить кликать' : 'Принято'} onClick={() => setClose(true)}/>
|
||||
<h2 className={styles.title} style={ETextStyles.RwSb24100}>{title}</h2>
|
||||
<p className={styles.text} style={ETextStyles.RwSb14120}>{text}</p>
|
||||
<Button text='Принято' onClick={() => setClose(true)}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ export const StylesSwiper: React.FC<IStylesSwiper> = memo(({ selectedStyle, setC
|
|||
return (
|
||||
<div
|
||||
ref={(el) => (slideRefs.current[index] = el as HTMLDivElement)}
|
||||
className={`${styles.card} ${cardStyle} ${selectedStyle === index && styles.selected} ${index > 0 && styles.disabled}`}
|
||||
className={`${styles.card} ${cardStyle} ${selectedStyle === index && styles.selected}`}
|
||||
style={{
|
||||
transform: `rotate(${isActive ? 0 : deg}deg)`,
|
||||
filter: `blur(${isActive ? 0 : 3}px)`
|
||||
|
|
|
@ -7,7 +7,6 @@ import { SectionsBlock } from '../../Clicker/SectionsBlock';
|
|||
import { ClickerFooter } from '../../Clicker/ClickerFooter';
|
||||
import { StyleElements } from '../../Clicker/StyleElements';
|
||||
import { PointsZoom } from '../../Clicker/PointsZoom';
|
||||
import { Timer } from '../../Auction/Timer';
|
||||
import { useWindowSize } from 'usehooks-ts';
|
||||
import { useAppSelector } from '../../hooks/useAppSelector';
|
||||
|
||||
|
@ -20,7 +19,7 @@ interface IClickerPageInterface {
|
|||
|
||||
export function ClickerPage({ name, points, img, energy }: IClickerPageInterface) {
|
||||
const styleIndex = Number(localStorage.getItem('selectedStyle'));
|
||||
const [coins, setCoins] = useState(points);
|
||||
const [coins, setCoins] = useState(0);
|
||||
const [mult, setMult] = useState(1);
|
||||
const [closePoints, setClosePoints] = useState(true);
|
||||
const [closePointsAnim, setClosePointsAnim] = useState(false);
|
||||
|
@ -35,7 +34,7 @@ export function ClickerPage({ name, points, img, energy }: IClickerPageInterface
|
|||
//@ts-ignore
|
||||
let timer;
|
||||
|
||||
if (points !== coins) {
|
||||
if (points !== coins && coins != 0) {
|
||||
setClosePoints(false);
|
||||
timer = setTimeout(() => {
|
||||
setClosePointsAnim(true);
|
||||
|
@ -50,8 +49,8 @@ export function ClickerPage({ name, points, img, energy }: IClickerPageInterface
|
|||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.records}>
|
||||
{!closePoints && <PointsZoom points={coins} setClosePointsAnim={setClosePointsAnim} setClose={setClosePoints} className={styles.pointsAnim} closePointsAnim={closePointsAnim}/>}
|
||||
<Profile name={name} points={coins} className={styles.profile} img={img}/>
|
||||
{!closePoints && <PointsZoom setCoins={setCoins} points={coins} setClosePointsAnim={setClosePointsAnim} setClose={setClosePoints} className={styles.pointsAnim} closePointsAnim={closePointsAnim}/>}
|
||||
<Profile name={name} className={styles.profile} img={img}/>
|
||||
<h1 style={ETextStyles.RwSb24100} className={styles.title}>Мои рекорды</h1>
|
||||
<SectionsBlock mult={mult}/>
|
||||
</div>
|
||||
|
|
39
frontend/src/shared/Pages/DevPage/DevPage.tsx
Normal file
39
frontend/src/shared/Pages/DevPage/DevPage.tsx
Normal file
|
@ -0,0 +1,39 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import styles from './devpage.module.css';
|
||||
import { ETextStyles } from '../../texts';
|
||||
import { Button } from '../../Button';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
|
||||
export function DevPage() {
|
||||
const [type, setType] = useState('');
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
const currentUrl = new URL(window.location.href);
|
||||
const typeURL = currentUrl.searchParams.get("type");
|
||||
if (typeURL)
|
||||
setType(typeURL)
|
||||
}, []);
|
||||
|
||||
|
||||
const icons = ['assets/shopping.png', 'assets/compass.png', 'assets/friends.png'];
|
||||
const titles = ['Упаковываем товары!', 'Рейтинг игроков формируется', 'Рейтинг друзей формируется'];
|
||||
const texts = [
|
||||
'Собираем подборку самых желанных подарков для тебя! Копи баллы, чтобы выигрывать в аукционах!',
|
||||
'Рейтинг откроется, когда накопится достаточное количество пользователей.',
|
||||
'Рейтинг откроется, когда накопится достаточное количество пользователей.'
|
||||
]
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.innerContainer}>
|
||||
<div className={styles.iconContainer}>
|
||||
<div className={styles.icon} style={{ backgroundImage: `url(${type === 'auction' ? icons[0] : (type === 'rating' ? icons[1] : icons[2])})` }}></div>
|
||||
</div>
|
||||
<h1 style={ETextStyles.RwSb26100} className={styles.title}>{type === 'auction' ? titles[0] : (type === 'rating' ? titles[1] : titles[2])}</h1>
|
||||
<p className={styles.descr} style={ETextStyles.InRg16130}>{type === 'auction' ? texts[0] : (type === 'rating' ? texts[1] : texts[2])}</p>
|
||||
<Button text='Продолжить кликать' onClick={() => navigate('/')}/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
38
frontend/src/shared/Pages/DevPage/devpage.module.css
Normal file
38
frontend/src/shared/Pages/DevPage/devpage.module.css
Normal file
|
@ -0,0 +1,38 @@
|
|||
.container {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.innerContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.iconContainer {
|
||||
margin-bottom: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.descr {
|
||||
margin-bottom: 24px;
|
||||
text-align: center;
|
||||
}
|
1
frontend/src/shared/Pages/DevPage/index.ts
Normal file
1
frontend/src/shared/Pages/DevPage/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export * from './DevPage';
|
|
@ -13,6 +13,7 @@ import { Spinner } from '../../Elements/Spinner';
|
|||
import { updateBackground } from '../../../utils/updateBackground';
|
||||
import { ErrorPage } from '../ErrorPage';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { DevPage } from '../DevPage';
|
||||
|
||||
interface IRoutePage {
|
||||
page: string
|
||||
|
@ -44,11 +45,12 @@ export function RoutePage({ page }: IRoutePage) {
|
|||
<div>
|
||||
{!verified ? <WrongSourcePage /> : <div>
|
||||
{ //@ts-ignore
|
||||
page === 'main' && !loadingUser && !errorUser && dataUser.name && <ClickerPage name={dataUser.name} points={Number(dataUser.points)} img={dataUser.avatar} energy={Number(dataUser.energy)}/>}
|
||||
{page === 'rating' && !loadingUser && !errorUser && <RatingPage />}
|
||||
{page === 'referral' && !loadingUser && !errorUser && <StoragePage />}
|
||||
{page === 'auction' && !loadingUser && !errorUser && <AuctionPage />}
|
||||
{page === 'styles' && !loadingUser && !errorUser && <StylesPage />}
|
||||
page === 'main' && (!loadingUser || dataUser.username) && !errorUser && dataUser.name && <ClickerPage name={dataUser.name} points={Number(dataUser.points)} img={dataUser.avatar} energy={Number(dataUser.energy)}/>}
|
||||
{page === 'rating' && (!loadingUser || dataUser.username) && !errorUser && <RatingPage />}
|
||||
{page === 'referral' && (!loadingUser || dataUser.username) && !errorUser && <StoragePage />}
|
||||
{page === 'auction' && (!loadingUser || dataUser.username) && !errorUser && <AuctionPage />}
|
||||
{page === 'styles' && (!loadingUser || dataUser.username) && !errorUser && <StylesPage />}
|
||||
{page === 'dev' && <DevPage/>}
|
||||
{(loadingUser) && <div className={styles.spinnerContainer}><Spinner color='#FFFFFF' size='50px' thickness='6px' className={styles.spinner} /></div> }
|
||||
{errorUser && !loadingUser && <ErrorPage detail={errorUser}/>}
|
||||
</div>}
|
||||
|
|
|
@ -9,16 +9,14 @@ import { Notification } from '../../Notification';
|
|||
import { StoragePageBlock } from '../../Storage/StoragePageBlock';
|
||||
import { FriendsPageBlock } from '../../Storage/FriendsPageBlock';
|
||||
import { useAppSelector } from '../../hooks/useAppSelector';
|
||||
import { DevPopup } from '../../Elements/DevPopup';
|
||||
import { ModalWindow } from '../../ModalWindow';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
export function StoragePage() {
|
||||
const userId = useAppSelector<string>(state => state.userTg.id);
|
||||
const [page, setPage] = useState('storage');
|
||||
const refLink = `https://t.me/sapphirecrown_bot?start=user_${userId}`;
|
||||
const [showNotif, setShow] = useState(false);
|
||||
const [closeAnimOut, setCloseAnimOut] = useState(false);
|
||||
const [closeDev, setCloseDev] = useState(true);
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -26,7 +24,7 @@ export function StoragePage() {
|
|||
<div className={styles.btnGroup}>
|
||||
<StorageBtn active={page === 'storage'} type={'storage'} onClick={() => setPage('storage')}/>
|
||||
<StorageBtn isDev={true} active={page === 'friends'} type={'friends'} onClick={() => {
|
||||
setCloseDev(false);
|
||||
navigate('/dev?type=friends')
|
||||
//setPage('friends')
|
||||
}
|
||||
} />
|
||||
|
@ -34,9 +32,6 @@ export function StoragePage() {
|
|||
{page === 'storage' ? <StoragePageBlock/> : <FriendsPageBlock/>}
|
||||
<Button className={styles.btn} icon={<Icon icon={EIcons.CopyIcon} />} text='Пригласить друга' onClick={() => { сopyTextToClipboard(refLink); setShow(true)}}/>
|
||||
{showNotif && <Notification title='Успешно' text='Пригласительная ссылка скопирована' setShow={setShow} />}
|
||||
{!closeDev && <ModalWindow removeBtn={true} setCloseAnimOut={setCloseAnimOut} closeAnimOut={closeAnimOut} setClose={setCloseDev} modalBlock={
|
||||
<DevPopup setClose={setCloseAnimOut} type='dev' />
|
||||
} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,10 +11,8 @@ export function StylesPage() {
|
|||
const [selectedStyle, setSelectedStyle] = useState(selectedIndex ? selectedIndex : 0);
|
||||
const [currentSlide, setCurrentSlide] = useState(0);
|
||||
const [showNotif, setShow] = useState(false);
|
||||
const isDev = true;
|
||||
|
||||
//const stylesNames = ['Черно-синий', 'Grapefruit', 'Tropic mamba', 'Mamba & Grapefruit'];
|
||||
const stylesNames = ['Черно-синий', 'Скоро будет доступен', 'Скоро будет доступен', 'Скоро будет доступен'];
|
||||
const stylesNames = ['Черно-синий', 'Grapefruit', 'Tropic mamba', 'Mamba & Grapefruit'];
|
||||
const colors = ['#7EB4DB', '#FE744B', '#F2D06B', '#EA9C55'];
|
||||
const gradients = ['linear-gradient(90deg, #90D7ED 13.05%, #6887C4 91.06%, #8085C0 172.24%)', 'linear-gradient(302deg, #FF5421 -59.57%, #FF7248 43.7%, #FF9576 163.26%)', 'linear-gradient(302deg, #6ACB54 -59.57%, #DCBB5A 43.7%, #E2883D 163.26%)', 'linear-gradient(302deg, #FF805A -1.15%, #DEAE53 83.89%)'];
|
||||
|
||||
|
@ -57,7 +55,7 @@ export function StylesPage() {
|
|||
<span>Будь круче —</span> будь на стиле!</h1>
|
||||
<StylesSwiper selectedStyle={selectedStyle} setCurrentSlide={setCurrentSlide}/>
|
||||
<p style={ETextStyles.RwSb16120} className={styles.styleName}>{stylesNames[currentSlide]}</p>
|
||||
{!isDev && <Button onClick={selectStyle} disabled={currentSlide === selectedStyle} text={currentSlide === selectedStyle ? 'Уже выбран' : 'Выбрать этот стиль'} className={styles.btn}/>}
|
||||
<Button onClick={selectStyle} disabled={currentSlide === selectedStyle} text={currentSlide === selectedStyle ? 'Уже выбран' : 'Выбрать этот стиль'} className={styles.btn}/>
|
||||
{showNotif && <Notification title={`Стиль ${stylesNames[selectedStyle]} выбран`} text='Можете вернуться на главную, чтобы увидеть изменения' setShow={setShow} />}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,33 +1,38 @@
|
|||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import styles from './storagepageblock.module.css';
|
||||
import { StorageScale } from '../StorageScale';
|
||||
import { ETextStyles } from '../../texts';
|
||||
import { PopupCard } from '../../Elements/PopupCard';
|
||||
import { ModalWindow } from '../../ModalWindow';
|
||||
import { DevPopup } from '../../Elements/DevPopup';
|
||||
import { useAppSelector } from '../../hooks/useAppSelector';
|
||||
|
||||
export function StoragePageBlock() {
|
||||
const [closeAnimOut, setCloseAnimOut] = useState(false);
|
||||
const [closeDev, setCloseDev] = useState(true);
|
||||
const isDev = true;
|
||||
const referralStorage = Number(useAppSelector<string | undefined>(state => state.me.data.referralStorage));
|
||||
const maxReferralStorage = useAppSelector<number>(state => state.me.data.maxStorage);
|
||||
const [referralPercent, serReferralPercent] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (referralStorage > maxReferralStorage) {
|
||||
serReferralPercent(100);
|
||||
} else {
|
||||
serReferralPercent(referralStorage / maxReferralStorage * 100);
|
||||
}
|
||||
|
||||
}, [referralStorage, maxReferralStorage]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2 style={ETextStyles.RwSb18120} className={styles.title}>Хранилище</h2>
|
||||
<div className={`${styles.containerStorage}`} onClick={() => setCloseDev(false)}>
|
||||
<StorageScale points='0' percent={0} className={styles.scale} isDev={true}/>
|
||||
{!isDev && <p style={ETextStyles.RwRg10120} className={styles.descr}>
|
||||
В хранилище приходит часть коинов, заработанная вашими друзьями. Считаем так: количество коинов * 5%. Хранилище пополняется каждый вечер.
|
||||
</p>}
|
||||
{isDev && <div style={{height: '30px'}}></div> }
|
||||
<div className={`${styles.containerStorage}`}>
|
||||
<StorageScale points={referralStorage.toString()} percent={referralPercent} className={styles.scale}/>
|
||||
<p style={ETextStyles.RwRg10120} className={styles.descr}>
|
||||
В хранилище приходит часть коинов, заработанных вашими друзьями. Считаем так: количество коинов * 5%. Хранилище пополняется каждый вечер.
|
||||
</p>
|
||||
</div>
|
||||
<h2 style={ETextStyles.RwSb18120} className={styles.title}>Как пригласить друга?</h2>
|
||||
<div className={styles.cards}>
|
||||
<PopupCard img='assets/Chain.png' title='Отправляй ссылку другу' text={<span>Друг присоединяется по пригласительной ссылке и становится рефералом, как только совершает активность в приложении.</span>} />
|
||||
<PopupCard img='assets/Money.png' title='Зарабатывайте вместе' text={<span>Друг кликает, ты получаешь 5% его кликов, а он 3% с твоих. Не забывай забирать коины из хранилища!</span>} />
|
||||
<PopupCard img='assets/Money.png' title='Зарабатывайте вместе' text={<span>Друг кликает, ты получаешь 5% его кликов, а он — 3% с твоих. Не забывай забирать коины из хранилища!</span>} />
|
||||
</div>
|
||||
{!closeDev && <ModalWindow removeBtn={true} setCloseAnimOut={setCloseAnimOut} closeAnimOut={closeAnimOut} setClose={setCloseDev} modalBlock={
|
||||
<DevPopup setClose={setCloseAnimOut} type='dev' />
|
||||
} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import styles from './storagescale.module.css';
|
||||
import { PointsBlock } from '../../Elements/PointsBlock';
|
||||
import { ETextStyles } from '../../texts';
|
||||
import { Notification } from '../../Notification';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { emptyReferralStorage } from '../../../store/me/actions';
|
||||
import { useAppSelector } from '../../hooks/useAppSelector';
|
||||
import axios from 'axios';
|
||||
import { ModalWindow } from '../../ModalWindow';
|
||||
import { DevPopup } from '../../Elements/DevPopup';
|
||||
|
||||
interface IStorageScale {
|
||||
percent: number,
|
||||
|
@ -13,26 +19,54 @@ interface IStorageScale {
|
|||
|
||||
export function StorageScale({ percent, points, className, isDev=false }: IStorageScale) {
|
||||
const [showNotif, setShow] = useState(false);
|
||||
const [initpercent, setPercent] = useState(percent);
|
||||
const [savedPoints, setSavedPoints] = useState(points);
|
||||
const URL = useAppSelector<string>(state => state.url);
|
||||
const token = useAppSelector<string>(state => state.token);
|
||||
const [closeError, setCloseError] = useState(true);
|
||||
const [error, setError] = useState(false);
|
||||
const [animClose, setAnimClose] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const click = () => {
|
||||
if(percent === 100) {
|
||||
setShow(true);
|
||||
setPercent(0);
|
||||
setError(false);
|
||||
|
||||
if(token) {
|
||||
axios.post(`${URL}/api/v1/users/empty-storage/`,
|
||||
{},
|
||||
{
|
||||
headers: {
|
||||
"Authorization": `TelegramToken ${token}`
|
||||
}
|
||||
}
|
||||
).then(resp => {
|
||||
if (!error) {
|
||||
setShow(true);
|
||||
dispatch<any>(emptyReferralStorage());
|
||||
//console.log(resp);
|
||||
}
|
||||
}).catch(err => {
|
||||
setError(true);
|
||||
setCloseError(false);
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`${styles.container} ${initpercent === 100 && styles.full} ${className}`} onClick={() => click()}>
|
||||
<div className={`${styles.container} ${percent === 100 && styles.full} ${className}`} onClick={() => click()}>
|
||||
<div className={styles.content} style={ETextStyles.InSb16120}>
|
||||
{initpercent ===100 && <p>Забрать</p>}
|
||||
{initpercent > 0 && <PointsBlock points={points} sizeIcon={20} sizeText={16} />}
|
||||
{initpercent === 0 && !isDev && <div className={styles.imgVolt} style={{backgroundImage: "url('assets/Volt.png')"}}></div>}
|
||||
{initpercent === 0 && !isDev && <p style={ETextStyles.InRg14120}>Больше друзей — быстрее заполнение</p> }
|
||||
{isDev && <p style={ETextStyles.InRg14120}>Скоро откроем</p>}
|
||||
{percent === 100 && <p>Забрать</p>}
|
||||
{percent > 0 && <PointsBlock points={(Number(points).toFixed(2)).toString()} sizeIcon={20} sizeText={16} />}
|
||||
{percent === 0 && <div className={styles.imgVolt} style={{backgroundImage: "url('assets/Volt.png')"}}></div>}
|
||||
{percent === 0 && <p style={ETextStyles.InRg14120}>{!isDev ? 'Больше друзей — быстрее заполнение' : 'Успевай привести друзей без лимитов'}</p> }
|
||||
</div>
|
||||
<div className={styles.scale} style={{ width: `${initpercent}%`}}></div>
|
||||
{showNotif && <Notification title='Пополнение' text={`Баланс баллов увеличен на ${points}`} setShow={setShow} />}
|
||||
<div className={styles.scale} style={{ width: `${percent}%`}}></div>
|
||||
{showNotif && <Notification title='Пополнение' text={`Баланс баллов увеличен на ${savedPoints}`} setShow={setShow} />}
|
||||
{!closeError && <ModalWindow removeBtn={true} setCloseAnimOut={setAnimClose} closeAnimOut={animClose} setClose={setCloseError} modalBlock={
|
||||
<DevPopup setClose={setAnimClose} title='Возникла ошибка' text='Не получилось забрать баллы из реферального хранилища, но скоро всё починим.' />
|
||||
} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -87,6 +87,12 @@ export const ETextStyles = {
|
|||
fontSize: '14px',
|
||||
lineHeight: '120%',
|
||||
},
|
||||
InRg16130: {
|
||||
fontFamily: 'Inter, sans-serif',
|
||||
fontWeight: '400',
|
||||
fontSize: '16px',
|
||||
lineHeight: '130%',
|
||||
},
|
||||
//SemiBold
|
||||
InSb10120: {
|
||||
fontFamily: 'Inter, sans-serif',
|
||||
|
|
|
@ -9,8 +9,10 @@ export interface IUserData {
|
|||
username?: string;
|
||||
name?: string;
|
||||
avatar?: string;
|
||||
points?: string
|
||||
points?: string;
|
||||
energy?: string;
|
||||
referralStorage?: string;
|
||||
maxStorage: number;
|
||||
}
|
||||
|
||||
export const ME_REQUEST = 'ME_REQUEST';
|
||||
|
@ -53,9 +55,15 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
|
|||
const firstName = getState().userTg.firstName;
|
||||
const secondName = getState().userTg.lastName;
|
||||
const token = getState().token;
|
||||
const URL = getState().url;
|
||||
const Url = getState().url;
|
||||
const URLClick = getState().urlClick;
|
||||
const referral = getState().referral;
|
||||
//const referral = getState().referral;
|
||||
let referral = '';
|
||||
const currentUrl = new URL(window.location.href);
|
||||
const referredBy = currentUrl.searchParams.get("referred_by");
|
||||
if (referredBy) {
|
||||
referral = referredBy;
|
||||
}
|
||||
|
||||
const firstClick = (token: string) => {
|
||||
axios.post(`${URLClick}/api/v1/click/`,
|
||||
|
@ -77,9 +85,9 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
|
|||
dispatch(meRequest());
|
||||
let urlUser = '';
|
||||
if (referral.length != 0) {
|
||||
urlUser = `${URL}/api/v1/users/${tgId}?referred_by=${referral}`;
|
||||
urlUser = `${Url}/api/v1/users/${tgId}?referred_by=${referral}`;
|
||||
} else {
|
||||
urlUser = `${URL}/api/v1/users/${tgId}/`;
|
||||
urlUser = `${Url}/api/v1/users/${tgId}/`;
|
||||
}
|
||||
axios.get(urlUser, {
|
||||
headers: {
|
||||
|
@ -132,7 +140,9 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
|
|||
avatar: user.avatar,
|
||||
energy: energy.toString(), //energy
|
||||
points: user.points,
|
||||
name: `${firstName} ${secondName}`
|
||||
name: `${firstName} ${secondName}`,
|
||||
referralStorage: user.referral_storage,
|
||||
maxStorage: Number(user.max_storage)
|
||||
};
|
||||
dispatch(meRequestSuccess(userData));
|
||||
}).catch((err) => {
|
||||
|
@ -152,8 +162,8 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
|
|||
}
|
||||
})
|
||||
}
|
||||
/*if (tgId && URL && !meData.username) {
|
||||
axios.get(`${URL}/api/v1/users/get-token/123456`, {
|
||||
/*if (tgId && Url && !meData.username) {
|
||||
axios.get(`${Url}/api/internal/users/get-token/123456`, {
|
||||
headers: {
|
||||
"Content-type": "application/json"
|
||||
}
|
||||
|
@ -165,9 +175,9 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
|
|||
dispatch(meRequest());
|
||||
let urlUser = '';
|
||||
if (referral.length != 0) {
|
||||
urlUser = `${URL}/api/v1/users/${tgId}?referred_by=${referral}`;
|
||||
urlUser = `${Url}/api/v1/users/${tgId}?referred_by=${referral}`;
|
||||
} else {
|
||||
urlUser = `${URL}/api/v1/users/${tgId}/`;
|
||||
urlUser = `${Url}/api/v1/users/${tgId}/`;
|
||||
}
|
||||
axios.get(urlUser, {
|
||||
headers: {
|
||||
|
@ -178,7 +188,6 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
|
|||
).then((resp) => {
|
||||
const user = resp.data;
|
||||
let avatar = user.avatar;
|
||||
avatar = null;
|
||||
if (!avatar) {
|
||||
avatar = '';
|
||||
}
|
||||
|
@ -221,7 +230,9 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
|
|||
avatar: avatar,
|
||||
energy: energy.toString(), //user.energy
|
||||
points: user.points,
|
||||
name: `${firstName} ${secondName}`
|
||||
name: `${firstName} ${secondName}`,
|
||||
referralStorage: '200', //user.referral_storage
|
||||
maxStorage: Number(user.max_storage)
|
||||
};
|
||||
dispatch(meRequestSuccess(userData));
|
||||
}).catch((err) => {
|
||||
|
@ -249,11 +260,48 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
|
|||
}
|
||||
|
||||
|
||||
export const updateCoinsRequestAsync = (coins: number, energy: number): ThunkAction<void, RootState, unknown, Action<string>> => (dispatch, getState) => {
|
||||
export const updateEnergyRequestAsync = (energy: number): ThunkAction<void, RootState, unknown, Action<string>> => (dispatch, getState) => {
|
||||
const meData = getState().me.data;
|
||||
|
||||
let newData = meData;
|
||||
newData.points = coins.toString();
|
||||
newData.energy = energy.toString();
|
||||
dispatch(meRequestSuccess(newData));
|
||||
}
|
||||
|
||||
export const updatePointsRequestAsync = (): ThunkAction<void, RootState, unknown, Action<string>> => (dispatch, getState) => {
|
||||
const meData = getState().me.data;
|
||||
const tgId = getState().userTg.id;
|
||||
const URL = getState().url;
|
||||
const token = getState().token;
|
||||
|
||||
if(token) {
|
||||
dispatch(meRequest());
|
||||
axios.get(`${URL}/api/v1/users/${tgId}/`, {
|
||||
headers: {
|
||||
"Content-type": "application/json",
|
||||
"Authorization": `TelegramToken ${token}`
|
||||
}
|
||||
},
|
||||
).then(resp => {
|
||||
const user = resp.data;
|
||||
const points = user.points;
|
||||
const newData = meData;
|
||||
newData.points = points;
|
||||
dispatch(meRequestSuccess(newData));
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
dispatch(meRequestError(String(err)));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const emptyReferralStorage = (): ThunkAction<void, RootState, unknown, Action<string>> => (dispatch, getState) => {
|
||||
const meData = getState().me.data;
|
||||
|
||||
let newData = meData;
|
||||
const referralPoints = Number(newData.referralStorage);
|
||||
newData.referralStorage = '0';
|
||||
newData.points = (Number(newData.points) + referralPoints).toString();
|
||||
dispatch(meRequestSuccess(newData));
|
||||
}
|
|
@ -15,7 +15,7 @@ export type RootState = {
|
|||
styleIndex: number,
|
||||
me: MeState,
|
||||
referral: string,
|
||||
mult: number
|
||||
mult: number,
|
||||
};
|
||||
|
||||
//'http://127.0.0.1:8000'
|
||||
|
@ -35,10 +35,12 @@ const initialState: RootState = {
|
|||
me: {
|
||||
loading: false,
|
||||
error: '',
|
||||
data: {}
|
||||
data: {
|
||||
maxStorage: 0
|
||||
}
|
||||
},
|
||||
referral: '',
|
||||
mult: 1
|
||||
mult: 1,
|
||||
};
|
||||
|
||||
export const RESET_STATE = 'RESET_STATE';
|
||||
|
|
22
frontend/src/utils/checkMobile.js
Normal file
22
frontend/src/utils/checkMobile.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
export const checkMobile = () => {
|
||||
const devices = new RegExp(
|
||||
"Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini",
|
||||
"i"
|
||||
);
|
||||
|
||||
if(devices.test(navigator.userAgent)) {
|
||||
return true
|
||||
};
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export const checkIOS = () => {
|
||||
const devicesIpone = new RegExp("iPhone|iPad|iPod", "i");
|
||||
|
||||
if (devicesIpone.test(navigator.userAgent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
|
@ -7,9 +7,7 @@ export const updateBackground = (page) => {
|
|||
back.style.background = 'linear-gradient(180deg, #0D0D0D 0%, #222 100%) fixed';
|
||||
} else if (page === 'auction') {
|
||||
back.style.background = '#0D0D0D';
|
||||
} else if (page === 'referral') {
|
||||
back.style.background = 'linear-gradient(167deg, #000 8.46%, #474747 96.84%) fixed';
|
||||
} else if (page === 'rating') {
|
||||
} else {
|
||||
back.style.background = 'linear-gradient(167deg, #000 8.46%, #474747 96.84%) fixed'
|
||||
}
|
||||
} else if (selectedStyle === 1) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user