frontend: add Loading

This commit is contained in:
tylen 2025-11-02 13:50:44 +02:00
parent 98e5ef06c0
commit cf9b0d53c1
6 changed files with 83 additions and 3 deletions

View File

@ -5,6 +5,7 @@ import Hosting from './components/Hosting';
import InitialSetup from './components/InitialSetup'; import InitialSetup from './components/InitialSetup';
import Program from './components/Program'; import Program from './components/Program';
import Snowflakes from './components/Snowflakes'; import Snowflakes from './components/Snowflakes';
import { FullScreenLoading } from './components/Loading';
function App() { function App() {
const [isNavOpen, setIsNavOpen] = useState(false); const [isNavOpen, setIsNavOpen] = useState(false);
@ -15,6 +16,7 @@ function App() {
return ( return (
<> <>
<FullScreenLoading/>
<Snowflakes /> <Snowflakes />
<InitialSetup /> <InitialSetup />

View File

@ -4,6 +4,7 @@ import { GUESTS } from '../constants/constants';
import useFetchUser from '../utils/fetchUser'; // Import your custom hook import useFetchUser from '../utils/fetchUser'; // Import your custom hook
import { useNotification } from '../NotificationContext'; import { useNotification } from '../NotificationContext';
import ApologyMessage from './Attendance'; import ApologyMessage from './Attendance';
import {Loading} from './Loading';
const InitialSetup = () => { const InitialSetup = () => {
const [cookie, setCookie] = useCookies(); const [cookie, setCookie] = useCookies();
@ -14,7 +15,7 @@ const InitialSetup = () => {
const [isPasswordSet, setIsPasswordSet] = useState(false); // To track if password is set const [isPasswordSet, setIsPasswordSet] = useState(false); // To track if password is set
const [userAttendance, setUserAttendance] = useState<boolean | null>(null); const [userAttendance, setUserAttendance] = useState<boolean | null>(null);
const { userSet, passwordCreate, signUser, validToken, getAttendance } = useFetchUser(); // Destructure functions from the hook const { userSet, passwordCreate, signUser, validToken, getAttendance, isLoading } = useFetchUser(); // Destructure functions from the hook
const notify = useNotification(); const notify = useNotification();
const checkUserPassword = async (name: string) => { const checkUserPassword = async (name: string) => {
@ -76,6 +77,14 @@ const InitialSetup = () => {
) )
} }
if (isLoading) {
return (
<div style={styles.container}>
<Loading/>
</div>
)
}
return ( return (
<div style={styles.container}> <div style={styles.container}>
<h2 style={styles.title}>Выбери себя</h2> <h2 style={styles.title}>Выбери себя</h2>

View File

@ -0,0 +1,29 @@
.spinner {
font-size: 100px; /* Adjust size as needed */
animation: spin 2s linear infinite; /* Spin animation */
position: fixed; /* Keep the snowflake in a fixed position */
top: 50%; /* Adjust vertical position */
left: 50%; /* Center horizontally */
transform: translateX(-50%); /* Center the snowflake */
z-index: 10000; /* Ensure it's above the full-screen loading */
}
/* Keyframes for spinning */
@keyframes spin {
0% { transform: translateX(-50%) rotate(0deg); }
100% { transform: translateX(-50%) rotate(360deg); }
}
.full-screen {
display: flex; /* Use flexbox for centering */
align-items: center; /* Center vertically */
justify-content: center; /* Center horizontally */
height: 100vh; /* Full viewport height */
width: 100vw; /* Full viewport width */
background-color: rgba(4, 0, 0); /* Semi-transparent background */
position: fixed; /* Fix it in the viewport */
top: 0;
left: 0;
z-index: 9999; /* Ensure it's above other content */
}

View File

@ -0,0 +1,34 @@
import React, { useEffect, useState } from 'react';
import './Loading.css'; // Import CSS for styling
export const Loading: React.FC = () => {
return (
<div className="spinner">
🎅🏻
</div>
);
};
export const FullScreenLoading: React.FC = () => {
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
// Set a timeout to change the loading state
const timer = setTimeout(() => {
setIsLoading(false);
}, 1000); // 1000 ms = 1 second
// Cleanup function to clear the timeout if the component unmounts
return () => clearTimeout(timer);
}, []); // Empty dependency array means it runs once on mount
if (!isLoading) {
return null;
}
return (
<div className="full-screen">
<Loading />
</div>
)
}

View File

@ -6,7 +6,7 @@
height: 100%; height: 100%;
pointer-events: none; /* Make snowflakes non-interactive */ pointer-events: none; /* Make snowflakes non-interactive */
overflow: hidden; /* Hide overflow */ overflow: hidden; /* Hide overflow */
z-index: 1000; /* Ensure snowflakes are above other content */ z-index: 998; /* Ensure snowflakes are above other content */
} }
.snowflake { .snowflake {

View File

@ -1,14 +1,18 @@
import { useCookies } from 'react-cookie'; import { useCookies } from 'react-cookie';
import { API_URL } from '../constants/constants'; import { API_URL } from '../constants/constants';
import { hashPassword } from './hashPassword'; import { hashPassword } from './hashPassword';
import { useState } from 'react';
const useFetchUser = () => { const useFetchUser = () => {
const [isLoading, setIsLoading] = useState(false)
const [apiCookie, setApiCookie] = useCookies(['apiToken']); const [apiCookie, setApiCookie] = useCookies(['apiToken']);
const [, setUserNameCookie] = useCookies(['userName']) const [, setUserNameCookie] = useCookies(['userName'])
const userSet = async (userName: string): Promise<boolean> => { const userSet = async (userName: string): Promise<boolean> => {
try { try {
setIsLoading(true)
const response = await fetch(`${API_URL}/users/isSet?userName=${encodeURIComponent(userName)}`); const response = await fetch(`${API_URL}/users/isSet?userName=${encodeURIComponent(userName)}`);
setIsLoading(false)
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const data = await response.json(); const data = await response.json();
return data; // Assuming the server returns true/false return data; // Assuming the server returns true/false
@ -84,6 +88,7 @@ const useFetchUser = () => {
const validToken = async (token: string | undefined): Promise<boolean> => { const validToken = async (token: string | undefined): Promise<boolean> => {
try { try {
setIsLoading(true)
const response = await fetch(`${API_URL}/login/validateToken`, { const response = await fetch(`${API_URL}/login/validateToken`, {
method: 'POST', method: 'POST',
headers: { headers: {
@ -93,6 +98,7 @@ const useFetchUser = () => {
token token
}), }),
}); });
setIsLoading(false)
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const data = await response.json(); const data = await response.json();
@ -156,7 +162,7 @@ const useFetchUser = () => {
} }
} }
return { userSet, passwordCreate, signUser, validToken, updateAttendance, getAttendance }; return { userSet, passwordCreate, signUser, validToken, updateAttendance, getAttendance, isLoading };
}; };
export default useFetchUser; export default useFetchUser;