add clicks

This commit is contained in:
Arseniy Sitnikov 2024-11-24 21:12:26 +03:00
parent 4352fcd884
commit e9e0729a77
32 changed files with 161 additions and 62 deletions

BIN
frontend/.DS_Store vendored

Binary file not shown.

BIN
frontend/src/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 566 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 532 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

View File

@ -42,11 +42,13 @@ export function ClickerBtn({ coins, setCoins, energy }: IClickerBtn) {
}, [styleIndex]);
const btnClick = () => {
if(!error) {
sendClick();
/*if(!error) {
sendClick();
const newEnergy = initEnergy - 1;
const newFill = (maxEnergy - newEnergy) / maxEnergy * 100;
if (newFill <= 100) {
//sendClick();
sendClick();
const newCoins = coins + 1;
dispatch<any>(updateCoinsRequestAsync(newCoins, newEnergy))
setCoins(newCoins);
@ -68,19 +70,46 @@ export function ClickerBtn({ coins, setCoins, energy }: IClickerBtn) {
}
} else {
sendClick();
}
}*/
};
const sendClick = () => {
if(urlClick && token) {
axios.get(`${urlClick}/click`, {
axios.get(`${urlClick}/api/v1/click`, {
headers: {
"Content-type": "application/json",
//"Content-type": "application/json",
"Authorization": `TelegramToken ${token}`
}
},
).then((resp) => {
console.log(resp);
if(resp.data) {
const click = Number(resp.data.click.value);
//
const newEnergy = initEnergy - click;
const newFill = (maxEnergy - newEnergy) / maxEnergy * 100;
if (newFill <= 100) {
const newCoins = coins + click;
dispatch<any>(updateCoinsRequestAsync(newCoins, newEnergy))
setCoins(newCoins);
setEnergy(newEnergy)
setFill(newFill);
} else {
setFill(100);
}
if (newFill < 100) {
setSize(220);
const timer = setTimeout(() => {
setSize(240);
clearTimeout(timer);
}, 100);
} else {
setClose(false);
}
//
}
if(error) {
setError(false)
}
@ -101,12 +130,12 @@ export function ClickerBtn({ coins, setCoins, energy }: IClickerBtn) {
},
{
title: 'Как продолжить кликать',
text: <span>Чтобы охладиться, нужно перезагрузить систему, нажав по&nbsp;кнопке ниже.</span>,
text: <span>Чтобы охладиться, нужно нужно закрыть приложение, нажав по&nbsp;кнопке ниже.</span>,
img: 'assets/Monocle.png'
},
{
title: 'Что дальше',
text: <span>Система перезагрузится и&nbsp;ты&nbsp;сможешь продолжить поддерживать свою большую концентрацию.</span>,
text: <span>Затем ты&nbsp;сможешь открыть приложение заново и&nbsp;продолжить поддерживать свою большую концентрацию.</span>,
img: 'assets/Rocket.png'
},
];
@ -121,8 +150,8 @@ export function ClickerBtn({ coins, setCoins, energy }: IClickerBtn) {
{gradient}
</defs>
</svg>
{!close && <ModalWindow setCloseAnimOut={setClose} setClose={setClose} modalBlock={
<ClickerPopup title='Кнопка перегрелась' cards={hotCards} setClose={setClose} />
{!close && <ModalWindow setCloseAnimOut={setClose} removeBtn={true} setClose={setClose} modalBlock={
<ClickerPopup title='Кнопка перегрелась' cards={hotCards} setClose={setClose} isBtn={true}/>
} />}
{!closeError && <ModalWindow removeBtn={true} setCloseAnimOut={setAnimClose} closeAnimOut={animClose} setClose={setCloseError} modalBlock={
<DevPopup setClose={setAnimClose} type='error'/>

View File

@ -10,7 +10,7 @@ export function ClickerFooter() {
const navigate = useNavigate();
const [closeAnimOut, setCloseAnimOut] = useState(false);
const [closeDev, setCloseDev] = useState(true);
const isDev = false;
const isDev = true;
return (
<div className={styles.container}>

View File

@ -3,6 +3,7 @@ import styles from './clickerpopup.module.css';
import { ETextStyles } from '../../texts';
import { PopupCard } from '../../Elements/PopupCard';
import { generateRandomString } from '../../../utils/generateRandom';
import { Button } from '../../Button';
interface ICardInterface {
title: string,
@ -14,10 +15,11 @@ interface IClickerPopup {
title: string,
cards: Array<ICardInterface>,
setClose(a: boolean): void,
text ?: string
text ?: string,
isBtn?: boolean
}
export function ClickerPopup({ title, cards, text }: IClickerPopup) {
export function ClickerPopup({ title, cards, text, isBtn=false }: IClickerPopup) {
const blockCards = cards.map((item) => {
return <PopupCard key={generateRandomString()} title={item.title} text={item.text} img={item.img}/>
@ -28,6 +30,13 @@ export function ClickerPopup({ title, cards, text }: IClickerPopup) {
<h2 style={ETextStyles.RwSb24100} className={styles.title}>{title}</h2>
<div className={styles.cards}>{blockCards}</div>
{text && <p className={styles.text}>{text}</p> }
{isBtn && <Button text='Закрыть' onClick={() => {
//@ts-ignore
if (window.Telegram) {
//@ts-ignore
window.Telegram.WebApp.close()
}
}}/>}
</div>
);
}

View File

@ -17,7 +17,7 @@ export function SectionsBlock() {
const [closeAnimOut, setCloseAnimOut] = useState(false);
const [closeDev, setCloseDev] = useState(true);
const isDev = false;
const isDev = true;
const multipCards = [
{

View File

@ -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}`}
className={`${styles.card} ${cardStyle} ${selectedStyle === index && styles.selected} ${index > 0 && styles.disabled}`}
style={{
transform: `rotate(${isActive ? 0 : deg}deg)`,
filter: `blur(${isActive ? 0 : 3}px)`

View File

@ -52,3 +52,18 @@
background-image: url('assets/style4.png');
}
.disabled {
position: relative;
pointer-events: none;
filter: blur(3px) !important;
}
.disabled::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
background-color: rgb(0, 0, 0, 0.3);
filter: blur(25px);
border-radius: 27px;
}

View File

@ -26,9 +26,11 @@ export function RoutePage({ page }: IRoutePage) {
updateStyles();
}, [page]);
//{!verified ? <WrongSourcePage/> :
//}
return (
<div>
{!verified ? <WrongSourcePage/> :
<div>
{page === 'main' && !loadingUser && !errorUser && dataUser.name && dataUser.avatar && <ClickerPage name={dataUser.name} points={Number(dataUser.points)} img={dataUser.avatar} energy={Number(dataUser.energy)}/>}
{page === 'rating' && !loadingUser && !errorUser && <RatingPage />}
@ -37,7 +39,7 @@ export function RoutePage({ page }: IRoutePage) {
{page === 'styles' && !loadingUser && !errorUser && <StylesPage />}
{(loadingUser) && <div className={styles.spinnerContainer}><Spinner color='#FFFFFF' size='50px' thickness='6px' className={styles.spinner} /></div> }
{errorUser && !loadingUser && <ErrorPage detail={errorUser}/>}
</div>}
</div>
</div>
);
}

View File

@ -11,8 +11,10 @@ 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 = ['Черно-синий', 'Grapefruit', 'Tropic mamba', 'Mamba & Grapefruit'];
const stylesNames = ['Черно-синий', 'Скоро будет доступен', 'Скоро будет доступен', 'Скоро будет доступен'];
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%)'];
@ -55,7 +57,7 @@ export function StylesPage() {
<span>Будь круче&nbsp;&mdash;</span> будь на&nbsp;стиле!</h1>
<StylesSwiper selectedStyle={selectedStyle} setCurrentSlide={setCurrentSlide}/>
<p style={ETextStyles.RwSb16120} className={styles.styleName}>{stylesNames[currentSlide]}</p>
<Button onClick={selectStyle} disabled={currentSlide === selectedStyle} text={currentSlide === selectedStyle ? 'Уже выбран' : 'Выбрать этот стиль'} className={styles.btn}/>
{!isDev && <Button onClick={selectStyle} disabled={currentSlide === selectedStyle} text={currentSlide === selectedStyle ? 'Уже выбран' : 'Выбрать этот стиль'} className={styles.btn}/>}
{showNotif && <Notification title={`Стиль ${stylesNames[selectedStyle]} выбран`} text='Можете вернуться на&nbsp;главную, чтобы увидеть изменения' setShow={setShow} />}
</div>
);

View File

@ -17,6 +17,8 @@ export function useTgData() {
if (savedToken.length === 0) {
//@ts-ignore
const [user, token]: [IUserTg, string] = verificationTg();
console.log(`user из useTgData ${user}`);
console.log(`token3 ${token}`);
if (token.length != 0 && user.id && user.id.length != 0) {
setVerified(true);
dispatch<any>(saveToken(token));

View File

@ -53,7 +53,9 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
const secondName = getState().userTg.lastName;
const token = getState().token;
const URL = getState().url;
if (tgId && URL && !meData.avatar && token.length != 0) {
const URLClick = getState().urlClick;
//localStorage.setItem('eg', '500');
/*if (tgId && URL && !meData.avatar && token.length != 0 && URLClick) {
dispatch(meRequest());
axios.get(`${URL}/api/v1/users/${tgId}/`, {
headers: {
@ -65,20 +67,28 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
const user = resp.data;
const encodeToken = btoa(unescape(encodeURIComponent(token)));
const savedToken = localStorage.getItem('sts');
axios.get(`${URLClick}/api/v1/energy`, {
headers: {
//"Content-type": "application/json",
"Authorization": `TelegramToken ${token}`
}
},
).then((resp) => {
const energy = resp.data.energy;
if (savedToken) {
if (savedToken != encodeToken) {
localStorage.setItem('eg', user.energy); //user.energy
localStorage.setItem('eg', '200'); //enegry
localStorage.setItem('sts', encodeToken);
}
} else {
localStorage.setItem('eg', user.energy); //user.energy
localStorage.setItem('eg', '200'); //energy
localStorage.setItem('sts', encodeToken);
}
const userData = {
tgId: user.tg_id,
username: user.username,
avatar: user.avatar,
energy: user.energy, //user.energy
energy: energy.toString(), //energy
points: user.points,
name: `${firstName} ${secondName}`
};
@ -91,9 +101,17 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
dispatch(meRequestError(String(err)));
}
})
}).catch((err) => {
console.log(err);
if (err.response.data.detail) {
dispatch(meRequestError(String(err.response.data.detail)));
} else {
dispatch(meRequestError(String(err)));
}
/*if (tgId && URL && !meData.avatar) {
axios.get(`${URL}/api/v1/users/get-token/1083462027`, {
})
}*/
if (tgId && URL && !meData.avatar) {
axios.get(`${URL}/api/v1/users/get-token/123456`, {
headers: {
"Content-type": "application/json"
}
@ -113,20 +131,28 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
const user = resp.data;
const encodeToken = btoa(unescape(encodeURIComponent(token)));
const savedToken = localStorage.getItem('sts');
axios.get(`${URLClick}/api/v1/energy`, {
headers: {
//"Content-type": "application/json",
"Authorization": `TelegramToken ${token}`
}
},
).then((resp) => {
const energy = resp.data.energy;
if (savedToken) {
if (savedToken != encodeToken) {
localStorage.setItem('eg', user.energy); //user.energy
localStorage.setItem('eg', '200'); //enegry
localStorage.setItem('sts', encodeToken);
}
} else {
localStorage.setItem('eg', user.energy); //user.energy
localStorage.setItem('eg', '200'); //energy
localStorage.setItem('sts', encodeToken);
}
const userData = {
tgId: user.tg_id,
username: user.username,
avatar: user.avatar,
energy: user.energy, //user.energy
energy: energy.toString(), //user.energy
points: user.points,
name: `${firstName} ${secondName}`
};
@ -139,11 +165,20 @@ export const meRequestAsync = (): ThunkAction<void, RootState, unknown, Action<s
dispatch(meRequestError(String(err)));
}
})
}).catch((err) => {
console.log(err);
if (err.response.data.detail) {
dispatch(meRequestError(String(err.response.data.detail)));
} else {
dispatch(meRequestError(String(err)));
}
})
}
}).catch((err) => {
console.log(err);
dispatch(meRequestError(String(err)));
})*/
})
}
}

View File

@ -18,8 +18,8 @@ export type RootState = {
//urlClick: 'http://127.0.0.1:8080',
const initialState: RootState = {
url: '/',
urlClick: '/',
url: '',
urlClick: '',
urlFull: '',
token: '',
userTg: {

View File

@ -6,6 +6,8 @@ export const verificationTg = () => {
};
let token = '';
console.log(`window.Telegram из verification ${window.Telegram}`);
if(window.Telegram) {
const tg = window.Telegram.WebApp;
tg.expand();
@ -39,14 +41,17 @@ export const verificationTg = () => {
token = btoa(
unescape(encodeURIComponent(validation))
);
console.log(`token1 ${token}`);
user.id = tg.initDataUnsafe?.user?.id;
user.firstName = tg.initDataUnsafe?.user?.first_name;
user.lastName = tg.initDataUnsafe?.user?.last_name;
}
console.log(`token2 ${token}`);
//локально
/*token = "TelegramToken";
user.id = "1083462027";
user.id = "123456";
user.firstName = 'User';
user.lastName = 'Name';*/