From 6648f01674ed707612093035c8575ff7d4ef5a61 Mon Sep 17 00:00:00 2001 From: "m::r" Date: Mon, 12 Jan 2026 01:44:41 +0000 Subject: [PATCH] feat(animation): correct/incorrect answer --- src/components/flags/FlagsApi.js | 18 +++- src/components/flags/Profile.js | 8 +- src/components/flags/styles.css | 42 +++++++++ src/components/home/Home.js | 153 +++++++++++++++---------------- src/components/home/styles.css | 41 +++++++++ 5 files changed, 180 insertions(+), 82 deletions(-) diff --git a/src/components/flags/FlagsApi.js b/src/components/flags/FlagsApi.js index 056a9b7..b79bae9 100644 --- a/src/components/flags/FlagsApi.js +++ b/src/components/flags/FlagsApi.js @@ -23,6 +23,10 @@ class FlagsApi extends React.Component { gameEnded = false; answerLocked = false; + state = { + loading: true + }; + async handleClick(action) { if (action === 'api') { const res = await axios.get(api.url+'/api/flags/test'); @@ -115,8 +119,12 @@ class FlagsApi extends React.Component { async startGame() { this.gameEnded = false; this.answerLocked = false; + this.setState({ loading: true }); this.stopTimer(); - await this.handleClick('api').then(() => this.startTimer()).then(() => this.prepareStat()); + await this.handleClick('api') + .then(() => this.startTimer()) + .then(() => this.prepareStat()) + .then(() => this.setState({ loading: false })); } async showFlags() { @@ -249,6 +257,10 @@ class FlagsApi extends React.Component { } render() { + if (this.state.loading) { + return
Fetching question...
; + } + return (
{/*// */} @@ -301,7 +313,9 @@ class FlagsApi extends React.Component { 'margin' : '10px', 'margin-bottom' : '0px' }}> - {this.props.text}  + + {this.props.text}  + Total time: {this.props.sessionTimer}
{ style={{ position: 'absolute', top: '10px', - right: '10px', + right: '15px', background: 'none', border: 'none', - fontSize: '1.5rem', + fontSize: '2rem', + fontWeight: 'bold', cursor: 'pointer', - opacity: 0.5 + opacity: 0.7, + lineHeight: 1 }} aria-label="Close" > diff --git a/src/components/flags/styles.css b/src/components/flags/styles.css index 1eaf718..a71dc7d 100644 --- a/src/components/flags/styles.css +++ b/src/components/flags/styles.css @@ -72,3 +72,45 @@ td:nth-of-type(2){ font-size: 15px; font-weight: bold; } + +/* Feedback animations */ +@keyframes pop-in { + 0% { + transform: scale(0.5); + opacity: 0; + } + 50% { + transform: scale(1.3); + } + 100% { + transform: scale(1); + opacity: 1; + } +} + +@keyframes shake { + 0%, 100% { + transform: translateX(0); + } + 20%, 60% { + transform: translateX(-5px); + } + 40%, 80% { + transform: translateX(5px); + } +} + +.feedback-correct { + display: inline-block; + color: #28a745; + font-weight: bold; + font-size: 1.1em; + animation: pop-in 0.4s ease-out; +} + +.feedback-incorrect { + display: inline-block; + color: #dc3545; + font-weight: bold; + animation: shake 0.4s ease-out; +} diff --git a/src/components/home/Home.js b/src/components/home/Home.js index 2c0e823..fc9728d 100644 --- a/src/components/home/Home.js +++ b/src/components/home/Home.js @@ -1,7 +1,6 @@ import React, {useEffect, useState} from 'react'; import "./styles.css"; import axios from "../../config/Axios"; -import Card from "react-bootstrap/Card"; import api from "../../config/Api"; import Container from "react-bootstrap/Container"; import Col from "react-bootstrap/Col"; @@ -23,15 +22,21 @@ const Home = () => { if (!token) return false; const expiresAt = localStorage.getItem('tokenExpiresAt'); - if (expiresAt) { - // Check if token is expired (with 60s buffer) - if (Date.now() >= parseInt(expiresAt) - 60000) { - // Token expired, clear it - localStorage.removeItem('accessToken'); - localStorage.removeItem('refreshToken'); - localStorage.removeItem('tokenExpiresAt'); - return false; - } + + // Token exists but no expiration - legacy token, treat as expired + if (!expiresAt) { + localStorage.removeItem('accessToken'); + localStorage.removeItem('refreshToken'); + return false; + } + + // Check if token is expired (with 60s buffer) + if (Date.now() >= parseInt(expiresAt) - 60000) { + // Token expired, clear it + localStorage.removeItem('accessToken'); + localStorage.removeItem('refreshToken'); + localStorage.removeItem('tokenExpiresAt'); + return false; } return true; @@ -67,9 +72,9 @@ const Home = () => { {isLoggedIn ? ( <>