auctions and bugs fixed about top imgs
This commit is contained in:
parent
07915ca426
commit
6ae11e83d6
BIN
frontend/src/.DS_Store
vendored
BIN
frontend/src/.DS_Store
vendored
Binary file not shown.
BIN
frontend/src/shared/.DS_Store
vendored
Normal file
BIN
frontend/src/shared/.DS_Store
vendored
Normal file
Binary file not shown.
|
@ -2,8 +2,6 @@ import React, { useState } from 'react';
|
||||||
import styles from './auctioncard.module.css';
|
import styles from './auctioncard.module.css';
|
||||||
import { ETextStyles } from '../../texts';
|
import { ETextStyles } from '../../texts';
|
||||||
import { PointsBlock } from '../../Elements/PointsBlock';
|
import { PointsBlock } from '../../Elements/PointsBlock';
|
||||||
import { PersonIcon } from '../../Elements/PersonIcon';
|
|
||||||
import { UsersIcons } from '../../Elements/UsersIcons';
|
|
||||||
import { Button } from '../../Button';
|
import { Button } from '../../Button';
|
||||||
import { EIcons } from '../../Icons';
|
import { EIcons } from '../../Icons';
|
||||||
import { Timer } from '../Timer';
|
import { Timer } from '../Timer';
|
||||||
|
@ -12,19 +10,23 @@ import { Slider } from '../../Elements/Slider';
|
||||||
import { ModalWindow } from '../../ModalWindow';
|
import { ModalWindow } from '../../ModalWindow';
|
||||||
import { AuctionPopup } from '../AuctionPopup';
|
import { AuctionPopup } from '../AuctionPopup';
|
||||||
import { ResultAuctionPopup } from '../ResultAuctionPopup';
|
import { ResultAuctionPopup } from '../ResultAuctionPopup';
|
||||||
|
import { DevPopup } from '../../Elements/DevPopup';
|
||||||
|
import { useAppSelector } from '../../hooks/useAppSelector';
|
||||||
|
|
||||||
interface IAuctionCard {
|
interface IAuctionCard {
|
||||||
|
auctionId: string,
|
||||||
name: string,
|
name: string,
|
||||||
imgs: Array<string>,
|
imgs: Array<string>,
|
||||||
minBet: string,
|
|
||||||
users: number,
|
users: number,
|
||||||
prevBet: string,
|
prevBet: string,
|
||||||
myBetInit: string,
|
myBetInit: string,
|
||||||
time: number,
|
time: number,
|
||||||
isLead: boolean
|
isLead: boolean,
|
||||||
|
commission: number,
|
||||||
|
className ?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function AuctionCard({ name, imgs, users, prevBet, myBetInit, time, isLead }: IAuctionCard) {
|
export function AuctionCard({ name, imgs, users, prevBet, myBetInit, time, isLead, commission, auctionId, className }: IAuctionCard) {
|
||||||
const [myBet, setBet] = useState(Number(myBetInit));
|
const [myBet, setBet] = useState(Number(myBetInit));
|
||||||
const [myNewBet, setMyNewBet] = useState(0);
|
const [myNewBet, setMyNewBet] = useState(0);
|
||||||
const [initPrevBet, setPrevBet] = useState(prevBet);
|
const [initPrevBet, setPrevBet] = useState(prevBet);
|
||||||
|
@ -33,9 +35,10 @@ export function AuctionCard({ name, imgs, users, prevBet, myBetInit, time, isLea
|
||||||
const [closeAnim, setCloseAnim] = useState(false);
|
const [closeAnim, setCloseAnim] = useState(false);
|
||||||
const [closeresultPopup, setCloseResultPopup] = useState(true);
|
const [closeresultPopup, setCloseResultPopup] = useState(true);
|
||||||
const styleIndex = Number(localStorage.getItem('selectedStyle'));
|
const styleIndex = Number(localStorage.getItem('selectedStyle'));
|
||||||
|
const [closeErrorBet, setCloseErrorBet] = useState(true);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`${styles.container} ${styleIndex===0 ? styles.darkContainer : styles.opacityContainer}`}>
|
<div className={`${styles.container} ${className} ${styleIndex===0 ? styles.darkContainer : styles.opacityContainer}`}>
|
||||||
<Slider className={styles.slider} imgs={imgs}/>
|
<Slider className={styles.slider} imgs={imgs}/>
|
||||||
<h2 style={ETextStyles.InBd18120} className={styles.title}>{name}</h2>
|
<h2 style={ETextStyles.InBd18120} className={styles.title}>{name}</h2>
|
||||||
<h3 style={ETextStyles.RwSb16120} className={styles.title2}>Подробности аукциона</h3>
|
<h3 style={ETextStyles.RwSb16120} className={styles.title2}>Подробности аукциона</h3>
|
||||||
|
@ -44,13 +47,13 @@ export function AuctionCard({ name, imgs, users, prevBet, myBetInit, time, isLea
|
||||||
<PointsBlock points={initPrevBet} sizeIcon={20}/>
|
<PointsBlock points={initPrevBet} sizeIcon={20}/>
|
||||||
</div>
|
</div>
|
||||||
<div className={`${styles.card} ${styles.cardFlex} ${styles.card2}`}>
|
<div className={`${styles.card} ${styles.cardFlex} ${styles.card2}`}>
|
||||||
<p style={ETextStyles.RwRg14100}>{users === 0 ? 'Ты единственный участник' : 'Участники аукциона'}</p>
|
<p style={ETextStyles.RwRg14100}>Количество победителей</p>
|
||||||
{users === 0 ? <PersonIcon /> : <div className={styles.usersBlock}><UsersIcons/> {users > 3 && <div className={styles.userCount} style={ETextStyles.InSb10120}>{users-3}</div>}</div>}
|
<div className={styles.winnersNumber}>{users}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={`${styles.card} ${initLead && styles.leadCard}`}>
|
<div className={`${styles.card} ${initLead && styles.leadCard}`}>
|
||||||
<div className={styles.cardTop}>
|
<div className={styles.cardTop}>
|
||||||
<div className={styles.cardLeft} style={ETextStyles.RwSb14120}>{!initLead ? 'Успей сделать ставку! До конца осталось:'
|
<div className={styles.cardLeft} style={ETextStyles.RwSb14120}>{initLead ? <p><span>Ты в числе победителей! </span>Но все может поменяться</p>
|
||||||
: <p><span>Ты в числе победителей! </span>Но все может поменяться</p>}</div>
|
: <p>{myBet > 0 ? 'Вашу ставку перебили, повысьте ее, чтобы сохранить лидерство' : 'Успей сделать ставку! До конца осталось:' }</p> }</div>
|
||||||
<Timer initTime={time}/>
|
<Timer initTime={time}/>
|
||||||
</div>
|
</div>
|
||||||
<Button onClick={() => setClose(false)} text={myBet === 0 ? 'Сделать первую ставку' : <div className={styles.newBtn}>
|
<Button onClick={() => setClose(false)} text={myBet === 0 ? 'Сделать первую ставку' : <div className={styles.newBtn}>
|
||||||
|
@ -63,11 +66,14 @@ export function AuctionCard({ name, imgs, users, prevBet, myBetInit, time, isLea
|
||||||
icon={EIcons.UpPriceIcon}/>
|
icon={EIcons.UpPriceIcon}/>
|
||||||
</div>
|
</div>
|
||||||
{!closeWindow && <ModalWindow closeAnimOut={closeAnim} setCloseAnimOut={setCloseAnim} setClose={setClose} removeBtn={true} modalBlock={
|
{!closeWindow && <ModalWindow closeAnimOut={closeAnim} setCloseAnimOut={setCloseAnim} setClose={setClose} removeBtn={true} modalBlock={
|
||||||
<AuctionPopup setLead={setLead} setClose={setCloseAnim} img={imgs[0]} name={name} prevBet={initPrevBet} prevUserImg={''} setBet={setMyNewBet} setCloseResultPopup={setCloseResultPopup}/>
|
<AuctionPopup myBet={myBet} setCloseErrorBet={setCloseErrorBet} auctionId={auctionId} commission={commission} setLead={setLead} setClose={setCloseAnim} img={imgs[0]} name={name} prevBet={initPrevBet} prevUserImg={''} setBet={setMyNewBet} setCloseResultPopup={setCloseResultPopup}/>
|
||||||
} />}
|
} />}
|
||||||
{!closeresultPopup && <ModalWindow closeAnimOut={closeAnim} setCloseAnimOut={setCloseAnim} setClose={setCloseResultPopup} removeBtn={true} modalBlock={
|
{!closeresultPopup && closeErrorBet && <ModalWindow closeAnimOut={closeAnim} setCloseAnimOut={setCloseAnim} setClose={setCloseResultPopup} removeBtn={true} modalBlock={
|
||||||
<ResultAuctionPopup prevBet={initPrevBet} prevMyBet={myBet} newBet={myNewBet} setBet={setBet} setClose={setCloseAnim} setCloseBetWindow={setClose} setPrevBet={setPrevBet}/>
|
<ResultAuctionPopup prevBet={initPrevBet} prevMyBet={myBet} newBet={myNewBet} setBet={setBet} setClose={setCloseAnim} setCloseBetWindow={setClose} setPrevBet={setPrevBet}/>
|
||||||
} />}
|
} />}
|
||||||
|
{!closeErrorBet && <ModalWindow closeAnimOut={closeAnim} setCloseAnimOut={setCloseAnim} setClose={setCloseErrorBet} removeBtn={true} modalBlock={
|
||||||
|
<DevPopup setClose={setCloseAnim} title='Возникла ошибка' text='Не получилось сделать ставку. Но мы скоро всё починим.' />
|
||||||
|
} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,4 +113,14 @@
|
||||||
aspect-ratio: 340/237;
|
aspect-ratio: 340/237;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.winnersNumber {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 27px;
|
||||||
|
height: 27px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: var(--grey34);
|
||||||
}
|
}
|
|
@ -4,6 +4,7 @@ import { useNavigate } from 'react-router-dom';
|
||||||
import { ETextStyles } from '../../texts';
|
import { ETextStyles } from '../../texts';
|
||||||
import { ProductCard } from '../ProductCard';
|
import { ProductCard } from '../ProductCard';
|
||||||
import { Button } from '../../Button';
|
import { Button } from '../../Button';
|
||||||
|
import { generateRandomString } from '../../../utils/generateRandom';
|
||||||
|
|
||||||
interface IProduct {
|
interface IProduct {
|
||||||
name: string,
|
name: string,
|
||||||
|
@ -28,7 +29,7 @@ export function AuctionLosePopup({ items, setClose }: IAuctionLosePopup) {
|
||||||
<h3 className={styles.title2} style={ETextStyles.RwSb18120}>Аукционы, в которых нужно увеличить ставку:</h3>
|
<h3 className={styles.title2} style={ETextStyles.RwSb18120}>Аукционы, в которых нужно увеличить ставку:</h3>
|
||||||
<div className={styles.cards}>
|
<div className={styles.cards}>
|
||||||
{items.map(item => {
|
{items.map(item => {
|
||||||
return <ProductCard name={item.name} img={item.img} bet={item.bet} />
|
return <ProductCard key={ generateRandomString() } name={item.name} img={item.img} bet={item.bet} />
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<Button text='Увеличить ставку' onClick={() => { navigate('/auction'); setClose(true) }} />
|
<Button text='Увеличить ставку' onClick={() => { navigate('/auction'); setClose(true) }} />
|
||||||
|
|
|
@ -1,39 +1,50 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import styles from './auctionmainpopups.module.css';
|
import styles from './auctionmainpopups.module.css';
|
||||||
import { ModalWindow } from '../../ModalWindow';
|
import { ModalWindow } from '../../ModalWindow';
|
||||||
import { AuctionWinPopup } from '../AuctionWinPopup';
|
import { AuctionWinPopup } from '../AuctionWinPopup';
|
||||||
import { AuctionTopPopup } from '../AuctionTopPopup';
|
import { AuctionTopPopup } from '../AuctionTopPopup';
|
||||||
import { AuctionLosePopup } from '../AuctionLosePopup';
|
import { AuctionLosePopup } from '../AuctionLosePopup';
|
||||||
|
import { useAppSelector } from '../../hooks/useAppSelector';
|
||||||
|
import { IAuctionItem } from '../../../store/me/actions';
|
||||||
|
|
||||||
export function AuctionMainPopups() {
|
export function AuctionMainPopups() {
|
||||||
const [closeWin, setCloseWin] = useState(true);
|
const [closeWin, setCloseWin] = useState(true);
|
||||||
const [closeTop, setCloseTop] = useState(true);
|
const [closeTop, setCloseTop] = useState(true);
|
||||||
const [closeLose, setCloseLose] = useState(true);
|
const [closeLose, setCloseLose] = useState(true);
|
||||||
const [closeAnim, setCloseAnim] = useState(false);
|
const [closeAnim, setCloseAnim] = useState(false);
|
||||||
|
const topAuctions = useAppSelector<Array<IAuctionItem> | undefined>(state=>state.me.data.topAuctions);
|
||||||
|
const loseAuctions = useAppSelector<Array<IAuctionItem> | undefined>(state => state.me.data.loseAuctions);
|
||||||
|
|
||||||
const items = [
|
useEffect(() => {
|
||||||
{
|
const show = sessionStorage.getItem('shT');
|
||||||
name: 'iPhone 15 Pro Max',
|
if (show === 't' && closeTop) {
|
||||||
img: '',
|
if (topAuctions && topAuctions.length != 0) {
|
||||||
bet: '788'
|
sessionStorage.setItem('shT', 'f');
|
||||||
},
|
setCloseTop(false);
|
||||||
{
|
}
|
||||||
name: 'iPhone 13 Pro',
|
|
||||||
img: '',
|
|
||||||
bet: '200'
|
|
||||||
}
|
}
|
||||||
];
|
}, [topAuctions]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const show = sessionStorage.getItem('shL');
|
||||||
|
if (show === 't' && closeLose) {
|
||||||
|
if (loseAuctions && loseAuctions.length != 0) {
|
||||||
|
sessionStorage.setItem('shL', 'f');
|
||||||
|
setCloseLose(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [loseAuctions]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{!closeWin && <ModalWindow closeAnimOut={closeAnim} setCloseAnimOut={setCloseAnim} setClose={setCloseWin} removeBtn={true} modalBlock={
|
{!closeWin && <ModalWindow closeAnimOut={closeAnim} setCloseAnimOut={setCloseAnim} setClose={setCloseWin} removeBtn={true} modalBlock={
|
||||||
<AuctionWinPopup name='iPhone 15 Pro Max ' img='' setClose={setCloseAnim}/>
|
<AuctionWinPopup name='iPhone 15 Pro Max ' img='' setClose={setCloseAnim}/>
|
||||||
} />}
|
} />}
|
||||||
{!closeTop && <ModalWindow closeAnimOut={closeAnim} setCloseAnimOut={setCloseAnim} setClose={setCloseTop} removeBtn={true} modalBlock={
|
{!closeTop && topAuctions != undefined && <ModalWindow closeAnimOut={closeAnim} setCloseAnimOut={setCloseAnim} setClose={setCloseTop} removeBtn={true} modalBlock={
|
||||||
<AuctionTopPopup items={items} setClose={setCloseAnim}/>
|
<AuctionTopPopup items={topAuctions} setClose={setCloseAnim}/>
|
||||||
} />}
|
} />}
|
||||||
{!closeLose && <ModalWindow closeAnimOut={closeAnim} setCloseAnimOut={setCloseAnim} setClose={setCloseLose} removeBtn={true} modalBlock={
|
{!closeLose && loseAuctions != undefined && <ModalWindow closeAnimOut={closeAnim} setCloseAnimOut={setCloseAnim} setClose={setCloseLose} removeBtn={true} modalBlock={
|
||||||
<AuctionLosePopup items={items} setClose={setCloseAnim} />
|
<AuctionLosePopup items={loseAuctions} setClose={setCloseAnim} />
|
||||||
} />}
|
} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import styles from './auctionpopup.module.css';
|
import styles from './auctionpopup.module.css';
|
||||||
import { ETextStyles } from '../../texts';
|
import { ETextStyles } from '../../texts';
|
||||||
import { PersonIcon } from '../../Elements/PersonIcon';
|
|
||||||
import { PointsBlock } from '../../Elements/PointsBlock';
|
|
||||||
import { Button } from '../../Button';
|
import { Button } from '../../Button';
|
||||||
import { EIcons } from '../../Icons';
|
import { EIcons } from '../../Icons';
|
||||||
import { declension } from '../../../utils/declension';
|
import { declension } from '../../../utils/declension';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { ProductCard } from '../ProductCard';
|
import { ProductCard } from '../ProductCard';
|
||||||
|
import { useAppSelector } from '../../hooks/useAppSelector';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { updatePointsRequestAsync } from '../../../store/me/actions';
|
||||||
|
import { updateAuction } from '../../../store/auction/actions';
|
||||||
|
|
||||||
interface IAuctionPopup {
|
interface IAuctionPopup {
|
||||||
|
auctionId: string,
|
||||||
setClose(a: boolean): void,
|
setClose(a: boolean): void,
|
||||||
setLead(a: boolean): void,
|
setLead(a: boolean): void,
|
||||||
img: string,
|
img: string,
|
||||||
|
@ -17,16 +21,23 @@ interface IAuctionPopup {
|
||||||
prevBet: string,
|
prevBet: string,
|
||||||
prevUserImg: string,
|
prevUserImg: string,
|
||||||
setBet(a: number): void,
|
setBet(a: number): void,
|
||||||
setCloseResultPopup(a: boolean): void
|
setCloseResultPopup(a: boolean): void,
|
||||||
|
commission: number,
|
||||||
|
setCloseErrorBet(a: boolean): void,
|
||||||
|
myBet: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export function AuctionPopup({ setClose, img, name, prevBet, prevUserImg, setBet, setLead, setCloseResultPopup }: IAuctionPopup) {
|
export function AuctionPopup({ setClose, setCloseErrorBet, auctionId, img, name, prevBet, prevUserImg, setBet, setLead, setCloseResultPopup, commission, myBet }: IAuctionPopup) {
|
||||||
const [value, setValue] = useState<string>('');
|
const [value, setValue] = useState<string>('');
|
||||||
const [disabled, setDis] = useState(true);
|
const [disabled, setDis] = useState(true);
|
||||||
const [autoBet, setAutoBet] = useState(false);
|
const [autoBet, setAutoBet] = useState(false);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const percent = 5;
|
const [percent, setPercent] = useState(commission);
|
||||||
const userPoints = 1000;
|
const userPoints = Number(useAppSelector<string | undefined>(state=>state.me.data.points));
|
||||||
|
const URL = useAppSelector<string>(state=>state.url);
|
||||||
|
const token = useAppSelector<string>(state => state.token);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
|
||||||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
let newValue = event.target.value;
|
let newValue = event.target.value;
|
||||||
|
@ -41,28 +52,43 @@ export function AuctionPopup({ setClose, img, name, prevBet, prevUserImg, setBet
|
||||||
}
|
}
|
||||||
|
|
||||||
const newBet = () => {
|
const newBet = () => {
|
||||||
setBet(Math.floor((1 + percent / 100) * Number(value)));
|
const bet = Number(value);
|
||||||
setClose(true);
|
setClose(true);
|
||||||
setLead(true);
|
|
||||||
|
|
||||||
const timer = setInterval(() => {
|
if (token) {
|
||||||
setCloseResultPopup(false);
|
axios.post(`${URL}/api/v1/auction/auction/${auctionId}/place-bet/?value=${bet}`, {},
|
||||||
clearTimeout(timer);
|
{
|
||||||
}, 400);
|
headers: {
|
||||||
|
"Authorization": `TelegramToken ${token}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).then(resp => {
|
||||||
|
const data = resp.data;
|
||||||
|
dispatch<any>(updatePointsRequestAsync());
|
||||||
|
dispatch<any>(updateAuction(auctionId));
|
||||||
|
setBet(bet);
|
||||||
|
setLead(true);
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
setCloseResultPopup(false);
|
||||||
|
clearTimeout(timer);
|
||||||
|
}, 400);
|
||||||
|
}).catch(err => {
|
||||||
|
setCloseErrorBet(false);
|
||||||
|
})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h2 className={styles.title} style={ETextStyles.RwSb24100}>Сделать ставку</h2>
|
<h2 className={styles.title} style={ETextStyles.RwSb24100}>Сделать ставку</h2>
|
||||||
<ProductCard name={name} img={img} bet={prevBet} personImg={prevUserImg} className={styles.card} />
|
<ProductCard name={name} img={img} bet={prevBet} personImg={prevUserImg} className={styles.card} />
|
||||||
{!autoBet ? <Button onClick={() => { setAutoBet(true), setValue((Number(prevBet) + 5).toString()), setDis(false) }} text='Сразу перебить ставку' className={styles.btnFirst} icon={<div className={styles.icon} style={{ backgroundImage: "url('assets/Rocket.png')" }}></div>} /> :
|
{!autoBet ? <Button onClick={() => { setAutoBet(true), setValue(Number(Number((1 + percent / 100) * Number(prevBet)).toFixed(2)).toString()), setDis(false) }} text='Сразу перебить ставку' className={styles.btnFirst} icon={<div className={styles.icon} style={{ backgroundImage: "url('assets/Rocket.png')" }}></div>} /> :
|
||||||
<button style={ETextStyles.InBd14120} className={styles.btnCancel} onClick={() => setClose(true)}>Не перебивать</button>
|
<button style={ETextStyles.InBd14120} className={styles.btnCancel} onClick={() => setClose(true)}>Не перебивать</button>
|
||||||
}
|
}
|
||||||
<p className={styles.descr} style={ETextStyles.RwRg10140}>Наши алгоритмы автоматически рассчитают стоимость, чтобы ваша ставка стала самой высокой</p>
|
<p className={styles.descr} style={ETextStyles.RwRg10140}>Наши алгоритмы автоматически рассчитают стоимость, чтобы ваша ставка стала самой высокой</p>
|
||||||
<h3 className={styles.title2} style={ETextStyles.InSb14120}>{!autoBet ? 'Ввести свою цену' : 'Цена, чтобы перебить ставку'}</h3>
|
<h3 className={styles.title2} style={ETextStyles.InSb14120}>{!autoBet ? 'Ввести свою цену' : 'Цена, чтобы перебить ставку'}</h3>
|
||||||
<input style={ETextStyles.InSb14120} className={styles.input} value={value} type="text" onChange={handleChange} inputMode="numeric" />
|
<input style={ETextStyles.InSb14120} className={styles.input} value={value} type="text" onChange={handleChange} inputMode="numeric" />
|
||||||
{(Math.floor((1 + percent / 100) * Number(value)) < userPoints) ? ((Number(value) < Number(prevBet) && value.length > 0) ?
|
{(Number(Number((1 + percent / 100) * Number(value))) - myBet < userPoints) ? ((Number(value) < Number(prevBet) && value.length > 0) ?
|
||||||
<button className={styles.btnForbidden}>
|
<button className={styles.btnForbidden}>
|
||||||
<p style={ETextStyles.InBd14120}>Ставка должна быть больше</p>
|
<p style={ETextStyles.InBd14120}>Ставка должна быть больше</p>
|
||||||
<p style={ETextStyles.InRg12140} className={styles.textForbidden}>Нельзя сделать ставку меньше предыдущей</p>
|
<p style={ETextStyles.InRg12140} className={styles.textForbidden}>Нельзя сделать ставку меньше предыдущей</p>
|
||||||
|
@ -70,7 +96,7 @@ export function AuctionPopup({ setClose, img, name, prevBet, prevUserImg, setBet
|
||||||
: <Button onClick={() => newBet()} disabled={disabled} text={disabled ? 'Перебить ставку' : <div className={styles.newBtn}>
|
: <Button onClick={() => newBet()} disabled={disabled} text={disabled ? 'Перебить ставку' : <div className={styles.newBtn}>
|
||||||
<p>Перебить ставку</p>
|
<p>Перебить ставку</p>
|
||||||
<div className={styles.btnText}>
|
<div className={styles.btnText}>
|
||||||
<p style={ETextStyles.InRg12140}>{`${declension(value, 'коин', 'коина', 'коинов', true)} + ${percent}% = ${declension(Math.floor((1 + percent / 100) * Number(value)), 'коин', 'коина', 'коинов', true)}`}</p>
|
<p style={ETextStyles.InRg12140}>{`${declension(value, 'коин', 'коина', 'коинов', true)} + ${percent}% = ${declension(Number(Number((1 + percent / 100) * Number(value)).toFixed(2)), 'коин', 'коина', 'коинов', true)}`}</p>
|
||||||
<div className={styles.icon} style={{ backgroundImage: "url('assets/btnIcon.png')" }}></div>
|
<div className={styles.icon} style={{ backgroundImage: "url('assets/btnIcon.png')" }}></div>
|
||||||
</div>
|
</div>
|
||||||
</div>}
|
</div>}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { ETextStyles } from '../../texts';
|
||||||
import { ProductCard } from '../ProductCard';
|
import { ProductCard } from '../ProductCard';
|
||||||
import { Button } from '../../Button';
|
import { Button } from '../../Button';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { generateRandomString } from '../../../utils/generateRandom';
|
||||||
|
|
||||||
interface IProduct {
|
interface IProduct {
|
||||||
name: string,
|
name: string,
|
||||||
|
@ -20,7 +21,7 @@ export function AuctionTopPopup({ items, setClose }: IAuctionTopPopup) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className='top'>
|
||||||
<div className={styles.iconBlock}>
|
<div className={styles.iconBlock}>
|
||||||
<div className={styles.icon} style={{ backgroundImage: "url('assets/Fire.png')" }}></div>
|
<div className={styles.icon} style={{ backgroundImage: "url('assets/Fire.png')" }}></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -29,7 +30,7 @@ export function AuctionTopPopup({ items, setClose }: IAuctionTopPopup) {
|
||||||
<h3 className={styles.title2} style={ETextStyles.RwSb18120}>Аукционы, в которых вы лидируете:</h3>
|
<h3 className={styles.title2} style={ETextStyles.RwSb18120}>Аукционы, в которых вы лидируете:</h3>
|
||||||
<div className={styles.cards}>
|
<div className={styles.cards}>
|
||||||
{items.map(item => {
|
{items.map(item => {
|
||||||
return <ProductCard name={item.name} img={item.img} bet={item.bet} />
|
return <ProductCard key={ generateRandomString() } name={item.name} img={item.img} bet={item.bet} />
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<Button text='Продолжить кликать' onClick={() => { navigate('/'); setClose(true)}}/>
|
<Button text='Продолжить кликать' onClick={() => { navigate('/'); setClose(true)}}/>
|
||||||
|
|
|
@ -18,12 +18,17 @@ interface IResultAuctionPopup {
|
||||||
export function ResultAuctionPopup({ prevBet, prevMyBet, newBet, setBet, setClose, setCloseBetWindow, setPrevBet }: IResultAuctionPopup) {
|
export function ResultAuctionPopup({ prevBet, prevMyBet, newBet, setBet, setClose, setCloseBetWindow, setPrevBet }: IResultAuctionPopup) {
|
||||||
const [diff, setDiff] = useState(0);
|
const [diff, setDiff] = useState(0);
|
||||||
const [prevBetOld, setPrevBetOld] = useState(prevBet);
|
const [prevBetOld, setPrevBetOld] = useState(prevBet);
|
||||||
|
const [prevMyOldBet, setPrevMyOld] = useState(prevMyBet);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setDiff(newBet - prevMyBet);
|
if (prevMyOldBet > 0) {
|
||||||
|
setDiff(newBet - prevMyOldBet);
|
||||||
|
} else {
|
||||||
|
setDiff(newBet - Number(prevBetOld));
|
||||||
|
}
|
||||||
setBet(newBet);
|
setBet(newBet);
|
||||||
setPrevBet(newBet.toString())
|
setPrevBet(newBet.toString());
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onClick = () => {
|
const onClick = () => {
|
||||||
|
@ -40,7 +45,7 @@ export function ResultAuctionPopup({ prevBet, prevMyBet, newBet, setBet, setClos
|
||||||
<div className={styles.icon} style={{backgroundImage: 'url("assets/Money.png")'}}></div>
|
<div className={styles.icon} style={{backgroundImage: 'url("assets/Money.png")'}}></div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.text} style={ETextStyles.InSb24100}>
|
<div className={styles.text} style={ETextStyles.InSb24100}>
|
||||||
Вы <span>увеличили</span> ставку <span>{`на ${diff}`}</span> {declension(diff, 'коин', 'коина', 'коинов')}
|
Вы <span>{prevMyOldBet > 0 ? 'увеличили' : 'перебили'}</span> ставку <span>{`на ${diff.toFixed(2)}`}</span> {declension(diff.toFixed(2), 'коин', 'коина', 'коинов')}
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.cards}>
|
<div className={styles.cards}>
|
||||||
<div className={styles.card}>
|
<div className={styles.card}>
|
||||||
|
|
|
@ -40,7 +40,7 @@ export function Timer({initTime}: ITimer) {
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.dot}></div>
|
<div className={styles.dot}></div>
|
||||||
<div className={styles.block}>
|
<div className={styles.block}>
|
||||||
<p className={styles.value} style={ETextStyles.InSb14120}>{min}</p>
|
<p className={styles.value} style={ETextStyles.InSb14120}>{min.toString().length === 1 ? `0${min}` : min}</p>
|
||||||
<p className={styles.text} style={ETextStyles.RwRg12120}>мин</p>
|
<p className={styles.text} style={ETextStyles.RwRg12120}>мин</p>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.dot}></div>
|
<div className={styles.dot}></div>
|
||||||
|
|
|
@ -17,10 +17,11 @@ interface IClickerBtn {
|
||||||
clickTime: number,
|
clickTime: number,
|
||||||
sameCoords: boolean,
|
sameCoords: boolean,
|
||||||
setSameCoords(a: boolean): void,
|
setSameCoords(a: boolean): void,
|
||||||
closeAutoClick: boolean
|
closeAutoClick: boolean,
|
||||||
|
setSameInterval(a: boolean): void,
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ClickerBtn({ setCoins, closeAutoClick, energy, setMult, coins, setEnergy, setClickTime, clickTime, setSameCoords }: IClickerBtn) {
|
export function ClickerBtn({ setCoins, setSameInterval, closeAutoClick, energy, setMult, coins, setEnergy, setClickTime, clickTime, setSameCoords }: IClickerBtn) {
|
||||||
const [fill, setFill] = useState(0);
|
const [fill, setFill] = useState(0);
|
||||||
const [size, setSize] = useState(240);
|
const [size, setSize] = useState(240);
|
||||||
const circumference = 2 * Math.PI * 125;
|
const circumference = 2 * Math.PI * 125;
|
||||||
|
@ -33,6 +34,7 @@ export function ClickerBtn({ setCoins, closeAutoClick, energy, setMult, coins, s
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [prevClickTime, setPrevClickTime] = useState(0);
|
const [prevClickTime, setPrevClickTime] = useState(0);
|
||||||
const [prevCoords, setPrevCoords] = useState(0);
|
const [prevCoords, setPrevCoords] = useState(0);
|
||||||
|
const [clickInterval, setClickInterval] = useState(0);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if(!closeAutoClick) {
|
if(!closeAutoClick) {
|
||||||
|
@ -78,9 +80,17 @@ export function ClickerBtn({ setCoins, closeAutoClick, energy, setMult, coins, s
|
||||||
setPrevCoords(coords);
|
setPrevCoords(coords);
|
||||||
|
|
||||||
const currentTime = Date.now();
|
const currentTime = Date.now();
|
||||||
const clickInterval = currentTime - prevClickTime;
|
const clickIntervalInit = currentTime - prevClickTime;
|
||||||
|
if (clickInterval != 0) {
|
||||||
|
if (clickInterval === clickIntervalInit) {
|
||||||
|
setSameInterval(true)
|
||||||
|
} else {
|
||||||
|
setSameInterval(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(prevClickTime != 0) {
|
if(prevClickTime != 0) {
|
||||||
setClickTime(clickTime + clickInterval);
|
setClickTime(clickTime + clickIntervalInit);
|
||||||
}
|
}
|
||||||
setPrevClickTime(currentTime);
|
setPrevClickTime(currentTime);
|
||||||
|
|
||||||
|
@ -136,7 +146,7 @@ export function ClickerBtn({ setCoins, closeAutoClick, energy, setMult, coins, s
|
||||||
{gradient}
|
{gradient}
|
||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>
|
||||||
{!close && !closeAutoClick && <ModalWindow setCloseAnimOut={setClose} removeBtn={true} setClose={setClose} modalBlock={
|
{!close && closeAutoClick && <ModalWindow setCloseAnimOut={setClose} removeBtn={true} setClose={setClose} modalBlock={
|
||||||
<ClickerPopup title='Кнопка перегрелась' cards={hotCards} setClose={setClose} isBtn={true}/>
|
<ClickerPopup title='Кнопка перегрелась' cards={hotCards} setClose={setClose} isBtn={true}/>
|
||||||
} />}
|
} />}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import styles from './clickerfooter.module.css';
|
import styles from './clickerfooter.module.css';
|
||||||
import { ClickerBtnFooter } from '../ClickerBtnFooter';
|
import { ClickerBtnFooter } from '../ClickerBtnFooter';
|
||||||
import { EIcons, Icon } from '../../Icons';
|
import { EIcons, Icon } from '../../Icons';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { isWhiteList } from '../../../utils/isWhiteList';
|
||||||
|
|
||||||
export function ClickerFooter() {
|
export function ClickerFooter() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const isDev = true;
|
const [isDev, setIsDev] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsDev(!isWhiteList());
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
|
|
|
@ -26,9 +26,11 @@ interface IPointsZoom {
|
||||||
setCloseAutoClick(a: boolean): void,
|
setCloseAutoClick(a: boolean): void,
|
||||||
sameCoords: boolean,
|
sameCoords: boolean,
|
||||||
setSameCoords(a: boolean): void,
|
setSameCoords(a: boolean): void,
|
||||||
|
setSameInterval(a: boolean): void,
|
||||||
|
sameInterval: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PointsZoom({ points, sameCoords, setSameCoords, setCloseAutoClick, setMult, setClose, setCoins, className, closePointsAnim, setClosePointsAnim, setCloseError, setEnergy, clickTime, setClickTime }: IPointsZoom) {
|
export function PointsZoom({ points, sameInterval, setSameInterval, sameCoords, setSameCoords, setCloseAutoClick, setMult, setClose, setCoins, className, closePointsAnim, setClosePointsAnim, setCloseError, setEnergy, clickTime, setClickTime }: IPointsZoom) {
|
||||||
const [open, setOpen] = useState(true);
|
const [open, setOpen] = useState(true);
|
||||||
const node = document.querySelector('#modal_root');
|
const node = document.querySelector('#modal_root');
|
||||||
const urlClick = useAppSelector<string>(state => state.urlClick);
|
const urlClick = useAppSelector<string>(state => state.urlClick);
|
||||||
|
@ -36,6 +38,7 @@ export function PointsZoom({ points, sameCoords, setSameCoords, setCloseAutoClic
|
||||||
const [sizeHand, setSizeHand] = useState(30);
|
const [sizeHand, setSizeHand] = useState(30);
|
||||||
const energy = Number(useAppSelector<string | undefined>(state => state.me.data.energy));
|
const energy = Number(useAppSelector<string | undefined>(state => state.me.data.energy));
|
||||||
const userData = useAppSelector<IUserData>(state => state.me.data);
|
const userData = useAppSelector<IUserData>(state => state.me.data);
|
||||||
|
const URL = useAppSelector<string>(state => state.url);
|
||||||
if (!node) return null;
|
if (!node) return null;
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
@ -43,6 +46,7 @@ export function PointsZoom({ points, sameCoords, setSameCoords, setCloseAutoClic
|
||||||
const initPoints = points;
|
const initPoints = points;
|
||||||
const clickTimeInit = clickTime;
|
const clickTimeInit = clickTime;
|
||||||
let initSameCoords = sameCoords;
|
let initSameCoords = sameCoords;
|
||||||
|
let initSameInterval = sameInterval;
|
||||||
let avtTime = 500;
|
let avtTime = 500;
|
||||||
if (points > 1) {
|
if (points > 1) {
|
||||||
avtTime = clickTimeInit / (initPoints - 1);
|
avtTime = clickTimeInit / (initPoints - 1);
|
||||||
|
@ -50,10 +54,21 @@ export function PointsZoom({ points, sameCoords, setSameCoords, setCloseAutoClic
|
||||||
|
|
||||||
setClickTime(0);
|
setClickTime(0);
|
||||||
setSameCoords(false);
|
setSameCoords(false);
|
||||||
|
|
||||||
|
if ((avtTime < 100 && initSameCoords) || (initSameInterval) && initPoints > 20) {
|
||||||
|
|
||||||
if (avtTime < 100 && initSameCoords && points > 40) {
|
/*axios.post(`${URL}/api/v1/users/warn/`, {}, {
|
||||||
|
headers: {
|
||||||
|
"Authorization": `TelegramToken ${token}`
|
||||||
|
}
|
||||||
|
}).then(resp => {
|
||||||
|
console.log(resp);
|
||||||
|
}).catch(err => {
|
||||||
|
//console.log(err)
|
||||||
|
})*/
|
||||||
sendAutoClickData(userData.tgId, points, avtTime);
|
sendAutoClickData(userData.tgId, points, avtTime);
|
||||||
setCloseAutoClick(false);
|
setCloseAutoClick(false);
|
||||||
|
setSameInterval(false);
|
||||||
const returnEnergy = energy + initPoints;
|
const returnEnergy = energy + initPoints;
|
||||||
setEnergy(returnEnergy);
|
setEnergy(returnEnergy);
|
||||||
dispatch<any>(updateEnergyRequestAsync(returnEnergy));
|
dispatch<any>(updateEnergyRequestAsync(returnEnergy));
|
||||||
|
|
|
@ -65,6 +65,8 @@ export function SectionsBlock({ mult }: ISectionsBlock) {
|
||||||
img: 'assets/Chain.png'
|
img: 'assets/Chain.png'
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
//<UsersIcons imgs={topImgs} size={16}/>
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.sectionContainer}>
|
<div className={styles.sectionContainer}>
|
||||||
|
@ -75,7 +77,6 @@ export function SectionsBlock({ mult }: ISectionsBlock) {
|
||||||
<span className={styles.rank1}>#</span>
|
<span className={styles.rank1}>#</span>
|
||||||
<span>{isDev ? '?' : (userRank ? formatNumber(userRank) : '?')}</span>
|
<span>{isDev ? '?' : (userRank ? formatNumber(userRank) : '?')}</span>
|
||||||
</div>
|
</div>
|
||||||
<UsersIcons imgs={topImgs} size={16}/>
|
|
||||||
</div>}
|
</div>}
|
||||||
</CardSection>
|
</CardSection>
|
||||||
<CardSection title='Множитель' onClick={() => { setClose(false) }}>
|
<CardSection title='Множитель' onClick={() => { setClose(false) }}>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styles from './usersicons.module.css';
|
import styles from './usersicons.module.css';
|
||||||
import { PersonIcon } from '../PersonIcon';
|
import { PersonIcon } from '../PersonIcon';
|
||||||
|
import { EIcons, Icon } from '../../Icons';
|
||||||
|
|
||||||
interface IUsersIcons {
|
interface IUsersIcons {
|
||||||
size?: number,
|
size?: number,
|
||||||
|
@ -11,9 +12,15 @@ interface IUsersIcons {
|
||||||
export function UsersIcons({ size = 25, imgs = [], className = '' }: IUsersIcons) {
|
export function UsersIcons({ size = 25, imgs = [], className = '' }: IUsersIcons) {
|
||||||
return (
|
return (
|
||||||
<div className={`${styles.users} ${className}`} style={{height: `${size}px`, width: `${size*2.5}px`}}>
|
<div className={`${styles.users} ${className}`} style={{height: `${size}px`, width: `${size*2.5}px`}}>
|
||||||
<PersonIcon className={`${styles.userIcon} ${styles.userIcon1}`} size={size} img={imgs[0] ? imgs[0] : ''}/>
|
<div className={`${styles.userIcon} ${styles.userIcon1}`}>
|
||||||
<PersonIcon className={`${styles.userIcon} ${styles.userIcon2}`} size={size} left={size / 1.4} img={imgs[1] ? imgs[1] : ''} />
|
<Icon icon={EIcons.MedalFirst}/>
|
||||||
<PersonIcon className={`${styles.userIcon} ${styles.userIcon3}`} size={size} left={2 * size / 1.4} img={imgs[2] ? imgs[2] : ''} />
|
</div>
|
||||||
|
<div className={`${styles.userIcon} ${styles.userIcon2}`}>
|
||||||
|
<Icon icon={EIcons.MedalSecond} />
|
||||||
|
</div>
|
||||||
|
<div className={`${styles.userIcon} ${styles.userIcon3}`}>
|
||||||
|
<Icon icon={EIcons.MedalThird} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.userIcon {
|
.userIcon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
border-radius: 50%;
|
width: 20px;
|
||||||
background-color: var(--grey6C);
|
height: 20px;
|
||||||
border: 1px solid var(--grey12);
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.userIcon1 {
|
.userIcon1 {
|
||||||
|
@ -17,8 +20,10 @@
|
||||||
|
|
||||||
.userIcon2 {
|
.userIcon2 {
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
left: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.userIcon3 {
|
.userIcon3 {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
left: 28px;
|
||||||
}
|
}
|
|
@ -10,9 +10,10 @@ interface IModalWindow {
|
||||||
removeBtn ?: boolean,
|
removeBtn ?: boolean,
|
||||||
closeAnimOut?: boolean,
|
closeAnimOut?: boolean,
|
||||||
setCloseAnimOut(a: boolean): void,
|
setCloseAnimOut(a: boolean): void,
|
||||||
|
isReload?: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ModalWindow({ modalBlock, setClose, removeBtn, closeAnimOut, setCloseAnimOut }: IModalWindow) {
|
export function ModalWindow({ modalBlock, setClose, removeBtn, closeAnimOut, setCloseAnimOut, isReload=false }: IModalWindow) {
|
||||||
const node = document.querySelector('#modal_root');
|
const node = document.querySelector('#modal_root');
|
||||||
const [closeAnim, setCloseAnim] = useState(false);
|
const [closeAnim, setCloseAnim] = useState(false);
|
||||||
const html = document.querySelector('html');
|
const html = document.querySelector('html');
|
||||||
|
@ -34,6 +35,9 @@ export function ModalWindow({ modalBlock, setClose, removeBtn, closeAnimOut, set
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
setClose(true);
|
setClose(true);
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
|
if(isReload) {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
}, 400);
|
}, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,39 @@
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import styles from './auctionpage.module.css';
|
import styles from './auctionpage.module.css';
|
||||||
import { ETextStyles } from '../../texts';
|
import { ETextStyles } from '../../texts';
|
||||||
import { AuctionCard } from '../../Auction/AuctionCard';
|
import { AuctionCard } from '../../Auction/AuctionCard';
|
||||||
|
import { useAuctionData } from '../../hooks/useAuctionData';
|
||||||
|
import { Spinner } from '../../Elements/Spinner';
|
||||||
|
import { ErrorPage } from '../ErrorPage';
|
||||||
|
|
||||||
export function AuctionPage() {
|
export function AuctionPage() {
|
||||||
const imgs = ['https://cdn.dribbble.com/userupload/11863775/file/original-6009708366fadd352f61fbaf0db5acee.png?resize=1200x853',
|
const { dataAuction, loadingAuction, errorAuction } = useAuctionData();
|
||||||
'https://cdn.dribbble.com/userupload/10040892/file/original-850d482568c1f1c870b7066113903bd2.png?resize=1200x900',
|
const [auctionBlock, setAuctionBlock] = useState( <div></div> );
|
||||||
'https://cdn.dribbble.com/users/9735273/screenshots/19338580/media/6657322ea7990bd504427ed1b171be3d.png?resize=1200x900']
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(dataAuction.length != 0) {
|
||||||
|
const newBlock = dataAuction.map(item => {
|
||||||
|
if (item.productName && item.productCover && item.initialCost && item.time && item.winnersNumber && item.commission && item.id && item.isLead != undefined && item.myBet != undefined)
|
||||||
|
return <AuctionCard className={styles.card} auctionId={item.id} key={`${item.id}${JSON.stringify(dataAuction)}`} name={item.productName} imgs={[item.productCover]} users={item.winnersNumber} prevBet={item.initialCost} myBetInit={item.myBet} time={item.time} isLead={item.isLead} commission={item.commission}/>
|
||||||
|
});
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
setAuctionBlock(newBlock);
|
||||||
|
}
|
||||||
|
}, [dataAuction]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h1 className={styles.title} style={ETextStyles.RwSb26100}> <span>Соревнуйся за товары</span> на аукционе!</h1>
|
{loadingAuction && <div className={styles.spinnerContainer}><Spinner color='#FFFFFF' size='40px' thickness='6px' className={styles.spinner} /></div>}
|
||||||
<AuctionCard name='iPhone 15 Pro Max, 256gb, Natural Titanium' imgs={imgs} minBet='200' users={23} prevBet='290' myBetInit='0' time={86400} isLead={false}/>
|
{!loadingAuction && <div>
|
||||||
|
{errorAuction ? <ErrorPage fullScreen={true} title='Возникла ошибка загрузки аукционов' text='Перезагрузите страницу или попробуйте позже' detail={errorAuction} /> :
|
||||||
|
<div>
|
||||||
|
<h1 className={styles.title} style={ETextStyles.RwSb26100}> <span>Соревнуйся за товары</span> на аукционе!</h1>
|
||||||
|
{auctionBlock}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,4 +4,16 @@
|
||||||
|
|
||||||
.title span {
|
.title span {
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinnerContainer {
|
||||||
|
display: flex;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
margin-bottom: 24px;
|
||||||
}
|
}
|
|
@ -11,6 +11,8 @@ import { useWindowSize } from 'usehooks-ts';
|
||||||
import { useAppSelector } from '../../hooks/useAppSelector';
|
import { useAppSelector } from '../../hooks/useAppSelector';
|
||||||
import { ModalWindow } from '../../ModalWindow';
|
import { ModalWindow } from '../../ModalWindow';
|
||||||
import { DevPopup } from '../../Elements/DevPopup';
|
import { DevPopup } from '../../Elements/DevPopup';
|
||||||
|
import { AuctionMainPopups } from '../../Auction/AuctionMainPopups';
|
||||||
|
import { useAuctionData } from '../../hooks/useAuctionData';
|
||||||
|
|
||||||
interface IClickerPageInterface {
|
interface IClickerPageInterface {
|
||||||
name: string,
|
name: string,
|
||||||
|
@ -33,6 +35,17 @@ export function ClickerPage({ name, points, img, energy }: IClickerPageInterface
|
||||||
const [clickTime, setClickTime] = useState(0);
|
const [clickTime, setClickTime] = useState(0);
|
||||||
const [closeAutoClick, setCloseAutoClick] = useState(true);
|
const [closeAutoClick, setCloseAutoClick] = useState(true);
|
||||||
const [sameCoords, setSameCoords] = useState(false);
|
const [sameCoords, setSameCoords] = useState(false);
|
||||||
|
const [sameInterval, setSameInterval] = useState(false);
|
||||||
|
useAuctionData();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const html = document.querySelector('html');
|
||||||
|
|
||||||
|
if(html) {
|
||||||
|
html.style.overflow = 'scroll';
|
||||||
|
}
|
||||||
|
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setMult(savedMult);
|
setMult(savedMult);
|
||||||
|
@ -57,13 +70,13 @@ export function ClickerPage({ name, points, img, energy }: IClickerPageInterface
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<div className={styles.records}>
|
<div className={styles.records}>
|
||||||
{!closePoints && <PointsZoom sameCoords={sameCoords} setSameCoords={setSameCoords} setCloseAutoClick={setCloseAutoClick} setClickTime={setClickTime} clickTime={clickTime} setMult={setMult} setEnergy={setInitEnergy} setCloseError={setCloseError} setCoins={setCoins} points={coins} setClosePointsAnim={setClosePointsAnim} setClose={setClosePoints} className={styles.pointsAnim} closePointsAnim={closePointsAnim}/>}
|
{!closePoints && <PointsZoom sameInterval={sameInterval} setSameInterval={setSameInterval} sameCoords={sameCoords} setSameCoords={setSameCoords} setCloseAutoClick={setCloseAutoClick} setClickTime={setClickTime} clickTime={clickTime} setMult={setMult} setEnergy={setInitEnergy} setCloseError={setCloseError} setCoins={setCoins} points={coins} setClosePointsAnim={setClosePointsAnim} setClose={setClosePoints} className={styles.pointsAnim} closePointsAnim={closePointsAnim}/>}
|
||||||
<Profile name={name} className={styles.profile} img={img}/>
|
<Profile name={name} className={styles.profile} img={img}/>
|
||||||
<h1 style={ETextStyles.RwSb24100} className={styles.title}>Мои рекорды</h1>
|
<h1 style={ETextStyles.RwSb24100} className={styles.title}>Мои рекорды</h1>
|
||||||
<SectionsBlock mult={mult}/>
|
<SectionsBlock mult={mult}/>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.clicker} style={{height: `${height > 670 && 'calc(100vh - 355px)'}`}}>
|
<div className={styles.clicker} style={{height: `${height > 670 && 'calc(100vh - 355px)'}`}}>
|
||||||
<ClickerBtn closeAutoClick={closeAutoClick} sameCoords={sameCoords} setSameCoords={setSameCoords} clickTime={clickTime} setClickTime={setClickTime} setEnergy={setInitEnergy} coins={coins} setCoins={setCoins} energy={initEnergy} setMult={setMult}/>
|
<ClickerBtn setSameInterval={setSameInterval} closeAutoClick={closeAutoClick} sameCoords={sameCoords} setSameCoords={setSameCoords} clickTime={clickTime} setClickTime={setClickTime} setEnergy={setInitEnergy} coins={coins} setCoins={setCoins} energy={initEnergy} setMult={setMult}/>
|
||||||
</div>
|
</div>
|
||||||
<ClickerFooter />
|
<ClickerFooter />
|
||||||
{styleIndex != 0 && <div>
|
{styleIndex != 0 && <div>
|
||||||
|
@ -75,6 +88,7 @@ export function ClickerPage({ name, points, img, energy }: IClickerPageInterface
|
||||||
{!closeAutoClick && <ModalWindow removeBtn={true} setCloseAnimOut={setAnimClose} closeAnimOut={animClose} setClose={setCloseAutoClick} modalBlock={
|
{!closeAutoClick && <ModalWindow removeBtn={true} setCloseAnimOut={setAnimClose} closeAnimOut={animClose} setClose={setCloseAutoClick} modalBlock={
|
||||||
<DevPopup setClose={setAnimClose} title='Кажется, вы используете автокликер...' text='Ваши клики не отправлены. Давайте играть честно.' img='assets/police.gif'/>
|
<DevPopup setClose={setAnimClose} title='Кажется, вы используете автокликер...' text='Ваши клики не отправлены. Давайте играть честно.' img='assets/police.gif'/>
|
||||||
} />}
|
} />}
|
||||||
|
<AuctionMainPopups/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
18
frontend/src/shared/hooks/useAuctionData.ts
Normal file
18
frontend/src/shared/hooks/useAuctionData.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useAppSelector } from './useAppSelector';
|
||||||
|
import { IAuction, auctionRequestAsync } from '../../store/auction/actions';
|
||||||
|
|
||||||
|
export function useAuctionData() {
|
||||||
|
const dataAuction = useAppSelector<Array<IAuction>>(state => state.auction.data);
|
||||||
|
const loadingAuction = useAppSelector<boolean>(state => state.auction.loading);
|
||||||
|
const errorAuction = useAppSelector<String>(state => state.auction.error);
|
||||||
|
const token = useAppSelector<string>(state => state.token);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
dispatch<any>(auctionRequestAsync());
|
||||||
|
}, [token]);
|
||||||
|
|
||||||
|
return { dataAuction, loadingAuction, errorAuction };
|
||||||
|
}
|
245
frontend/src/store/auction/actions.ts
Normal file
245
frontend/src/store/auction/actions.ts
Normal file
|
@ -0,0 +1,245 @@
|
||||||
|
import { Action, ActionCreator } from "redux";
|
||||||
|
import { ThunkAction } from "redux-thunk";
|
||||||
|
import { RootState } from "../reducer";
|
||||||
|
import axios from "axios";
|
||||||
|
import { updateMyAuctions } from "../me/actions";
|
||||||
|
|
||||||
|
export interface IAuction {
|
||||||
|
id?: string,
|
||||||
|
commission?: number,
|
||||||
|
time?: number,
|
||||||
|
initialCost?: string,
|
||||||
|
productId?: string,
|
||||||
|
productCover?: string,
|
||||||
|
productName?: string,
|
||||||
|
winnersNumber?: number,
|
||||||
|
isLead?: boolean,
|
||||||
|
myBet?: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AUCTION_REQUEST = 'AUCTION_REQUEST';
|
||||||
|
|
||||||
|
export type AuctionRequestAction = {
|
||||||
|
type: typeof AUCTION_REQUEST
|
||||||
|
};
|
||||||
|
|
||||||
|
export const auctionRequest: ActionCreator<AuctionRequestAction> = () => ({
|
||||||
|
type: AUCTION_REQUEST,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const AUCTION_REQUEST_SUCCESS = 'AUCTION_REQUEST_SUCCESS';
|
||||||
|
|
||||||
|
export type AuctionRequestSuccessAction = {
|
||||||
|
type: typeof AUCTION_REQUEST_SUCCESS;
|
||||||
|
data: Array<IAuction>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const auctionRequestSuccess: ActionCreator<AuctionRequestSuccessAction> = (data: Array<IAuction>) => ({
|
||||||
|
type: AUCTION_REQUEST_SUCCESS,
|
||||||
|
data
|
||||||
|
});
|
||||||
|
|
||||||
|
export const AUCTION_REQUEST_ERROR = 'AUCTION_REQUEST_ERROR';
|
||||||
|
|
||||||
|
export type AuctionRequestErrorAction = {
|
||||||
|
type: typeof AUCTION_REQUEST_ERROR;
|
||||||
|
error: String;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const auctionRequestError: ActionCreator<AuctionRequestErrorAction> = (error: String) => ({
|
||||||
|
type: AUCTION_REQUEST_ERROR,
|
||||||
|
error
|
||||||
|
});
|
||||||
|
|
||||||
|
export const auctionRequestAsync = (): ThunkAction<void, RootState, unknown, Action<string>> => (dispatch, getState) => {
|
||||||
|
const URL = getState().url;
|
||||||
|
const token = getState().token;
|
||||||
|
const userTg = getState().userTg.id;
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
axios.get(`${URL}/api/v1/auction/auction?is_active=true`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Authorization": `TelegramToken ${token}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).then(resp => {
|
||||||
|
const data = resp.data.results;
|
||||||
|
|
||||||
|
axios.get(`${URL}/api/v1/auction/bet?order_by=-value&is_winning=true`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Authorization": `TelegramToken ${token}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).then(resp2 => {
|
||||||
|
const dataBet = resp2.data.results;
|
||||||
|
const auctionResults: Array<IAuction> = [];
|
||||||
|
|
||||||
|
axios.get(`${URL}/api/v1/auction/bet?user=${userTg}&order_by=-value`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Authorization": `TelegramToken ${token}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).then(resp3 => {
|
||||||
|
const userData = resp3.data.results;
|
||||||
|
const topAuctions = [];
|
||||||
|
const loseAuctions = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
const nowDate = new Date();
|
||||||
|
const endDate = new Date(data[i].end_time);
|
||||||
|
const time = Math.ceil(Math.abs(endDate.getTime() - nowDate.getTime()) / 1000);
|
||||||
|
let maxBet = Number(data[i].initial_cost);
|
||||||
|
let isLead = false;
|
||||||
|
let myBet = 0;
|
||||||
|
|
||||||
|
if (dataBet.length != 0) {
|
||||||
|
for (let k = 0; k < dataBet.length; k++) {
|
||||||
|
if (dataBet[k].auction === data[i].id) {
|
||||||
|
if (Number(dataBet[k].value) > maxBet) {
|
||||||
|
maxBet = Number(dataBet[k].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Number(dataBet[k].user.tg_id) === Number(userTg)) {
|
||||||
|
|
||||||
|
isLead = true;
|
||||||
|
|
||||||
|
const topItem = {
|
||||||
|
name: data[i].product.name,
|
||||||
|
img: data[i].product.cover,
|
||||||
|
bet: dataBet[k].value
|
||||||
|
}
|
||||||
|
|
||||||
|
topAuctions.push(topItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userData.length != 0) {
|
||||||
|
for (let z = 0; z < userData.length; z++) {
|
||||||
|
if (userData[z].auction === data[i].id) {
|
||||||
|
if (Number(userData[z].value) > myBet) {
|
||||||
|
myBet = Number(userData[z].value);
|
||||||
|
|
||||||
|
if(!isLead) {
|
||||||
|
const loseItem = {
|
||||||
|
name: data[i].product.name,
|
||||||
|
img: data[i].product.cover,
|
||||||
|
bet: userData[z].value
|
||||||
|
}
|
||||||
|
|
||||||
|
loseAuctions.push(loseItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const item = {
|
||||||
|
id: data[i].id,
|
||||||
|
initialCost: maxBet.toString(),
|
||||||
|
commission: Number(data[i].commission) * 100,
|
||||||
|
time: time,
|
||||||
|
winnersNumber: data[i].quantity,
|
||||||
|
productId: data[i].product.id,
|
||||||
|
productName: data[i].product.name,
|
||||||
|
productCover: data[i].product.cover,
|
||||||
|
isLead: isLead,
|
||||||
|
myBet: myBet.toString()
|
||||||
|
};
|
||||||
|
|
||||||
|
auctionResults.push(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(updateMyAuctions(topAuctions, 'top'));
|
||||||
|
dispatch(updateMyAuctions(loseAuctions, 'lose'));
|
||||||
|
|
||||||
|
dispatch(auctionRequestSuccess(auctionResults));
|
||||||
|
})
|
||||||
|
|
||||||
|
}).catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
if (err.response.data.detail) {
|
||||||
|
dispatch(auctionRequestError(String(err.response.data.detail)));
|
||||||
|
} else {
|
||||||
|
dispatch(auctionRequestError(String(err)));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
if (err.response.data.detail) {
|
||||||
|
dispatch(auctionRequestError(String(err.response.data.detail)));
|
||||||
|
} else {
|
||||||
|
dispatch(auctionRequestError(String(err)));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const updateAuction = (id: string): ThunkAction<void, RootState, unknown, Action<string>> => (dispatch, getState) => {
|
||||||
|
const auctionData = getState().auction.data;
|
||||||
|
const URL = getState().url;
|
||||||
|
const token = getState().token;
|
||||||
|
const userTg = getState().userTg.id;
|
||||||
|
let newData = auctionData;
|
||||||
|
|
||||||
|
axios.get(`${URL}/api/v1/auction/bet?order_by=-value&is_winning=true&auction=${id}`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Authorization": `TelegramToken ${token}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).then(resp => {
|
||||||
|
const dataBet = resp.data.results;
|
||||||
|
let maxBet = 0;
|
||||||
|
let isLead = false;
|
||||||
|
|
||||||
|
if (dataBet.length != 0) {
|
||||||
|
for (let i = 0; i < dataBet.length; i++) {
|
||||||
|
if (Number(dataBet[i].value) > maxBet) {
|
||||||
|
maxBet = Number(dataBet[i].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Number(dataBet[i].user.tg_id) === Number(userTg)) {
|
||||||
|
isLead = true;
|
||||||
|
newData[i].isLead = isLead;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
axios.get(`${URL}/api/v1/auction/bet?auction=${id}&user=${userTg}&order_by=-value`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Authorization": `TelegramToken ${token}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).then(resp2 => {
|
||||||
|
const data = resp2.data.results;
|
||||||
|
let myBet = 0;
|
||||||
|
|
||||||
|
if (data.length != 0) {
|
||||||
|
myBet = Number(dataBet[0].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//обновляем данные
|
||||||
|
for (let i = 0; i < newData.length; i++) {
|
||||||
|
if (newData[i].id === id) {
|
||||||
|
if (myBet != 0) {
|
||||||
|
newData[i].myBet = myBet.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxBet != 0) {
|
||||||
|
newData[i].initialCost = maxBet.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dispatch(auctionRequestSuccess(newData));
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
36
frontend/src/store/auction/reducer.ts
Normal file
36
frontend/src/store/auction/reducer.ts
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import { Reducer } from 'react';
|
||||||
|
import { AUCTION_REQUEST, AUCTION_REQUEST_ERROR, AUCTION_REQUEST_SUCCESS, AuctionRequestAction, AuctionRequestErrorAction, AuctionRequestSuccessAction, IAuction } from './actions';
|
||||||
|
|
||||||
|
export type AuctionState = {
|
||||||
|
loading: boolean,
|
||||||
|
error: String,
|
||||||
|
data: Array<IAuction>
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuctionAction = AuctionRequestAction | AuctionRequestSuccessAction | AuctionRequestErrorAction;
|
||||||
|
|
||||||
|
export const auctionReducer: Reducer<AuctionState, AuctionAction> = (state, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case AUCTION_REQUEST:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
loading: true,
|
||||||
|
error: ''
|
||||||
|
};
|
||||||
|
case AUCTION_REQUEST_ERROR:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
error: action.error,
|
||||||
|
loading: false,
|
||||||
|
};
|
||||||
|
case AUCTION_REQUEST_SUCCESS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
data: action.data,
|
||||||
|
loading: false,
|
||||||
|
error: ''
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,12 @@ import axios from "axios";
|
||||||
import { saveMult } from "../mult";
|
import { saveMult } from "../mult";
|
||||||
import { saveToken } from "../token";
|
import { saveToken } from "../token";
|
||||||
|
|
||||||
|
export interface IAuctionItem {
|
||||||
|
name: string,
|
||||||
|
img: string,
|
||||||
|
bet: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface IUserData {
|
export interface IUserData {
|
||||||
tgId?: number;
|
tgId?: number;
|
||||||
username?: string;
|
username?: string;
|
||||||
|
@ -14,7 +20,9 @@ export interface IUserData {
|
||||||
energy?: string;
|
energy?: string;
|
||||||
referralStorage?: string;
|
referralStorage?: string;
|
||||||
maxStorage: number;
|
maxStorage: number;
|
||||||
rank ?: number
|
rank ?: number,
|
||||||
|
loseAuctions?: Array<IAuctionItem>,
|
||||||
|
topAuctions?: Array<IAuctionItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ME_REQUEST = 'ME_REQUEST';
|
export const ME_REQUEST = 'ME_REQUEST';
|
||||||
|
@ -117,6 +125,8 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
|
||||||
const savedToken = sessionStorage.getItem('tk');
|
const savedToken = sessionStorage.getItem('tk');
|
||||||
if (savedToken) {
|
if (savedToken) {
|
||||||
if (savedToken != encodeToken) {
|
if (savedToken != encodeToken) {
|
||||||
|
sessionStorage.setItem('shT', 't');
|
||||||
|
sessionStorage.setItem('shL', 't');
|
||||||
sessionStorage.setItem('tk', encodeToken);
|
sessionStorage.setItem('tk', encodeToken);
|
||||||
firstClick(token);
|
firstClick(token);
|
||||||
const energyCode = btoa(energy.toString());
|
const energyCode = btoa(energy.toString());
|
||||||
|
@ -170,7 +180,7 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/*if (tgId && Url && !meData.username) {
|
/*if (tgId && Url && !meData.username) {
|
||||||
axios.get(`${Url}/api/internal/users/get-token/123456`, {
|
axios.get(`${Url}/api/internal/users/get-token/${tgId}`, {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-type": "application/json"
|
"Content-type": "application/json"
|
||||||
}
|
}
|
||||||
|
@ -211,6 +221,8 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
|
||||||
const savedToken = sessionStorage.getItem('tk');
|
const savedToken = sessionStorage.getItem('tk');
|
||||||
if (savedToken) {
|
if (savedToken) {
|
||||||
if (savedToken != encodeToken) {
|
if (savedToken != encodeToken) {
|
||||||
|
sessionStorage.setItem('shT', 't');
|
||||||
|
sessionStorage.setItem('shL', 't');
|
||||||
sessionStorage.setItem('tk', encodeToken);
|
sessionStorage.setItem('tk', encodeToken);
|
||||||
firstClick(token);
|
firstClick(token);
|
||||||
const energyCode = btoa(energy.toString());
|
const energyCode = btoa(energy.toString());
|
||||||
|
@ -295,6 +307,7 @@ export const updatePointsRequestAsync = (): ThunkAction<void, RootState, unknown
|
||||||
const newData = meData;
|
const newData = meData;
|
||||||
newData.points = points;
|
newData.points = points;
|
||||||
dispatch(meRequestSuccess(newData));
|
dispatch(meRequestSuccess(newData));
|
||||||
|
dispatch(loadNewRank());
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
dispatch(meRequestError(String(err)));
|
dispatch(meRequestError(String(err)));
|
||||||
|
@ -319,4 +332,44 @@ export const updateRank = (rank: number): ThunkAction<void, RootState, unknown,
|
||||||
let newData = meData;
|
let newData = meData;
|
||||||
newData.rank = rank;
|
newData.rank = rank;
|
||||||
dispatch(meRequestSuccess(newData));
|
dispatch(meRequestSuccess(newData));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const loadNewRank = (): ThunkAction<void, RootState, unknown, Action<string>> => (dispatch, getState) => {
|
||||||
|
const token = getState().token;
|
||||||
|
const URL = getState().url;
|
||||||
|
const userTg = getState().userTg.id;
|
||||||
|
|
||||||
|
if(token) {
|
||||||
|
axios.get(`${URL}/api/v1/users/rank/neighbours?limit=1`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Authorization": `TelegramToken ${token}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).then(resp => {
|
||||||
|
const data = resp.data;
|
||||||
|
if(data.length != 0) {
|
||||||
|
|
||||||
|
for(let i = 0; i<data.length; i++) {
|
||||||
|
if (Number(data[i].tg_id) === Number(userTg)) {
|
||||||
|
dispatch<any>(updateRank(Number(data[i].rank)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const updateMyAuctions = (data: Array<IAuctionItem>, type: string): ThunkAction<void, RootState, unknown, Action<string>> => (dispatch, getState) => {
|
||||||
|
const meData = getState().me.data;
|
||||||
|
let newData = meData;
|
||||||
|
|
||||||
|
if(type === 'top') {
|
||||||
|
newData.topAuctions = data;
|
||||||
|
} else {
|
||||||
|
newData.loseAuctions = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(meRequestSuccess(newData));
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ import { RankState, friendsReducer } from './friends/reducer';
|
||||||
import { FRIENDS_REQUEST, FRIENDS_REQUEST_ERROR, FRIENDS_REQUEST_SUCCESS } from './friends/actions';
|
import { FRIENDS_REQUEST, FRIENDS_REQUEST_ERROR, FRIENDS_REQUEST_SUCCESS } from './friends/actions';
|
||||||
import { RANK_REQUEST, RANK_REQUEST_ERROR, RANK_REQUEST_SUCCESS } from './rank/actions';
|
import { RANK_REQUEST, RANK_REQUEST_ERROR, RANK_REQUEST_SUCCESS } from './rank/actions';
|
||||||
import { rankReducer } from './rank/reducer';
|
import { rankReducer } from './rank/reducer';
|
||||||
|
import { AuctionState, auctionReducer } from './auction/reducer';
|
||||||
|
import { AUCTION_REQUEST, AUCTION_REQUEST_ERROR, AUCTION_REQUEST_SUCCESS } from './auction/actions';
|
||||||
|
|
||||||
export type RootState = {
|
export type RootState = {
|
||||||
url: string,
|
url: string,
|
||||||
|
@ -22,6 +24,7 @@ export type RootState = {
|
||||||
mult: number,
|
mult: number,
|
||||||
friends: RankState,
|
friends: RankState,
|
||||||
rank: RankState,
|
rank: RankState,
|
||||||
|
auction: AuctionState
|
||||||
};
|
};
|
||||||
|
|
||||||
//'http://127.0.0.1:8000'
|
//'http://127.0.0.1:8000'
|
||||||
|
@ -55,6 +58,11 @@ const initialState: RootState = {
|
||||||
error: '',
|
error: '',
|
||||||
data: []
|
data: []
|
||||||
},
|
},
|
||||||
|
auction: {
|
||||||
|
loading: false,
|
||||||
|
error: '',
|
||||||
|
data: []
|
||||||
|
},
|
||||||
referral: '',
|
referral: '',
|
||||||
mult: 1,
|
mult: 1,
|
||||||
};
|
};
|
||||||
|
@ -108,6 +116,13 @@ export const rootReducer: Reducer<RootState> = (state = initialState, action) =>
|
||||||
...state,
|
...state,
|
||||||
rank: rankReducer(state.rank, action)
|
rank: rankReducer(state.rank, action)
|
||||||
};
|
};
|
||||||
|
case AUCTION_REQUEST:
|
||||||
|
case AUCTION_REQUEST_SUCCESS:
|
||||||
|
case AUCTION_REQUEST_ERROR:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
auction: auctionReducer(state.auction, action)
|
||||||
|
};
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ export const isWhiteList = () => {
|
||||||
//123456,
|
//123456,
|
||||||
const whiteList = [
|
const whiteList = [
|
||||||
342495217, 6374536117, 322861155, 5219438370, 193428034, 402449803,
|
342495217, 6374536117, 322861155, 5219438370, 193428034, 402449803,
|
||||||
406350282
|
406350282, 1083462027
|
||||||
];
|
];
|
||||||
|
|
||||||
const userId = Number(getTgUserId());
|
const userId = Number(getTgUserId());
|
||||||
|
|
Loading…
Reference in New Issue
Block a user