add: background, custom topbar

This commit is contained in:
2025-07-07 04:41:17 +05:00
parent 261b9ac253
commit 76917e3f90
11 changed files with 291 additions and 28 deletions

View File

@ -16,7 +16,7 @@ body {
position: relative;
color: white;
height: 100vh;
background: linear-gradient(200.96deg, #000000, #3b4187);
background: linear-gradient(242.94deg, #000000 39.07%, #3b4187 184.73%);
font-family: 'Benzin-Bold' !important;
overflow-y: hidden;
display: flex;

View File

@ -8,6 +8,9 @@ import Login from './pages/Login';
import LaunchPage from './pages/LaunchPage';
import { ReactNode, useEffect, useState } from 'react';
import './App.css';
import TopBar from './components/TopBar';
import { Box } from '@mui/material';
import MinecraftBackround from './components/MinecraftBackround';
// Переместите launchOptions сюда, вне компонентов
const launchOptions = {
@ -71,19 +74,38 @@ const AuthCheck = ({ children }: { children: ReactNode }) => {
};
const App = () => {
// Просто используйте window.open без useNavigate
const handleRegister = () => {
window.open('https://account.ely.by/register', '_blank');
};
return (
<Router>
<Routes>
<Route path="/login" element={<Login />} />
<Route
path="/"
element={
<AuthCheck>
<LaunchPage launchOptions={launchOptions} />
</AuthCheck>
}
/>
</Routes>
<Box
sx={{
height: '100vh',
width: '100vw',
position: 'relative',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}
>
<MinecraftBackround />
<TopBar onRegister={handleRegister} />
<Routes>
<Route path="/login" element={<Login />} />
<Route
path="/"
element={
<AuthCheck>
<LaunchPage launchOptions={launchOptions} />
</AuthCheck>
}
/>
</Routes>
</Box>
</Router>
);
};

View File

@ -0,0 +1,73 @@
import { Box } from '@mui/material';
import heart from '../../../assets/images/heart.svg';
export default function MinecraftBackround() {
return (
<Box
sx={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
opacity: 0.25,
overflow: 'hidden',
}}
>
<Box
sx={{
position: 'absolute',
bottom: 0,
right: 0,
gap: '1vw',
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
rotate: '-20deg',
paddingTop: '30vw',
}}
>
<img
src={heart}
style={{ width: '20vw', height: '20vw', rotate: '-20deg' }}
/>
<img
src={heart}
style={{ width: '20vw', height: '20vw', paddingBottom: '5vw' }}
/>
<img
src={heart}
style={{ width: '20vw', height: '20vw', rotate: '20deg' }}
/>
</Box>
<Box
sx={{
position: 'absolute',
top: 0,
left: 0,
gap: '1vw',
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
rotate: '160deg',
paddingTop: '80vw',
}}
>
<img
src={heart}
style={{ width: '20vw', height: '20vw', rotate: '-20deg' }}
/>
<img
src={heart}
style={{ width: '20vw', height: '20vw', paddingBottom: '5vw' }}
/>
<img
src={heart}
style={{ width: '20vw', height: '20vw', rotate: '20deg' }}
/>
</Box>
</Box>
);
}

View File

@ -0,0 +1,109 @@
import { Box, Button, Typography } from '@mui/material';
import CloseIcon from '@mui/icons-material/Close';
import MinimizeIcon from '@mui/icons-material/Minimize';
import { useLocation } from 'react-router-dom';
declare global {
interface Window {
electron: {
ipcRenderer: {
invoke(channel: string, ...args: unknown[]): Promise<any>;
on(channel: string, func: (...args: unknown[]) => void): void;
removeAllListeners(channel: string): void;
};
};
}
}
// Определяем пропсы
interface TopBarProps {
onRegister?: () => void; // Опционально, если нужен обработчик регистрации
}
export default function TopBar({ onRegister }: TopBarProps) {
// Получаем текущий путь
const location = useLocation();
const isLoginPage = location.pathname === '/login';
return (
<Box
sx={{
display: 'flex',
position: 'absolute',
top: 0,
left: 0,
right: 0,
height: '50px',
zIndex: 1000,
width: '100%',
WebkitAppRegion: 'drag',
overflow: 'hidden',
justifyContent: 'flex-end', // Всё содержимое справа
}}
>
{/* Правая часть со всеми кнопками */}
<Box
sx={{
display: 'flex',
WebkitAppRegion: 'no-drag',
gap: '2vw',
padding: '1em',
alignItems: 'center',
}}
>
{/* Кнопка регистрации, если на странице логина */}
{isLoginPage && (
<Button
variant="outlined"
color="primary"
onClick={() => onRegister && onRegister()}
sx={{
width: '10em',
height: '3em',
borderRadius: '1.5vw',
color: 'white',
backgroundImage: 'linear-gradient(to right, #7BB8FF, #FFB7ED)',
border: 'unset',
'&:hover': {
backgroundImage: 'linear-gradient(to right, #6AA8EE, #EEA7DD)',
},
boxShadow: '0.5em 0.5em 0.5em 0px #00000040 inset',
}}
>
Регистрация
</Button>
)}
{/* Кнопки управления окном */}
<Button
onClick={() => {
window.electron.ipcRenderer.invoke('minimize-app');
}}
sx={{
minWidth: 'unset',
minHeight: 'unset',
width: '3em',
height: '3em',
borderRadius: '50%',
}}
>
<MinimizeIcon sx={{ color: 'white' }} />
</Button>
<Button
onClick={() => {
window.electron.ipcRenderer.invoke('close-app');
}}
sx={{
minWidth: 'unset',
minHeight: 'unset',
width: '3em',
height: '3em',
borderRadius: '50%',
}}
>
<CloseIcon sx={{ color: 'white' }} />
</Button>
</Box>
</Box>
);
}

View File

@ -61,21 +61,25 @@ const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
setDownloadProgress(progress);
setBuffer(Math.min(progress + 10, 100));
};
const statusListener = (...args: unknown[]) => {
const status = args[0] as { step: string; message: string };
setInstallStep(status.step);
setInstallMessage(status.message);
};
window.electron.ipcRenderer.on('download-progress', progressListener);
window.electron.ipcRenderer.on(
'installation-status',
(...args: unknown[]) => {
const status = args[0] as { step: string; message: string };
setInstallStep(status.step);
setInstallMessage(status.message);
},
);
window.electron.ipcRenderer.on('installation-status', statusListener);
return () => {
window.electron.ipcRenderer.removeAllListeners('download-progress');
window.electron.ipcRenderer.removeAllListeners('installation-progress');
window.electron.ipcRenderer.removeAllListeners('installation-status');
// Удаляем только конкретных слушателей, а не всех
// Это безопаснее, чем removeAllListeners
const cleanup = window.electron.ipcRenderer.on;
if (typeof cleanup === 'function') {
cleanup('download-progress', progressListener);
cleanup('installation-status', statusListener);
}
// Удаляем использование removeAllListeners
};
}, [navigate]);